From c822f66bb83eaa0baf90ce662375c0b0aefb9dec Mon Sep 17 00:00:00 2001 From: Germano Cavalcante Date: Mon, 7 Dec 2020 17:36:11 -0300 Subject: Fix T83307: Some modal keys of transform operators don't correspond to the expected effect The transform modes `shrinkfatten` and `seq_slide` have a special way of handling events. They use modal events in a different way than expected. Therefore, this commit adds special event handles for these modes and removes the keymodal tips from the status bar. These effects are already described in the header anyway. --- source/blender/editors/transform/transform.c | 18 ++++++++---------- .../transform/transform_mode_edge_seq_slide.c | 21 +++++++++++++++++++-- .../transform/transform_mode_shrink_fatten.c | 19 ++++++++++++++++++- 3 files changed, 45 insertions(+), 13 deletions(-) (limited to 'source/blender/editors') diff --git a/source/blender/editors/transform/transform.c b/source/blender/editors/transform/transform.c index 5969de5b5da..2b56b30be90 100644 --- a/source/blender/editors/transform/transform.c +++ b/source/blender/editors/transform/transform.c @@ -637,6 +637,14 @@ static bool transform_modal_item_poll(const wmOperator *op, int value) } break; } + case TFM_MODAL_TRANSLATE: + case TFM_MODAL_ROTATE: + case TFM_MODAL_RESIZE: { + if (!transform_mode_is_changeable(t->mode)) { + return false; + } + break; + } } return true; } @@ -876,11 +884,6 @@ int transformEvent(TransInfo *t, const wmEvent *event) handled = true; } } - else if (t->mode == TFM_SEQ_SLIDE) { - t->flag ^= T_ALT_TRANSFORM; - t->redraw |= TREDRAW_HARD; - handled = true; - } else if (transform_mode_is_changeable(t->mode)) { restoreTransObjects(t); resetTransModal(t); @@ -922,11 +925,6 @@ int transformEvent(TransInfo *t, const wmEvent *event) handled = true; } } - else if (t->mode == TFM_SHRINKFATTEN) { - t->flag ^= T_ALT_TRANSFORM; - t->redraw |= TREDRAW_HARD; - handled = true; - } else if (transform_mode_is_changeable(t->mode)) { /* Scale isn't normally very useful after extrude along normals, see T39756 */ if ((t->con.mode & CON_APPLY) && (t->orient[t->orient_curr].type == V3D_ORIENT_NORMAL)) { diff --git a/source/blender/editors/transform/transform_mode_edge_seq_slide.c b/source/blender/editors/transform/transform_mode_edge_seq_slide.c index dfa5c164acf..1682b5bfe31 100644 --- a/source/blender/editors/transform/transform_mode_edge_seq_slide.c +++ b/source/blender/editors/transform/transform_mode_edge_seq_slide.c @@ -32,6 +32,7 @@ #include "ED_screen.h" #include "WM_api.h" +#include "WM_types.h" #include "UI_interface.h" @@ -45,6 +46,18 @@ /** \name Transform (Sequencer Slide) * \{ */ +static eRedrawFlag seq_slide_handleEvent(struct TransInfo *t, const wmEvent *event) +{ + BLI_assert(t->mode == TFM_SEQ_SLIDE); + wmKeyMapItem *kmi = t->custom.mode.data; + if (event->type == kmi->type && event->val == kmi->val) { + /* Allows the 'Expand to fit' effect to be enabled as a toogle. */ + t->flag ^= T_ALT_TRANSFORM; + return TREDRAW_HARD; + } + return TREDRAW_NOTHING; +} + static void headerSeqSlide(TransInfo *t, const float val[2], char str[UI_MAX_DRAW_STR]) { char tvec[NUM_STR_REP_LEN * 3]; @@ -61,7 +74,7 @@ static void headerSeqSlide(TransInfo *t, const float val[2], char str[UI_MAX_DRA str + ofs, UI_MAX_DRAW_STR - ofs, TIP_("Sequence Slide: %s%s, ("), &tvec[0], t->con.text); if (t->keymap) { - wmKeyMapItem *kmi = WM_modalkeymap_find_propvalue(t->keymap, TFM_MODAL_TRANSLATE); + wmKeyMapItem *kmi = t->custom.mode.data; if (kmi) { ofs += WM_keymap_item_to_string(kmi, false, str + ofs, UI_MAX_DRAW_STR - ofs); } @@ -91,7 +104,7 @@ static void applySeqSlideValue(TransInfo *t, const float val[2]) static void applySeqSlide(TransInfo *t, const int mval[2]) { char str[UI_MAX_DRAW_STR]; - float values_final[2] = {0.0f}; + float values_final[3] = {0.0f}; snapSequenceBounds(t, mval); if (applyNumInput(&t->num, values_final)) { @@ -126,6 +139,7 @@ static void applySeqSlide(TransInfo *t, const int mval[2]) void initSeqSlide(TransInfo *t) { t->transform = applySeqSlide; + t->handleEvent = seq_slide_handleEvent; initMouseInputMode(t, &t->mouse, INPUT_VECTOR); @@ -142,5 +156,8 @@ void initSeqSlide(TransInfo *t) * (supporting frames in addition to "natural" time...). */ t->num.unit_type[0] = B_UNIT_NONE; t->num.unit_type[1] = B_UNIT_NONE; + + /* Workaround to use the same key as the modal keymap. */ + t->custom.mode.data = WM_modalkeymap_find_propvalue(t->keymap, TFM_MODAL_TRANSLATE); } /** \} */ diff --git a/source/blender/editors/transform/transform_mode_shrink_fatten.c b/source/blender/editors/transform/transform_mode_shrink_fatten.c index cdea388529f..6058a2824e9 100644 --- a/source/blender/editors/transform/transform_mode_shrink_fatten.c +++ b/source/blender/editors/transform/transform_mode_shrink_fatten.c @@ -32,6 +32,7 @@ #include "ED_screen.h" #include "WM_api.h" +#include "WM_types.h" #include "UI_interface.h" @@ -45,6 +46,18 @@ /** \name Transform (Shrink-Fatten) * \{ */ +static eRedrawFlag shrinkfatten_handleEvent(struct TransInfo *t, const wmEvent *event) +{ + BLI_assert(t->mode == TFM_SHRINKFATTEN); + wmKeyMapItem *kmi = t->custom.mode.data; + if (event->type == kmi->type && event->val == kmi->val) { + /* Allows the 'Even Thickness' effect to be enabled as a toogle. */ + t->flag ^= T_ALT_TRANSFORM; + return TREDRAW_HARD; + } + return TREDRAW_NOTHING; +} + static void applyShrinkFatten(TransInfo *t, const int UNUSED(mval[2])) { float distance; @@ -78,7 +91,7 @@ static void applyShrinkFatten(TransInfo *t, const int UNUSED(mval[2])) ofs += BLI_strncpy_rlen(str + ofs, ", (", sizeof(str) - ofs); if (t->keymap) { - wmKeyMapItem *kmi = WM_modalkeymap_find_propvalue(t->keymap, TFM_MODAL_RESIZE); + wmKeyMapItem *kmi = t->custom.mode.data; if (kmi) { ofs += WM_keymap_item_to_string(kmi, false, str + ofs, sizeof(str) - ofs); } @@ -121,6 +134,7 @@ void initShrinkFatten(TransInfo *t) else { t->mode = TFM_SHRINKFATTEN; t->transform = applyShrinkFatten; + t->handleEvent = shrinkfatten_handleEvent; initMouseInputMode(t, &t->mouse, INPUT_VERTICAL_ABSOLUTE); @@ -134,6 +148,9 @@ void initShrinkFatten(TransInfo *t) t->num.unit_type[0] = B_UNIT_LENGTH; t->flag |= T_NO_CONSTRAINT; + + /* Workaround to use the same key as the modal keymap. */ + t->custom.mode.data = WM_modalkeymap_find_propvalue(t->keymap, TFM_MODAL_RESIZE); } } /** \} */ -- cgit v1.2.3 From ab9952e55fe1bfe84e157cd25c90f9bed3bea6aa Mon Sep 17 00:00:00 2001 From: Yevgeny Makarov Date: Mon, 7 Dec 2020 14:51:06 -0800 Subject: Spelling: Bit Depth Compound Modifiers Correct usage of compound modifiers like '32-bit'. Differential Revision: https://developer.blender.org/D9769 Reviewed by Julian Eisel --- .../editors/sculpt_paint/paint_image_proj.c | 2 +- source/blender/editors/sound/sound_ops.c | 32 +++++++++++----------- source/blender/editors/space_image/image_ops.c | 4 +-- 3 files changed, 19 insertions(+), 19 deletions(-) (limited to 'source/blender/editors') diff --git a/source/blender/editors/sculpt_paint/paint_image_proj.c b/source/blender/editors/sculpt_paint/paint_image_proj.c index 8c16300a047..98f4b4013cb 100644 --- a/source/blender/editors/sculpt_paint/paint_image_proj.c +++ b/source/blender/editors/sculpt_paint/paint_image_proj.c @@ -6748,7 +6748,7 @@ void PAINT_OT_add_texture_paint_slot(wmOperatorType *ot) "Generated Type", "Fill the image with a grid for UV map testing"); RNA_def_boolean( - ot->srna, "float", 0, "32 bit Float", "Create image with 32 bit floating point bit depth"); + ot->srna, "float", 0, "32-bit Float", "Create image with 32-bit floating-point bit depth"); } static int add_simple_uvs_exec(bContext *C, wmOperator *UNUSED(op)) diff --git a/source/blender/editors/sound/sound_ops.c b/source/blender/editors/sound/sound_ops.c index c6961cc9d4b..8dac90c2346 100644 --- a/source/blender/editors/sound/sound_ops.c +++ b/source/blender/editors/sound/sound_ops.c @@ -518,27 +518,27 @@ static bool sound_mixdown_draw_check_prop(PointerRNA *UNUSED(ptr), static void sound_mixdown_draw(bContext *C, wmOperator *op) { static const EnumPropertyItem pcm_format_items[] = { - {AUD_FORMAT_U8, "U8", 0, "U8", "8 bit unsigned"}, - {AUD_FORMAT_S16, "S16", 0, "S16", "16 bit signed"}, + {AUD_FORMAT_U8, "U8", 0, "U8", "8-bit unsigned"}, + {AUD_FORMAT_S16, "S16", 0, "S16", "16-bit signed"}, # ifdef WITH_SNDFILE - {AUD_FORMAT_S24, "S24", 0, "S24", "24 bit signed"}, + {AUD_FORMAT_S24, "S24", 0, "S24", "24-bit signed"}, # endif - {AUD_FORMAT_S32, "S32", 0, "S32", "32 bit signed"}, - {AUD_FORMAT_FLOAT32, "F32", 0, "F32", "32 bit floating point"}, - {AUD_FORMAT_FLOAT64, "F64", 0, "F64", "64 bit floating point"}, + {AUD_FORMAT_S32, "S32", 0, "S32", "32-bit signed"}, + {AUD_FORMAT_FLOAT32, "F32", 0, "F32", "32-bit floating-point"}, + {AUD_FORMAT_FLOAT64, "F64", 0, "F64", "64-bit floating-point"}, {0, NULL, 0, NULL, NULL}, }; static const EnumPropertyItem mp3_format_items[] = { - {AUD_FORMAT_S16, "S16", 0, "S16", "16 bit signed"}, - {AUD_FORMAT_S32, "S32", 0, "S32", "32 bit signed"}, + {AUD_FORMAT_S16, "S16", 0, "S16", "16-bit signed"}, + {AUD_FORMAT_S32, "S32", 0, "S32", "32-bit signed"}, {0, NULL, 0, NULL, NULL}, }; # ifdef WITH_SNDFILE static const EnumPropertyItem flac_format_items[] = { - {AUD_FORMAT_S16, "S16", 0, "S16", "16 bit signed"}, - {AUD_FORMAT_S24, "S24", 0, "S24", "24 bit signed"}, + {AUD_FORMAT_S16, "S16", 0, "S16", "16-bit signed"}, + {AUD_FORMAT_S24, "S24", 0, "S24", "24-bit signed"}, {0, NULL, 0, NULL, NULL}, }; # endif @@ -672,12 +672,12 @@ static void SOUND_OT_mixdown(wmOperatorType *ot) { #ifdef WITH_AUDASPACE static const EnumPropertyItem format_items[] = { - {AUD_FORMAT_U8, "U8", 0, "U8", "8 bit unsigned"}, - {AUD_FORMAT_S16, "S16", 0, "S16", "16 bit signed"}, - {AUD_FORMAT_S24, "S24", 0, "S24", "24 bit signed"}, - {AUD_FORMAT_S32, "S32", 0, "S32", "32 bit signed"}, - {AUD_FORMAT_FLOAT32, "F32", 0, "F32", "32 bit floating point"}, - {AUD_FORMAT_FLOAT64, "F64", 0, "F64", "64 bit floating point"}, + {AUD_FORMAT_U8, "U8", 0, "U8", "8-bit unsigned"}, + {AUD_FORMAT_S16, "S16", 0, "S16", "16-bit signed"}, + {AUD_FORMAT_S24, "S24", 0, "S24", "24-bit signed"}, + {AUD_FORMAT_S32, "S32", 0, "S32", "32-bit signed"}, + {AUD_FORMAT_FLOAT32, "F32", 0, "F32", "32-bit floating-point"}, + {AUD_FORMAT_FLOAT64, "F64", 0, "F64", "64-bit floating-point"}, {0, NULL, 0, NULL, NULL}, }; diff --git a/source/blender/editors/space_image/image_ops.c b/source/blender/editors/space_image/image_ops.c index 0fa48059cdc..a2c0819dc60 100644 --- a/source/blender/editors/space_image/image_ops.c +++ b/source/blender/editors/space_image/image_ops.c @@ -2649,7 +2649,7 @@ void IMAGE_OT_new(wmOperatorType *ot) "Generated Type", "Fill the image with a grid for UV map testing"); RNA_def_boolean( - ot->srna, "float", 0, "32 bit Float", "Create image with 32 bit floating point bit depth"); + ot->srna, "float", 0, "32-bit Float", "Create image with 32-bit floating-point bit depth"); RNA_def_property_flag(prop, PROP_HIDDEN); prop = RNA_def_boolean( ot->srna, "use_stereo_3d", 0, "Stereo 3D", "Create an image with left and right views"); @@ -3737,7 +3737,7 @@ static void def_fill_tile(StructOrFunctionRNA *srna) /* Only needed when filling the first tile. */ RNA_def_boolean( - srna, "float", 0, "32 bit Float", "Create image with 32 bit floating point bit depth"); + srna, "float", 0, "32-bit Float", "Create image with 32-bit floating-point bit depth"); RNA_def_boolean(srna, "alpha", 1, "Alpha", "Create an image with an alpha channel"); } -- cgit v1.2.3 From 682ccd770c629402b771491d45a0523f75750f30 Mon Sep 17 00:00:00 2001 From: Bastien Montagne Date: Tue, 8 Dec 2020 09:40:42 +0100 Subject: LibOverride: Refactor collection items 'local' helper functions. It's easier to read and less 'weird' to check that an item is non-local in a liboverride data-block, than the other way around. Thanks to @sybren for noticing it. --- source/blender/editors/object/object_constraint.c | 5 +++-- source/blender/editors/object/object_gpencil_modifier.c | 6 +++--- source/blender/editors/object/object_modifier.c | 5 +++-- 3 files changed, 9 insertions(+), 7 deletions(-) (limited to 'source/blender/editors') diff --git a/source/blender/editors/object/object_constraint.c b/source/blender/editors/object/object_constraint.c index e684ad03f53..dd015f59e8d 100644 --- a/source/blender/editors/object/object_constraint.c +++ b/source/blender/editors/object/object_constraint.c @@ -706,8 +706,9 @@ static bool edit_constraint_poll_generic(bContext *C, return false; } - if (!is_liboverride_allowed && !BKE_constraint_is_local_in_liboverride(ob, con)) { - CTX_wm_operator_poll_msg_set(C, "Cannot edit constraints coming from library override"); + if (!is_liboverride_allowed && BKE_constraint_is_nonlocal_in_liboverride(ob, con)) { + CTX_wm_operator_poll_msg_set( + C, "Cannot edit constraints coming from linked data in a library override"); return false; } diff --git a/source/blender/editors/object/object_gpencil_modifier.c b/source/blender/editors/object/object_gpencil_modifier.c index d3f165678c3..af95f5581bd 100644 --- a/source/blender/editors/object/object_gpencil_modifier.c +++ b/source/blender/editors/object/object_gpencil_modifier.c @@ -443,9 +443,9 @@ static bool gpencil_edit_modifier_poll_generic(bContext *C, return false; } - if (!is_liboverride_allowed && - (mod == NULL || !BKE_gpencil_modifier_is_local_in_liboverride(ob, mod))) { - CTX_wm_operator_poll_msg_set(C, "Cannot edit modifiers coming from library override"); + if (!is_liboverride_allowed && BKE_gpencil_modifier_is_nonlocal_in_liboverride(ob, mod)) { + CTX_wm_operator_poll_msg_set( + C, "Cannot edit modifiers coming from linked data in a library override"); return false; } diff --git a/source/blender/editors/object/object_modifier.c b/source/blender/editors/object/object_modifier.c index bb4581b0ee8..3111003703f 100644 --- a/source/blender/editors/object/object_modifier.c +++ b/source/blender/editors/object/object_modifier.c @@ -1052,8 +1052,9 @@ bool edit_modifier_poll_generic(bContext *C, return false; } - if (!is_liboverride_allowed && !BKE_modifier_is_local_in_liboverride(ob, mod)) { - CTX_wm_operator_poll_msg_set(C, "Cannot edit modifiers coming from library override"); + if (!is_liboverride_allowed && BKE_modifier_is_nonlocal_in_liboverride(ob, mod)) { + CTX_wm_operator_poll_msg_set( + C, "Cannot edit modifiers coming from linked data in a library override"); return false; } -- cgit v1.2.3 From f43c9499bfccbfaf7add1d57407150b1871c2f66 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Tue, 8 Dec 2020 20:44:45 +1100 Subject: Cleanup: use static declarations --- source/blender/editors/space_view3d/view3d_placement.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source/blender/editors') diff --git a/source/blender/editors/space_view3d/view3d_placement.c b/source/blender/editors/space_view3d/view3d_placement.c index 6d10aa5f957..7e8ed276766 100644 --- a/source/blender/editors/space_view3d/view3d_placement.c +++ b/source/blender/editors/space_view3d/view3d_placement.c @@ -72,7 +72,7 @@ static void preview_plane_cursor_visible_set(wmGizmoGroup *gzgroup, bool do_draw * In this case we can't usefully project the mouse cursor onto the plane, * so use a fall-back plane instead. */ -const float eps_view_align = 1e-2f; +static const float eps_view_align = 1e-2f; /* -------------------------------------------------------------------- */ /** \name Local Types -- cgit v1.2.3 From c0bd240ad0a17402db9d2e4799a433b81b62fca8 Mon Sep 17 00:00:00 2001 From: Bastien Montagne Date: Mon, 7 Dec 2020 16:58:18 +0100 Subject: LibOverride: Add initial support for adding new NLA tracks. Also makes NLA tracks and strips overridable. User can either edit existing strips in existing NLA tracks (but not add or remove them), and/or add new NLA tracks after those comming from the linked data. Most of the work was as usual checking operators and adding protections against illegal operations in override context. Note that since we can only rely on indices to deal with local added tracks, we forbid any local track being before any linked/original track. Maniphest Tasks: T72629 Differential Revision: https://developer.blender.org/D9611 --- .../blender/editors/animation/anim_channels_edit.c | 52 ++++++++++-- source/blender/editors/object/object_add.c | 5 +- source/blender/editors/space_action/action_data.c | 11 ++- source/blender/editors/space_nla/nla_channels.c | 17 ++-- source/blender/editors/space_nla/nla_edit.c | 99 +++++++++++++++++----- .../blender/editors/transform/transform_convert.c | 2 +- .../editors/transform/transform_convert_nla.c | 16 +++- 7 files changed, 162 insertions(+), 40 deletions(-) (limited to 'source/blender/editors') diff --git a/source/blender/editors/animation/anim_channels_edit.c b/source/blender/editors/animation/anim_channels_edit.c index ba3796ad245..124992bed71 100644 --- a/source/blender/editors/animation/anim_channels_edit.c +++ b/source/blender/editors/animation/anim_channels_edit.c @@ -49,6 +49,7 @@ #include "BKE_gpencil.h" #include "BKE_lib_id.h" #include "BKE_mask.h" +#include "BKE_nla.h" #include "BKE_scene.h" #include "DEG_depsgraph.h" @@ -1063,18 +1064,27 @@ static void rearrange_animchannels_filter_visible(ListBase *anim_data_visible, eAnim_ChannelType type) { ListBase anim_data = {NULL, NULL}; - bAnimListElem *ale, *ale_next; - int filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE | ANIMFILTER_LIST_CHANNELS); + eAnimFilter_Flags filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE | + ANIMFILTER_LIST_CHANNELS); /* get all visible channels */ ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype); /* now, only keep the ones that are of the types we are interested in */ - for (ale = anim_data.first; ale; ale = ale_next) { - ale_next = ale->next; - + LISTBASE_FOREACH_MUTABLE (bAnimListElem *, ale, &anim_data) { if (ale->type != type) { BLI_freelinkN(&anim_data, ale); + continue; + } + + if (type == ANIMTYPE_NLATRACK) { + NlaTrack *nlt = (NlaTrack *)ale->data; + + if (BKE_nlatrack_is_nonlocal_in_liboverride(ale->id, nlt)) { + /* No re-arrangement of non-local tracks of override data. */ + BLI_freelinkN(&anim_data, ale); + continue; + } } } @@ -1146,6 +1156,7 @@ static void rearrange_nla_channels(bAnimContext *ac, AnimData *adt, eRearrangeAn { AnimChanRearrangeFp rearrange_func; ListBase anim_data_visible = {NULL, NULL}; + const bool is_liboverride = ID_IS_OVERRIDE_LIBRARY(ac->obact); /* hack: invert mode so that functions will work in right order */ mode *= -1; @@ -1156,6 +1167,29 @@ static void rearrange_nla_channels(bAnimContext *ac, AnimData *adt, eRearrangeAn return; } + /* In liboverride case, we need to extract non-local NLA tracks from current anim data before we + * can perform the move, and add then back afterwards. It's the only way to prevent them from + * being affected by the reordering. + * + * Note that both override apply code for NLA tracks collection, and NLA editing code, are + * responsible to ensure that non-local tracks always remain first in the list. */ + ListBase extracted_nonlocal_nla_tracks = {NULL, NULL}; + if (is_liboverride) { + NlaTrack *nla_track; + for (nla_track = adt->nla_tracks.first; nla_track != NULL; nla_track = nla_track->next) { + if (!BKE_nlatrack_is_nonlocal_in_liboverride(&ac->obact->id, nla_track)) { + break; + } + } + if (nla_track != NULL && nla_track->prev != NULL) { + extracted_nonlocal_nla_tracks.first = adt->nla_tracks.first; + extracted_nonlocal_nla_tracks.last = nla_track->prev; + adt->nla_tracks.first = nla_track; + nla_track->prev->next = NULL; + nla_track->prev = NULL; + } + } + /* Filter visible data. */ rearrange_animchannels_filter_visible(&anim_data_visible, ac, ANIMTYPE_NLATRACK); @@ -1163,6 +1197,14 @@ static void rearrange_nla_channels(bAnimContext *ac, AnimData *adt, eRearrangeAn rearrange_animchannel_islands( &adt->nla_tracks, rearrange_func, mode, ANIMTYPE_NLATRACK, &anim_data_visible); + /* Add back non-local NLA tracks at the begining of the animation data's list. */ + if (!BLI_listbase_is_empty(&extracted_nonlocal_nla_tracks)) { + BLI_assert(is_liboverride); + ((NlaTrack *)extracted_nonlocal_nla_tracks.last)->next = adt->nla_tracks.first; + ((NlaTrack *)adt->nla_tracks.first)->prev = extracted_nonlocal_nla_tracks.last; + adt->nla_tracks.first = extracted_nonlocal_nla_tracks.first; + } + /* free temp data */ BLI_freelistN(&anim_data_visible); } diff --git a/source/blender/editors/object/object_add.c b/source/blender/editors/object/object_add.c index 4e0f6211c18..bbfdfb2532d 100644 --- a/source/blender/editors/object/object_add.c +++ b/source/blender/editors/object/object_add.c @@ -1618,6 +1618,7 @@ static int object_speaker_add_exec(bContext *C, wmOperator *op) return OPERATOR_CANCELLED; } Object *ob = ED_object_add_type(C, OB_SPEAKER, NULL, loc, rot, false, local_view_bits); + const bool is_liboverride = ID_IS_OVERRIDE_LIBRARY(ob); /* to make it easier to start using this immediately in NLA, a default sound clip is created * ready to be moved around to retime the sound and/or make new sound clips @@ -1625,13 +1626,13 @@ static int object_speaker_add_exec(bContext *C, wmOperator *op) { /* create new data for NLA hierarchy */ AnimData *adt = BKE_animdata_add_id(&ob->id); - NlaTrack *nlt = BKE_nlatrack_add(adt, NULL); + NlaTrack *nlt = BKE_nlatrack_add(adt, NULL, is_liboverride); NlaStrip *strip = BKE_nla_add_soundstrip(bmain, scene, ob->data); strip->start = CFRA; strip->end += strip->start; /* hook them up */ - BKE_nlatrack_add_strip(nlt, strip); + BKE_nlatrack_add_strip(nlt, strip, is_liboverride); /* auto-name the strip, and give the track an interesting name */ BLI_strncpy(nlt->name, DATA_("SoundTrack"), sizeof(nlt->name)); diff --git a/source/blender/editors/space_action/action_data.c b/source/blender/editors/space_action/action_data.c index e20be9c8328..3a584a7f0cb 100644 --- a/source/blender/editors/space_action/action_data.c +++ b/source/blender/editors/space_action/action_data.c @@ -240,7 +240,7 @@ static int action_new_exec(bContext *C, wmOperator *UNUSED(op)) /* Perform stashing operation - But only if there is an action */ if (adt && oldact) { /* stash the action */ - if (BKE_nla_action_stash(adt)) { + if (BKE_nla_action_stash(adt, ID_IS_OVERRIDE_LIBRARY(ptr.owner_id))) { /* The stash operation will remove the user already * (and unlink the action from the AnimData action slot). * Hence, we must unset the ref to the action in the @@ -339,7 +339,8 @@ static int action_pushdown_exec(bContext *C, wmOperator *op) } /* action can be safely added */ - BKE_nla_action_pushdown(adt); + const Object *ob = CTX_data_active_object(C); + BKE_nla_action_pushdown(adt, ID_IS_OVERRIDE_LIBRARY(ob)); /* Stop displaying this action in this editor * NOTE: The editor itself doesn't set a user... @@ -384,7 +385,8 @@ static int action_stash_exec(bContext *C, wmOperator *op) } /* stash the action */ - if (BKE_nla_action_stash(adt)) { + Object *ob = CTX_data_active_object(C); + if (BKE_nla_action_stash(adt, ID_IS_OVERRIDE_LIBRARY(ob))) { /* The stash operation will remove the user already, * so the flushing step later shouldn't double up * the user-count fixes. Hence, we must unset this ref @@ -486,7 +488,8 @@ static int action_stash_create_exec(bContext *C, wmOperator *op) } /* stash the action */ - if (BKE_nla_action_stash(adt)) { + Object *ob = CTX_data_active_object(C); + if (BKE_nla_action_stash(adt, ID_IS_OVERRIDE_LIBRARY(ob))) { bAction *new_action = NULL; /* Create new action not based on the old one diff --git a/source/blender/editors/space_nla/nla_channels.c b/source/blender/editors/space_nla/nla_channels.c index 561de5e82a6..9832ca975cf 100644 --- a/source/blender/editors/space_nla/nla_channels.c +++ b/source/blender/editors/space_nla/nla_channels.c @@ -292,7 +292,7 @@ static int mouse_nla_channels( /* TODO: make this use the operator instead of calling the function directly * however, calling the operator requires that we supply the args, * and that works with proper buttons only */ - BKE_nla_action_pushdown(adt); + BKE_nla_action_pushdown(adt, ID_IS_OVERRIDE_LIBRARY(ale->id)); } else { /* when in tweakmode, this button becomes the toggle for mapped editing */ @@ -516,7 +516,7 @@ static int nlachannels_pushdown_exec(bContext *C, wmOperator *op) } /* 'push-down' action - only usable when not in TweakMode */ - BKE_nla_action_pushdown(adt); + BKE_nla_action_pushdown(adt, ID_IS_OVERRIDE_LIBRARY(id)); struct Main *bmain = CTX_data_main(C); DEG_id_tag_update_ex(bmain, id, ID_RECALC_ANIMATION); @@ -648,19 +648,21 @@ bool nlaedit_add_tracks_existing(bAnimContext *ac, bool above_sel) NlaTrack *nlt = (NlaTrack *)ale->data; AnimData *adt = ale->adt; + const bool is_liboverride = ID_IS_OVERRIDE_LIBRARY(ale->id); + /* check if just adding a new track above this one, * or whether we're adding a new one to the top of the stack that this one belongs to */ if (above_sel) { /* just add a new one above this one */ - BKE_nlatrack_add(adt, nlt); + BKE_nlatrack_add(adt, nlt, is_liboverride); ale->update = ANIM_UPDATE_DEPS; added = true; } else if ((lastAdt == NULL) || (adt != lastAdt)) { /* add one track to the top of the owning AnimData's stack, * then don't add anymore to this stack */ - BKE_nlatrack_add(adt, NULL); + BKE_nlatrack_add(adt, NULL, is_liboverride); lastAdt = adt; ale->update = ANIM_UPDATE_DEPS; added = true; @@ -698,7 +700,7 @@ bool nlaedit_add_tracks_empty(bAnimContext *ac) /* ensure it is empty */ if (BLI_listbase_is_empty(&adt->nla_tracks)) { /* add new track to this AnimData block then */ - BKE_nlatrack_add(adt, NULL); + BKE_nlatrack_add(adt, NULL, ID_IS_OVERRIDE_LIBRARY(ale->id)); ale->update = ANIM_UPDATE_DEPS; added = true; } @@ -796,6 +798,11 @@ static int nlaedit_delete_tracks_exec(bContext *C, wmOperator *UNUSED(op)) NlaTrack *nlt = (NlaTrack *)ale->data; AnimData *adt = ale->adt; + if (BKE_nlatrack_is_nonlocal_in_liboverride(ale->id, nlt)) { + /* No deletion of non-local tracks of override data. */ + continue; + } + /* if track is currently 'solo', then AnimData should have its * 'has solo' flag disabled */ diff --git a/source/blender/editors/space_nla/nla_edit.c b/source/blender/editors/space_nla/nla_edit.c index ed8e5ad76e9..3fa1b614a03 100644 --- a/source/blender/editors/space_nla/nla_edit.c +++ b/source/blender/editors/space_nla/nla_edit.c @@ -649,6 +649,7 @@ static int nlaedit_add_actionclip_exec(bContext *C, wmOperator *op) NlaTrack *nlt = (NlaTrack *)ale->data; AnimData *adt = ale->adt; NlaStrip *strip = NULL; + const bool is_liboverride = ID_IS_OVERRIDE_LIBRARY(ale->id); /* Sanity check: only apply actions of the right type for this ID. * NOTE: in the case that this hasn't been set, @@ -671,12 +672,12 @@ static int nlaedit_add_actionclip_exec(bContext *C, wmOperator *op) strip->start = cfra; /* firstly try adding strip to our current track, but if that fails, add to a new track */ - if (BKE_nlatrack_add_strip(nlt, strip) == 0) { + if (BKE_nlatrack_add_strip(nlt, strip, is_liboverride) == 0) { /* trying to add to the current failed (no space), * so add a new track to the stack, and add to that... */ - nlt = BKE_nlatrack_add(adt, NULL); - BKE_nlatrack_add_strip(nlt, strip); + nlt = BKE_nlatrack_add(adt, NULL, is_liboverride); + BKE_nlatrack_add_strip(nlt, strip, is_liboverride); } /* auto-name it */ @@ -886,6 +887,7 @@ static int nlaedit_add_sound_exec(bContext *C, wmOperator *UNUSED(op)) AnimData *adt = ale->adt; NlaTrack *nlt = (NlaTrack *)ale->data; NlaStrip *strip; + const bool is_liboverride = ID_IS_OVERRIDE_LIBRARY(ale->id); /* does this belong to speaker - assumed to live on Object level only */ if ((GS(ale->id->name) != ID_OB) || (ob->type != OB_SPEAKER)) { @@ -899,12 +901,12 @@ static int nlaedit_add_sound_exec(bContext *C, wmOperator *UNUSED(op)) strip->end += cfra; /* firstly try adding strip to our current track, but if that fails, add to a new track */ - if (BKE_nlatrack_add_strip(nlt, strip) == 0) { + if (BKE_nlatrack_add_strip(nlt, strip, is_liboverride) == 0) { /* trying to add to the current failed (no space), * so add a new track to the stack, and add to that... */ - nlt = BKE_nlatrack_add(adt, NULL); - BKE_nlatrack_add_strip(nlt, strip); + nlt = BKE_nlatrack_add(adt, NULL, is_liboverride); + BKE_nlatrack_add_strip(nlt, strip, is_liboverride); } /* auto-name it */ @@ -966,6 +968,11 @@ static int nlaedit_add_meta_exec(bContext *C, wmOperator *UNUSED(op)) AnimData *adt = ale->adt; NlaStrip *strip; + if (BKE_nlatrack_is_nonlocal_in_liboverride(ale->id, nlt)) { + /* No making metastrips in non-local tracks of override data. */ + continue; + } + /* create meta-strips from the continuous chains of selected strips */ BKE_nlastrips_make_metas(&nlt->strips, 0); @@ -1030,6 +1037,11 @@ static int nlaedit_remove_meta_exec(bContext *C, wmOperator *UNUSED(op)) for (ale = anim_data.first; ale; ale = ale->next) { NlaTrack *nlt = (NlaTrack *)ale->data; + if (BKE_nlatrack_is_nonlocal_in_liboverride(ale->id, nlt)) { + /* No removing metastrips from non-local tracks of override data. */ + continue; + } + /* clear all selected meta-strips, regardless of whether they are temporary or not */ BKE_nlastrips_clear_metas(&nlt->strips, 1, 0); @@ -1096,6 +1108,11 @@ static int nlaedit_duplicate_exec(bContext *C, wmOperator *op) NlaStrip *strip, *nstrip, *next; NlaTrack *track; + /* Note: We allow this operator in override context because it is almost always (from possible + * default user interactions) paired with the transform one, which will ensure that the new + * strip ends up in a valid (local) track. */ + + const bool is_liboverride = ID_IS_OVERRIDE_LIBRARY(ale->id); for (strip = nlt->strips.first; strip; strip = next) { next = strip->next; @@ -1106,13 +1123,13 @@ static int nlaedit_duplicate_exec(bContext *C, wmOperator *op) /* in case there's no space in the track above, * or we haven't got a reference to it yet, try adding */ - if (BKE_nlatrack_add_strip(nlt->next, nstrip) == 0) { + if (BKE_nlatrack_add_strip(nlt->next, nstrip, is_liboverride) == 0) { /* need to add a new track above the one above the current one * - if the current one is the last one, nlt->next will be NULL, which defaults to adding * at the top of the stack anyway... */ - track = BKE_nlatrack_add(adt, nlt->next); - BKE_nlatrack_add_strip(track, nstrip); + track = BKE_nlatrack_add(adt, nlt->next, is_liboverride); + BKE_nlatrack_add_strip(track, nstrip, is_liboverride); } /* deselect the original and the active flag */ @@ -1209,6 +1226,11 @@ static int nlaedit_delete_exec(bContext *C, wmOperator *UNUSED(op)) NlaTrack *nlt = (NlaTrack *)ale->data; NlaStrip *strip, *nstrip; + if (BKE_nlatrack_is_nonlocal_in_liboverride(ale->id, nlt)) { + /* No deletion of strips in non-local tracks of override data. */ + continue; + } + for (strip = nlt->strips.first; strip; strip = nstrip) { nstrip = strip->next; @@ -1359,6 +1381,11 @@ static int nlaedit_split_exec(bContext *C, wmOperator *UNUSED(op)) AnimData *adt = ale->adt; NlaStrip *strip, *next; + if (BKE_nlatrack_is_nonlocal_in_liboverride(ale->id, nlt)) { + /* No splitting of strips in non-local tracks of override data. */ + continue; + } + for (strip = nlt->strips.first; strip; strip = next) { next = strip->next; @@ -1502,6 +1529,12 @@ static int nlaedit_swap_exec(bContext *C, wmOperator *op) NlaStrip *strip, *stripN = NULL; NlaStrip *area = NULL, *sb = NULL; + const bool is_liboverride = ID_IS_OVERRIDE_LIBRARY(ale->id); + + if (BKE_nlatrack_is_nonlocal_in_liboverride(ale->id, nlt)) { + /* No re-ordering of strips whithin non-local tracks of override data. */ + continue; + } /* make temporary metastrips so that entire islands of selections can be moved around */ BKE_nlastrips_make_metas(&nlt->strips, 1); @@ -1610,8 +1643,8 @@ static int nlaedit_swap_exec(bContext *C, wmOperator *op) } /* add strips back to track now */ - BKE_nlatrack_add_strip(nlt, area); - BKE_nlatrack_add_strip(nlt, sb); + BKE_nlatrack_add_strip(nlt, area, is_liboverride); + BKE_nlatrack_add_strip(nlt, sb, is_liboverride); } /* clear (temp) metastrips */ @@ -1674,11 +1707,19 @@ static int nlaedit_move_up_exec(bContext *C, wmOperator *UNUSED(op)) NlaTrack *nltn = nlt->next; NlaStrip *strip, *stripn; + const bool is_liboverride = ID_IS_OVERRIDE_LIBRARY(ale->id); + /* if this track has no tracks after it, skip for now... */ if (nltn == NULL) { continue; } + if (BKE_nlatrack_is_nonlocal_in_liboverride(ale->id, nlt) || + BKE_nlatrack_is_nonlocal_in_liboverride(ale->id, nltn)) { + /* No moving of strips in non-local tracks of override data. */ + continue; + } + /* for every selected strip, try to move */ for (strip = nlt->strips.first; strip; strip = stripn) { stripn = strip->next; @@ -1689,7 +1730,7 @@ static int nlaedit_move_up_exec(bContext *C, wmOperator *UNUSED(op)) /* remove from its current track, and add to the one above * (it 'should' work, so no need to worry) */ BLI_remlink(&nlt->strips, strip); - BKE_nlatrack_add_strip(nltn, strip); + BKE_nlatrack_add_strip(nltn, strip, is_liboverride); } } } @@ -1751,11 +1792,19 @@ static int nlaedit_move_down_exec(bContext *C, wmOperator *UNUSED(op)) NlaTrack *nltp = nlt->prev; NlaStrip *strip, *stripn; + const bool is_liboverride = ID_IS_OVERRIDE_LIBRARY(ale->id); + /* if this track has no tracks before it, skip for now... */ if (nltp == NULL) { continue; } + if (BKE_nlatrack_is_nonlocal_in_liboverride(ale->id, nlt) || + BKE_nlatrack_is_nonlocal_in_liboverride(ale->id, nltp)) { + /* No moving of strips in non-local tracks of override data. */ + continue; + } + /* for every selected strip, try to move */ for (strip = nlt->strips.first; strip; strip = stripn) { stripn = strip->next; @@ -1766,7 +1815,7 @@ static int nlaedit_move_down_exec(bContext *C, wmOperator *UNUSED(op)) /* remove from its current track, and add to the one above * (it 'should' work, so no need to worry) */ BLI_remlink(&nlt->strips, strip); - BKE_nlatrack_add_strip(nltp, strip); + BKE_nlatrack_add_strip(nltp, strip, is_liboverride); } } } @@ -2023,11 +2072,11 @@ static int nlaedit_apply_scale_exec(bContext *C, wmOperator *UNUSED(op)) /* strip must be selected, and must be action-clip only * (transitions don't have scale) */ if ((strip->flag & NLASTRIP_FLAG_SELECT) && (strip->type == NLASTRIP_TYPE_CLIP)) { - /* if the referenced action is used by other strips, - * make this strip use its own copy */ - if (strip->act == NULL) { + if (strip->act == NULL || ID_IS_OVERRIDE_LIBRARY(strip->act) || ID_IS_LINKED(strip->act)) { continue; } + /* if the referenced action is used by other strips, + * make this strip use its own copy */ if (strip->act->id.us > 1) { /* make a copy of the Action to work on */ bAction *act = (bAction *)BKE_id_copy(bmain, &strip->act->id); @@ -2200,6 +2249,8 @@ static int nlaedit_snap_exec(bContext *C, wmOperator *op) NlaStrip *strip, *stripn; NlaTrack *track; + const bool is_liboverride = ID_IS_OVERRIDE_LIBRARY(ale->id); + /* create meta-strips from the continuous chains of selected strips */ BKE_nlastrips_make_metas(&nlt->strips, 1); @@ -2255,10 +2306,10 @@ static int nlaedit_snap_exec(bContext *C, wmOperator *op) BLI_remlink(&tmp_strips, strip); /* in case there's no space in the current track, try adding */ - if (BKE_nlatrack_add_strip(nlt, strip) == 0) { + if (BKE_nlatrack_add_strip(nlt, strip, is_liboverride) == 0) { /* need to add a new track above the current one */ - track = BKE_nlatrack_add(adt, nlt); - BKE_nlatrack_add_strip(track, strip); + track = BKE_nlatrack_add(adt, nlt, is_liboverride); + BKE_nlatrack_add_strip(track, strip, is_liboverride); /* clear temp meta-strips on this new track, * as we may not be able to get back to it */ @@ -2375,6 +2426,11 @@ static int nla_fmodifier_add_exec(bContext *C, wmOperator *op) NlaTrack *nlt = (NlaTrack *)ale->data; NlaStrip *strip; + if (BKE_nlatrack_is_nonlocal_in_liboverride(ale->id, nlt)) { + /* No adding f-modifiers to strips in non-local tracks of override data. */ + continue; + } + for (strip = nlt->strips.first; strip; strip = strip->next) { /* can F-Modifier be added to the current strip? */ if (active_only) { @@ -2552,6 +2608,11 @@ static int nla_fmodifier_paste_exec(bContext *C, wmOperator *op) NlaTrack *nlt = (NlaTrack *)ale->data; NlaStrip *strip; + if (BKE_nlatrack_is_nonlocal_in_liboverride(ale->id, nlt)) { + /* No pasting in non-local tracks of override data. */ + continue; + } + for (strip = nlt->strips.first; strip; strip = strip->next) { /* can F-Modifier be added to the current strip? */ if (active_only) { diff --git a/source/blender/editors/transform/transform_convert.c b/source/blender/editors/transform/transform_convert.c index c23ee5b771c..c81c954bd0a 100644 --- a/source/blender/editors/transform/transform_convert.c +++ b/source/blender/editors/transform/transform_convert.c @@ -1438,7 +1438,7 @@ void animrecord_check_state(TransInfo *t, struct Object *ob) /* only push down if action is more than 1-2 frames long */ calc_action_range(adt->action, &astart, &aend, 1); if (aend > astart + 2.0f) { - NlaStrip *strip = BKE_nlastack_add_strip(adt, adt->action); + NlaStrip *strip = BKE_nlastack_add_strip(adt, adt->action, ID_IS_OVERRIDE_LIBRARY(id)); /* clear reference to action now that we've pushed it onto the stack */ id_us_min(&adt->action->id); diff --git a/source/blender/editors/transform/transform_convert_nla.c b/source/blender/editors/transform/transform_convert_nla.c index 8f18f6a8c96..fa60a88a45b 100644 --- a/source/blender/editors/transform/transform_convert_nla.c +++ b/source/blender/editors/transform/transform_convert_nla.c @@ -462,6 +462,12 @@ void recalcData_nla(TransInfo *t) * - we need to calculate both, * as only one may have been altered by transform if only 1 handle moved. */ + /* In LibOverride case, we cannot move strips across tracks that come from the linked data. */ + const bool is_liboverride = ID_IS_OVERRIDE_LIBRARY(tdn->id); + if (BKE_nlatrack_is_nonlocal_in_liboverride(tdn->id, tdn->nlt)) { + continue; + } + delta_y1 = ((int)tdn->h1[1] / NLACHANNEL_STEP(snla) - tdn->trackIndex); delta_y2 = ((int)tdn->h2[1] / NLACHANNEL_STEP(snla) - tdn->trackIndex); @@ -477,10 +483,11 @@ void recalcData_nla(TransInfo *t) if (delta > 0) { for (track = tdn->nlt->next, n = 0; (track) && (n < delta); track = track->next, n++) { /* check if space in this track for the strip */ - if (BKE_nlatrack_has_space(track, strip->start, strip->end)) { + if (BKE_nlatrack_has_space(track, strip->start, strip->end) && + !BKE_nlatrack_is_nonlocal_in_liboverride(tdn->id, tdn->nlt)) { /* move strip to this track */ BLI_remlink(&tdn->nlt->strips, strip); - BKE_nlatrack_add_strip(track, strip); + BKE_nlatrack_add_strip(track, strip, is_liboverride); tdn->nlt = track; tdn->trackIndex++; @@ -496,10 +503,11 @@ void recalcData_nla(TransInfo *t) for (track = tdn->nlt->prev, n = 0; (track) && (n < delta); track = track->prev, n++) { /* check if space in this track for the strip */ - if (BKE_nlatrack_has_space(track, strip->start, strip->end)) { + if (BKE_nlatrack_has_space(track, strip->start, strip->end) && + !BKE_nlatrack_is_nonlocal_in_liboverride(tdn->id, tdn->nlt)) { /* move strip to this track */ BLI_remlink(&tdn->nlt->strips, strip); - BKE_nlatrack_add_strip(track, strip); + BKE_nlatrack_add_strip(track, strip, is_liboverride); tdn->nlt = track; tdn->trackIndex--; -- cgit v1.2.3 From 2a4fe88c13a1cb5bd79787e17eeaafec01c4d294 Mon Sep 17 00:00:00 2001 From: Julian Eisel Date: Tue, 8 Dec 2020 12:56:11 +0100 Subject: Cleanup: Use guarded allocator for data-block names returned from file reading Direcly using the C library allocator functions is usually avoided in favor of our guarded allocator. It's more useful when debugging. --- source/blender/editors/space_file/filelist.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source/blender/editors') diff --git a/source/blender/editors/space_file/filelist.c b/source/blender/editors/space_file/filelist.c index 9e51b6ca4ba..b6d016aca7c 100644 --- a/source/blender/editors/space_file/filelist.c +++ b/source/blender/editors/space_file/filelist.c @@ -2620,7 +2620,7 @@ static int filelist_readjob_list_lib(const char *root, ListBase *entries, const nbr_entries++; } - BLI_linklist_free(names, free); + BLI_linklist_free(names, MEM_freeN); return nbr_entries; } -- cgit v1.2.3 From 95b3c4c966f9baeb6f73b84568b7f03287e1a350 Mon Sep 17 00:00:00 2001 From: Julian Eisel Date: Tue, 8 Dec 2020 13:47:37 +0100 Subject: File Browser: Refactor access to the selection parameters struct * Avoid direct access to `SpaceFile.params`, use a getter instead. This matters because once the asset-browser changes are in, there will be an alternative selection parameter object. The getter can return the correct one. * Rename the function to ensure the parameters. The old name `ED_fileselect_get_params()` wasn't a mere getter, it would create the parameters if necessary. Now we have an actual getter, so better be clear. * In some instances, I replaced the old "get" function with the new mere getter. So the ensure logic is called less often. However, in these cases we should be able to assume the selection parameters were created already as part of the editor creation routine. The term "active" in the new function names may seem a bit odd in the current context, but that is a preparation for the Asset Browser merge as well. Like said, there will be two file selection parameter objects in the space. --- source/blender/editors/include/ED_fileselect.h | 4 +- source/blender/editors/space_file/file_draw.c | 42 ++-- source/blender/editors/space_file/file_ops.c | 299 ++++++++++++------------ source/blender/editors/space_file/file_panels.c | 2 +- source/blender/editors/space_file/filelist.c | 3 +- source/blender/editors/space_file/filesel.c | 104 +++++---- source/blender/editors/space_file/space_file.c | 6 +- 7 files changed, 241 insertions(+), 219 deletions(-) (limited to 'source/blender/editors') diff --git a/source/blender/editors/include/ED_fileselect.h b/source/blender/editors/include/ED_fileselect.h index 84808416074..a5a8df916d6 100644 --- a/source/blender/editors/include/ED_fileselect.h +++ b/source/blender/editors/include/ED_fileselect.h @@ -101,9 +101,9 @@ typedef struct FileSelection { struct View2D; struct rcti; -struct FileSelectParams *ED_fileselect_get_params(struct SpaceFile *sfile); +struct FileSelectParams *ED_fileselect_ensure_active_params(struct SpaceFile *sfile); +struct FileSelectParams *ED_fileselect_get_active_params(const struct SpaceFile *sfile); -short ED_fileselect_set_params(struct SpaceFile *sfile); void ED_fileselect_set_params_from_userdef(struct SpaceFile *sfile); void ED_fileselect_params_to_userdef(struct SpaceFile *sfile, const int temp_win_size[], diff --git a/source/blender/editors/space_file/file_draw.c b/source/blender/editors/space_file/file_draw.c index 4b277435f63..e3bdda7c480 100644 --- a/source/blender/editors/space_file/file_draw.c +++ b/source/blender/editors/space_file/file_draw.c @@ -400,11 +400,12 @@ static void renamebutton_cb(bContext *C, void *UNUSED(arg1), char *oldname) wmWindowManager *wm = CTX_wm_manager(C); SpaceFile *sfile = (SpaceFile *)CTX_wm_space_data(C); ARegion *region = CTX_wm_region(C); + FileSelectParams *params = ED_fileselect_get_active_params(sfile); - BLI_join_dirfile(orgname, sizeof(orgname), sfile->params->dir, oldname); - BLI_strncpy(filename, sfile->params->renamefile, sizeof(filename)); + BLI_join_dirfile(orgname, sizeof(orgname), params->dir, oldname); + BLI_strncpy(filename, params->renamefile, sizeof(filename)); BLI_filename_make_safe(filename); - BLI_join_dirfile(newname, sizeof(newname), sfile->params->dir, filename); + BLI_join_dirfile(newname, sizeof(newname), params->dir, filename); if (!STREQ(orgname, newname)) { if (!BLI_exists(newname)) { @@ -415,8 +416,8 @@ static void renamebutton_cb(bContext *C, void *UNUSED(arg1), char *oldname) } else { /* If rename is successful, scroll to newly renamed entry. */ - BLI_strncpy(sfile->params->renamefile, filename, sizeof(sfile->params->renamefile)); - sfile->params->rename_flag = FILE_PARAMS_RENAME_POSTSCROLL_PENDING; + BLI_strncpy(params->renamefile, filename, sizeof(params->renamefile)); + params->rename_flag = FILE_PARAMS_RENAME_POSTSCROLL_PENDING; if (sfile->smoothscroll_timer != NULL) { WM_event_remove_timer(CTX_wm_manager(C), CTX_wm_window(C), sfile->smoothscroll_timer); @@ -688,7 +689,7 @@ static void draw_details_columns(const FileSelectParams *params, void file_draw_list(const bContext *C, ARegion *region) { SpaceFile *sfile = CTX_wm_space_file(C); - FileSelectParams *params = ED_fileselect_get_params(sfile); + FileSelectParams *params = ED_fileselect_get_active_params(sfile); FileLayout *layout = ED_fileselect_get_layout(sfile, region); View2D *v2d = ®ion->v2d; struct FileList *files = sfile->files; @@ -847,26 +848,25 @@ void file_draw_list(const bContext *C, ARegion *region) } if (file_selflag & FILE_SEL_EDITING) { - uiBut *but; const short width = (params->display == FILE_IMGDISPLAY) ? textwidth : layout->attribute_columns[COLUMN_NAME].width - ATTRIBUTE_COLUMN_PADDING; - but = uiDefBut(block, - UI_BTYPE_TEXT, - 1, - "", - sx + icon_ofs, - sy - layout->tile_h - 0.15f * UI_UNIT_X, - width - icon_ofs, - textheight, - sfile->params->renamefile, - 1.0f, - (float)sizeof(sfile->params->renamefile), - 0, - 0, - ""); + uiBut *but = uiDefBut(block, + UI_BTYPE_TEXT, + 1, + "", + sx + icon_ofs, + sy - layout->tile_h - 0.15f * UI_UNIT_X, + width - icon_ofs, + textheight, + params->renamefile, + 1.0f, + (float)sizeof(params->renamefile), + 0, + 0, + ""); UI_but_func_rename_set(but, renamebutton_cb, file); UI_but_flag_enable(but, UI_BUT_NO_UTF8); /* allow non utf8 names */ UI_but_flag_disable(but, UI_BUT_UNDO); diff --git a/source/blender/editors/space_file/file_ops.c b/source/blender/editors/space_file/file_ops.c index 93367ad3d3c..b98348307f3 100644 --- a/source/blender/editors/space_file/file_ops.c +++ b/source/blender/editors/space_file/file_ops.c @@ -188,7 +188,7 @@ static FileSelect file_select_do(bContext *C, int selected_idx, bool do_diropen) Main *bmain = CTX_data_main(C); FileSelect retval = FILE_SELECT_NOTHING; SpaceFile *sfile = CTX_wm_space_file(C); - FileSelectParams *params = ED_fileselect_get_params(sfile); + FileSelectParams *params = ED_fileselect_get_active_params(sfile); int numfiles = filelist_files_ensure(sfile->files); const FileDirEntry *file; @@ -302,10 +302,10 @@ static FileSelect file_select( bContext *C, const rcti *rect, FileSelType select, bool fill, bool do_diropen) { SpaceFile *sfile = CTX_wm_space_file(C); + FileSelectParams *params = ED_fileselect_get_active_params(sfile); FileSelect retval = FILE_SELECT_NOTHING; FileSelection sel = file_selection_get(C, rect, fill); /* get the selection */ - const FileCheckType check_type = (sfile->params->flag & FILE_DIRSEL_ONLY) ? CHECK_DIRS : - CHECK_ALL; + const FileCheckType check_type = (params->flag & FILE_DIRSEL_ONLY) ? CHECK_DIRS : CHECK_ALL; /* flag the files as selected in the filelist */ filelist_entries_select_index_range_set( @@ -325,7 +325,7 @@ static FileSelect file_select( } if (select != FILE_SEL_ADD && !file_is_any_selected(sfile->files)) { - sfile->params->active_file = -1; + params->active_file = -1; } else if (sel.last >= 0) { ARegion *region = CTX_wm_region(C); @@ -390,7 +390,7 @@ static int file_box_select_modal(bContext *C, wmOperator *op, const wmEvent *eve { ARegion *region = CTX_wm_region(C); SpaceFile *sfile = CTX_wm_space_file(C); - FileSelectParams *params = ED_fileselect_get_params(sfile); + FileSelectParams *params = ED_fileselect_get_active_params(sfile); FileSelection sel; rcti rect; @@ -521,8 +521,9 @@ static int file_select_invoke(bContext *C, wmOperator *op, const wmEvent *event) return OPERATOR_CANCELLED | OPERATOR_PASS_THROUGH; } - if (sfile && sfile->params) { - int idx = sfile->params->highlight_file; + const FileSelectParams *params = ED_fileselect_get_active_params(sfile); + if (sfile && params) { + int idx = params->highlight_file; int numfiles = filelist_files_ensure(sfile->files); if ((idx >= 0) && (idx < numfiles)) { @@ -613,7 +614,7 @@ static bool file_walk_select_selection_set(wmWindow *win, const bool extend, const bool fill) { - FileSelectParams *params = sfile->params; + FileSelectParams *params = ED_fileselect_get_active_params(sfile); struct FileList *files = sfile->files; const int last_sel = params->active_file; /* store old value */ int active = active_old; /* could use active_old instead, just for readability */ @@ -804,7 +805,7 @@ static bool file_walk_select_do(bContext *C, static int file_walk_select_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event)) { SpaceFile *sfile = (SpaceFile *)CTX_wm_space_data(C); - FileSelectParams *params = sfile->params; + FileSelectParams *params = ED_fileselect_get_active_params(sfile); const int direction = RNA_enum_get(op->ptr, "direction"); const bool extend = RNA_boolean_get(op->ptr, "extend"); const bool fill = RNA_boolean_get(op->ptr, "fill"); @@ -853,6 +854,7 @@ static int file_select_all_exec(bContext *C, wmOperator *op) { ScrArea *area = CTX_wm_area(C); SpaceFile *sfile = CTX_wm_space_file(C); + FileSelectParams *params = ED_fileselect_get_active_params(sfile); FileSelection sel; const int numfiles = filelist_files_ensure(sfile->files); int action = RNA_enum_get(op->ptr, "action"); @@ -870,7 +872,7 @@ static int file_select_all_exec(bContext *C, wmOperator *op) switch (action) { case SEL_SELECT: case SEL_INVERT: { - check_type = (sfile->params->flag & FILE_DIRSEL_ONLY) ? CHECK_DIRS : CHECK_FILES; + check_type = (params->flag & FILE_DIRSEL_ONLY) ? CHECK_DIRS : CHECK_FILES; filesel_type = (action == SEL_INVERT) ? FILE_SEL_TOGGLE : FILE_SEL_ADD; break; } @@ -888,11 +890,11 @@ static int file_select_all_exec(bContext *C, wmOperator *op) filelist_entries_select_index_range_set( sfile->files, &sel, filesel_type, FILE_SEL_SELECTED, check_type); - sfile->params->active_file = -1; + params->active_file = -1; if (action != SEL_DESELECT) { for (int i = 0; i < numfiles; i++) { if (filelist_entry_select_index_get(sfile->files, i, check_type)) { - sfile->params->active_file = i; + params->active_file = i; break; } } @@ -935,8 +937,8 @@ static int bookmark_select_exec(bContext *C, wmOperator *op) PropertyRNA *prop; if ((prop = RNA_struct_find_property(op->ptr, "dir"))) { + FileSelectParams *params = ED_fileselect_get_active_params(sfile); char entry[256]; - FileSelectParams *params = sfile->params; RNA_property_string_get(op->ptr, prop, entry); BLI_strncpy(params->dir, entry, sizeof(params->dir)); @@ -978,7 +980,7 @@ static int bookmark_add_exec(bContext *C, wmOperator *UNUSED(op)) ScrArea *area = CTX_wm_area(C); SpaceFile *sfile = CTX_wm_space_file(C); struct FSMenu *fsmenu = ED_fsmenu_get(); - struct FileSelectParams *params = ED_fileselect_get_params(sfile); + struct FileSelectParams *params = ED_fileselect_get_active_params(sfile); if (params->dir[0] != '\0') { char name[FILE_MAX]; @@ -1274,7 +1276,7 @@ int file_highlight_set(SpaceFile *sfile, ARegion *region, int mx, int my) } numfiles = filelist_files_ensure(sfile->files); - params = ED_fileselect_get_params(sfile); + params = ED_fileselect_get_active_params(sfile); origfile = params->highlight_file; @@ -1345,20 +1347,21 @@ static int file_column_sort_ui_context_invoke(bContext *C, if (file_attribute_column_header_is_inside( ®ion->v2d, sfile->layout, event->mval[0], event->mval[1])) { + FileSelectParams *params = ED_fileselect_get_active_params(sfile); const FileAttributeColumnType column_type = file_attribute_column_type_find_isect( - ®ion->v2d, sfile->params, sfile->layout, event->mval[0]); + ®ion->v2d, params, sfile->layout, event->mval[0]); if (column_type != COLUMN_NONE) { const FileAttributeColumn *column = &sfile->layout->attribute_columns[column_type]; BLI_assert(column->sort_type != FILE_SORT_DEFAULT); - if (sfile->params->sort == column->sort_type) { + if (params->sort == column->sort_type) { /* Already sorting by selected column -> toggle sort invert (three state logic). */ - sfile->params->flag ^= FILE_SORT_INVERT; + params->flag ^= FILE_SORT_INVERT; } else { - sfile->params->sort = column->sort_type; - sfile->params->flag &= ~FILE_SORT_INVERT; + params->sort = column->sort_type; + params->flag &= ~FILE_SORT_INVERT; } WM_event_add_notifier(C, NC_SPACE | ND_SPACE_FILE_PARAMS, NULL); @@ -1433,10 +1436,11 @@ void FILE_OT_cancel(struct wmOperatorType *ot) void file_sfile_to_operator_ex(Main *bmain, wmOperator *op, SpaceFile *sfile, char *filepath) { + FileSelectParams *params = ED_fileselect_get_active_params(sfile); PropertyRNA *prop; /* XXX, not real length */ - BLI_join_dirfile(filepath, FILE_MAX, sfile->params->dir, sfile->params->file); + BLI_join_dirfile(filepath, FILE_MAX, params->dir, params->file); if ((prop = RNA_struct_find_property(op->ptr, "relative_path"))) { if (RNA_property_boolean_get(op->ptr, prop)) { @@ -1445,10 +1449,10 @@ void file_sfile_to_operator_ex(Main *bmain, wmOperator *op, SpaceFile *sfile, ch } if ((prop = RNA_struct_find_property(op->ptr, "filename"))) { - RNA_property_string_set(op->ptr, prop, sfile->params->file); + RNA_property_string_set(op->ptr, prop, params->file); } if ((prop = RNA_struct_find_property(op->ptr, "directory"))) { - RNA_property_string_set(op->ptr, prop, sfile->params->dir); + RNA_property_string_set(op->ptr, prop, params->dir); } if ((prop = RNA_struct_find_property(op->ptr, "filepath"))) { RNA_property_string_set(op->ptr, prop, filepath); @@ -1479,7 +1483,7 @@ void file_sfile_to_operator_ex(Main *bmain, wmOperator *op, SpaceFile *sfile, ch * files selected */ if (0 == num_files) { RNA_property_collection_add(op->ptr, prop, &itemptr); - RNA_string_set(&itemptr, "name", sfile->params->file); + RNA_string_set(&itemptr, "name", params->file); } } @@ -1500,7 +1504,7 @@ void file_sfile_to_operator_ex(Main *bmain, wmOperator *op, SpaceFile *sfile, ch * directory selected */ if (0 == num_dirs) { RNA_property_collection_add(op->ptr, prop, &itemptr); - RNA_string_set(&itemptr, "name", sfile->params->dir); + RNA_string_set(&itemptr, "name", params->dir); } } } @@ -1514,30 +1518,28 @@ void file_sfile_to_operator(Main *bmain, wmOperator *op, SpaceFile *sfile) void file_operator_to_sfile(Main *bmain, SpaceFile *sfile, wmOperator *op) { + FileSelectParams *params = ED_fileselect_get_active_params(sfile); PropertyRNA *prop; /* If neither of the above are set, split the filepath back */ if ((prop = RNA_struct_find_property(op->ptr, "filepath"))) { char filepath[FILE_MAX]; RNA_property_string_get(op->ptr, prop, filepath); - BLI_split_dirfile(filepath, - sfile->params->dir, - sfile->params->file, - sizeof(sfile->params->dir), - sizeof(sfile->params->file)); + BLI_split_dirfile( + filepath, params->dir, params->file, sizeof(params->dir), sizeof(params->file)); } else { if ((prop = RNA_struct_find_property(op->ptr, "filename"))) { - RNA_property_string_get(op->ptr, prop, sfile->params->file); + RNA_property_string_get(op->ptr, prop, params->file); } if ((prop = RNA_struct_find_property(op->ptr, "directory"))) { - RNA_property_string_get(op->ptr, prop, sfile->params->dir); + RNA_property_string_get(op->ptr, prop, params->dir); } } /* we could check for relative_path property which is used when converting * in the other direction but doesn't hurt to do this every time */ - BLI_path_abs(sfile->params->dir, BKE_main_blendfile_path(bmain)); + BLI_path_abs(params->dir, BKE_main_blendfile_path(bmain)); /* XXX, files and dirs updates missing, not really so important though */ } @@ -1547,21 +1549,19 @@ void file_operator_to_sfile(Main *bmain, SpaceFile *sfile, wmOperator *op) */ void file_sfile_filepath_set(SpaceFile *sfile, const char *filepath) { + FileSelectParams *params = ED_fileselect_get_active_params(sfile); BLI_assert(BLI_exists(filepath)); if (BLI_is_dir(filepath)) { - BLI_strncpy(sfile->params->dir, filepath, sizeof(sfile->params->dir)); + BLI_strncpy(params->dir, filepath, sizeof(params->dir)); } else { - if ((sfile->params->flag & FILE_DIRSEL_ONLY) == 0) { - BLI_split_dirfile(filepath, - sfile->params->dir, - sfile->params->file, - sizeof(sfile->params->dir), - sizeof(sfile->params->file)); + if ((params->flag & FILE_DIRSEL_ONLY) == 0) { + BLI_split_dirfile( + filepath, params->dir, params->file, sizeof(params->dir), sizeof(params->file)); } else { - BLI_split_dir_part(filepath, sfile->params->dir, sizeof(sfile->params->dir)); + BLI_split_dir_part(filepath, params->dir, sizeof(params->dir)); } } } @@ -1605,9 +1605,10 @@ void file_draw_check_cb(bContext *C, void *UNUSED(arg1), void *UNUSED(arg2)) bool file_draw_check_exists(SpaceFile *sfile) { if (sfile->op) { /* fails on reload */ - if (sfile->params && (sfile->params->flag & FILE_CHECK_EXISTING)) { + const FileSelectParams *params = ED_fileselect_get_active_params(sfile); + if (params && (params->flag & FILE_CHECK_EXISTING)) { char filepath[FILE_MAX]; - BLI_join_dirfile(filepath, sizeof(filepath), sfile->params->dir, sfile->params->file); + BLI_join_dirfile(filepath, sizeof(filepath), params->dir, params->file); if (BLI_is_file(filepath)) { return true; } @@ -1628,21 +1629,22 @@ static int file_exec(bContext *C, wmOperator *exec_op) Main *bmain = CTX_data_main(C); wmWindowManager *wm = CTX_wm_manager(C); SpaceFile *sfile = CTX_wm_space_file(C); - struct FileDirEntry *file = filelist_file(sfile->files, sfile->params->active_file); + FileSelectParams *params = ED_fileselect_get_active_params(sfile); + struct FileDirEntry *file = filelist_file(sfile->files, params->active_file); char filepath[FILE_MAX]; if (file && file->redirection_path) { /* redirection_path is an absolute path that takes precedence - * over using sfile->params->dir + sfile->params->file. */ + * over using params->dir + params->file. */ BLI_split_dirfile(file->redirection_path, - sfile->params->dir, - sfile->params->file, - sizeof(sfile->params->dir), - sizeof(sfile->params->file)); + params->dir, + params->file, + sizeof(params->dir), + sizeof(params->file)); /* Update relpath with redirected filename as well so that the alternative - * combination of sfile->params->dir + relpath remains valid as well. */ + * combination of params->dir + relpath remains valid as well. */ MEM_freeN(file->relpath); - file->relpath = BLI_strdup(sfile->params->file); + file->relpath = BLI_strdup(params->file); } /* directory change */ @@ -1652,12 +1654,12 @@ static int file_exec(bContext *C, wmOperator *exec_op) } if (FILENAME_IS_PARENT(file->relpath)) { - BLI_path_parent_dir(sfile->params->dir); + BLI_path_parent_dir(params->dir); } else { - BLI_path_normalize(BKE_main_blendfile_path(bmain), sfile->params->dir); - BLI_path_append(sfile->params->dir, sizeof(sfile->params->dir) - 1, file->relpath); - BLI_path_slash_ensure(sfile->params->dir); + BLI_path_normalize(BKE_main_blendfile_path(bmain), params->dir); + BLI_path_append(params->dir, sizeof(params->dir) - 1, file->relpath); + BLI_path_slash_ensure(params->dir); } ED_file_change_dir(C); } @@ -1685,10 +1687,10 @@ static int file_exec(bContext *C, wmOperator *exec_op) file_sfile_to_operator_ex(bmain, op, sfile, filepath); - if (BLI_exists(sfile->params->dir)) { + if (BLI_exists(params->dir)) { fsmenu_insert_entry(ED_fsmenu_get(), FS_CATEGORY_RECENT, - sfile->params->dir, + params->dir, NULL, ICON_FILE_FOLDER, FS_INSERT_SAVE | FS_INSERT_FIRST); @@ -1792,15 +1794,16 @@ static int file_parent_exec(bContext *C, wmOperator *UNUSED(unused)) { Main *bmain = CTX_data_main(C); SpaceFile *sfile = CTX_wm_space_file(C); + FileSelectParams *params = ED_fileselect_get_active_params(sfile); - if (sfile->params) { - if (BLI_path_parent_dir(sfile->params->dir)) { - BLI_path_normalize_dir(BKE_main_blendfile_path(bmain), sfile->params->dir); + if (params) { + if (BLI_path_parent_dir(params->dir)) { + BLI_path_normalize_dir(BKE_main_blendfile_path(bmain), params->dir); ED_file_change_dir(C); - if (sfile->params->recursion_level > 1) { + if (params->recursion_level > 1) { /* Disable 'dirtree' recursion when going up in tree. */ - sfile->params->recursion_level = 0; - filelist_setrecursion(sfile->files, sfile->params->recursion_level); + params->recursion_level = 0; + filelist_setrecursion(sfile->files, params->recursion_level); } WM_event_add_notifier(C, NC_SPACE | ND_SPACE_FILE_LIST, NULL); } @@ -1830,15 +1833,16 @@ void FILE_OT_parent(struct wmOperatorType *ot) static int file_previous_exec(bContext *C, wmOperator *UNUSED(op)) { SpaceFile *sfile = CTX_wm_space_file(C); + FileSelectParams *params = ED_fileselect_get_active_params(sfile); - if (sfile->params) { + if (params) { if (!sfile->folders_next) { sfile->folders_next = folderlist_new(); } - folderlist_pushdir(sfile->folders_next, sfile->params->dir); - folderlist_popdir(sfile->folders_prev, sfile->params->dir); - folderlist_pushdir(sfile->folders_next, sfile->params->dir); + folderlist_pushdir(sfile->folders_next, params->dir); + folderlist_popdir(sfile->folders_prev, params->dir); + folderlist_pushdir(sfile->folders_next, params->dir); ED_file_change_dir(C); } @@ -1868,16 +1872,17 @@ void FILE_OT_previous(struct wmOperatorType *ot) static int file_next_exec(bContext *C, wmOperator *UNUSED(unused)) { SpaceFile *sfile = CTX_wm_space_file(C); - if (sfile->params) { + FileSelectParams *params = ED_fileselect_get_active_params(sfile); + if (params) { if (!sfile->folders_next) { sfile->folders_next = folderlist_new(); } - folderlist_pushdir(sfile->folders_prev, sfile->params->dir); - folderlist_popdir(sfile->folders_next, sfile->params->dir); + folderlist_pushdir(sfile->folders_prev, params->dir); + folderlist_popdir(sfile->folders_next, params->dir); /* update folders_prev so we can check for it in #folderlist_clear_next() */ - folderlist_pushdir(sfile->folders_prev, sfile->params->dir); + folderlist_pushdir(sfile->folders_prev, params->dir); ED_file_change_dir(C); } @@ -1923,7 +1928,7 @@ static int file_smoothscroll_invoke(bContext *C, wmOperator *UNUSED(op), const w /* Due to async nature of file listing, we may execute this code before `file_refresh()` * editing entry is available in our listing, * so we also have to handle switching to rename mode here. */ - FileSelectParams *params = ED_fileselect_get_params(sfile); + FileSelectParams *params = ED_fileselect_get_active_params(sfile); if ((params->rename_flag & (FILE_PARAMS_RENAME_PENDING | FILE_PARAMS_RENAME_POSTSCROLL_PENDING)) != 0) { file_params_renamefile_activate(sfile, params); @@ -2175,9 +2180,10 @@ static int file_directory_new_exec(bContext *C, wmOperator *op) wmWindowManager *wm = CTX_wm_manager(C); SpaceFile *sfile = CTX_wm_space_file(C); + FileSelectParams *params = ED_fileselect_get_active_params(sfile); const bool do_diropen = RNA_boolean_get(op->ptr, "open"); - if (!sfile->params) { + if (!params) { BKE_report(op->reports, RPT_WARNING, "No parent directory given"); return OPERATOR_CANCELLED; } @@ -2193,7 +2199,7 @@ static int file_directory_new_exec(bContext *C, wmOperator *op) if (generate_name) { /* create a new, non-existing folder name */ - if (!new_folder_path(sfile->params->dir, path, name)) { + if (!new_folder_path(params->dir, path, name)) { BKE_report(op->reports, RPT_ERROR, "Could not create new folder name"); return OPERATOR_CANCELLED; } @@ -2226,8 +2232,8 @@ static int file_directory_new_exec(bContext *C, wmOperator *op) /* If we don't enter the directory directly, remember file to jump into editing. */ if (do_diropen == false) { - BLI_strncpy(sfile->params->renamefile, name, FILE_MAXFILE); - sfile->params->rename_flag = FILE_PARAMS_RENAME_PENDING; + BLI_strncpy(params->renamefile, name, FILE_MAXFILE); + params->rename_flag = FILE_PARAMS_RENAME_PENDING; } /* set timer to smoothly view newly generated file */ @@ -2242,7 +2248,7 @@ static int file_directory_new_exec(bContext *C, wmOperator *op) ED_fileselect_clear(wm, CTX_data_scene(C), sfile); if (do_diropen) { - BLI_strncpy(sfile->params->dir, path, sizeof(sfile->params->dir)); + BLI_strncpy(params->dir, path, sizeof(params->dir)); ED_file_change_dir(C); } @@ -2284,38 +2290,37 @@ static void file_expand_directory(bContext *C) { Main *bmain = CTX_data_main(C); SpaceFile *sfile = CTX_wm_space_file(C); + FileSelectParams *params = ED_fileselect_get_active_params(sfile); - if (sfile->params) { - if (BLI_path_is_rel(sfile->params->dir)) { + if (params) { + if (BLI_path_is_rel(params->dir)) { /* Use of 'default' folder here is just to avoid an error message on '//' prefix. */ - BLI_path_abs(sfile->params->dir, + BLI_path_abs(params->dir, G.relbase_valid ? BKE_main_blendfile_path(bmain) : BKE_appdir_folder_default()); } - else if (sfile->params->dir[0] == '~') { - char tmpstr[sizeof(sfile->params->dir) - 1]; - BLI_strncpy(tmpstr, sfile->params->dir + 1, sizeof(tmpstr)); - BLI_join_dirfile( - sfile->params->dir, sizeof(sfile->params->dir), BKE_appdir_folder_default(), tmpstr); + else if (params->dir[0] == '~') { + char tmpstr[sizeof(params->dir) - 1]; + BLI_strncpy(tmpstr, params->dir + 1, sizeof(tmpstr)); + BLI_join_dirfile(params->dir, sizeof(params->dir), BKE_appdir_folder_default(), tmpstr); } - else if (sfile->params->dir[0] == '\0') + else if (params->dir[0] == '\0') #ifndef WIN32 { - sfile->params->dir[0] = '/'; - sfile->params->dir[1] = '\0'; + params->dir[0] = '/'; + params->dir[1] = '\0'; } #else { - BLI_windows_get_default_root_dir(sfile->params->dir); + BLI_windows_get_default_root_dir(params->dir); } /* change "C:" --> "C:\", T28102. */ - else if ((isalpha(sfile->params->dir[0]) && (sfile->params->dir[1] == ':')) && - (sfile->params->dir[2] == '\0')) { - sfile->params->dir[2] = '\\'; - sfile->params->dir[3] = '\0'; + else if ((isalpha(params->dir[0]) && (params->dir[1] == ':')) && (params->dir[2] == '\0')) { + params->dir[2] = '\\'; + params->dir[3] = '\0'; } - else if (BLI_path_is_unc(sfile->params->dir)) { - BLI_path_normalize_unc(sfile->params->dir, FILE_MAX_LIBEXTRA); + else if (BLI_path_is_unc(params->dir)) { + BLI_path_normalize_unc(params->dir, FILE_MAX_LIBEXTRA); } #endif } @@ -2343,46 +2348,44 @@ void file_directory_enter_handle(bContext *C, void *UNUSED(arg_unused), void *UN { Main *bmain = CTX_data_main(C); SpaceFile *sfile = CTX_wm_space_file(C); + FileSelectParams *params = ED_fileselect_get_active_params(sfile); - if (sfile->params) { - char old_dir[sizeof(sfile->params->dir)]; + if (params) { + char old_dir[sizeof(params->dir)]; - BLI_strncpy(old_dir, sfile->params->dir, sizeof(old_dir)); + BLI_strncpy(old_dir, params->dir, sizeof(old_dir)); file_expand_directory(C); /* special case, user may have pasted a filepath into the directory */ - if (!filelist_is_dir(sfile->files, sfile->params->dir)) { + if (!filelist_is_dir(sfile->files, params->dir)) { char tdir[FILE_MAX_LIBEXTRA]; char *group, *name; - if (BLI_is_file(sfile->params->dir)) { - char path[sizeof(sfile->params->dir)]; - BLI_strncpy(path, sfile->params->dir, sizeof(path)); - BLI_split_dirfile(path, - sfile->params->dir, - sfile->params->file, - sizeof(sfile->params->dir), - sizeof(sfile->params->file)); + if (BLI_is_file(params->dir)) { + char path[sizeof(params->dir)]; + BLI_strncpy(path, params->dir, sizeof(path)); + BLI_split_dirfile( + path, params->dir, params->file, sizeof(params->dir), sizeof(params->file)); } - else if (BLO_library_path_explode(sfile->params->dir, tdir, &group, &name)) { + else if (BLO_library_path_explode(params->dir, tdir, &group, &name)) { if (group) { BLI_path_append(tdir, sizeof(tdir), group); } - BLI_strncpy(sfile->params->dir, tdir, sizeof(sfile->params->dir)); + BLI_strncpy(params->dir, tdir, sizeof(params->dir)); if (name) { - BLI_strncpy(sfile->params->file, name, sizeof(sfile->params->file)); + BLI_strncpy(params->file, name, sizeof(params->file)); } else { - sfile->params->file[0] = '\0'; + params->file[0] = '\0'; } } } - BLI_path_normalize_dir(BKE_main_blendfile_path(bmain), sfile->params->dir); + BLI_path_normalize_dir(BKE_main_blendfile_path(bmain), params->dir); - if (filelist_is_dir(sfile->files, sfile->params->dir)) { - if (!STREQ(sfile->params->dir, old_dir)) { /* Avoids flickering when nothing's changed. */ + if (filelist_is_dir(sfile->files, params->dir)) { + if (!STREQ(params->dir, old_dir)) { /* Avoids flickering when nothing's changed. */ /* if directory exists, enter it immediately */ ED_file_change_dir(C); } @@ -2392,10 +2395,10 @@ void file_directory_enter_handle(bContext *C, void *UNUSED(arg_unused), void *UN /* UI_textbutton_activate_but(C, but); */ } #if defined(WIN32) - else if (!can_create_dir(sfile->params->dir)) { + else if (!can_create_dir(params->dir)) { const char *lastdir = folderlist_peeklastdir(sfile->folders_prev); if (lastdir) { - BLI_strncpy(sfile->params->dir, lastdir, sizeof(sfile->params->dir)); + BLI_strncpy(params->dir, lastdir, sizeof(params->dir)); } } #endif @@ -2405,21 +2408,21 @@ void file_directory_enter_handle(bContext *C, void *UNUSED(arg_unused), void *UN /* If we are 'inside' a blend library, we cannot do anything... */ if (lastdir && BLO_library_path_explode(lastdir, tdir, NULL, NULL)) { - BLI_strncpy(sfile->params->dir, lastdir, sizeof(sfile->params->dir)); + BLI_strncpy(params->dir, lastdir, sizeof(params->dir)); } else { /* if not, ask to create it and enter if confirmed */ wmOperatorType *ot = WM_operatortype_find("FILE_OT_directory_new", false); PointerRNA ptr; WM_operator_properties_create_ptr(&ptr, ot); - RNA_string_set(&ptr, "directory", sfile->params->dir); + RNA_string_set(&ptr, "directory", params->dir); RNA_boolean_set(&ptr, "open", true); /* Enable confirmation prompt, else it's too easy * to accidentally create new directories. */ RNA_boolean_set(&ptr, "confirm", true); if (lastdir) { - BLI_strncpy(sfile->params->dir, lastdir, sizeof(sfile->params->dir)); + BLI_strncpy(params->dir, lastdir, sizeof(params->dir)); } WM_operator_name_call_ptr(C, ot, WM_OP_INVOKE_DEFAULT, &ptr); @@ -2435,39 +2438,39 @@ void file_filename_enter_handle(bContext *C, void *UNUSED(arg_unused), void *arg { Main *bmain = CTX_data_main(C); SpaceFile *sfile = CTX_wm_space_file(C); + FileSelectParams *params = ED_fileselect_get_active_params(sfile); uiBut *but = arg_but; char matched_file[FILE_MAX]; - char filepath[sizeof(sfile->params->dir)]; - if (sfile->params) { + if (params) { + char filepath[sizeof(params->dir)]; int matches; matched_file[0] = '\0'; filepath[0] = '\0'; file_expand_directory(C); - matches = file_select_match(sfile, sfile->params->file, matched_file); + matches = file_select_match(sfile, params->file, matched_file); /* *After* file_select_match! */ - BLI_filename_make_safe(sfile->params->file); + BLI_filename_make_safe(params->file); if (matches) { /* replace the pattern (or filename that the user typed in, * with the first selected file of the match */ - BLI_strncpy(sfile->params->file, matched_file, sizeof(sfile->params->file)); + BLI_strncpy(params->file, matched_file, sizeof(params->file)); WM_event_add_notifier(C, NC_SPACE | ND_SPACE_FILE_PARAMS, NULL); } if (matches == 1) { - BLI_join_dirfile( - filepath, sizeof(sfile->params->dir), sfile->params->dir, sfile->params->file); + BLI_join_dirfile(filepath, sizeof(params->dir), params->dir, params->file); /* if directory, open it and empty filename field */ if (filelist_is_dir(sfile->files, filepath)) { BLI_path_normalize_dir(BKE_main_blendfile_path(bmain), filepath); - BLI_strncpy(sfile->params->dir, filepath, sizeof(sfile->params->dir)); - sfile->params->file[0] = '\0'; + BLI_strncpy(params->dir, filepath, sizeof(params->dir)); + params->file[0] = '\0'; ED_file_change_dir(C); UI_textbutton_activate_but(C, but); WM_event_add_notifier(C, NC_SPACE | ND_SPACE_FILE_PARAMS, NULL); @@ -2489,9 +2492,10 @@ static int file_hidedot_exec(bContext *C, wmOperator *UNUSED(unused)) { wmWindowManager *wm = CTX_wm_manager(C); SpaceFile *sfile = CTX_wm_space_file(C); + FileSelectParams *params = ED_fileselect_get_active_params(sfile); - if (sfile->params) { - sfile->params->flag ^= FILE_HIDE_DOT; + if (params) { + params->flag ^= FILE_HIDE_DOT; ED_fileselect_clear(wm, CTX_data_scene(C), sfile); WM_event_add_notifier(C, NC_SPACE | ND_SPACE_FILE_LIST, NULL); } @@ -2525,7 +2529,8 @@ static bool file_filenum_poll(bContext *C) return false; } - return sfile->params && (sfile->params->flag & FILE_CHECK_EXISTING); + FileSelectParams *params = ED_fileselect_get_active_params(sfile); + return params && (params->flag & FILE_CHECK_EXISTING); } /** @@ -2563,11 +2568,12 @@ static void filenum_newname(char *name, size_t name_size, int add) static int file_filenum_exec(bContext *C, wmOperator *op) { SpaceFile *sfile = CTX_wm_space_file(C); + FileSelectParams *params = ED_fileselect_get_active_params(sfile); ScrArea *area = CTX_wm_area(C); int inc = RNA_int_get(op->ptr, "increment"); - if (sfile->params && (inc != 0)) { - filenum_newname(sfile->params->file, sizeof(sfile->params->file), inc); + if (params && (inc != 0)) { + filenum_newname(params->file, sizeof(params->file), inc); ED_area_tag_redraw(area); file_draw_check(C); // WM_event_add_notifier(C, NC_WINDOW, NULL); @@ -2606,12 +2612,14 @@ static void file_rename_state_activate(SpaceFile *sfile, int file_idx, bool requ if ((require_selected == false) || (filelist_entry_select_get(sfile->files, file, CHECK_ALL) & FILE_SEL_SELECTED)) { + FileSelectParams *params = ED_fileselect_get_active_params(sfile); + filelist_entry_select_index_set( sfile->files, file_idx, FILE_SEL_ADD, FILE_SEL_EDITING, CHECK_ALL); - BLI_strncpy(sfile->params->renamefile, file->relpath, FILE_MAXFILE); + BLI_strncpy(params->renamefile, file->relpath, FILE_MAXFILE); /* We can skip the pending state, * as we can directly set FILE_SEL_EDITING on the expected entry here. */ - sfile->params->rename_flag = FILE_PARAMS_RENAME_ACTIVE; + params->rename_flag = FILE_PARAMS_RENAME_ACTIVE; } } } @@ -2620,9 +2628,10 @@ static int file_rename_invoke(bContext *C, wmOperator *UNUSED(op), const wmEvent { ScrArea *area = CTX_wm_area(C); SpaceFile *sfile = (SpaceFile *)CTX_wm_space_data(C); + FileSelectParams *params = ED_fileselect_get_active_params(sfile); - if (sfile->params) { - file_rename_state_activate(sfile, sfile->params->active_file, true); + if (params) { + file_rename_state_activate(sfile, params->active_file, true); ED_area_tag_redraw(area); } @@ -2633,9 +2642,10 @@ static int file_rename_exec(bContext *C, wmOperator *UNUSED(op)) { ScrArea *area = CTX_wm_area(C); SpaceFile *sfile = (SpaceFile *)CTX_wm_space_data(C); + FileSelectParams *params = ED_fileselect_get_active_params(sfile); - if (sfile->params) { - file_rename_state_activate(sfile, sfile->params->highlight_file, false); + if (params) { + file_rename_state_activate(sfile, params->highlight_file, false); ED_area_tag_redraw(area); } @@ -2665,8 +2675,9 @@ static bool file_delete_poll(bContext *C) { bool poll = ED_operator_file_active(C); SpaceFile *sfile = CTX_wm_space_file(C); + FileSelectParams *params = ED_fileselect_get_active_params(sfile); - if (sfile && sfile->params) { + if (sfile && params) { char dir[FILE_MAX_LIBEXTRA]; int numfiles = filelist_files_ensure(sfile->files); int i; @@ -2695,6 +2706,7 @@ static int file_delete_exec(bContext *C, wmOperator *op) { wmWindowManager *wm = CTX_wm_manager(C); SpaceFile *sfile = CTX_wm_space_file(C); + FileSelectParams *params = ED_fileselect_get_active_params(sfile); int numfiles = filelist_files_ensure(sfile->files); const char *error_message = NULL; @@ -2704,7 +2716,7 @@ static int file_delete_exec(bContext *C, wmOperator *op) if (filelist_entry_select_index_get(sfile->files, i, CHECK_ALL)) { FileDirEntry *file = filelist_file(sfile->files, i); char str[FILE_MAX]; - BLI_join_dirfile(str, sizeof(str), sfile->params->dir, file->relpath); + BLI_join_dirfile(str, sizeof(str), params->dir, file->relpath); if (BLI_delete_soft(str, &error_message) != 0 || BLI_exists(str)) { report_error = true; } @@ -2752,11 +2764,12 @@ static int file_start_filter_exec(bContext *C, wmOperator *UNUSED(op)) { ScrArea *area = CTX_wm_area(C); ARegion *region = BKE_area_find_region_type(area, RGN_TYPE_UI); - SpaceFile *sf = CTX_wm_space_file(C); + SpaceFile *sfile = CTX_wm_space_file(C); + FileSelectParams *params = ED_fileselect_get_active_params(sfile); ARegion *region_ctx = CTX_wm_region(C); CTX_wm_region_set(C, region); - UI_textbutton_activate_rna(C, region, sf->params, "filter_search"); + UI_textbutton_activate_rna(C, region, params, "filter_search"); CTX_wm_region_set(C, region_ctx); return OPERATOR_FINISHED; diff --git a/source/blender/editors/space_file/file_panels.c b/source/blender/editors/space_file/file_panels.c index 22d206c0a70..afa85d183d8 100644 --- a/source/blender/editors/space_file/file_panels.c +++ b/source/blender/editors/space_file/file_panels.c @@ -132,7 +132,7 @@ static void file_panel_execution_buttons_draw(const bContext *C, Panel *panel) { bScreen *screen = CTX_wm_screen(C); SpaceFile *sfile = CTX_wm_space_file(C); - FileSelectParams *params = ED_fileselect_get_params(sfile); + FileSelectParams *params = ED_fileselect_get_active_params(sfile); uiBlock *block = uiLayoutGetBlock(panel->layout); uiBut *but; uiLayout *row; diff --git a/source/blender/editors/space_file/filelist.c b/source/blender/editors/space_file/filelist.c index b6d016aca7c..58887ae745b 100644 --- a/source/blender/editors/space_file/filelist.c +++ b/source/blender/editors/space_file/filelist.c @@ -149,6 +149,7 @@ const char *folderlist_peeklastdir(ListBase *folderlist) int folderlist_clear_next(struct SpaceFile *sfile) { + const FileSelectParams *params = ED_fileselect_get_active_params(sfile); struct FolderList *folder; /* if there is no folder_next there is nothing we can clear */ @@ -159,7 +160,7 @@ int folderlist_clear_next(struct SpaceFile *sfile) /* if previous_folder, next_folder or refresh_folder operators are executed * it doesn't clear folder_next */ folder = sfile->folders_prev->last; - if ((!folder) || (BLI_path_cmp(folder->foldername, sfile->params->dir) == 0)) { + if ((!folder) || (BLI_path_cmp(folder->foldername, params->dir) == 0)) { return 0; } diff --git a/source/blender/editors/space_file/filesel.c b/source/blender/editors/space_file/filesel.c index 15c6972c5f5..ffa44083473 100644 --- a/source/blender/editors/space_file/filesel.c +++ b/source/blender/editors/space_file/filesel.c @@ -77,18 +77,20 @@ #define VERTLIST_MAJORCOLUMN_WIDTH (25 * UI_UNIT_X) -FileSelectParams *ED_fileselect_get_params(struct SpaceFile *sfile) +FileSelectParams *ED_fileselect_get_active_params(const SpaceFile *sfile) { - if (!sfile->params) { - ED_fileselect_set_params(sfile); + if (!sfile) { + /* Sometimes called in poll before space type was checked. */ + return NULL; } + return sfile->params; } /** * \note RNA_struct_property_is_set_ex is used here because we want * the previously used settings to be used here rather than overriding them */ -short ED_fileselect_set_params(SpaceFile *sfile) +static void fileselect_ensure_file_params(SpaceFile *sfile) { FileSelectParams *params; wmOperator *op = sfile->op; @@ -136,20 +138,17 @@ short ED_fileselect_set_params(SpaceFile *sfile) RNA_string_get(op->ptr, "filepath", name); if (params->type == FILE_LOADLIB) { BLI_strncpy(params->dir, name, sizeof(params->dir)); - sfile->params->file[0] = '\0'; + params->file[0] = '\0'; } else { - BLI_split_dirfile(name, - sfile->params->dir, - sfile->params->file, - sizeof(sfile->params->dir), - sizeof(sfile->params->file)); + BLI_split_dirfile( + name, params->dir, params->file, sizeof(params->dir), sizeof(params->file)); } } else { if (is_directory && RNA_struct_property_is_set_ex(op->ptr, "directory", false)) { RNA_string_get(op->ptr, "directory", params->dir); - sfile->params->file[0] = '\0'; + params->file[0] = '\0'; } if (is_filename && RNA_struct_property_is_set_ex(op->ptr, "filename", false)) { @@ -306,26 +305,32 @@ short ED_fileselect_set_params(SpaceFile *sfile) sfile->folders_prev = folderlist_new(); } - if (!sfile->params->dir[0]) { + if (!params->dir[0]) { if (blendfile_path[0] != '\0') { - BLI_split_dir_part(blendfile_path, sfile->params->dir, sizeof(sfile->params->dir)); + BLI_split_dir_part(blendfile_path, params->dir, sizeof(params->dir)); } else { const char *doc_path = BKE_appdir_folder_default(); if (doc_path) { - BLI_strncpy(sfile->params->dir, doc_path, sizeof(sfile->params->dir)); + BLI_strncpy(params->dir, doc_path, sizeof(params->dir)); } } } - folderlist_pushdir(sfile->folders_prev, sfile->params->dir); + folderlist_pushdir(sfile->folders_prev, params->dir); /* Switching thumbnails needs to recalc layout T28809. */ if (sfile->layout) { sfile->layout->dirty = true; } +} - return 1; +FileSelectParams *ED_fileselect_ensure_active_params(SpaceFile *sfile) +{ + if (!sfile->params) { + fileselect_ensure_file_params(sfile); + } + return sfile->params; } /* The subset of FileSelectParams.flag items we store into preferences. Note that FILE_SORT_ALPHA @@ -364,28 +369,26 @@ void ED_fileselect_set_params_from_userdef(SpaceFile *sfile) wmOperator *op = sfile->op; UserDef_FileSpaceData *sfile_udata = &U.file_space_data; - ED_fileselect_set_params(sfile); - + FileSelectParams *params = ED_fileselect_ensure_active_params(sfile); if (!op) { return; } - sfile->params->thumbnail_size = sfile_udata->thumbnail_size; - sfile->params->details_flags = sfile_udata->details_flags; - sfile->params->filter_id = sfile_udata->filter_id; + params->thumbnail_size = sfile_udata->thumbnail_size; + params->details_flags = sfile_udata->details_flags; + params->filter_id = sfile_udata->filter_id; /* Combine flags we take from params with the flags we take from userdef. */ - sfile->params->flag = (sfile->params->flag & ~PARAMS_FLAGS_REMEMBERED) | - (sfile_udata->flag & PARAMS_FLAGS_REMEMBERED); + params->flag = (params->flag & ~PARAMS_FLAGS_REMEMBERED) | + (sfile_udata->flag & PARAMS_FLAGS_REMEMBERED); if (file_select_use_default_display_type(sfile)) { - sfile->params->display = sfile_udata->display_type; + params->display = sfile_udata->display_type; } if (file_select_use_default_sort_type(sfile)) { - sfile->params->sort = sfile_udata->sort_type; + params->sort = sfile_udata->sort_type; /* For the default sorting, also take invert flag from userdef. */ - sfile->params->flag = (sfile->params->flag & ~FILE_SORT_INVERT) | - (sfile_udata->flag & FILE_SORT_INVERT); + params->flag = (params->flag & ~FILE_SORT_INVERT) | (sfile_udata->flag & FILE_SORT_INVERT); } } @@ -400,25 +403,26 @@ void ED_fileselect_params_to_userdef(SpaceFile *sfile, const int temp_win_size[2], const bool is_maximized) { + FileSelectParams *params = ED_fileselect_get_active_params(sfile); UserDef_FileSpaceData *sfile_udata_new = &U.file_space_data; UserDef_FileSpaceData sfile_udata_old = U.file_space_data; - sfile_udata_new->thumbnail_size = sfile->params->thumbnail_size; - sfile_udata_new->details_flags = sfile->params->details_flags; - sfile_udata_new->flag = sfile->params->flag & PARAMS_FLAGS_REMEMBERED; - sfile_udata_new->filter_id = sfile->params->filter_id; + sfile_udata_new->thumbnail_size = params->thumbnail_size; + sfile_udata_new->details_flags = params->details_flags; + sfile_udata_new->flag = params->flag & PARAMS_FLAGS_REMEMBERED; + sfile_udata_new->filter_id = params->filter_id; /* In some rare cases, operators ask for a specific display or sort type (e.g. chronological * sorting for "Recover Auto Save"). So the settings are optimized for a specific operation. * Don't let that change the userdef memory for more general cases. */ if (file_select_use_default_display_type(sfile)) { - sfile_udata_new->display_type = sfile->params->display; + sfile_udata_new->display_type = params->display; } if (file_select_use_default_sort_type(sfile)) { - sfile_udata_new->sort_type = sfile->params->sort; + sfile_udata_new->sort_type = params->sort; /* In this case also remember the invert flag. */ sfile_udata_new->flag = (sfile_udata_new->flag & ~FILE_SORT_INVERT) | - (sfile->params->flag & FILE_SORT_INVERT); + (params->flag & FILE_SORT_INVERT); } if (temp_win_size && !is_maximized) { @@ -434,10 +438,11 @@ void ED_fileselect_params_to_userdef(SpaceFile *sfile, void ED_fileselect_reset_params(SpaceFile *sfile) { - sfile->params->type = FILE_UNIX; - sfile->params->flag = 0; - sfile->params->title[0] = '\0'; - sfile->params->active_file = -1; + FileSelectParams *params = ED_fileselect_get_active_params(sfile); + params->type = FILE_UNIX; + params->flag = 0; + params->title[0] = '\0'; + params->active_file = -1; } /** @@ -447,7 +452,8 @@ void fileselect_file_set(SpaceFile *sfile, const int index) { const struct FileDirEntry *file = filelist_file(sfile->files, index); if (file && file->relpath && file->relpath[0] && !(file->typeflag & FILE_TYPE_DIR)) { - BLI_strncpy(sfile->params->file, file->relpath, FILE_MAXFILE); + FileSelectParams *params = ED_fileselect_get_active_params(sfile); + BLI_strncpy(params->file, file->relpath, FILE_MAXFILE); } } @@ -759,7 +765,7 @@ static void file_attribute_columns_init(const FileSelectParams *params, FileLayo void ED_fileselect_init_layout(struct SpaceFile *sfile, ARegion *region) { - FileSelectParams *params = ED_fileselect_get_params(sfile); + FileSelectParams *params = ED_fileselect_get_active_params(sfile); FileLayout *layout = NULL; View2D *v2d = ®ion->v2d; int numfiles; @@ -873,7 +879,8 @@ void ED_file_change_dir_ex(bContext *C, bScreen *screen, ScrArea *area) return; } SpaceFile *sfile = area->spacedata.first; - if (sfile->params) { + FileSelectParams *params = ED_fileselect_get_active_params(sfile); + if (params) { wmWindowManager *wm = CTX_wm_manager(C); Scene *scene = WM_windows_scene_get_from_screen(wm, screen); if (LIKELY(scene != NULL)) { @@ -882,20 +889,20 @@ void ED_file_change_dir_ex(bContext *C, bScreen *screen, ScrArea *area) /* Clear search string, it is very rare to want to keep that filter while changing dir, * and usually very annoying to keep it actually! */ - sfile->params->filter_search[0] = '\0'; - sfile->params->active_file = -1; + params->filter_search[0] = '\0'; + params->active_file = -1; - if (!filelist_is_dir(sfile->files, sfile->params->dir)) { - BLI_strncpy(sfile->params->dir, filelist_dir(sfile->files), sizeof(sfile->params->dir)); + if (!filelist_is_dir(sfile->files, params->dir)) { + BLI_strncpy(params->dir, filelist_dir(sfile->files), sizeof(params->dir)); /* could return but just refresh the current dir */ } - filelist_setdir(sfile->files, sfile->params->dir); + filelist_setdir(sfile->files, params->dir); if (folderlist_clear_next(sfile)) { folderlist_free(sfile->folders_next); } - folderlist_pushdir(sfile->folders_prev, sfile->params->dir); + folderlist_pushdir(sfile->folders_prev, params->dir); file_draw_check_ex(C, area); } @@ -1010,7 +1017,8 @@ void ED_fileselect_clear(wmWindowManager *wm, Scene *owner_scene, SpaceFile *sfi filelist_clear(sfile->files); } - sfile->params->highlight_file = -1; + FileSelectParams *params = ED_fileselect_get_active_params(sfile); + params->highlight_file = -1; WM_main_add_notifier(NC_SPACE | ND_SPACE_FILE_LIST, NULL); } diff --git a/source/blender/editors/space_file/space_file.c b/source/blender/editors/space_file/space_file.c index 6ffe553e076..c72ca58abba 100644 --- a/source/blender/editors/space_file/space_file.c +++ b/source/blender/editors/space_file/space_file.c @@ -270,7 +270,7 @@ static void file_refresh(const bContext *C, ScrArea *area) wmWindowManager *wm = CTX_wm_manager(C); wmWindow *win = CTX_wm_window(C); SpaceFile *sfile = CTX_wm_space_file(C); - FileSelectParams *params = ED_fileselect_get_params(sfile); + FileSelectParams *params = ED_fileselect_ensure_active_params(sfile); struct FSMenu *fsmenu = ED_fsmenu_get(); if (!sfile->folders_prev) { @@ -413,7 +413,7 @@ static void file_main_region_message_subscribe(const struct bContext *UNUSED(C), struct wmMsgBus *mbus) { SpaceFile *sfile = area->spacedata.first; - FileSelectParams *params = ED_fileselect_get_params(sfile); + FileSelectParams *params = ED_fileselect_ensure_active_params(sfile); /* This is a bit odd that a region owns the subscriber for an area, * keep for now since all subscribers for WM are regions. * May be worth re-visiting later. */ @@ -446,7 +446,7 @@ static void file_main_region_draw(const bContext *C, ARegion *region) { /* draw entirely, view changes should be handled here */ SpaceFile *sfile = CTX_wm_space_file(C); - FileSelectParams *params = ED_fileselect_get_params(sfile); + FileSelectParams *params = ED_fileselect_ensure_active_params(sfile); View2D *v2d = ®ion->v2d; -- cgit v1.2.3 From 2678953f699c27122d059eb8ab14e84a5be75c28 Mon Sep 17 00:00:00 2001 From: Julian Eisel Date: Tue, 8 Dec 2020 15:00:31 +0100 Subject: Cleanup: Correct an own earlier commit to use an existing utility function Didn't know this function existed, better to use it then to avoid verbosity. --- source/blender/editors/space_file/filelist.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source/blender/editors') diff --git a/source/blender/editors/space_file/filelist.c b/source/blender/editors/space_file/filelist.c index 58887ae745b..1271feda1e7 100644 --- a/source/blender/editors/space_file/filelist.c +++ b/source/blender/editors/space_file/filelist.c @@ -2621,7 +2621,7 @@ static int filelist_readjob_list_lib(const char *root, ListBase *entries, const nbr_entries++; } - BLI_linklist_free(names, MEM_freeN); + BLI_linklist_freeN(names); return nbr_entries; } -- cgit v1.2.3 From e17967f890a09c3bd810632c2c3244f9f988919f Mon Sep 17 00:00:00 2001 From: Julian Eisel Date: Tue, 8 Dec 2020 21:19:22 +0100 Subject: Fix T83559: File Browser uses wrong operation When opening a temporary File Browser, we have to make sure the file selection parameters are refreshed. When opening it in a new Window that would always be the case, if the File Browser uses a maximized window (as set in the Preferences), it might reuse space-data from a previous use. So we have to force the refresh. Also renamed the relevant function to be more clear about what it's doing. Mistake in 95b3c4c966f9. --- source/blender/editors/space_file/filesel.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) (limited to 'source/blender/editors') diff --git a/source/blender/editors/space_file/filesel.c b/source/blender/editors/space_file/filesel.c index ffa44083473..6e933e53a8f 100644 --- a/source/blender/editors/space_file/filesel.c +++ b/source/blender/editors/space_file/filesel.c @@ -90,7 +90,7 @@ FileSelectParams *ED_fileselect_get_active_params(const SpaceFile *sfile) /** * \note RNA_struct_property_is_set_ex is used here because we want * the previously used settings to be used here rather than overriding them */ -static void fileselect_ensure_file_params(SpaceFile *sfile) +static FileSelectParams *fileselect_ensure_updated_file_params(SpaceFile *sfile) { FileSelectParams *params; wmOperator *op = sfile->op; @@ -323,12 +323,14 @@ static void fileselect_ensure_file_params(SpaceFile *sfile) if (sfile->layout) { sfile->layout->dirty = true; } + + return params; } FileSelectParams *ED_fileselect_ensure_active_params(SpaceFile *sfile) { if (!sfile->params) { - fileselect_ensure_file_params(sfile); + fileselect_ensure_updated_file_params(sfile); } return sfile->params; } @@ -369,7 +371,7 @@ void ED_fileselect_set_params_from_userdef(SpaceFile *sfile) wmOperator *op = sfile->op; UserDef_FileSpaceData *sfile_udata = &U.file_space_data; - FileSelectParams *params = ED_fileselect_ensure_active_params(sfile); + FileSelectParams *params = fileselect_ensure_updated_file_params(sfile); if (!op) { return; } -- cgit v1.2.3 From cdfe733e7061d32882824896c7e62823447d7c94 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Wed, 9 Dec 2020 14:34:40 +1100 Subject: Cleanup: use doxy sections for graph_edit.c --- source/blender/editors/space_graph/graph_edit.c | 170 +++++++++++++++++++----- 1 file changed, 137 insertions(+), 33 deletions(-) (limited to 'source/blender/editors') diff --git a/source/blender/editors/space_graph/graph_edit.c b/source/blender/editors/space_graph/graph_edit.c index ae34cd6cf6d..c3e4eceef6e 100644 --- a/source/blender/editors/space_graph/graph_edit.c +++ b/source/blender/editors/space_graph/graph_edit.c @@ -72,7 +72,9 @@ /* ************************************************************************** */ /* INSERT DUPLICATE AND BAKE KEYFRAMES */ -/* ******************** Insert Keyframes Operator ************************* */ +/* -------------------------------------------------------------------- */ +/** \name Insert Keyframes Operator + * \{ */ /* Mode defines for insert keyframes tool. */ typedef enum eGraphKeys_InsertKey_Types { @@ -290,7 +292,11 @@ void GRAPH_OT_keyframe_insert(wmOperatorType *ot) ot->prop = RNA_def_enum(ot->srna, "type", prop_graphkeys_insertkey_types, 0, "Type", ""); } -/* ******************** Click-Insert Keyframes Operator ************************* */ +/** \} */ + +/* -------------------------------------------------------------------- */ +/** \name Click-Insert Keyframes Operator + * \{ */ static int graphkeys_click_insert_exec(bContext *C, wmOperator *op) { @@ -444,8 +450,13 @@ void GRAPH_OT_click_insert(wmOperatorType *ot) "Extend selection instead of deselecting everything first"); } -/* ******************** Copy/Paste Keyframes Operator ************************* */ -/* NOTE: the backend code for this is shared with the dopesheet editor */ +/** \} */ + +/* -------------------------------------------------------------------- */ +/** \name Copy/Paste Keyframes Operator + * + * \note the back-end code for this is shared with the dope-sheet editor. + * \{ */ static short copy_graph_keys(bAnimContext *ac) { @@ -605,7 +616,11 @@ void GRAPH_OT_paste(wmOperatorType *ot) RNA_def_property_flag(prop, PROP_SKIP_SAVE); } -/* ******************** Duplicate Keyframes Operator ************************* */ +/** \} */ + +/* -------------------------------------------------------------------- */ +/** \name Duplicate Keyframes Operator + * \{ */ static void duplicate_graph_keys(bAnimContext *ac) { @@ -667,7 +682,11 @@ void GRAPH_OT_duplicate(wmOperatorType *ot) RNA_def_enum(ot->srna, "mode", rna_enum_transform_mode_types, TFM_TRANSLATION, "Mode", ""); } -/* ******************** Delete Keyframes Operator ************************* */ +/** \} */ + +/* -------------------------------------------------------------------- */ +/** \name Delete Keyframes Operator + * \{ */ static bool delete_graph_keys(bAnimContext *ac) { @@ -746,7 +765,11 @@ void GRAPH_OT_delete(wmOperatorType *ot) ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; } -/* ******************** Clean Keyframes Operator ************************* */ +/** \} */ + +/* -------------------------------------------------------------------- */ +/** \name Clean Keyframes Operator + * \{ */ static void clean_graph_keys(bAnimContext *ac, float thresh, bool clean_chan) { @@ -816,8 +839,13 @@ void GRAPH_OT_clean(wmOperatorType *ot) RNA_def_boolean(ot->srna, "channels", false, "Channels", ""); } -/* ******************** Bake F-Curve Operator *********************** */ -/* This operator bakes the data of the selected F-Curves to F-Points */ +/** \} */ + +/* -------------------------------------------------------------------- */ +/** \name Bake F-Curve Operator + * + * This operator bakes the data of the selected F-Curves to F-Points. + * \{ */ /* Bake each F-Curve into a set of samples. */ static void bake_graph_curves(bAnimContext *ac, int start, int end) @@ -899,8 +927,13 @@ void GRAPH_OT_bake(wmOperatorType *ot) /* TODO: add props for start/end frames (Joshua Leung 2009) */ } -/* ******************** Un-Bake F-Curve Operator *********************** */ -/* This operator unbakes the data of the selected F-Points to F-Curves. */ +/** \} */ + +/* -------------------------------------------------------------------- */ +/** \name Un-Bake F-Curve Operator + * + * This operator un-bakes the data of the selected F-Points to F-Curves. + * \{ */ /* Un-Bake F-Points into F-Curves. */ static void unbake_graph_curves(bAnimContext *ac, int start, int end) @@ -970,8 +1003,13 @@ void GRAPH_OT_unbake(wmOperatorType *ot) #ifdef WITH_AUDASPACE -/* ******************** Sound Bake F-Curve Operator *********************** */ -/* This operator bakes the given sound to the selected F-Curves */ +/** \} */ + +/* -------------------------------------------------------------------- */ +/** \name Sound Bake F-Curve Operator + * + * This operator bakes the given sound to the selected F-Curves. + * \{ */ /* ------------------- */ @@ -1204,10 +1242,14 @@ void GRAPH_OT_sound_bake(wmOperatorType *ot) 0.1); } -/* ******************** Sample Keyframes Operator *********************** */ -/* This operator 'bakes' the values of the curve into new keyframes between pairs +/** \} */ + +/* -------------------------------------------------------------------- */ +/** \name Sample Keyframes Operator + * + * This operator 'bakes' the values of the curve into new keyframes between pairs * of selected keyframes. It is useful for creating keyframes for tweaking overlap. - */ + * \{ */ /* Evaluates the curves between each selected keyframe on each frame, and keys the value. */ static void sample_graph_keys(bAnimContext *ac) @@ -1267,10 +1309,14 @@ void GRAPH_OT_sample(wmOperatorType *ot) ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; } +/** \} */ + /* ************************************************************************** */ /* EXTRAPOLATION MODE AND KEYFRAME HANDLE SETTINGS */ -/* ******************** Set Extrapolation-Type Operator *********************** */ +/* -------------------------------------------------------------------- */ +/** \name Set Extrapolation-Type Operator + * \{ */ /* Defines for make/clear cyclic extrapolation tools. */ #define MAKE_CYCLIC_EXPO -1 @@ -1400,7 +1446,11 @@ void GRAPH_OT_extrapolation_type(wmOperatorType *ot) ot->prop = RNA_def_enum(ot->srna, "type", prop_graphkeys_expo_types, 0, "Type", ""); } -/* ******************** Set Interpolation-Type Operator *********************** */ +/** \} */ + +/* -------------------------------------------------------------------- */ +/** \name Set Interpolation-Type Operator + * \{ */ /* This function is responsible for setting interpolation mode for keyframes. */ static void setipo_graph_keys(bAnimContext *ac, short mode) @@ -1474,7 +1524,11 @@ void GRAPH_OT_interpolation_type(wmOperatorType *ot) ot->srna, "type", rna_enum_beztriple_interpolation_mode_items, 0, "Type", ""); } -/* ******************** Set Easing Operator *********************** */ +/** \} */ + +/* -------------------------------------------------------------------- */ +/** \name Set Easing Operator + * \{ */ static void seteasing_graph_keys(bAnimContext *ac, short mode) { @@ -1545,7 +1599,11 @@ void GRAPH_OT_easing_type(wmOperatorType *ot) ot->srna, "type", rna_enum_beztriple_interpolation_easing_items, 0, "Type", ""); } -/* ******************** Set Handle-Type Operator *********************** */ +/** \} */ + +/* -------------------------------------------------------------------- */ +/** \name Set Handle-Type Operator + * \{ */ /* This function is responsible for setting handle-type of selected keyframes. */ static void sethandles_graph_keys(bAnimContext *ac, short mode) @@ -1624,15 +1682,19 @@ void GRAPH_OT_handle_type(wmOperatorType *ot) ot->prop = RNA_def_enum(ot->srna, "type", rna_enum_keyframe_handle_type_items, 0, "Type", ""); } +/** \} */ + /* ************************************************************************** */ /* EULER FILTER */ -/* ***************** 'Euler Filter' Operator **************************** */ -/* Euler filter tools (as seen in Maya), are necessary for working with 'baked' +/* -------------------------------------------------------------------- */ +/** \name 'Euler Filter' Operator + * + * Euler filter tools (as seen in Maya), are necessary for working with 'baked' * rotation curves (with Euler rotations). The main purpose of such tools is to * resolve any discontinuities that may arise in the curves due to the clamping * of values to -180 degrees to 180 degrees. - */ + * \{ */ /* Set of three euler-rotation F-Curves. */ typedef struct tEulerFilter { @@ -1955,10 +2017,14 @@ void GRAPH_OT_euler_filter(wmOperatorType *ot) ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; } +/** \} */ + /* ************************************************************************** */ /* SNAPPING */ -/* ***************** Jump to Selected Frames Operator *********************** */ +/* -------------------------------------------------------------------- */ +/** \name Jump to Selected Frames Operator + * \{ */ static bool graphkeys_framejump_poll(bContext *C) { @@ -2110,7 +2176,11 @@ void GRAPH_OT_snap_cursor_value(wmOperatorType *ot) ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; } -/* ******************** Snap Keyframes Operator *********************** */ +/** \} */ + +/* -------------------------------------------------------------------- */ +/** \name Snap Keyframes Operator + * \{ */ /* Defines for snap keyframes tool. */ static const EnumPropertyItem prop_graphkeys_snap_types[] = { @@ -2262,7 +2332,11 @@ void GRAPH_OT_snap(wmOperatorType *ot) ot->prop = RNA_def_enum(ot->srna, "type", prop_graphkeys_snap_types, 0, "Type", ""); } -/* ******************** Mirror Keyframes Operator *********************** */ +/** \} */ + +/* -------------------------------------------------------------------- */ +/** \name Mirror Keyframes Operator + * \{ */ /* Defines for mirror keyframes tool. */ static const EnumPropertyItem prop_graphkeys_mirror_types[] = { @@ -2421,7 +2495,11 @@ void GRAPH_OT_mirror(wmOperatorType *ot) ot->prop = RNA_def_enum(ot->srna, "type", prop_graphkeys_mirror_types, 0, "Type", ""); } -/* ******************** Smooth Keyframes Operator *********************** */ +/** \} */ + +/* -------------------------------------------------------------------- */ +/** \name Smooth Keyframes Operator + * \{ */ static int graphkeys_smooth_exec(bContext *C, wmOperator *UNUSED(op)) { @@ -2475,10 +2553,14 @@ void GRAPH_OT_smooth(wmOperatorType *ot) ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; } +/** \} */ + /* ************************************************************************** */ /* F-CURVE MODIFIERS */ -/* ******************** Add F-Modifier Operator *********************** */ +/* -------------------------------------------------------------------- */ +/** \name Add F-Modifier Operator + * \{ */ static const EnumPropertyItem *graph_fmodifier_itemf(bContext *C, PointerRNA *UNUSED(ptr), @@ -2596,7 +2678,11 @@ void GRAPH_OT_fmodifier_add(wmOperatorType *ot) ot->srna, "only_active", 1, "Only Active", "Only add F-Modifier to active F-Curve"); } -/* ******************** Copy F-Modifiers Operator *********************** */ +/** \} */ + +/* -------------------------------------------------------------------- */ +/** \name Copy F-Modifiers Operator + * \{ */ static int graph_fmodifier_copy_exec(bContext *C, wmOperator *op) { @@ -2658,7 +2744,11 @@ void GRAPH_OT_fmodifier_copy(wmOperatorType *ot) #endif } -/* ******************** Paste F-Modifiers Operator *********************** */ +/** \} */ + +/* -------------------------------------------------------------------- */ +/** \name Paste F-Modifiers Operator + * \{ */ static int graph_fmodifier_paste_exec(bContext *C, wmOperator *op) { @@ -2746,10 +2836,14 @@ void GRAPH_OT_fmodifier_paste(wmOperatorType *ot) "Replace existing F-Modifiers, instead of just appending to the end of the existing list"); } +/** \} */ + /* ************************************************************************** */ /* Drivers */ -/* ******************** Copy Driver Vars Operator *********************** */ +/* -------------------------------------------------------------------- */ +/** \name Copy Driver Variables Operator + * \{ */ static int graph_driver_vars_copy_exec(bContext *C, wmOperator *op) { @@ -2786,7 +2880,11 @@ void GRAPH_OT_driver_variables_copy(wmOperatorType *ot) ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; } -/* ******************** Paste Driver Vars Operator *********************** */ +/** \} */ + +/* -------------------------------------------------------------------- */ +/** \name Paste Driver Variables Operator + * \{ */ static int graph_driver_vars_paste_exec(bContext *C, wmOperator *op) { @@ -2838,7 +2936,11 @@ void GRAPH_OT_driver_variables_paste(wmOperatorType *ot) "existing list"); } -/* ************************************************************************** */ +/** \} */ + +/* -------------------------------------------------------------------- */ +/** \name Delete Invalid Drivers Operator + * \{ */ static int graph_driver_delete_invalid_exec(bContext *C, wmOperator *op) { @@ -2926,3 +3028,5 @@ void GRAPH_OT_driver_delete_invalid(wmOperatorType *ot) /* Flags */ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; } + +/** \} */ -- cgit v1.2.3 From b9eb5921332922757acacd2c9251d8c89c9a239a Mon Sep 17 00:00:00 2001 From: Germano Cavalcante Date: Wed, 9 Dec 2020 09:10:56 -0300 Subject: Fix T83460: Regression in snap for measure tool Now the gizmo is drawn only when the eventstate located in `wm->winactive->eventstate` has not changed. So it doesn't matter if it's "selected" or not. This commit also removes the use of the private header "wm.h" Reviewed By: campbellbarton Differential Revision: https://developer.blender.org/D9539 --- .../gizmo_library/gizmo_types/snap3d_gizmo.c | 102 ++++++++++++++------- .../editors/space_view3d/view3d_gizmo_ruler.c | 9 +- .../editors/space_view3d/view3d_placement.c | 9 +- 3 files changed, 71 insertions(+), 49 deletions(-) (limited to 'source/blender/editors') diff --git a/source/blender/editors/gizmo_library/gizmo_types/snap3d_gizmo.c b/source/blender/editors/gizmo_library/gizmo_types/snap3d_gizmo.c index f7caf8e4c6a..8755dea51e1 100644 --- a/source/blender/editors/gizmo_library/gizmo_types/snap3d_gizmo.c +++ b/source/blender/editors/gizmo_library/gizmo_types/snap3d_gizmo.c @@ -50,7 +50,6 @@ #include "WM_api.h" #include "WM_types.h" -#include "wm.h" /* own includes */ #include "../gizmo_geometry.h" @@ -66,7 +65,13 @@ typedef struct SnapGizmo3D { /* We could have other snap contexts, for now only support 3D view. */ SnapObjectContext *snap_context_v3d; - int mval[2]; + + /* Copy of the parameters of the last event state in order to detect updates. */ + struct { + int x; + int y; + short shift, ctrl, alt, oskey; + } last_eventstate; #ifdef USE_SNAP_DETECT_FROM_KEYMAP_HACK wmKeyMap *keymap; @@ -77,6 +82,37 @@ typedef struct SnapGizmo3D { short snap_elem; } SnapGizmo3D; +/* Checks if the current event is different from the one captured in the last update. */ +static bool eventstate_has_changed(SnapGizmo3D *snap_gizmo, const wmWindowManager *wm) +{ + if (wm && wm->winactive) { + const wmEvent *event = wm->winactive->eventstate; + if ((event->x != snap_gizmo->last_eventstate.x) || + (event->y != snap_gizmo->last_eventstate.y) || + (event->ctrl != snap_gizmo->last_eventstate.ctrl) || + (event->shift != snap_gizmo->last_eventstate.shift) || + (event->alt != snap_gizmo->last_eventstate.alt) || + (event->oskey != snap_gizmo->last_eventstate.oskey)) { + return true; + } + } + return false; +} + +/* Copies the current eventstate. */ +static void eventstate_save(SnapGizmo3D *snap_gizmo, const wmWindowManager *wm) +{ + if (wm && wm->winactive) { + const wmEvent *event = wm->winactive->eventstate; + snap_gizmo->last_eventstate.x = event->x; + snap_gizmo->last_eventstate.y = event->y; + snap_gizmo->last_eventstate.ctrl = event->ctrl; + snap_gizmo->last_eventstate.shift = event->shift; + snap_gizmo->last_eventstate.alt = event->alt; + snap_gizmo->last_eventstate.oskey = event->oskey; + } +} + #ifdef USE_SNAP_DETECT_FROM_KEYMAP_HACK static bool invert_snap(SnapGizmo3D *snap_gizmo, const wmWindowManager *wm) { @@ -84,6 +120,15 @@ static bool invert_snap(SnapGizmo3D *snap_gizmo, const wmWindowManager *wm) return false; } + const wmEvent *event = wm->winactive->eventstate; + if ((event->ctrl == snap_gizmo->last_eventstate.ctrl) && + (event->shift == snap_gizmo->last_eventstate.shift) && + (event->alt == snap_gizmo->last_eventstate.alt) && + (event->oskey == snap_gizmo->last_eventstate.oskey)) { + /* Nothing has changed. */ + return snap_gizmo->invert_snap; + } + if (snap_gizmo->keymap == NULL) { /* Lazy initialization. */ snap_gizmo->keymap = WM_modalkeymap_find(wm->defaultconf, "Generic Gizmo Tweak Modal Map"); @@ -92,7 +137,6 @@ static bool invert_snap(SnapGizmo3D *snap_gizmo, const wmWindowManager *wm) const int snap_on = snap_gizmo->snap_on; wmKeyMap *keymap = WM_keymap_active(wm, snap_gizmo->keymap); - const wmEvent *event = wm->winactive->eventstate; for (wmKeyMapItem *kmi = keymap->items.first; kmi; kmi = kmi->next) { if (kmi->flag & KMI_INACTIVE) { continue; @@ -250,12 +294,6 @@ short ED_gizmotypes_snap_3d_update(wmGizmo *gz, float r_nor[3]) { SnapGizmo3D *snap_gizmo = (SnapGizmo3D *)gz; - Scene *scene = DEG_get_input_scene(depsgraph); - float co[3], no[3]; - short snap_elem = 0; - int snap_elem_index[3] = {-1, -1, -1}; - int index = -1; - if (snap_gizmo->use_snap_override != -1) { if (snap_gizmo->use_snap_override == false) { snap_gizmo->snap_elem = 0; @@ -265,7 +303,12 @@ short ED_gizmotypes_snap_3d_update(wmGizmo *gz, #ifdef USE_SNAP_DETECT_FROM_KEYMAP_HACK snap_gizmo->invert_snap = invert_snap(snap_gizmo, wm); +#endif + eventstate_save(snap_gizmo, wm); + Scene *scene = DEG_get_input_scene(depsgraph); + +#ifdef USE_SNAP_DETECT_FROM_KEYMAP_HACK if (snap_gizmo->use_snap_override == -1) { const ToolSettings *ts = scene->toolsettings; if (snap_gizmo->invert_snap != !(ts->snap_flag & SCE_SNAP)) { @@ -273,10 +316,13 @@ short ED_gizmotypes_snap_3d_update(wmGizmo *gz, return 0; } } -#else - UNUSED_VARS(wm); #endif + float co[3], no[3]; + short snap_elem = 0; + int snap_elem_index[3] = {-1, -1, -1}; + int index = -1; + wmGizmoProperty *gz_prop = WM_gizmo_target_property_find(gz, "snap_elements"); int snap_elements = RNA_property_enum_get(&gz_prop->ptr, gz_prop->prop); if (gz_prop->prop != snap_gizmo->prop_snap_force) { @@ -381,14 +427,17 @@ static void snap_gizmo_draw(const bContext *C, wmGizmo *gz) return; } - ARegion *region = CTX_wm_region(C); - RegionView3D *rv3d = region->regiondata; + wmWindowManager *wm = CTX_wm_manager(C); + if (eventstate_has_changed(snap_gizmo, wm)) { + /* The eventstate has changed but the snap has not been updated. + * This means that the current position is no longer valid. */ + snap_gizmo->snap_elem = 0; + return; + } - /* Ideally, we shouldn't assign values here. - * But `test_select` is not called during navigation. - * And `snap_elem` is not really useful in this case. */ - if ((rv3d->rflag & RV3D_NAVIGATING) || - (!(gz->state & WM_GIZMO_STATE_HIGHLIGHT) && !wm_gizmomap_modal_get(region->gizmo_map))) { + RegionView3D *rv3d = CTX_wm_region_data(C); + if (rv3d->rflag & RV3D_NAVIGATING) { + /* Don't draw the gizmo while navigating. It can be distracting. */ snap_gizmo->snap_elem = 0; return; } @@ -418,30 +467,17 @@ static void snap_gizmo_draw(const bContext *C, wmGizmo *gz) static int snap_gizmo_test_select(bContext *C, wmGizmo *gz, const int mval[2]) { SnapGizmo3D *snap_gizmo = (SnapGizmo3D *)gz; - -#ifdef USE_SNAP_DETECT_FROM_KEYMAP_HACK wmWindowManager *wm = CTX_wm_manager(C); - const bool invert = invert_snap(snap_gizmo, wm); - if (snap_gizmo->invert_snap == invert && snap_gizmo->mval[0] == mval[0] && - snap_gizmo->mval[1] == mval[1]) { + if (!eventstate_has_changed(snap_gizmo, wm)) { /* Performance, do not update. */ return snap_gizmo->snap_elem ? 0 : -1; } - snap_gizmo->invert_snap = invert; -#else - if (snap_gizmo->mval[0] == mval[0] && snap_gizmo->mval[1] == mval[1]) { - /* Performance, do not update. */ - return snap_gizmo->snap_elem ? 0 : -1; - } -#endif - copy_v2_v2_int(snap_gizmo->mval, mval); - ARegion *region = CTX_wm_region(C); View3D *v3d = CTX_wm_view3d(C); const float mval_fl[2] = {UNPACK2(mval)}; short snap_elem = ED_gizmotypes_snap_3d_update( - gz, CTX_data_ensure_evaluated_depsgraph(C), region, v3d, NULL, mval_fl, NULL, NULL); + gz, CTX_data_ensure_evaluated_depsgraph(C), region, v3d, wm, mval_fl, NULL, NULL); if (snap_elem) { ED_region_tag_redraw_editor_overlays(region); diff --git a/source/blender/editors/space_view3d/view3d_gizmo_ruler.c b/source/blender/editors/space_view3d/view3d_gizmo_ruler.c index fdba74ed3a6..9b0ce27b1e3 100644 --- a/source/blender/editors/space_view3d/view3d_gizmo_ruler.c +++ b/source/blender/editors/space_view3d/view3d_gizmo_ruler.c @@ -315,8 +315,6 @@ static bool view3d_ruler_item_mousemove(struct Depsgraph *depsgraph, const float eps_bias = 0.0002f; float dist_px = MVAL_MAX_PX_DIST * U.pixelsize; /* snap dist */ - WM_gizmo_set_flag(snap_gizmo, WM_GIZMO_HIDDEN, true); - if (ruler_item) { RulerInteraction *inter = ruler_item->gz.interaction_data; float *co = ruler_item->co[inter->co_index]; @@ -388,12 +386,8 @@ static bool view3d_ruler_item_mousemove(struct Depsgraph *depsgraph, snap_gizmo->ptr, ruler_info->snap_data.prop_prevpoint, prev_point); } - short snap_elem = ED_gizmotypes_snap_3d_update( + ED_gizmotypes_snap_3d_update( snap_gizmo, depsgraph, ruler_info->region, v3d, ruler_info->wm, mval_fl, co, NULL); - - if (snap_elem) { - WM_gizmo_set_flag(snap_gizmo, WM_GIZMO_HIDDEN, false); - } } return true; } @@ -1074,7 +1068,6 @@ static void gizmo_ruler_exit(bContext *C, wmGizmo *gz, const bool cancel) if (!cancel) { if (ruler_info->state == RULER_STATE_DRAG) { - WM_gizmo_set_flag(ruler_info->snap_data.gizmo, WM_GIZMO_HIDDEN, false); RNA_property_unset(ruler_info->snap_data.gizmo->ptr, ruler_info->snap_data.prop_prevpoint); ruler_state_set(ruler_info, RULER_STATE_NORMAL); } diff --git a/source/blender/editors/space_view3d/view3d_placement.c b/source/blender/editors/space_view3d/view3d_placement.c index 7e8ed276766..bd71a768c0f 100644 --- a/source/blender/editors/space_view3d/view3d_placement.c +++ b/source/blender/editors/space_view3d/view3d_placement.c @@ -1357,7 +1357,6 @@ static int view3d_interactive_add_modal(bContext *C, wmOperator *op, const wmEve const float mval_fl[2] = {UNPACK2(event->mval)}; /* Calculate the snap location on mouse-move or when toggling snap. */ - bool is_snap_found_prev = ipd->is_snap_found; ipd->is_snap_found = false; if (ipd->use_snap) { if (ipd->snap_gizmo != NULL) { @@ -1366,7 +1365,7 @@ static int view3d_interactive_add_modal(bContext *C, wmOperator *op, const wmEve CTX_data_ensure_evaluated_depsgraph(C), ipd->region, ipd->v3d, - NULL, + G_MAIN->wm.first, mval_fl, ipd->snap_co, NULL)) { @@ -1376,12 +1375,6 @@ static int view3d_interactive_add_modal(bContext *C, wmOperator *op, const wmEve } } - /* Workaround because test_select doesn't run at the same time as the modal operator. */ - if (is_snap_found_prev != ipd->is_snap_found) { - wmGizmoMap *gzmap = ipd->region->gizmo_map; - WM_gizmo_highlight_set(gzmap, ipd->is_snap_found ? ipd->snap_gizmo : NULL); - } - if (ipd->step_index == STEP_BASE) { if (ipd->is_snap_found) { closest_to_plane_normalized_v3( -- cgit v1.2.3 From 37bf71ad0475549e0458f1e864a30c68c5880e88 Mon Sep 17 00:00:00 2001 From: Germano Cavalcante Date: Wed, 9 Dec 2020 10:30:23 -0300 Subject: Fix T83588: Crash with Shrink/Fatten and Offset Even `t->keymap` can be `NULL`. Bug introduced in rBc822f66bb83 --- .../editors/transform/transform_mode_edge_seq_slide.c | 17 +++++++++-------- .../editors/transform/transform_mode_shrink_fatten.c | 17 +++++++++-------- 2 files changed, 18 insertions(+), 16 deletions(-) (limited to 'source/blender/editors') diff --git a/source/blender/editors/transform/transform_mode_edge_seq_slide.c b/source/blender/editors/transform/transform_mode_edge_seq_slide.c index 1682b5bfe31..7ccfd0149bd 100644 --- a/source/blender/editors/transform/transform_mode_edge_seq_slide.c +++ b/source/blender/editors/transform/transform_mode_edge_seq_slide.c @@ -50,7 +50,7 @@ static eRedrawFlag seq_slide_handleEvent(struct TransInfo *t, const wmEvent *eve { BLI_assert(t->mode == TFM_SEQ_SLIDE); wmKeyMapItem *kmi = t->custom.mode.data; - if (event->type == kmi->type && event->val == kmi->val) { + if (kmi && event->type == kmi->type && event->val == kmi->val) { /* Allows the 'Expand to fit' effect to be enabled as a toogle. */ t->flag ^= T_ALT_TRANSFORM; return TREDRAW_HARD; @@ -73,12 +73,11 @@ static void headerSeqSlide(TransInfo *t, const float val[2], char str[UI_MAX_DRA ofs += BLI_snprintf( str + ofs, UI_MAX_DRAW_STR - ofs, TIP_("Sequence Slide: %s%s, ("), &tvec[0], t->con.text); - if (t->keymap) { - wmKeyMapItem *kmi = t->custom.mode.data; - if (kmi) { - ofs += WM_keymap_item_to_string(kmi, false, str + ofs, UI_MAX_DRAW_STR - ofs); - } + wmKeyMapItem *kmi = t->custom.mode.data; + if (kmi) { + ofs += WM_keymap_item_to_string(kmi, false, str + ofs, UI_MAX_DRAW_STR - ofs); } + ofs += BLI_snprintf(str + ofs, UI_MAX_DRAW_STR - ofs, TIP_(" or Alt) Expand to fit %s"), @@ -157,7 +156,9 @@ void initSeqSlide(TransInfo *t) t->num.unit_type[0] = B_UNIT_NONE; t->num.unit_type[1] = B_UNIT_NONE; - /* Workaround to use the same key as the modal keymap. */ - t->custom.mode.data = WM_modalkeymap_find_propvalue(t->keymap, TFM_MODAL_TRANSLATE); + if (t->keymap) { + /* Workaround to use the same key as the modal keymap. */ + t->custom.mode.data = WM_modalkeymap_find_propvalue(t->keymap, TFM_MODAL_TRANSLATE); + } } /** \} */ diff --git a/source/blender/editors/transform/transform_mode_shrink_fatten.c b/source/blender/editors/transform/transform_mode_shrink_fatten.c index 6058a2824e9..2a5c631df41 100644 --- a/source/blender/editors/transform/transform_mode_shrink_fatten.c +++ b/source/blender/editors/transform/transform_mode_shrink_fatten.c @@ -50,7 +50,7 @@ static eRedrawFlag shrinkfatten_handleEvent(struct TransInfo *t, const wmEvent * { BLI_assert(t->mode == TFM_SHRINKFATTEN); wmKeyMapItem *kmi = t->custom.mode.data; - if (event->type == kmi->type && event->val == kmi->val) { + if (kmi && event->type == kmi->type && event->val == kmi->val) { /* Allows the 'Even Thickness' effect to be enabled as a toogle. */ t->flag ^= T_ALT_TRANSFORM; return TREDRAW_HARD; @@ -90,12 +90,11 @@ static void applyShrinkFatten(TransInfo *t, const int UNUSED(mval[2])) } ofs += BLI_strncpy_rlen(str + ofs, ", (", sizeof(str) - ofs); - if (t->keymap) { - wmKeyMapItem *kmi = t->custom.mode.data; - if (kmi) { - ofs += WM_keymap_item_to_string(kmi, false, str + ofs, sizeof(str) - ofs); - } + wmKeyMapItem *kmi = t->custom.mode.data; + if (kmi) { + ofs += WM_keymap_item_to_string(kmi, false, str + ofs, sizeof(str) - ofs); } + BLI_snprintf(str + ofs, sizeof(str) - ofs, TIP_(" or Alt) Even Thickness %s"), @@ -149,8 +148,10 @@ void initShrinkFatten(TransInfo *t) t->flag |= T_NO_CONSTRAINT; - /* Workaround to use the same key as the modal keymap. */ - t->custom.mode.data = WM_modalkeymap_find_propvalue(t->keymap, TFM_MODAL_RESIZE); + if (t->keymap) { + /* Workaround to use the same key as the modal keymap. */ + t->custom.mode.data = WM_modalkeymap_find_propvalue(t->keymap, TFM_MODAL_RESIZE); + } } } /** \} */ -- cgit v1.2.3 From c93f826661334926fc15504243f61c85242bec42 Mon Sep 17 00:00:00 2001 From: Jacques Lucke Date: Wed, 9 Dec 2020 16:29:11 +0100 Subject: Cleanup: various clang tidy fixes --- source/blender/editors/space_outliner/tree/tree_display_data.cc | 2 +- source/blender/editors/space_outliner/tree/tree_display_orphaned.cc | 2 +- source/blender/editors/space_outliner/tree/tree_display_scenes.cc | 4 ++-- .../blender/editors/space_outliner/tree/tree_display_sequencer.cc | 6 +++--- source/blender/editors/space_outliner/tree/tree_element.h | 2 +- 5 files changed, 8 insertions(+), 8 deletions(-) (limited to 'source/blender/editors') diff --git a/source/blender/editors/space_outliner/tree/tree_display_data.cc b/source/blender/editors/space_outliner/tree/tree_display_data.cc index 41ca4f72903..8a5c2e7d9f3 100644 --- a/source/blender/editors/space_outliner/tree/tree_display_data.cc +++ b/source/blender/editors/space_outliner/tree/tree_display_data.cc @@ -41,7 +41,7 @@ ListBase TreeDisplayDataAPI::buildTree(const TreeSourceData &source_data) RNA_main_pointer_create(source_data.bmain, &mainptr); TreeElement *te = outliner_add_element( - &space_outliner_, &tree, (void *)&mainptr, NULL, TSE_RNA_STRUCT, -1); + &space_outliner_, &tree, (void *)&mainptr, nullptr, TSE_RNA_STRUCT, -1); /* On first view open parent data elements */ const int show_opened = !space_outliner_.treestore || diff --git a/source/blender/editors/space_outliner/tree/tree_display_orphaned.cc b/source/blender/editors/space_outliner/tree/tree_display_orphaned.cc index 71c1d344057..0b17ea98831 100644 --- a/source/blender/editors/space_outliner/tree/tree_display_orphaned.cc +++ b/source/blender/editors/space_outliner/tree/tree_display_orphaned.cc @@ -68,7 +68,7 @@ ListBase TreeDisplayIDOrphans::buildTree(const TreeSourceData &source_data) TreeElement *te = nullptr; if (!filter_id_type) { ID *id = (ID *)lbarray[a]->first; - te = outliner_add_element(&space_outliner_, &tree, lbarray[a], NULL, TSE_ID_BASE, 0); + te = outliner_add_element(&space_outliner_, &tree, lbarray[a], nullptr, TSE_ID_BASE, 0); te->directdata = lbarray[a]; te->name = outliner_idcode_to_plural(GS(id->name)); } diff --git a/source/blender/editors/space_outliner/tree/tree_display_scenes.cc b/source/blender/editors/space_outliner/tree/tree_display_scenes.cc index c4a5688504d..f377512d81e 100644 --- a/source/blender/editors/space_outliner/tree/tree_display_scenes.cc +++ b/source/blender/editors/space_outliner/tree/tree_display_scenes.cc @@ -46,7 +46,7 @@ ListBase TreeDisplayScenes::buildTree(const TreeSourceData &source_data) for (ID *id : List(source_data.bmain->scenes)) { Scene *scene = reinterpret_cast(id); - TreeElement *te = outliner_add_element(&space_outliner_, &tree, scene, NULL, 0, 0); + TreeElement *te = outliner_add_element(&space_outliner_, &tree, scene, nullptr, 0, 0); TreeStoreElem *tselem = TREESTORE(te); /* New scene elements open by default */ @@ -60,4 +60,4 @@ ListBase TreeDisplayScenes::buildTree(const TreeSourceData &source_data) return tree; } -} // namespace blender::ed::outliner \ No newline at end of file +} // namespace blender::ed::outliner diff --git a/source/blender/editors/space_outliner/tree/tree_display_sequencer.cc b/source/blender/editors/space_outliner/tree/tree_display_sequencer.cc index 486f735be9f..48f0322ccb9 100644 --- a/source/blender/editors/space_outliner/tree/tree_display_sequencer.cc +++ b/source/blender/editors/space_outliner/tree/tree_display_sequencer.cc @@ -18,7 +18,7 @@ * \ingroup spoutliner */ -#include +#include #include "BLI_listbase.h" #include "BLI_listbase_wrapper.hh" @@ -51,11 +51,11 @@ ListBase TreeDisplaySequencer::buildTree(const TreeSourceData &source_data) for (Sequence *seq : List(ed->seqbasep)) { SequenceAddOp op = need_add_seq_dup(seq); if (op == SEQUENCE_DUPLICATE_NONE) { - outliner_add_element(&space_outliner_, &tree, seq, NULL, TSE_SEQUENCE, 0); + outliner_add_element(&space_outliner_, &tree, seq, nullptr, TSE_SEQUENCE, 0); } else if (op == SEQUENCE_DUPLICATE_ADD) { TreeElement *te = outliner_add_element( - &space_outliner_, &tree, seq, NULL, TSE_SEQUENCE_DUP, 0); + &space_outliner_, &tree, seq, nullptr, TSE_SEQUENCE_DUP, 0); add_seq_dup(seq, te, 0); } } diff --git a/source/blender/editors/space_outliner/tree/tree_element.h b/source/blender/editors/space_outliner/tree/tree_element.h index 9012321a323..d88c37180b3 100644 --- a/source/blender/editors/space_outliner/tree/tree_element.h +++ b/source/blender/editors/space_outliner/tree/tree_element.h @@ -36,7 +36,7 @@ extern "C" { typedef struct TreeElementType TreeElementType; TreeElementType *outliner_tree_element_type_create(int type, TreeElement *legacy_te, void *idv); -void outliner_tree_element_type_free(TreeElementType **element); +void outliner_tree_element_type_free(TreeElementType **type); void outliner_tree_element_type_expand(TreeElementType *type, SpaceOutliner *space_outliner); -- cgit v1.2.3 From 19560eef1aedd64fc604c1f6151fa62c5c3c3957 Mon Sep 17 00:00:00 2001 From: Aaron Carlisle Date: Wed, 9 Dec 2020 16:08:21 -0500 Subject: Cleanup: Remove unused c popup menu for text editor This code hase been usused for 10 years and the right click menu is now in python. --- source/blender/editors/space_text/text_header.c | 98 ------------------------- 1 file changed, 98 deletions(-) (limited to 'source/blender/editors') diff --git a/source/blender/editors/space_text/text_header.c b/source/blender/editors/space_text/text_header.c index c583634f440..84b7a6f6831 100644 --- a/source/blender/editors/space_text/text_header.c +++ b/source/blender/editors/space_text/text_header.c @@ -108,101 +108,3 @@ void TEXT_OT_start_find(wmOperatorType *ot) ot->exec = text_text_search_exec; ot->poll = text_properties_poll; } - -/******************** XXX popup menus *******************/ - -#if 0 -{ - /* RMB */ - - uiPopupMenu *pup; - - if (text) { - pup = UI_popup_menu_begin(C, IFACE_("Text"), ICON_NONE); - if (txt_has_sel(text)) { - uiItemO(layout, NULL, ICON_NONE, "TEXT_OT_cut"); - uiItemO(layout, NULL, ICON_NONE, "TEXT_OT_copy"); - } - uiItemO(layout, NULL, ICON_NONE, "TEXT_OT_paste"); - uiItemO(layout, NULL, ICON_NONE, "TEXT_OT_new"); - uiItemO(layout, NULL, ICON_NONE, "TEXT_OT_open"); - uiItemO(layout, NULL, ICON_NONE, "TEXT_OT_save"); - uiItemO(layout, NULL, ICON_NONE, "TEXT_OT_save_as"); - uiItemO(layout, NULL, ICON_NONE, "TEXT_OT_run_script"); - UI_popup_menu_end(C, pup); - } - else { - pup = UI_popup_menu_begin(C, IFACE_("File"), ICON_NONE); - uiItemO(layout, NULL, ICON_NONE, "TEXT_OT_new"); - uiItemO(layout, NULL, ICON_NONE, "TEXT_OT_open"); - UI_popup_menu_end(C, pup); - } -} - -{ - /* Alt+Shift+E */ - - uiPopupMenu *pup; - - pup = UI_popup_menu_begin(C, IFACE_("Edit"), ICON_NONE); - uiItemO(layout, NULL, ICON_NONE, "TEXT_OT_cut"); - uiItemO(layout, NULL, ICON_NONE, "TEXT_OT_copy"); - uiItemO(layout, NULL, ICON_NONE, "TEXT_OT_paste"); - UI_popup_menu_end(C, pup); -} - -{ - /* Alt+Shift+F */ - - uiPopupMenu *pup; - - if (text) { - pup = UI_popup_menu_begin(C, IFACE_("Text"), ICON_NONE); - uiItemO(layout, NULL, ICON_NONE, "TEXT_OT_new"); - uiItemO(layout, NULL, ICON_NONE, "TEXT_OT_open"); - uiItemO(layout, NULL, ICON_NONE, "TEXT_OT_save"); - uiItemO(layout, NULL, ICON_NONE, "TEXT_OT_save_as"); - uiItemO(layout, NULL, ICON_NONE, "TEXT_OT_run_script"); - UI_popup_menu_end(C, pup); - } - else { - pup = UI_popup_menu_begin(C, IFACE_("File"), ICON_NONE); - uiItemO(layout, NULL, ICON_NONE, "TEXT_OT_new"); - uiItemO(layout, NULL, ICON_NONE, "TEXT_OT_open"); - UI_popup_menu_end(C, pup); - } -} - -{ - /* Alt+Shift+V */ - - uiPopupMenu *pup; - - pup = UI_popup_menu_begin(C, IFACE_("Text"), ICON_NONE); - uiItemEnumO(layout, - "TEXT_OT_move", - CTX_IFACE_(BLT_I18NCONTEXT_OPERATOR_DEFAULT, "Top of File"), - 0, - "type", - FILE_TOP); - uiItemEnumO(layout, - "TEXT_OT_move", - CTX_IFACE_(BLT_I18NCONTEXT_OPERATOR_DEFAULT, "Bottom of File"), - 0, - "type", - FILE_BOTTOM); - uiItemEnumO(layout, - "TEXT_OT_move", - CTX_IFACE_(BLT_I18NCONTEXT_OPERATOR_DEFAULT, "Page Up"), - 0, - "type", - PREV_PAGE); - uiItemEnumO(layout, - "TEXT_OT_move", - CTX_IFACE_(BLT_I18NCONTEXT_OPERATOR_DEFAULT, "Page Down"), - 0, - "type", - NEXT_PAGE); - UI_popup_menu_end(C, pup); -} -#endif -- cgit v1.2.3 From d870a60dd9270764d5f61457224252200376dd2d Mon Sep 17 00:00:00 2001 From: Pablo Dobarro Date: Wed, 9 Dec 2020 22:19:34 +0100 Subject: Sculpt: Elastic deform type for Snake Hook This adds deformation types to snake hook and the elastic deformation type. This mode deforms the mesh using a kelvinlet instead of applying the displacement directly inside the brush radius, which is great for stylized shapes sketching. Changes in rake rotation when using elastic are too strong when set to 1, so I'll add a nicer way to support rake rotations with smoother transitions in the future. Reviewed By: sergey, JulienKaspar Differential Revision: https://developer.blender.org/D9560 --- source/blender/editors/sculpt_paint/sculpt.c | 55 ++++++++++++++-------- .../blender/editors/sculpt_paint/sculpt_intern.h | 32 +++++++++++++ 2 files changed, 67 insertions(+), 20 deletions(-) (limited to 'source/blender/editors') diff --git a/source/blender/editors/sculpt_paint/sculpt.c b/source/blender/editors/sculpt_paint/sculpt.c index b9427677745..fd7ec1da497 100644 --- a/source/blender/editors/sculpt_paint/sculpt.c +++ b/source/blender/editors/sculpt_paint/sculpt.c @@ -4232,6 +4232,8 @@ static void do_snake_hook_brush_task_cb_ex(void *__restrict userdata, (len_v3(grab_delta) / ss->cache->radius)) : 0.0f; + const bool do_elastic = brush->snake_hook_deform_type == BRUSH_SNAKE_HOOK_DEFORM_ELASTIC; + proxy = BKE_pbvh_node_add_proxy(ss->pbvh, data->nodes[n])->co; SculptBrushTest test; @@ -4239,18 +4241,28 @@ static void do_snake_hook_brush_task_cb_ex(void *__restrict userdata, ss, &test, data->brush->falloff_shape); const int thread_id = BLI_task_parallel_thread_id(tls); + KelvinletParams params; + BKE_kelvinlet_init_params(¶ms, ss->cache->radius, bstrength, 1.0f, 0.4f); + BKE_pbvh_vertex_iter_begin(ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE) { - if (sculpt_brush_test_sq_fn(&test, vd.co)) { - const float fade = bstrength * SCULPT_brush_strength_factor(ss, - brush, - vd.co, - sqrtf(test.dist), - vd.no, - vd.fno, - vd.mask ? *vd.mask : 0.0f, - vd.index, - thread_id); + if (do_elastic || sculpt_brush_test_sq_fn(&test, vd.co)) { + + float fade; + if (do_elastic) { + fade = 1.0f; + } + else { + fade = bstrength * SCULPT_brush_strength_factor(ss, + brush, + vd.co, + sqrtf(test.dist), + vd.no, + vd.fno, + vd.mask ? *vd.mask : 0.0f, + vd.index, + thread_id); + } mul_v3_v3fl(proxy[vd.i], grab_delta, fade); @@ -4289,6 +4301,17 @@ static void do_snake_hook_brush_task_cb_ex(void *__restrict userdata, add_v3_v3(proxy[vd.i], delta_rotate); } + if (do_elastic) { + float disp[3]; + BKE_kelvinlet_grab_triscale(disp, ¶ms, vd.co, ss->cache->location, proxy[vd.i]); + mul_v3_fl(disp, bstrength * 20.0f); + if (vd.mask) { + mul_v3_fl(disp, 1.0f - *vd.mask); + } + mul_v3_fl(disp, SCULPT_automasking_factor_get(ss->cache->automasking, ss, vd.index)); + copy_v3_v3(proxy[vd.i], disp); + } + if (vd.mvert) { vd.mvert->flag |= ME_VERT_PBVH_UPDATE; } @@ -5714,16 +5737,8 @@ static void do_brush_action(Sculpt *sd, Object *ob, Brush *brush, UnifiedPaintSe /* Build a list of all nodes that are potentially within the brush's area of influence */ - /* These brushes need to update all nodes as they are not constrained by the brush radius */ - /* Elastic deform needs all nodes to avoid artifacts as the effect of the brush is not - * constrained by the radius. */ - /* Pose needs all nodes because it applies all symmetry iterations at the same time and the IK - * chain can grow to any area of the model. */ - /* This can be optimized by filtering the nodes after calculating the chain. */ - if (ELEM(brush->sculpt_tool, - SCULPT_TOOL_ELASTIC_DEFORM, - SCULPT_TOOL_POSE, - SCULPT_TOOL_BOUNDARY)) { + if (SCULPT_tool_needs_all_pbvh_nodes(brush)) { + /* These brushes need to update all nodes as they are not constrained by the brush radius */ BKE_pbvh_search_gather(ss->pbvh, NULL, NULL, &nodes, &totnode); } else if (brush->sculpt_tool == SCULPT_TOOL_CLOTH) { diff --git a/source/blender/editors/sculpt_paint/sculpt_intern.h b/source/blender/editors/sculpt_paint/sculpt_intern.h index 99ee22328ea..3b48207f461 100644 --- a/source/blender/editors/sculpt_paint/sculpt_intern.h +++ b/source/blender/editors/sculpt_paint/sculpt_intern.h @@ -434,6 +434,38 @@ BLI_INLINE bool SCULPT_is_cloth_deform_brush(const Brush *brush) brush->deform_target == BRUSH_DEFORM_TARGET_CLOTH_SIM); } +BLI_INLINE bool SCULPT_tool_needs_all_pbvh_nodes(const Brush *brush) +{ + if (brush->sculpt_tool == SCULPT_TOOL_ELASTIC_DEFORM) { + /* Elastic deformations in any brush need all nodes to avoid artifacts as the effect + * of the Kelvinlet is not constrained by the radius. */ + return true; + } + + if (brush->sculpt_tool == SCULPT_TOOL_POSE) { + /* Pose needs all nodes because it applies all symmetry iterations at the same time + * and the IK chain can grow to any area of the model. */ + /* TODO: This can be optimized by filtering the nodes after calculating the chain. */ + return true; + } + + if (brush->sculpt_tool == SCULPT_TOOL_BOUNDARY) { + /* Boundary needs all nodes because it is not possible to know where the boundary + * deformation is going to be propagated before calculating it. */ + /* TODO: after calculating the boudnary info in the first iteration, it should be + * possible to get the nodes that have vertices included in any boundary deformation + * and cache them. */ + return true; + } + + if (brush->sculpt_tool == SCULPT_TOOL_SNAKE_HOOK && + brush->snake_hook_deform_type == BRUSH_SNAKE_HOOK_DEFORM_ELASTIC) { + /* Snake hook in elastic deform type has same requirements as the elastic deform tool. */ + return true; + } + return false; +} + /* Pose Brush. */ void SCULPT_do_pose_brush(struct Sculpt *sd, struct Object *ob, -- cgit v1.2.3 From b379f9348487ad4e13650f10820a987deef76fe6 Mon Sep 17 00:00:00 2001 From: Julian Eisel Date: Wed, 9 Dec 2020 23:43:01 +0100 Subject: Cleanup: Use const for filter queries --- source/blender/editors/space_file/filelist.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'source/blender/editors') diff --git a/source/blender/editors/space_file/filelist.c b/source/blender/editors/space_file/filelist.c index 1271feda1e7..e87142a7096 100644 --- a/source/blender/editors/space_file/filelist.c +++ b/source/blender/editors/space_file/filelist.c @@ -630,7 +630,7 @@ void filelist_setsorting(struct FileList *filelist, const short sort, bool inver /* ********** Filter helpers ********** */ /* True if filename is meant to be hidden, eg. starting with period. */ -static bool is_hidden_dot_filename(const char *filename, FileListInternEntry *file) +static bool is_hidden_dot_filename(const char *filename, const FileListInternEntry *file) { if (filename[0] == '.' && !ELEM(filename[1], '.', '\0')) { return true; /* ignore .file */ @@ -671,8 +671,8 @@ static bool is_hidden_dot_filename(const char *filename, FileListInternEntry *fi /* True if should be hidden, based on current filtering. */ static bool is_filtered_hidden(const char *filename, - FileListFilter *filter, - FileListInternEntry *file) + const FileListFilter *filter, + const FileListInternEntry *file) { if ((filename[0] == '.') && (filename[1] == '\0')) { return true; /* Ignore . */ -- cgit v1.2.3 From 51cbd5d91d426ecf987585e49585e09db7cb2bc9 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Thu, 10 Dec 2020 14:25:20 +1100 Subject: Cleanup: avoid '_ln' suffix Use '_len' or '_line_number'. --- source/blender/editors/interface/interface_ops.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) (limited to 'source/blender/editors') diff --git a/source/blender/editors/interface/interface_ops.c b/source/blender/editors/interface/interface_ops.c index 0d1e2802242..e5aa0665a16 100644 --- a/source/blender/editors/interface/interface_ops.c +++ b/source/blender/editors/interface/interface_ops.c @@ -1223,7 +1223,7 @@ typedef struct uiEditSourceStore { typedef struct uiEditSourceButStore { char py_dbg_fn[FILE_MAX]; - int py_dbg_ln; + int py_dbg_line_number; } uiEditSourceButStore; /* should only ever be set while the edit source operator is running */ @@ -1276,21 +1276,21 @@ void UI_editsource_active_but_test(uiBut *but) struct uiEditSourceButStore *but_store = MEM_callocN(sizeof(uiEditSourceButStore), __func__); const char *fn; - int lineno = -1; + int line_number = -1; # if 0 printf("comparing buttons: '%s' == '%s'\n", but->drawstr, ui_editsource_info->but_orig.drawstr); # endif - PyC_FileAndNum_Safe(&fn, &lineno); + PyC_FileAndNum_Safe(&fn, &line_number); - if (lineno != -1) { + if (line_number != -1) { BLI_strncpy(but_store->py_dbg_fn, fn, sizeof(but_store->py_dbg_fn)); - but_store->py_dbg_ln = lineno; + but_store->py_dbg_line_number = line_number; } else { but_store->py_dbg_fn[0] = '\0'; - but_store->py_dbg_ln = -1; + but_store->py_dbg_line_number = -1; } BLI_ghash_insert(ui_editsource_info->hash, but, but_store); @@ -1375,8 +1375,8 @@ static int editsource_exec(bContext *C, wmOperator *op) } if (but_store) { - if (but_store->py_dbg_ln != -1) { - ret = editsource_text_edit(C, op, but_store->py_dbg_fn, but_store->py_dbg_ln); + if (but_store->py_dbg_line_number != -1) { + ret = editsource_text_edit(C, op, but_store->py_dbg_fn, but_store->py_dbg_line_number); } else { BKE_report( -- cgit v1.2.3 From d97845a693c28b8d56934c1b34bdb5c346a2603b Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Thu, 10 Dec 2020 16:46:04 +1100 Subject: BLI_string: return NULL from BLI_str_quoted_substrN on failure This was returning an empty allocated string, however almost all callers checked if the return value was NULL before freeing, making for misunderstandings on the intended use of this function. BCAnimationSampler::initialize_curves for example detected the f-curves animation type to 'bone' based on a non-NULL return value which never failed. Also fixes two leaks where the the result of BLI_str_quoted_substrN wasn't freed. --- source/blender/editors/animation/anim_deps.c | 8 ++++--- source/blender/editors/animation/anim_filter.c | 19 +++++++-------- source/blender/editors/animation/anim_ipo_utils.c | 3 ++- .../blender/editors/animation/keyframes_general.c | 13 +++++----- source/blender/editors/animation/keyframing.c | 23 ++++++++---------- source/blender/editors/armature/pose_select.c | 4 +--- .../editors/transform/transform_convert_armature.c | 28 +++++++++++----------- 7 files changed, 46 insertions(+), 52 deletions(-) (limited to 'source/blender/editors') diff --git a/source/blender/editors/animation/anim_deps.c b/source/blender/editors/animation/anim_deps.c index e552a321bca..32ce78e405e 100644 --- a/source/blender/editors/animation/anim_deps.c +++ b/source/blender/editors/animation/anim_deps.c @@ -216,11 +216,13 @@ static void animchan_sync_fcurve_scene(bAnimListElem *ale) /* get strip name, and check if this strip is selected */ char *seq_name = BLI_str_quoted_substrN(fcu->rna_path, "sequences_all["); - Sequence *seq = BKE_sequence_get_by_name(ed->seqbasep, seq_name, false); - if (seq_name) { - MEM_freeN(seq_name); + if (seq_name == NULL) { + return; } + Sequence *seq = BKE_sequence_get_by_name(ed->seqbasep, seq_name, false); + MEM_freeN(seq_name); + if (seq == NULL) { return; } diff --git a/source/blender/editors/animation/anim_filter.c b/source/blender/editors/animation/anim_filter.c index 2e65fff69f1..f4a487140ff 100644 --- a/source/blender/editors/animation/anim_filter.c +++ b/source/blender/editors/animation/anim_filter.c @@ -1063,13 +1063,12 @@ static bool skip_fcurve_selected_data(bDopeSheet *ads, FCurve *fcu, ID *owner_id /* only consider if F-Curve involves pose.bones */ if ((fcu->rna_path) && strstr(fcu->rna_path, "pose.bones")) { - bPoseChannel *pchan; - char *bone_name; /* get bone-name, and check if this bone is selected */ - bone_name = BLI_str_quoted_substrN(fcu->rna_path, "pose.bones["); - pchan = BKE_pose_channel_find_name(ob->pose, bone_name); + bPoseChannel *pchan = NULL; + char *bone_name = BLI_str_quoted_substrN(fcu->rna_path, "pose.bones["); if (bone_name) { + pchan = BKE_pose_channel_find_name(ob->pose, bone_name); MEM_freeN(bone_name); } @@ -1106,13 +1105,12 @@ static bool skip_fcurve_selected_data(bDopeSheet *ads, FCurve *fcu, ID *owner_id if ((fcu->rna_path) && strstr(fcu->rna_path, "sequences_all")) { Editing *ed = BKE_sequencer_editing_get(scene, false); Sequence *seq = NULL; - char *seq_name; if (ed) { /* get strip name, and check if this strip is selected */ - seq_name = BLI_str_quoted_substrN(fcu->rna_path, "sequences_all["); - seq = BKE_sequence_get_by_name(ed->seqbasep, seq_name, false); + char *seq_name = BLI_str_quoted_substrN(fcu->rna_path, "sequences_all["); if (seq_name) { + seq = BKE_sequence_get_by_name(ed->seqbasep, seq_name, false); MEM_freeN(seq_name); } } @@ -1130,13 +1128,12 @@ static bool skip_fcurve_selected_data(bDopeSheet *ads, FCurve *fcu, ID *owner_id /* check for selected nodes */ if ((fcu->rna_path) && strstr(fcu->rna_path, "nodes")) { - bNode *node; - char *node_name; + bNode *node = NULL; /* get strip name, and check if this strip is selected */ - node_name = BLI_str_quoted_substrN(fcu->rna_path, "nodes["); - node = nodeFindNodebyName(ntree, node_name); + char *node_name = BLI_str_quoted_substrN(fcu->rna_path, "nodes["); if (node_name) { + node = nodeFindNodebyName(ntree, node_name); MEM_freeN(node_name); } diff --git a/source/blender/editors/animation/anim_ipo_utils.c b/source/blender/editors/animation/anim_ipo_utils.c index 72103d68b05..5992545bdbe 100644 --- a/source/blender/editors/animation/anim_ipo_utils.c +++ b/source/blender/editors/animation/anim_ipo_utils.c @@ -112,7 +112,8 @@ int getname_anim_fcurve(char *name, ID *id, FCurve *fcu) char *constName = BLI_str_quoted_substrN(fcu->rna_path, "constraints["); /* assemble the string to display in the UI... */ - structname = BLI_sprintfN("%s : %s", pchanName, constName); + structname = BLI_sprintfN( + "%s : %s", pchanName ? pchanName : "", constName ? constName : ""); free_structname = 1; /* free the temp names */ diff --git a/source/blender/editors/animation/keyframes_general.c b/source/blender/editors/animation/keyframes_general.c index 08b02020f76..6ed9803dbd3 100644 --- a/source/blender/editors/animation/keyframes_general.c +++ b/source/blender/editors/animation/keyframes_general.c @@ -767,16 +767,15 @@ short copy_animedit_keys(bAnimContext *ac, ListBase *anim_data) * Storing the relevant information here helps avoiding crashes if we undo-repaste. */ if ((aci->id_type == ID_OB) && (((Object *)aci->id)->type == OB_ARMATURE) && aci->rna_path) { Object *ob = (Object *)aci->id; - bPoseChannel *pchan; - char *bone_name; - bone_name = BLI_str_quoted_substrN(aci->rna_path, "pose.bones["); - pchan = BKE_pose_channel_find_name(ob->pose, bone_name); - if (pchan) { - aci->is_bone = true; - } + char *bone_name = BLI_str_quoted_substrN(aci->rna_path, "pose.bones["); if (bone_name) { + bPoseChannel *pchan = BKE_pose_channel_find_name(ob->pose, bone_name); MEM_freeN(bone_name); + + if (pchan) { + aci->is_bone = true; + } } } diff --git a/source/blender/editors/animation/keyframing.c b/source/blender/editors/animation/keyframing.c index 09c33c48170..e8146ca960a 100644 --- a/source/blender/editors/animation/keyframing.c +++ b/source/blender/editors/animation/keyframing.c @@ -2236,20 +2236,18 @@ static int clear_anim_v3d_exec(bContext *C, wmOperator *UNUSED(op)) /* in pose mode, only delete the F-Curve if it belongs to a selected bone */ if (ob->mode & OB_MODE_POSE) { if ((fcu->rna_path) && strstr(fcu->rna_path, "pose.bones[")) { - bPoseChannel *pchan; - char *bone_name; /* get bone-name, and check if this bone is selected */ - bone_name = BLI_str_quoted_substrN(fcu->rna_path, "pose.bones["); - pchan = BKE_pose_channel_find_name(ob->pose, bone_name); + char *bone_name = BLI_str_quoted_substrN(fcu->rna_path, "pose.bones["); if (bone_name) { + bPoseChannel *pchan = BKE_pose_channel_find_name(ob->pose, bone_name); MEM_freeN(bone_name); - } - /* delete if bone is selected*/ - if ((pchan) && (pchan->bone)) { - if (pchan->bone->flag & BONE_SELECTED) { - can_delete = true; + /* delete if bone is selected*/ + if ((pchan) && (pchan->bone)) { + if (pchan->bone->flag & BONE_SELECTED) { + can_delete = true; + } } } } @@ -2342,13 +2340,12 @@ static int delete_key_v3d_exec(bContext *C, wmOperator *op) * In object mode, we're dealing with the entire object. */ if ((ob->mode & OB_MODE_POSE) && strstr(fcu->rna_path, "pose.bones[\"")) { - bPoseChannel *pchan; - char *bone_name; + bPoseChannel *pchan = NULL; /* get bone-name, and check if this bone is selected */ - bone_name = BLI_str_quoted_substrN(fcu->rna_path, "pose.bones["); - pchan = BKE_pose_channel_find_name(ob->pose, bone_name); + char *bone_name = BLI_str_quoted_substrN(fcu->rna_path, "pose.bones["); if (bone_name) { + pchan = BKE_pose_channel_find_name(ob->pose, bone_name); MEM_freeN(bone_name); } diff --git a/source/blender/editors/armature/pose_select.c b/source/blender/editors/armature/pose_select.c index 731d0d10e0b..6a03207b3b0 100644 --- a/source/blender/editors/armature/pose_select.c +++ b/source/blender/editors/armature/pose_select.c @@ -1090,6 +1090,7 @@ static bool pose_select_same_keyingset(bContext *C, ReportList *reports, bool ex if (boneName) { bPoseChannel *pchan = BKE_pose_channel_find_name(pose, boneName); + MEM_freeN(boneName); if (pchan) { /* select if bone is visible and can be affected */ @@ -1098,9 +1099,6 @@ static bool pose_select_same_keyingset(bContext *C, ReportList *reports, bool ex changed = true; } } - - /* free temp memory */ - MEM_freeN(boneName); } } } diff --git a/source/blender/editors/transform/transform_convert_armature.c b/source/blender/editors/transform/transform_convert_armature.c index a7301161570..e9b2273b343 100644 --- a/source/blender/editors/transform/transform_convert_armature.c +++ b/source/blender/editors/transform/transform_convert_armature.c @@ -164,21 +164,21 @@ static void autokeyframe_pose( /* only if bone name matches too... * NOTE: this will do constraints too, but those are ok to do here too? */ - if (pchanName && STREQ(pchanName, pchan->name)) { - insert_keyframe(bmain, - reports, - id, - act, - ((fcu->grp) ? (fcu->grp->name) : (NULL)), - fcu->rna_path, - fcu->array_index, - &anim_eval_context, - ts->keyframe_type, - &nla_cache, - flag); - } - if (pchanName) { + if (STREQ(pchanName, pchan->name)) { + insert_keyframe(bmain, + reports, + id, + act, + ((fcu->grp) ? (fcu->grp->name) : (NULL)), + fcu->rna_path, + fcu->array_index, + &anim_eval_context, + ts->keyframe_type, + &nla_cache, + flag); + } + MEM_freeN(pchanName); } } -- cgit v1.2.3 From 348bd319d5a88f45410a22f8ce2f527d8da48ef0 Mon Sep 17 00:00:00 2001 From: Hans Goudey Date: Thu, 10 Dec 2020 07:58:45 -0600 Subject: Geometry Nodes: Attribute Fill Node This commit adds a node that fills every element of an attribute with the same value. Currently it supports float, vector, and color attributes. An immediate use case is for "billboard" scattering. Currently people are using the same input to a Random Attribute node's min and max input to fill every element of a vector with the same value, which is an unintuitive way to accomplish the same thing. Differential Revision: https://developer.blender.org/D9790 --- source/blender/editors/space_node/drawnode.c | 11 +++++++++++ 1 file changed, 11 insertions(+) (limited to 'source/blender/editors') diff --git a/source/blender/editors/space_node/drawnode.c b/source/blender/editors/space_node/drawnode.c index 84e7a74fab3..2ff32a4a82e 100644 --- a/source/blender/editors/space_node/drawnode.c +++ b/source/blender/editors/space_node/drawnode.c @@ -3182,6 +3182,14 @@ static void node_geometry_buts_attribute_math(uiLayout *layout, uiItemR(layout, ptr, "input_type_b", DEFAULT_FLAGS, IFACE_("Type B"), ICON_NONE); } +static void node_geometry_buts_attribute_fill(uiLayout *layout, + bContext *UNUSED(C), + PointerRNA *ptr) +{ + uiItemR(layout, ptr, "data_type", DEFAULT_FLAGS, "", ICON_NONE); + // uiItemR(layout, ptr, "domain", DEFAULT_FLAGS, "", ICON_NONE); +} + static void node_geometry_set_butfunc(bNodeType *ntype) { switch (ntype->type) { @@ -3200,6 +3208,9 @@ static void node_geometry_set_butfunc(bNodeType *ntype) case GEO_NODE_ATTRIBUTE_MATH: ntype->draw_buttons = node_geometry_buts_attribute_math; break; + case GEO_NODE_ATTRIBUTE_FILL: + ntype->draw_buttons = node_geometry_buts_attribute_fill; + break; } } -- cgit v1.2.3 From caed4849d0903c09c63ef5b80e506aa4bdfcb994 Mon Sep 17 00:00:00 2001 From: Philipp Oeser Date: Thu, 10 Dec 2020 22:39:28 +0100 Subject: Fix T83640: No immediate updates when changing the settings of a just- duplicated particle system When particle settings are duplicated along with the particle system, this means a change in relations, was missing 'DEG_relations_tag_update'. Maniphest Tasks: T83640 Differential Revision: https://developer.blender.org/D9823 --- source/blender/editors/physics/particle_object.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'source/blender/editors') diff --git a/source/blender/editors/physics/particle_object.c b/source/blender/editors/physics/particle_object.c index 017cd63d9d5..f5c3fc17552 100644 --- a/source/blender/editors/physics/particle_object.c +++ b/source/blender/editors/physics/particle_object.c @@ -1203,6 +1203,9 @@ static bool copy_particle_systems_to_object(const bContext *C, #undef PSYS_FROM_FIRST #undef PSYS_FROM_NEXT + if (duplicate_settings) { + DEG_relations_tag_update(bmain); + } DEG_id_tag_update(&ob_to->id, ID_RECALC_GEOMETRY); WM_main_add_notifier(NC_OBJECT | ND_PARTICLE | NA_EDITED, ob_to); return true; -- cgit v1.2.3 From a4a42f3171c021f2f7eb28e1ed10873b3314587b Mon Sep 17 00:00:00 2001 From: Yevgeny Makarov Date: Thu, 10 Dec 2020 18:22:16 -0800 Subject: UI: Use 'and' Instead of '&' in Descriptions Use 'and' instead of ampersand in descriptions and comments. Differential Revision: https://developer.blender.org/D9797 Reviewed by Aaron Carlisle --- source/blender/editors/armature/armature_edit.c | 2 +- source/blender/editors/mesh/editmesh_tools.c | 6 +++--- source/blender/editors/screen/screen_ops.c | 2 +- source/blender/editors/transform/transform_ops.c | 2 +- 4 files changed, 6 insertions(+), 6 deletions(-) (limited to 'source/blender/editors') diff --git a/source/blender/editors/armature/armature_edit.c b/source/blender/editors/armature/armature_edit.c index b20d2738bda..f2cb00f67f0 100644 --- a/source/blender/editors/armature/armature_edit.c +++ b/source/blender/editors/armature/armature_edit.c @@ -1014,7 +1014,7 @@ void ARMATURE_OT_switch_direction(wmOperatorType *ot) /* identifiers */ ot->name = "Switch Direction"; ot->idname = "ARMATURE_OT_switch_direction"; - ot->description = "Change the direction that a chain of bones points in (head <-> tail swap)"; + ot->description = "Change the direction that a chain of bones points in (head and tail swap)"; /* api callbacks */ ot->exec = armature_switch_direction_exec; diff --git a/source/blender/editors/mesh/editmesh_tools.c b/source/blender/editors/mesh/editmesh_tools.c index b961f81e16a..ccc27ec19b6 100644 --- a/source/blender/editors/mesh/editmesh_tools.c +++ b/source/blender/editors/mesh/editmesh_tools.c @@ -395,7 +395,7 @@ void MESH_OT_unsubdivide(wmOperatorType *ot) { /* identifiers */ ot->name = "Un-Subdivide"; - ot->description = "UnSubdivide selected edges & faces"; + ot->description = "Un-subdivide selected edges and faces"; ot->idname = "MESH_OT_unsubdivide"; /* api callbacks */ @@ -698,7 +698,7 @@ void MESH_OT_edge_collapse(wmOperatorType *ot) /* identifiers */ ot->name = "Collapse Edges & Faces"; ot->description = - "Collapse isolated edges & faces regions, merging data such as UV's and vertex colors. " + "Collapse isolated edge and face regions, merging data such as UV's and vertex colors. " "This can collapse edge-rings as well as regions of connected faces into vertices"; ot->idname = "MESH_OT_edge_collapse"; @@ -1904,7 +1904,7 @@ void MESH_OT_edge_split(wmOperatorType *ot) "VERT", 0, "Faces & Edges by Vertices", - "Split faces & edges connected to selected vertices"}, + "Split faces and edges connected to selected vertices"}, {0, NULL, 0, NULL, NULL}, }; diff --git a/source/blender/editors/screen/screen_ops.c b/source/blender/editors/screen/screen_ops.c index 72b3b344813..649279f8e08 100644 --- a/source/blender/editors/screen/screen_ops.c +++ b/source/blender/editors/screen/screen_ops.c @@ -3918,7 +3918,7 @@ 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->description = "Split selected area into camera, front, right, and top views"; ot->idname = "SCREEN_OT_region_quadview"; /* api callbacks */ diff --git a/source/blender/editors/transform/transform_ops.c b/source/blender/editors/transform/transform_ops.c index 5153fdedcae..5d758a6c6c6 100644 --- a/source/blender/editors/transform/transform_ops.c +++ b/source/blender/editors/transform/transform_ops.c @@ -717,7 +717,7 @@ void Transform_Properties(struct wmOperatorType *ot, int flags) "use_automerge_and_split", 0, "Auto Merge & Split", - "Forces the use of Auto Merge & Split"); + "Forces the use of Auto Merge and Split"); RNA_def_property_flag(prop, PROP_HIDDEN); } } -- cgit v1.2.3 From ff6d7e907269c3e090d4234df6eb7e812c809050 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Fri, 11 Dec 2020 14:51:43 +1100 Subject: Cleanup: spelling, expand on FCurve.rna_path docstring --- source/blender/editors/sculpt_paint/sculpt_intern.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source/blender/editors') diff --git a/source/blender/editors/sculpt_paint/sculpt_intern.h b/source/blender/editors/sculpt_paint/sculpt_intern.h index 3b48207f461..e0d413bc75f 100644 --- a/source/blender/editors/sculpt_paint/sculpt_intern.h +++ b/source/blender/editors/sculpt_paint/sculpt_intern.h @@ -452,7 +452,7 @@ BLI_INLINE bool SCULPT_tool_needs_all_pbvh_nodes(const Brush *brush) if (brush->sculpt_tool == SCULPT_TOOL_BOUNDARY) { /* Boundary needs all nodes because it is not possible to know where the boundary * deformation is going to be propagated before calculating it. */ - /* TODO: after calculating the boudnary info in the first iteration, it should be + /* TODO: after calculating the boundary info in the first iteration, it should be * possible to get the nodes that have vertices included in any boundary deformation * and cache them. */ return true; -- cgit v1.2.3 From 8cc951d2aebe27651ba9a2b8a3ee4c59fafdb920 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Fri, 11 Dec 2020 14:59:08 +1100 Subject: Cleanup: trailing space --- source/blender/editors/space_graph/graph_view.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source/blender/editors') diff --git a/source/blender/editors/space_graph/graph_view.c b/source/blender/editors/space_graph/graph_view.c index 0b9ba3762a3..cde0dab3503 100644 --- a/source/blender/editors/space_graph/graph_view.c +++ b/source/blender/editors/space_graph/graph_view.c @@ -533,4 +533,4 @@ void GRAPH_OT_ghost_curves_clear(wmOperatorType *ot) /* Flags */ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; -} \ No newline at end of file +} -- cgit v1.2.3 From 392a8e2907ee1c08813258c1a477bbea060ba06d Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Fri, 11 Dec 2020 15:00:22 +1100 Subject: Cleanup: sort cmake file lists --- source/blender/editors/object/CMakeLists.txt | 2 +- source/blender/editors/space_graph/CMakeLists.txt | 2 +- source/blender/editors/space_node/CMakeLists.txt | 2 +- source/blender/editors/space_outliner/CMakeLists.txt | 6 +++--- source/blender/editors/space_view3d/CMakeLists.txt | 2 +- source/blender/editors/transform/CMakeLists.txt | 2 +- source/blender/editors/uvedit/CMakeLists.txt | 2 +- 7 files changed, 9 insertions(+), 9 deletions(-) (limited to 'source/blender/editors') diff --git a/source/blender/editors/object/CMakeLists.txt b/source/blender/editors/object/CMakeLists.txt index a1be9b9df61..d872511ae03 100644 --- a/source/blender/editors/object/CMakeLists.txt +++ b/source/blender/editors/object/CMakeLists.txt @@ -31,8 +31,8 @@ set(INC ../../makesrna ../../modifiers ../../python - ../../shader_fx ../../render + ../../shader_fx ../../windowmanager ../../../../intern/clog ../../../../intern/glew-mx diff --git a/source/blender/editors/space_graph/CMakeLists.txt b/source/blender/editors/space_graph/CMakeLists.txt index 414e5c87f5a..2a795dd954c 100644 --- a/source/blender/editors/space_graph/CMakeLists.txt +++ b/source/blender/editors/space_graph/CMakeLists.txt @@ -34,8 +34,8 @@ set(SRC graph_draw.c graph_edit.c graph_ops.c - graph_slider_ops.c graph_select.c + graph_slider_ops.c graph_utils.c graph_view.c space_graph.c diff --git a/source/blender/editors/space_node/CMakeLists.txt b/source/blender/editors/space_node/CMakeLists.txt index d8f31161c20..f4a3bb96aeb 100644 --- a/source/blender/editors/space_node/CMakeLists.txt +++ b/source/blender/editors/space_node/CMakeLists.txt @@ -21,6 +21,7 @@ set(INC ../../blenkernel ../../blenlib ../../blentranslation + ../../compositor ../../depsgraph ../../draw ../../gpu @@ -29,7 +30,6 @@ set(INC ../../makesrna ../../nodes ../../render - ../../compositor ../../windowmanager ../../../../intern/glew-mx ../../../../intern/guardedalloc diff --git a/source/blender/editors/space_outliner/CMakeLists.txt b/source/blender/editors/space_outliner/CMakeLists.txt index 74f99540bee..8e989f5568e 100644 --- a/source/blender/editors/space_outliner/CMakeLists.txt +++ b/source/blender/editors/space_outliner/CMakeLists.txt @@ -46,12 +46,12 @@ set(SRC space_outliner.c tree/common.cc tree/tree_display.cc + tree/tree_display_data.cc tree/tree_display_libraries.cc - tree/tree_display_view_layer.cc - tree/tree_display_sequencer.cc tree/tree_display_orphaned.cc tree/tree_display_scenes.cc - tree/tree_display_data.cc + tree/tree_display_sequencer.cc + tree/tree_display_view_layer.cc tree/tree_element.cc tree/tree_element_anim_data.cc tree/tree_element_driver_base.cc diff --git a/source/blender/editors/space_view3d/CMakeLists.txt b/source/blender/editors/space_view3d/CMakeLists.txt index 0371b4e271f..9242fc15021 100644 --- a/source/blender/editors/space_view3d/CMakeLists.txt +++ b/source/blender/editors/space_view3d/CMakeLists.txt @@ -22,13 +22,13 @@ set(INC ../../blenlib ../../blentranslation ../../bmesh + ../../depsgraph ../../draw ../../gpu ../../imbuf ../../makesdna ../../makesrna ../../render - ../../depsgraph ../../windowmanager ../../../../intern/glew-mx ../../../../intern/guardedalloc diff --git a/source/blender/editors/transform/CMakeLists.txt b/source/blender/editors/transform/CMakeLists.txt index 73d6a376da6..a2eb68a1b71 100644 --- a/source/blender/editors/transform/CMakeLists.txt +++ b/source/blender/editors/transform/CMakeLists.txt @@ -22,12 +22,12 @@ set(INC ../../blenlib ../../blentranslation ../../bmesh + ../../depsgraph ../../gpu ../../ikplugin ../../makesdna ../../makesrna ../../render - ../../depsgraph ../../sequencer ../../windowmanager ../../../../intern/glew-mx diff --git a/source/blender/editors/uvedit/CMakeLists.txt b/source/blender/editors/uvedit/CMakeLists.txt index 8e4a3df920e..1c8a56e0608 100644 --- a/source/blender/editors/uvedit/CMakeLists.txt +++ b/source/blender/editors/uvedit/CMakeLists.txt @@ -35,11 +35,11 @@ set(INC set(SRC uvedit_buttons.c uvedit_draw.c + uvedit_islands.c uvedit_ops.c uvedit_parametrizer.c uvedit_path.c uvedit_rip.c - uvedit_islands.c uvedit_select.c uvedit_smart_stitch.c uvedit_unwrap_ops.c -- cgit v1.2.3 From 219dba8506ffca7b5cc4ba0a849f9c3a9394334e Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Fri, 11 Dec 2020 15:30:30 +1100 Subject: Workaround T83651: Crash dragging multiple buttons in the clip editor Avoid the crash, dragging multiple buttons still needs fixing. --- source/blender/editors/interface/interface_handlers.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'source/blender/editors') diff --git a/source/blender/editors/interface/interface_handlers.c b/source/blender/editors/interface/interface_handlers.c index f914ccd7497..bcb79743b12 100644 --- a/source/blender/editors/interface/interface_handlers.c +++ b/source/blender/editors/interface/interface_handlers.c @@ -1349,6 +1349,9 @@ static void ui_multibut_states_apply(bContext *C, uiHandleButtonData *data, uiBl if (mbut_state == NULL) { /* Highly unlikely. */ printf("%s: Can't find button\n", __func__); + /* While this avoids crashing, multi-button dragging will fail, + * which is still a bug from the user perspective. See T83651. */ + continue; } void *active_back; -- cgit v1.2.3 From b62a9ef66faad1ba37dde053af3394eca9559e46 Mon Sep 17 00:00:00 2001 From: Bastien Montagne Date: Fri, 11 Dec 2020 09:37:29 +0100 Subject: Cleanup: Fix typo in comment. --- source/blender/editors/interface/interface_layout.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source/blender/editors') diff --git a/source/blender/editors/interface/interface_layout.c b/source/blender/editors/interface/interface_layout.c index 0403287125c..ebd2235cb82 100644 --- a/source/blender/editors/interface/interface_layout.c +++ b/source/blender/editors/interface/interface_layout.c @@ -651,7 +651,7 @@ static void ui_item_array(uiLayout *layout, uiDefAutoButR(block, ptr, prop, -1, "", ICON_NONE, 0, 0, w, UI_UNIT_Y); } else { - /* even if 'expand' is fale, expanding anyway */ + /* Even if 'expand' is false, we expand anyway. */ /* layout for known array subtypes */ char str[3] = {'\0'}; -- cgit v1.2.3 From f5c72467176c1f5e8922c86c697e58861cf782a4 Mon Sep 17 00:00:00 2001 From: Bastien Montagne Date: Fri, 11 Dec 2020 11:05:28 +0100 Subject: Fix wrong operator return values in Outliner code. Mistakes in rBac8b641b77e0 and rBf254f66587f2. Spotted while inverstigating T83592. --- source/blender/editors/space_outliner/outliner_tools.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source/blender/editors') diff --git a/source/blender/editors/space_outliner/outliner_tools.c b/source/blender/editors/space_outliner/outliner_tools.c index 159a4616ba7..098a0edb614 100644 --- a/source/blender/editors/space_outliner/outliner_tools.c +++ b/source/blender/editors/space_outliner/outliner_tools.c @@ -2791,7 +2791,7 @@ static int do_outliner_operation_event(bContext *C, } if (datalevel == TSE_ID_BASE) { /* do nothing... there are no ops needed here yet */ - return 0; + return OPERATOR_CANCELLED; } if (datalevel == TSE_CONSTRAINT) { return outliner_operator_menu(C, "OUTLINER_OT_constraint_operation"); @@ -2802,7 +2802,7 @@ static int do_outliner_operation_event(bContext *C, return outliner_operator_menu(C, "OUTLINER_OT_data_operation"); } - return 0; + return OPERATOR_CANCELLED; } static int outliner_operation(bContext *C, wmOperator *op, const wmEvent *event) -- cgit v1.2.3 From d72ec16e70721408c875040325c984941687b4a2 Mon Sep 17 00:00:00 2001 From: Jacques Lucke Date: Fri, 11 Dec 2020 12:00:48 +0100 Subject: Geometry Nodes: add Attribute Mix node This node can be used to mix two attributes in various ways. The blend modes are the same as in the MixRGB shader node. Differential Revision: https://developer.blender.org/D9737 Ref T82374. --- source/blender/editors/space_node/drawnode.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+) (limited to 'source/blender/editors') diff --git a/source/blender/editors/space_node/drawnode.c b/source/blender/editors/space_node/drawnode.c index 2ff32a4a82e..0d371915316 100644 --- a/source/blender/editors/space_node/drawnode.c +++ b/source/blender/editors/space_node/drawnode.c @@ -3190,6 +3190,17 @@ static void node_geometry_buts_attribute_fill(uiLayout *layout, // uiItemR(layout, ptr, "domain", DEFAULT_FLAGS, "", ICON_NONE); } +static void node_geometry_buts_attribute_mix(uiLayout *layout, + bContext *UNUSED(C), + PointerRNA *ptr) +{ + uiItemR(layout, ptr, "blend_type", DEFAULT_FLAGS, "", ICON_NONE); + uiLayout *col = uiLayoutColumn(layout, false); + uiItemR(col, ptr, "input_type_factor", DEFAULT_FLAGS, IFACE_("Factor"), ICON_NONE); + uiItemR(col, ptr, "input_type_a", DEFAULT_FLAGS, IFACE_("A"), ICON_NONE); + uiItemR(col, ptr, "input_type_b", DEFAULT_FLAGS, IFACE_("B"), ICON_NONE); +} + static void node_geometry_set_butfunc(bNodeType *ntype) { switch (ntype->type) { @@ -3211,6 +3222,9 @@ static void node_geometry_set_butfunc(bNodeType *ntype) case GEO_NODE_ATTRIBUTE_FILL: ntype->draw_buttons = node_geometry_buts_attribute_fill; break; + case GEO_NODE_ATTRIBUTE_MIX: + ntype->draw_buttons = node_geometry_buts_attribute_mix; + break; } } -- cgit v1.2.3 From 727d5013a7771ffa7d8f1fa799af5142b274c127 Mon Sep 17 00:00:00 2001 From: Philipp Oeser Date: Mon, 23 Nov 2020 12:44:44 +0100 Subject: Fix T82881: Paint mask 'deselect on nothing' missed viewport update Was failing for weightpaint and vertexpaint. Selection flags were actually changed, but the update in the viewport wasnt immediate, leading to confusion when the update happened later (e.g. when using the weight gradient tool as done in the report). We need to tag ID_RECALC_SELECT and send ND_SELECT notifier here. This could be done explicitly, but there is also existing functionality available that does this. Note: the way updates happen for paintfaces vs. paintverts looks a bit inconsistent (so this could be part of a later cleanup commit) Maniphest Tasks: T82881 Differential Revision: https://developer.blender.org/D9631 --- source/blender/editors/space_view3d/view3d_select.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'source/blender/editors') diff --git a/source/blender/editors/space_view3d/view3d_select.c b/source/blender/editors/space_view3d/view3d_select.c index 5b400bbf60a..96bd25f85e7 100644 --- a/source/blender/editors/space_view3d/view3d_select.c +++ b/source/blender/editors/space_view3d/view3d_select.c @@ -2457,13 +2457,16 @@ static int view3d_select_exec(bContext *C, wmOperator *op) else if (obact && BKE_paint_select_face_test(obact)) { retval = paintface_mouse_select(C, obact, location, extend, deselect, toggle); if (!retval && deselect_all) { - retval = paintface_deselect_all_visible(C, CTX_data_active_object(C), SEL_DESELECT, false); + retval = paintface_deselect_all_visible(C, CTX_data_active_object(C), SEL_DESELECT, true); } } else if (BKE_paint_select_vert_test(obact)) { retval = ed_wpaint_vertex_select_pick(C, location, extend, deselect, toggle, obact); if (!retval && deselect_all) { retval = paintvert_deselect_all_visible(obact, SEL_DESELECT, false); + if (retval) { + paintvert_tag_select_update(C, obact); + } } } else { -- cgit v1.2.3 From c8a3d1a1fa65f2ff21202d79c5f027119203319f Mon Sep 17 00:00:00 2001 From: Antonio Vazquez Date: Thu, 10 Dec 2020 23:04:54 +0100 Subject: GPencil: Add Link support to Effects using Ctrl+L The effects were not supported in this operator, but it was supported in the Outliner. Differential Revision: https://developer.blender.org/D9824 --- source/blender/editors/object/object_relations.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) (limited to 'source/blender/editors') diff --git a/source/blender/editors/object/object_relations.c b/source/blender/editors/object/object_relations.c index 8841b1955bf..3ad500d3d0d 100644 --- a/source/blender/editors/object/object_relations.c +++ b/source/blender/editors/object/object_relations.c @@ -1554,6 +1554,7 @@ enum { MAKE_LINKS_DUPLICOLLECTION = 5, MAKE_LINKS_MODIFIERS = 6, MAKE_LINKS_FONTS = 7, + MAKE_LINKS_SHADERFX = 8, }; /* Return true if make link data is allowed, false otherwise */ @@ -1589,6 +1590,11 @@ static bool allow_make_links_data(const int type, Object *ob_src, Object *ob_dst return true; } break; + case MAKE_LINKS_SHADERFX: + if ((ob_src->type == OB_GPENCIL) && (ob_dst->type == OB_GPENCIL)) { + return true; + } + break; } return false; } @@ -1720,6 +1726,11 @@ static int make_links_data_exec(bContext *C, wmOperator *op) ID_RECALC_TRANSFORM | ID_RECALC_GEOMETRY | ID_RECALC_ANIMATION); break; } + case MAKE_LINKS_SHADERFX: + ED_object_shaderfx_link(ob_dst, ob_src); + DEG_id_tag_update(&ob_dst->id, + ID_RECALC_TRANSFORM | ID_RECALC_GEOMETRY | ID_RECALC_ANIMATION); + break; } } } @@ -1782,6 +1793,7 @@ void OBJECT_OT_make_links_data(wmOperatorType *ot) {MAKE_LINKS_DUPLICOLLECTION, "DUPLICOLLECTION", 0, "Instance Collection", ""}, {MAKE_LINKS_MODIFIERS, "MODIFIERS", 0, "Modifiers", ""}, {MAKE_LINKS_FONTS, "FONTS", 0, "Fonts", ""}, + {MAKE_LINKS_SHADERFX, "EFFECTS", 0, "Effects", ""}, {0, NULL, 0, NULL, NULL}, }; -- cgit v1.2.3 From badbf816b867ffeb5920a1575d0159ec516b2819 Mon Sep 17 00:00:00 2001 From: Yevgeny Makarov Date: Fri, 11 Dec 2020 07:35:44 -0800 Subject: UI: Consistent Range Descriptions Unifying range descriptions as a value 'to' a value. Differential Revision: https://developer.blender.org/D9771 Reviewed by Julian Eisel --- source/blender/editors/mesh/editmesh_tools.c | 2 +- source/blender/editors/sculpt_paint/paint_image.c | 2 +- source/blender/editors/space_clip/clip_ops.c | 2 +- source/blender/editors/uvedit/uvedit_ops.c | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) (limited to 'source/blender/editors') diff --git a/source/blender/editors/mesh/editmesh_tools.c b/source/blender/editors/mesh/editmesh_tools.c index ccc27ec19b6..cf01170dd8a 100644 --- a/source/blender/editors/mesh/editmesh_tools.c +++ b/source/blender/editors/mesh/editmesh_tools.c @@ -180,7 +180,7 @@ void MESH_OT_subdivide(wmOperatorType *ot) "ngon", true, "Create N-Gons", - "When disabled, newly created faces are limited to 3-4 sided faces"); + "When disabled, newly created faces are limited to 3 and 4 sided faces"); RNA_def_enum( ot->srna, "quadcorner", diff --git a/source/blender/editors/sculpt_paint/paint_image.c b/source/blender/editors/sculpt_paint/paint_image.c index 3a6b91443a0..999d364a3cd 100644 --- a/source/blender/editors/sculpt_paint/paint_image.c +++ b/source/blender/editors/sculpt_paint/paint_image.c @@ -934,7 +934,7 @@ void PAINT_OT_grab_clone(wmOperatorType *ot) -FLT_MAX, FLT_MAX, "Delta", - "Delta offset of clone image in 0.0..1.0 coordinates", + "Delta offset of clone image in 0.0 to 1.0 coordinates", -1.0f, 1.0f); } diff --git a/source/blender/editors/space_clip/clip_ops.c b/source/blender/editors/space_clip/clip_ops.c index 3f00e3114a5..8f36ccb019a 100644 --- a/source/blender/editors/space_clip/clip_ops.c +++ b/source/blender/editors/space_clip/clip_ops.c @@ -859,7 +859,7 @@ void CLIP_OT_view_zoom_out(wmOperatorType *ot) -FLT_MAX, FLT_MAX, "Location", - "Cursor location in normalized (0.0-1.0) coordinates", + "Cursor location in normalized (0.0 to 1.0) coordinates", -10.0f, 10.0f); RNA_def_property_flag(prop, PROP_HIDDEN); diff --git a/source/blender/editors/uvedit/uvedit_ops.c b/source/blender/editors/uvedit/uvedit_ops.c index 5b3d858329a..aac5b96f737 100644 --- a/source/blender/editors/uvedit/uvedit_ops.c +++ b/source/blender/editors/uvedit/uvedit_ops.c @@ -1812,7 +1812,7 @@ static void UV_OT_cursor_set(wmOperatorType *ot) -FLT_MAX, FLT_MAX, "Location", - "Cursor location in normalized (0.0-1.0) coordinates", + "Cursor location in normalized (0.0 to 1.0) coordinates", -10.0f, 10.0f); } -- cgit v1.2.3 From 4885fbc07b50af0f7b93c0df41d6f64cc79b2fa7 Mon Sep 17 00:00:00 2001 From: Jacques Lucke Date: Fri, 11 Dec 2020 17:32:08 +0100 Subject: Nodes: add Collection socket type The implementation is pretty much the same as for Object sockets. The socket color is the one that is used for collections in the outliner. Part of D9739. --- source/blender/editors/space_node/drawnode.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'source/blender/editors') diff --git a/source/blender/editors/space_node/drawnode.c b/source/blender/editors/space_node/drawnode.c index 0d371915316..f1ab433c639 100644 --- a/source/blender/editors/space_node/drawnode.c +++ b/source/blender/editors/space_node/drawnode.c @@ -3414,6 +3414,7 @@ static const float std_node_socket_colors[][4] = { {0.93, 0.62, 0.36, 1.0}, /* SOCK_OBJECT */ {0.89, 0.76, 0.43, 1.0}, /* SOCK_IMAGE */ {0.00, 0.84, 0.64, 1.0}, /* SOCK_GEOMETRY */ + {0.96, 0.96, 0.96, 1.0}, /* SOCK_COLLECTION */ }; /* common color callbacks for standard types */ @@ -3537,6 +3538,10 @@ static void std_node_socket_draw( uiItemR(layout, ptr, "default_value", DEFAULT_FLAGS, text, 0); break; } + case SOCK_COLLECTION: { + uiItemR(layout, ptr, "default_value", DEFAULT_FLAGS, text, 0); + break; + } default: node_socket_button_label(C, layout, ptr, node_ptr, text); break; -- cgit v1.2.3 From f5dc34ec9c05cc8f1163313baafe634f4798c29b Mon Sep 17 00:00:00 2001 From: Jacques Lucke Date: Fri, 11 Dec 2020 18:00:37 +0100 Subject: Geometry Nodes: support instancing collections The Point Instance node can instance entire collections now. Before, only individual collections were supported. Randomly selecting objects from the collection on a per point basis is not support, yet. Last part of D9739. Ref T82372. --- source/blender/editors/space_node/drawnode.c | 10 ++++++++++ 1 file changed, 10 insertions(+) (limited to 'source/blender/editors') diff --git a/source/blender/editors/space_node/drawnode.c b/source/blender/editors/space_node/drawnode.c index f1ab433c639..f8c71791054 100644 --- a/source/blender/editors/space_node/drawnode.c +++ b/source/blender/editors/space_node/drawnode.c @@ -3182,6 +3182,13 @@ static void node_geometry_buts_attribute_math(uiLayout *layout, uiItemR(layout, ptr, "input_type_b", DEFAULT_FLAGS, IFACE_("Type B"), ICON_NONE); } +static void node_geometry_buts_point_instance(uiLayout *layout, + bContext *UNUSED(C), + PointerRNA *ptr) +{ + uiItemR(layout, ptr, "instance_type", DEFAULT_FLAGS | UI_ITEM_R_EXPAND, NULL, ICON_NONE); +} + static void node_geometry_buts_attribute_fill(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr) @@ -3219,6 +3226,9 @@ static void node_geometry_set_butfunc(bNodeType *ntype) case GEO_NODE_ATTRIBUTE_MATH: ntype->draw_buttons = node_geometry_buts_attribute_math; break; + case GEO_NODE_POINT_INSTANCE: + ntype->draw_buttons = node_geometry_buts_point_instance; + break; case GEO_NODE_ATTRIBUTE_FILL: ntype->draw_buttons = node_geometry_buts_attribute_fill; break; -- cgit v1.2.3 From af008f553293d91ef624ab4950e6d5dcc91650fe Mon Sep 17 00:00:00 2001 From: Julian Eisel Date: Fri, 11 Dec 2020 21:54:10 +0100 Subject: UI: Allow Outliners to pass selected data-blocks to operators via context The way the Outliner integrates operations on selected tree elements is known to be quite problematic amongst developers. The context menu is generated in an unusual way and doesn't use the normal operator system. Instead, changes are applied via a recursive callback system. Things are quite ad-hoc, and the callbacks often implement logic that should not be in the Outliner, but in entirely different modules. Often these modules already contain the logic, but as proper operators. This commit is a step into a hopefully better direction that should allow us to put actual operators into Outliner context menus. It starts solving the problem of: How can the Outliner pass selected data to operators. It implements it for data-blocks only, but other data could do it in the same way. Idea is to keep doing what operators were initially designed to do: Operate on context. Operators can now query a "selected_ids" context member (`CTX_data_selected_ids()` in C, `bpy.context.selected_ids` in .py). If an Outliner is active, it will generate a list of selected data-blocks as a response, via its `SpaceType.context` callback. Any other editor could do the same. No user visible changes. This new design isn't actually used yet. It will be soon for asset operators. Reviewed as part of https://developer.blender.org/D9717. Reviewed by: Brecht Van Lommel --- .../blender/editors/space_outliner/CMakeLists.txt | 1 + .../editors/space_outliner/outliner_context.c | 73 ++++++++++++++++++++++ .../editors/space_outliner/outliner_intern.h | 7 +++ .../editors/space_outliner/space_outliner.c | 1 + 4 files changed, 82 insertions(+) create mode 100644 source/blender/editors/space_outliner/outliner_context.c (limited to 'source/blender/editors') diff --git a/source/blender/editors/space_outliner/CMakeLists.txt b/source/blender/editors/space_outliner/CMakeLists.txt index 8e989f5568e..e0262371559 100644 --- a/source/blender/editors/space_outliner/CMakeLists.txt +++ b/source/blender/editors/space_outliner/CMakeLists.txt @@ -34,6 +34,7 @@ set(INC set(SRC outliner_collections.c + outliner_context.c outliner_dragdrop.c outliner_draw.c outliner_edit.c diff --git a/source/blender/editors/space_outliner/outliner_context.c b/source/blender/editors/space_outliner/outliner_context.c new file mode 100644 index 00000000000..760fa8e4604 --- /dev/null +++ b/source/blender/editors/space_outliner/outliner_context.c @@ -0,0 +1,73 @@ +/* + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * The Original Code is Copyright (C) 2017 Blender Foundation. + * All rights reserved. + */ + +/** \file + * \ingroup spoutliner + */ + +#include "BLI_listbase.h" + +#include "BKE_context.h" + +#include "DNA_space_types.h" + +#include "RNA_access.h" + +#include "outliner_intern.h" + +static void outliner_context_selected_ids_recursive(const ListBase *subtree, + bContextDataResult *result) +{ + LISTBASE_FOREACH (const TreeElement *, te, subtree) { + const TreeStoreElem *tse = TREESTORE(te); + if ((tse->flag & TSE_SELECTED) && (ELEM(tse->type, 0, TSE_LAYER_COLLECTION))) { + CTX_data_id_list_add(result, tse->id); + } + outliner_context_selected_ids_recursive(&te->subtree, result); + } +} + +static void outliner_context_selected_ids(const SpaceOutliner *space_outliner, + bContextDataResult *result) +{ + outliner_context_selected_ids_recursive(&space_outliner->tree, result); + CTX_data_type_set(result, CTX_DATA_TYPE_COLLECTION); +} + +const char *outliner_context_dir[] = {"selected_ids", NULL}; + +int /*eContextResult*/ outliner_context(const bContext *C, + const char *member, + bContextDataResult *result) +{ + SpaceOutliner *space_outliner = CTX_wm_space_outliner(C); + + if (CTX_data_dir(member)) { + CTX_data_dir_set(result, outliner_context_dir); + return CTX_RESULT_OK; + } + else if (CTX_data_equals(member, "selected_ids")) { + outliner_context_selected_ids(space_outliner, result); + return CTX_RESULT_OK; + } + /* Note: Querying non-ID selection could also work if tree elements stored their matching RNA + * struct type. */ + + return CTX_RESULT_MEMBER_NOT_FOUND; +} diff --git a/source/blender/editors/space_outliner/outliner_intern.h b/source/blender/editors/space_outliner/outliner_intern.h index 0294b4836c8..ccb481197e4 100644 --- a/source/blender/editors/space_outliner/outliner_intern.h +++ b/source/blender/editors/space_outliner/outliner_intern.h @@ -32,6 +32,7 @@ extern "C" { /* internal exports only */ struct ARegion; +struct bContextDataResult; struct EditBone; struct ID; struct ListBase; @@ -561,6 +562,12 @@ void outliner_tag_redraw_avoid_rebuild_on_open_change(const struct SpaceOutliner void outliner_sync_selection(const struct bContext *C, struct SpaceOutliner *space_outliner); +/* outliner_context.c ------------------------------------------- */ + +int outliner_context(const struct bContext *C, + const char *member, + struct bContextDataResult *result); + #ifdef __cplusplus } #endif diff --git a/source/blender/editors/space_outliner/space_outliner.c b/source/blender/editors/space_outliner/space_outliner.c index 3d675fdd9e4..c7c207caca0 100644 --- a/source/blender/editors/space_outliner/space_outliner.c +++ b/source/blender/editors/space_outliner/space_outliner.c @@ -451,6 +451,7 @@ void ED_spacetype_outliner(void) st->dropboxes = outliner_dropboxes; st->id_remap = outliner_id_remap; st->deactivate = outliner_deactivate; + st->context = outliner_context; /* regions: main window */ art = MEM_callocN(sizeof(ARegionType), "spacetype outliner region"); -- cgit v1.2.3 From 0c1d4769235c95fc976be8988e2d4c529f3fdf49 Mon Sep 17 00:00:00 2001 From: Julian Eisel Date: Fri, 11 Dec 2020 22:20:31 +0100 Subject: UI: Allow UI to pass focused data-block to operators via context This is similar to c4a2067130130d, but applies to the general UI and is only about single data-blocks. Here there was a similar problem: How can buttons pass the data they represent to operators? We currently resort to ugly ad-hoc solutions like `UI_context_active_but_get_tab_ID()`. So the operator would need to know that it is executed on a tab button that represents a data-block. A single button can now hand operators a data-block to operate on. The operator can request it via the "id" context member (`CTX_data_pointer_get_type(C, "id", &RNA_ID)` in C, `bpy.context.id` in .py). In this commit, it is already set in the following places: * Generic RNA button code sets it to the pointed to data-block, if the button represents a data-block RNA pointer property. (I.e for general data-block search buttons.) * Data-block selectors (`templateID`) set it to the currently active data-block. * The material slot UI-List sets it for each slot to the material it represents. The button context menu code is modified so its operators use the context set for the layout of its parent button (i.e. `layout.context_pointer_set()`). No user visible changes. This new design isn't actually used yet. It will be soon for asset operators. Reviewed as part of https://developer.blender.org/D9717. Reviewed by: Brecht Van Lommel --- source/blender/editors/include/UI_interface.h | 1 + source/blender/editors/interface/interface.c | 9 +++++++++ source/blender/editors/interface/interface_context_menu.c | 10 ++++++++++ source/blender/editors/interface/interface_layout.c | 5 +++++ source/blender/editors/interface/interface_templates.c | 7 +++++++ 5 files changed, 32 insertions(+) (limited to 'source/blender/editors') diff --git a/source/blender/editors/include/UI_interface.h b/source/blender/editors/include/UI_interface.h index 005dbf0e381..352c58032f5 100644 --- a/source/blender/editors/include/UI_interface.h +++ b/source/blender/editors/include/UI_interface.h @@ -1879,6 +1879,7 @@ uiBlock *uiLayoutGetBlock(uiLayout *layout); void uiLayoutSetFunc(uiLayout *layout, uiMenuHandleFunc handlefunc, void *argv); void uiLayoutSetContextPointer(uiLayout *layout, const char *name, struct PointerRNA *ptr); +struct bContextStore *uiLayoutGetContextStore(uiLayout *layout); void uiLayoutContextCopy(uiLayout *layout, struct bContextStore *context); struct wmOperatorType *UI_but_operatortype_get_from_enum_menu(struct uiBut *but, PropertyRNA **r_prop); diff --git a/source/blender/editors/interface/interface.c b/source/blender/editors/interface/interface.c index 4a02c6b6e88..254d0909367 100644 --- a/source/blender/editors/interface/interface.c +++ b/source/blender/editors/interface/interface.c @@ -4552,6 +4552,15 @@ static uiBut *ui_def_but_rna(uiBlock *block, UI_but_disable(but, info); } + if (proptype == PROP_POINTER) { + /* If the button shows an ID, automatically set it as focused in context so operators can + * access it.*/ + const PointerRNA pptr = RNA_property_pointer_get(ptr, prop); + if (pptr.data && RNA_struct_is_ID(pptr.type)) { + but->context = CTX_store_add(&block->contexts, "id", &pptr); + } + } + if (but->flag & UI_BUT_UNDO && (ui_but_is_rna_undo(but) == false)) { but->flag &= ~UI_BUT_UNDO; } diff --git a/source/blender/editors/interface/interface_context_menu.c b/source/blender/editors/interface/interface_context_menu.c index 39b405a02b8..3e76cd1cde4 100644 --- a/source/blender/editors/interface/interface_context_menu.c +++ b/source/blender/editors/interface/interface_context_menu.c @@ -503,6 +503,7 @@ bool ui_popup_context_menu_for_button(bContext *C, uiBut *but) uiPopupMenu *pup; uiLayout *layout; + bContextStore *previous_ctx = CTX_store_get(C); { uiStringInfo label = {BUT_GET_LABEL, NULL}; @@ -514,6 +515,11 @@ bool ui_popup_context_menu_for_button(bContext *C, uiBut *but) if (label.strinfo) { MEM_freeN(label.strinfo); } + + if (but->context) { + uiLayoutContextCopy(layout, but->context); + CTX_store_set(C, uiLayoutGetContextStore(layout)); + } uiLayoutSetOperatorContext(layout, WM_OP_INVOKE_DEFAULT); } @@ -1210,6 +1216,10 @@ bool ui_popup_context_menu_for_button(bContext *C, uiBut *but) UI_menutype_draw(C, mt, uiLayoutColumn(layout, false)); } + if (but->context) { + CTX_store_set(C, previous_ctx); + } + return UI_popup_menu_end_or_cancel(C, pup); } diff --git a/source/blender/editors/interface/interface_layout.c b/source/blender/editors/interface/interface_layout.c index ebd2235cb82..4b19b8f97f4 100644 --- a/source/blender/editors/interface/interface_layout.c +++ b/source/blender/editors/interface/interface_layout.c @@ -5663,6 +5663,11 @@ void uiLayoutSetContextPointer(uiLayout *layout, const char *name, PointerRNA *p layout->context = CTX_store_add(&block->contexts, name, ptr); } +bContextStore *uiLayoutGetContextStore(uiLayout *layout) +{ + return layout->context; +} + void uiLayoutContextCopy(uiLayout *layout, bContextStore *context) { uiBlock *block = layout->root->block; diff --git a/source/blender/editors/interface/interface_templates.c b/source/blender/editors/interface/interface_templates.c index 43ead511cfe..352afe72e76 100644 --- a/source/blender/editors/interface/interface_templates.c +++ b/source/blender/editors/interface/interface_templates.c @@ -895,6 +895,9 @@ static void template_ID(const bContext *C, idfrom = template_ui->ptr.owner_id; // lb = template_ui->idlb; + /* Allow opertators to take the ID from context. */ + uiLayoutSetContextPointer(layout, "id", &idptr); + block = uiLayoutGetBlock(layout); UI_block_align_begin(block); @@ -6170,6 +6173,10 @@ void uiTemplateList(uiLayout *layout, org_i, flt_flag); + /* Items should be able to set context pointers for the layout. But the listrow button + * swallows events, so it needs the context storage too for handlers to see it. */ + but->context = uiLayoutGetContextStore(sub); + /* If we are "drawing" active item, set all labels as active. */ if (i == activei) { ui_layout_list_set_labels_active(sub); -- cgit v1.2.3 From ae94a390a72763f2cd1d7108e723d153c549c310 Mon Sep 17 00:00:00 2001 From: Jacques Lucke Date: Sat, 12 Dec 2020 12:24:14 +0100 Subject: Cleanup: clang tidy --- source/blender/editors/space_outliner/outliner_context.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source/blender/editors') diff --git a/source/blender/editors/space_outliner/outliner_context.c b/source/blender/editors/space_outliner/outliner_context.c index 760fa8e4604..e7dc2780c37 100644 --- a/source/blender/editors/space_outliner/outliner_context.c +++ b/source/blender/editors/space_outliner/outliner_context.c @@ -62,7 +62,7 @@ int /*eContextResult*/ outliner_context(const bContext *C, CTX_data_dir_set(result, outliner_context_dir); return CTX_RESULT_OK; } - else if (CTX_data_equals(member, "selected_ids")) { + if (CTX_data_equals(member, "selected_ids")) { outliner_context_selected_ids(space_outliner, result); return CTX_RESULT_OK; } -- cgit v1.2.3 From 57f900e4efdaa0e4daba8e3c52684acb52a67a2e Mon Sep 17 00:00:00 2001 From: Antonio Vazquez Date: Sat, 12 Dec 2020 18:40:48 +0100 Subject: Fix T83705: GPencil - Duplicate strokes of destination layer when merge layer If the destination layer hadn't keyframe, a new keyframe was added and later the merge layer strokes were added, but this could change the animation because the new frame replaced the old drawings of the target layer. Now, before merge the layer, all keyframes are added in the target layer in order to keep the drawings. --- source/blender/editors/gpencil/gpencil_data.c | 21 +++++++++++++-------- 1 file changed, 13 insertions(+), 8 deletions(-) (limited to 'source/blender/editors') diff --git a/source/blender/editors/gpencil/gpencil_data.c b/source/blender/editors/gpencil/gpencil_data.c index 33a1469beab..203e86e9e15 100644 --- a/source/blender/editors/gpencil/gpencil_data.c +++ b/source/blender/editors/gpencil/gpencil_data.c @@ -1330,19 +1330,24 @@ static int gpencil_merge_layer_exec(bContext *C, wmOperator *op) BLI_ghash_insert(gh_frames_dst, POINTER_FROM_INT(gpf_dst->framenum), gpf_dst); } - /* Read all frames from merge layer and add any missing in destination layer. */ + /* Read all frames from merge layer and add any missing in destination layer, + * copying all previous strokes to keep the image equals. Need to do it in a separated + * loop to avoid strokes acumulation. */ LISTBASE_FOREACH (bGPDframe *, gpf_src, &gpl_src->frames) { /* Try to find frame in destination layer hash table. */ bGPDframe *gpf_dst = BLI_ghash_lookup(gh_frames_dst, POINTER_FROM_INT(gpf_src->framenum)); if (!gpf_dst) { - gpf_dst = BKE_gpencil_frame_addnew(gpl_dst, gpf_src->framenum); - /* Duplicate strokes into destination frame. */ - if (gpf_dst) { - BKE_gpencil_frame_copy_strokes(gpf_src, gpf_dst); - } + gpf_dst = BKE_gpencil_layer_frame_get(gpl_dst, gpf_src->framenum, GP_GETFRAME_ADD_COPY); + BLI_ghash_insert(gh_frames_dst, POINTER_FROM_INT(gpf_src->framenum), gpf_dst); } - else { - /* Add to tail all strokes. */ + } + + /* Read all frames from merge layer and add strokes. */ + LISTBASE_FOREACH (bGPDframe *, gpf_src, &gpl_src->frames) { + /* Try to find frame in destination layer hash table. */ + bGPDframe *gpf_dst = BLI_ghash_lookup(gh_frames_dst, POINTER_FROM_INT(gpf_src->framenum)); + /* Add to tail all strokes. */ + if (gpf_dst) { BLI_movelisttolist(&gpf_dst->strokes, &gpf_src->strokes); } } -- cgit v1.2.3 From c6075118d5d35657f9adcd6867b9655962e7386c Mon Sep 17 00:00:00 2001 From: Hans Goudey Date: Sun, 13 Dec 2020 09:27:37 -0600 Subject: Cleanup: Reduce variable scope in view_2d_ops.c --- source/blender/editors/interface/view2d_ops.c | 72 ++++++++++----------------- 1 file changed, 25 insertions(+), 47 deletions(-) (limited to 'source/blender/editors') diff --git a/source/blender/editors/interface/view2d_ops.c b/source/blender/editors/interface/view2d_ops.c index a5999962e09..7de0ec0255f 100644 --- a/source/blender/editors/interface/view2d_ops.c +++ b/source/blender/editors/interface/view2d_ops.c @@ -109,14 +109,13 @@ typedef struct v2dViewPanData { static bool view_pan_poll(bContext *C) { ARegion *region = CTX_wm_region(C); - View2D *v2d; /* check if there's a region in context to work with */ if (region == NULL) { return false; } - v2d = ®ion->v2d; + View2D *v2d = ®ion->v2d; /* check that 2d-view can pan */ if ((v2d->keepofs & V2D_LOCKOFS_X) && (v2d->keepofs & V2D_LOCKOFS_Y)) { @@ -191,10 +190,7 @@ static void view_pan_apply(bContext *C, wmOperator *op) /* cleanup temp customdata */ static void view_pan_exit(wmOperator *op) { - if (op->customdata) { - MEM_freeN(op->customdata); - op->customdata = NULL; - } + MEM_SAFE_FREE(op->customdata); } /** \} */ @@ -216,14 +212,12 @@ static int view_pan_exec(bContext *C, wmOperator *op) static int view_pan_invoke(bContext *C, wmOperator *op, const wmEvent *event) { wmWindow *window = CTX_wm_window(C); - v2dViewPanData *vpd; - View2D *v2d; /* set up customdata */ view_pan_init(C, op); - vpd = op->customdata; - v2d = vpd->v2d; + v2dViewPanData *vpd = op->customdata; + View2D *v2d = vpd->v2d; /* set initial settings */ vpd->startx = vpd->lastx = event->x; @@ -787,7 +781,6 @@ static void view_zoom_axis_lock_defaults(bContext *C, bool r_do_zoom_xy[2]) static bool view_zoom_poll(bContext *C) { ARegion *region = CTX_wm_region(C); - View2D *v2d; /* check if there's a region in context to work with */ if (region == NULL) { @@ -799,7 +792,7 @@ static bool view_zoom_poll(bContext *C) return false; } - v2d = ®ion->v2d; + View2D *v2d = ®ion->v2d; /* check that 2d-view is zoomable */ if ((v2d->keepzoom & V2D_LOCKZOOM_X) && (v2d->keepzoom & V2D_LOCKZOOM_Y)) { @@ -836,12 +829,12 @@ static void view_zoomstep_apply_ex(bContext *C, ARegion *region = CTX_wm_region(C); View2D *v2d = ®ion->v2d; const rctf cur_old = v2d->cur; - float dx, dy; const int snap_test = ED_region_snap_size_test(region); /* calculate amount to move view by, ensuring symmetry so the * old zoom level is restored after zooming back the same amount */ + float dx, dy; if (facx >= 0.0f) { dx = BLI_rctf_size_x(&v2d->cur) * facx; dy = BLI_rctf_size_y(&v2d->cur) * facy; @@ -955,10 +948,7 @@ static void view_zoomstep_exit(wmOperator *op) { UI_view2d_zoom_cache_reset(); - if (op->customdata) { - MEM_freeN(op->customdata); - op->customdata = NULL; - } + MEM_SAFE_FREE(op->customdata); } /* this operator only needs this single callback, where it calls the view_zoom_*() methods */ @@ -1107,15 +1097,14 @@ static void view_zoomdrag_apply(bContext *C, wmOperator *op) { v2dViewZoomData *vzd = op->customdata; View2D *v2d = vzd->v2d; - float dx, dy; const int snap_test = ED_region_snap_size_test(vzd->region); const bool use_cursor_init = RNA_boolean_get(op->ptr, "use_cursor_init"); const bool zoom_to_pos = use_cursor_init && vzd->zoom_to_mouse_pos; /* get amount to move view by */ - dx = RNA_float_get(op->ptr, "deltax") / U.dpi_fac; - dy = RNA_float_get(op->ptr, "deltay") / U.dpi_fac; + float dx = RNA_float_get(op->ptr, "deltax") / U.dpi_fac; + float dy = RNA_float_get(op->ptr, "deltay") / U.dpi_fac; if (U.uiflag & USER_ZOOM_INVERT) { dx *= -1; @@ -1223,14 +1212,12 @@ static int view_zoomdrag_exec(bContext *C, wmOperator *op) static int view_zoomdrag_invoke(bContext *C, wmOperator *op, const wmEvent *event) { wmWindow *window = CTX_wm_window(C); - v2dViewZoomData *vzd; - View2D *v2d; /* set up customdata */ view_zoomdrag_init(C, op); - vzd = op->customdata; - v2d = vzd->v2d; + v2dViewZoomData *vzd = op->customdata; + View2D *v2d = vzd->v2d; if (U.uiflag & USER_ZOOM_TO_MOUSEPOS) { ARegion *region = CTX_wm_region(C); @@ -1242,20 +1229,18 @@ static int view_zoomdrag_invoke(bContext *C, wmOperator *op, const wmEvent *even } if (ELEM(event->type, MOUSEZOOM, MOUSEPAN)) { - float dx, dy, fac; - vzd->lastx = event->prevx; vzd->lasty = event->prevy; /* As we have only 1D information (magnify value), feed both axes * with magnify information that is stored in x axis */ - fac = 0.01f * (event->prevx - event->x); - dx = fac * BLI_rctf_size_x(&v2d->cur) / 10.0f; + float fac = 0.01f * (event->prevx - event->x); + float dx = fac * BLI_rctf_size_x(&v2d->cur) / 10.0f; if (event->type == MOUSEPAN) { fac = 0.01f * (event->prevy - event->y); } - dy = fac * BLI_rctf_size_y(&v2d->cur) / 10.0f; + float dy = fac * BLI_rctf_size_y(&v2d->cur) / 10.0f; /* support trackpad zoom to always zoom entirely - the v2d code uses portrait or * landscape exceptions */ @@ -1491,11 +1476,11 @@ static int view_borderzoom_exec(bContext *C, wmOperator *op) { ARegion *region = CTX_wm_region(C); View2D *v2d = ®ion->v2d; - rctf rect; rctf cur_new = v2d->cur; const int smooth_viewtx = WM_operator_smooth_viewtx_get(op); /* convert coordinates of rect to 'tot' rect coordinates */ + rctf rect; WM_operator_properties_border_to_rctf(op, &rect); UI_view2d_region_to_view_rctf(v2d, &rect, &rect); @@ -1766,13 +1751,13 @@ static int view2d_smoothview_invoke(bContext *C, wmOperator *UNUSED(op), const w ARegion *region = CTX_wm_region(C); View2D *v2d = ®ion->v2d; struct SmoothView2DStore *sms = v2d->sms; - float step; /* escape if not our timer */ if (v2d->smooth_timer == NULL || v2d->smooth_timer != event->customdata) { return OPERATOR_PASS_THROUGH; } + float step; if (sms->time_allowed != 0.0) { step = (float)((v2d->smooth_timer->duration) / sms->time_allowed); } @@ -1978,15 +1963,11 @@ static void scroller_activate_init(bContext *C, const wmEvent *event, const char in_scroller) { - v2dScrollerMove *vsm; - View2DScrollers scrollers; ARegion *region = CTX_wm_region(C); View2D *v2d = ®ion->v2d; - rctf tot_cur_union; - float mask_size; /* set custom-data for operator */ - vsm = MEM_callocN(sizeof(v2dScrollerMove), "v2dScrollerMove"); + v2dScrollerMove *vsm = MEM_callocN(sizeof(v2dScrollerMove), "v2dScrollerMove"); op->customdata = vsm; /* set general data */ @@ -2000,16 +1981,17 @@ static void scroller_activate_init(bContext *C, /* 'zone' depends on where mouse is relative to bubble * - zooming must be allowed on this axis, otherwise, default to pan */ + View2DScrollers scrollers; UI_view2d_scrollers_calc(v2d, NULL, &scrollers); /* Use a union of 'cur' & 'tot' in case the current view is far outside 'tot'. In this cases * moving the scroll bars has far too little effect and the view can get stuck T31476. */ - tot_cur_union = v2d->tot; + rctf tot_cur_union = v2d->tot; BLI_rctf_union(&tot_cur_union, &v2d->cur); if (in_scroller == 'h') { /* horizontal scroller - calculate adjustment factor first */ - mask_size = (float)BLI_rcti_size_x(&v2d->hor); + float mask_size = (float)BLI_rcti_size_x(&v2d->hor); vsm->fac = BLI_rctf_size_x(&tot_cur_union) / mask_size; /* pixel rounding */ @@ -2029,7 +2011,7 @@ static void scroller_activate_init(bContext *C, } else { /* vertical scroller - calculate adjustment factor first */ - mask_size = (float)BLI_rcti_size_y(&v2d->vert); + float mask_size = (float)BLI_rcti_size_y(&v2d->vert); vsm->fac = BLI_rctf_size_y(&tot_cur_union) / mask_size; /* pixel rounding */ @@ -2076,10 +2058,9 @@ static void scroller_activate_apply(bContext *C, wmOperator *op) { v2dScrollerMove *vsm = op->customdata; View2D *v2d = vsm->v2d; - float temp; /* calculate amount to move view by */ - temp = vsm->fac * vsm->delta; + float temp = vsm->fac * vsm->delta; /* round to pixel */ temp = roundf(temp / vsm->fac_round) * vsm->fac_round; @@ -2219,11 +2200,9 @@ static int scroller_activate_invoke(bContext *C, wmOperator *op, const wmEvent * /* if in a scroller, init customdata then set modal handler which will * catch mouse-down to start doing useful stuff */ if (in_scroller) { - v2dScrollerMove *vsm; - /* initialize customdata */ scroller_activate_init(C, op, event, in_scroller); - vsm = (v2dScrollerMove *)op->customdata; + v2dScrollerMove *vsm = (v2dScrollerMove *)op->customdata; /* support for quick jump to location - gtk and qt do this on linux */ if (event->type == MIDDLEMOUSE) { @@ -2324,12 +2303,11 @@ static int reset_exec(bContext *C, wmOperator *UNUSED(op)) const uiStyle *style = UI_style_get(); ARegion *region = CTX_wm_region(C); View2D *v2d = ®ion->v2d; - int winx, winy; const int snap_test = ED_region_snap_size_test(region); /* zoom 1.0 */ - winx = (float)(BLI_rcti_size_x(&v2d->mask) + 1); - winy = (float)(BLI_rcti_size_y(&v2d->mask) + 1); + const int winx = (float)(BLI_rcti_size_x(&v2d->mask) + 1); + const int winy = (float)(BLI_rcti_size_y(&v2d->mask) + 1); v2d->cur.xmax = v2d->cur.xmin + winx; v2d->cur.ymax = v2d->cur.ymin + winy; -- cgit v1.2.3 From bec583951d736776d2096368ef8d2b764287ac11 Mon Sep 17 00:00:00 2001 From: Yevgeny Makarov Date: Sun, 13 Dec 2020 12:28:01 -0800 Subject: UI: Remove Unused 'U.wheellinescroll' Property Remove 'U.wheellinescroll' preference, currently hidden and unused. Differential Revision: https://developer.blender.org/D9616 Reviewed by Brecht Van Lommel --- source/blender/editors/space_text/text_ops.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source/blender/editors') diff --git a/source/blender/editors/space_text/text_ops.c b/source/blender/editors/space_text/text_ops.c index f8b7c62686f..932bacfb8a0 100644 --- a/source/blender/editors/space_text/text_ops.c +++ b/source/blender/editors/space_text/text_ops.c @@ -2588,7 +2588,7 @@ static int text_scroll_exec(bContext *C, wmOperator *op) return OPERATOR_CANCELLED; } - txt_screen_skip(st, region, lines * U.wheellinescroll); + txt_screen_skip(st, region, lines * 3); ED_area_tag_redraw(CTX_wm_area(C)); -- cgit v1.2.3 From a2693ba43e8cfb12a286f87fd2e14659822a1fd2 Mon Sep 17 00:00:00 2001 From: Yevgeny Makarov Date: Sun, 13 Dec 2020 12:59:36 -0800 Subject: Cleanup: removing some uses of equal sign in descriptions Using 'is/means/equal' words in place of equal sign in descriptions. Differential Revision: https://developer.blender.org/D9799 Reviewed by Hans Goudey --- source/blender/editors/mesh/editmesh_select.c | 3 ++- source/blender/editors/space_action/action_edit.c | 2 +- source/blender/editors/space_graph/graph_edit.c | 4 ++-- source/blender/editors/space_outliner/outliner_dragdrop.c | 4 ++-- 4 files changed, 7 insertions(+), 6 deletions(-) (limited to 'source/blender/editors') diff --git a/source/blender/editors/mesh/editmesh_select.c b/source/blender/editors/mesh/editmesh_select.c index a2fe949b6c5..d3eaa9048d3 100644 --- a/source/blender/editors/mesh/editmesh_select.c +++ b/source/blender/editors/mesh/editmesh_select.c @@ -4552,7 +4552,8 @@ void MESH_OT_select_non_manifold(wmOperatorType *ot) /* edges */ RNA_def_boolean(ot->srna, "use_wire", true, "Wire", "Wire edges"); RNA_def_boolean(ot->srna, "use_boundary", true, "Boundaries", "Boundary edges"); - RNA_def_boolean(ot->srna, "use_multi_face", true, "Multiple Faces", "Edges shared by 3+ faces"); + RNA_def_boolean( + ot->srna, "use_multi_face", true, "Multiple Faces", "Edges shared by more than two faces"); RNA_def_boolean(ot->srna, "use_non_contiguous", true, diff --git a/source/blender/editors/space_action/action_edit.c b/source/blender/editors/space_action/action_edit.c index 167215b3813..d186cafb857 100644 --- a/source/blender/editors/space_action/action_edit.c +++ b/source/blender/editors/space_action/action_edit.c @@ -1827,7 +1827,7 @@ static const EnumPropertyItem prop_actkeys_mirror_types[] = { {ACTKEYS_MIRROR_XAXIS, "XAXIS", 0, - "By Values Over Value=0", + "By Values Over Zero Value", "Flip values of selected keyframes (i.e. negative values become positive, and vice versa)"}, {ACTKEYS_MIRROR_MARKER, "MARKER", diff --git a/source/blender/editors/space_graph/graph_edit.c b/source/blender/editors/space_graph/graph_edit.c index c3e4eceef6e..e56d71913d6 100644 --- a/source/blender/editors/space_graph/graph_edit.c +++ b/source/blender/editors/space_graph/graph_edit.c @@ -2354,12 +2354,12 @@ static const EnumPropertyItem prop_graphkeys_mirror_types[] = { {GRAPHKEYS_MIRROR_YAXIS, "YAXIS", 0, - "By Times Over Time=0", + "By Times Over Zero Time", "Flip times of selected keyframes, effectively reversing the order they appear in"}, {GRAPHKEYS_MIRROR_XAXIS, "XAXIS", 0, - "By Values Over Value=0", + "By Values Over Zero Value", "Flip values of selected keyframes (i.e. negative values become positive, and vice versa)"}, {GRAPHKEYS_MIRROR_MARKER, "MARKER", diff --git a/source/blender/editors/space_outliner/outliner_dragdrop.c b/source/blender/editors/space_outliner/outliner_dragdrop.c index d3da7b80765..dcb8ef9c954 100644 --- a/source/blender/editors/space_outliner/outliner_dragdrop.c +++ b/source/blender/editors/space_outliner/outliner_dragdrop.c @@ -445,7 +445,7 @@ static int parent_drop_invoke(bContext *C, wmOperator *op, const wmEvent *event) void OUTLINER_OT_parent_drop(wmOperatorType *ot) { /* identifiers */ - ot->name = "Drop to Set Parent [+Alt keeps transforms]"; + ot->name = "Drop to Set Parent (hold Alt to keep transforms)"; ot->description = "Drag to parent in Outliner"; ot->idname = "OUTLINER_OT_parent_drop"; @@ -531,7 +531,7 @@ static int parent_clear_invoke(bContext *C, wmOperator *UNUSED(op), const wmEven void OUTLINER_OT_parent_clear(wmOperatorType *ot) { /* identifiers */ - ot->name = "Drop to Clear Parent [+Alt keeps transforms]"; + ot->name = "Drop to Clear Parent (hold Alt to keep transforms)"; ot->description = "Drag to clear parent in Outliner"; ot->idname = "OUTLINER_OT_parent_clear"; -- cgit v1.2.3 From 977ef04746d8a6a36a217330a02024cf768f636d Mon Sep 17 00:00:00 2001 From: Yevgeny Makarov Date: Sun, 13 Dec 2020 13:12:56 -0800 Subject: Cleanup: Fix capitalization in various places Approximately 33 changes of capitalization to conform to MLA title style. Differential Revision: https://developer.blender.org/D9796 Reviewed by Julian Eisel --- source/blender/editors/animation/anim_ops.c | 2 +- source/blender/editors/curve/editcurve.c | 2 +- source/blender/editors/mesh/editmesh_bevel.c | 2 +- source/blender/editors/mesh/editmesh_knife_project.c | 2 +- source/blender/editors/object/object_gpencil_modifier.c | 2 +- source/blender/editors/object/object_relations.c | 2 +- source/blender/editors/sculpt_paint/paint_image_proj.c | 2 +- source/blender/editors/sculpt_paint/sculpt.c | 2 +- source/blender/editors/sculpt_paint/sculpt_detail.c | 2 +- source/blender/editors/sculpt_paint/sculpt_filter_color.c | 4 ++-- source/blender/editors/sculpt_paint/sculpt_filter_mask.c | 4 ++-- source/blender/editors/sculpt_paint/sculpt_filter_mesh.c | 6 +++--- source/blender/editors/space_action/action_select.c | 4 ++-- source/blender/editors/space_graph/graph_select.c | 4 ++-- source/blender/editors/space_info/info_report.c | 2 +- source/blender/editors/space_node/node_view.c | 2 +- source/blender/editors/space_script/script_edit.c | 2 +- source/blender/editors/uvedit/uvedit_smart_stitch.c | 2 +- 18 files changed, 24 insertions(+), 24 deletions(-) (limited to 'source/blender/editors') diff --git a/source/blender/editors/animation/anim_ops.c b/source/blender/editors/animation/anim_ops.c index 9e622aea6ab..0db3e984b60 100644 --- a/source/blender/editors/animation/anim_ops.c +++ b/source/blender/editors/animation/anim_ops.c @@ -503,7 +503,7 @@ static void ANIM_OT_previewrange_clear(wmOperatorType *ot) /* identifiers */ ot->name = "Clear Preview Range"; ot->idname = "ANIM_OT_previewrange_clear"; - ot->description = "Clear Preview Range"; + ot->description = "Clear preview range"; /* api callbacks */ ot->exec = previewrange_clear_exec; diff --git a/source/blender/editors/curve/editcurve.c b/source/blender/editors/curve/editcurve.c index db472c9ffa7..2b627971286 100644 --- a/source/blender/editors/curve/editcurve.c +++ b/source/blender/editors/curve/editcurve.c @@ -3838,7 +3838,7 @@ void CURVE_OT_subdivide(wmOperatorType *ot) /* flags */ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; - prop = RNA_def_int(ot->srna, "number_cuts", 1, 1, 1000, "Number of cuts", "", 1, 10); + prop = RNA_def_int(ot->srna, "number_cuts", 1, 1, 1000, "Number of Cuts", "", 1, 10); /* Avoid re-using last var because it can cause _very_ high poly meshes * and annoy users (or worse crash). */ RNA_def_property_flag(prop, PROP_SKIP_SAVE); diff --git a/source/blender/editors/mesh/editmesh_bevel.c b/source/blender/editors/mesh/editmesh_bevel.c index b8badd207fe..e788b28d3b4 100644 --- a/source/blender/editors/mesh/editmesh_bevel.c +++ b/source/blender/editors/mesh/editmesh_bevel.c @@ -1129,7 +1129,7 @@ void MESH_OT_bevel(wmOperatorType *ot) prop_affect_items, BEVEL_AFFECT_EDGES, "Affect", - "Affect Edges or Vertices"); + "Affect edges or vertices"); RNA_def_boolean(ot->srna, "clamp_overlap", diff --git a/source/blender/editors/mesh/editmesh_knife_project.c b/source/blender/editors/mesh/editmesh_knife_project.c index ef78d31a6bb..aa144dd3f3c 100644 --- a/source/blender/editors/mesh/editmesh_knife_project.c +++ b/source/blender/editors/mesh/editmesh_knife_project.c @@ -177,6 +177,6 @@ void MESH_OT_knife_project(wmOperatorType *ot) RNA_def_boolean(ot->srna, "cut_through", false, - "Cut through", + "Cut Through", "Cut through all faces, not just visible ones"); } diff --git a/source/blender/editors/object/object_gpencil_modifier.c b/source/blender/editors/object/object_gpencil_modifier.c index af95f5581bd..9ea67df6daf 100644 --- a/source/blender/editors/object/object_gpencil_modifier.c +++ b/source/blender/editors/object/object_gpencil_modifier.c @@ -789,7 +789,7 @@ void OBJECT_OT_gpencil_modifier_apply(wmOperatorType *ot) "apply_as", gpencil_modifier_apply_as_items, MODIFIER_APPLY_DATA, - "Apply as", + "Apply As", "How to apply the modifier to the geometry"); gpencil_edit_modifier_properties(ot); gpencil_edit_modifier_report_property(ot); diff --git a/source/blender/editors/object/object_relations.c b/source/blender/editors/object/object_relations.c index 3ad500d3d0d..8ec9f7af184 100644 --- a/source/blender/editors/object/object_relations.c +++ b/source/blender/editors/object/object_relations.c @@ -2556,7 +2556,7 @@ static int convert_proxy_to_override_exec(bContext *C, wmOperator *UNUSED(op)) void OBJECT_OT_convert_proxy_to_override(wmOperatorType *ot) { /* identifiers */ - ot->name = "Convert Proxy To Override"; + ot->name = "Convert Proxy to Override"; ot->description = "Convert a proxy to a local library override"; ot->idname = "OBJECT_OT_convert_proxy_to_override"; diff --git a/source/blender/editors/sculpt_paint/paint_image_proj.c b/source/blender/editors/sculpt_paint/paint_image_proj.c index 98f4b4013cb..cca4ffd4d78 100644 --- a/source/blender/editors/sculpt_paint/paint_image_proj.c +++ b/source/blender/editors/sculpt_paint/paint_image_proj.c @@ -6781,7 +6781,7 @@ static bool add_simple_uvs_poll(bContext *C) void PAINT_OT_add_simple_uvs(wmOperatorType *ot) { /* identifiers */ - ot->name = "Add simple UVs"; + ot->name = "Add Simple UVs"; ot->description = "Add cube map uvs on mesh"; ot->idname = "PAINT_OT_add_simple_uvs"; diff --git a/source/blender/editors/sculpt_paint/sculpt.c b/source/blender/editors/sculpt_paint/sculpt.c index fd7ec1da497..94f05560f79 100644 --- a/source/blender/editors/sculpt_paint/sculpt.c +++ b/source/blender/editors/sculpt_paint/sculpt.c @@ -8685,7 +8685,7 @@ static int sculpt_sample_color_invoke(bContext *C, static void SCULPT_OT_sample_color(wmOperatorType *ot) { /* identifiers */ - ot->name = "Sample color"; + ot->name = "Sample Color"; ot->idname = "SCULPT_OT_sample_color"; ot->description = "Sample the vertex color of the active vertex"; diff --git a/source/blender/editors/sculpt_paint/sculpt_detail.c b/source/blender/editors/sculpt_paint/sculpt_detail.c index ddf5b39f080..aa1d407dc24 100644 --- a/source/blender/editors/sculpt_paint/sculpt_detail.c +++ b/source/blender/editors/sculpt_paint/sculpt_detail.c @@ -363,7 +363,7 @@ void SCULPT_OT_sample_detail_size(wmOperatorType *ot) 0, SHRT_MAX, "Location", - "Screen Coordinates of sampling", + "Screen coordinates of sampling", 0, SHRT_MAX); RNA_def_enum(ot->srna, diff --git a/source/blender/editors/sculpt_paint/sculpt_filter_color.c b/source/blender/editors/sculpt_paint/sculpt_filter_color.c index f3c07a86201..76a6b05cdff 100644 --- a/source/blender/editors/sculpt_paint/sculpt_filter_color.c +++ b/source/blender/editors/sculpt_paint/sculpt_filter_color.c @@ -328,9 +328,9 @@ void SCULPT_OT_color_filter(struct wmOperatorType *ot) ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; /* rna */ - RNA_def_enum(ot->srna, "type", prop_color_filter_types, COLOR_FILTER_HUE, "Filter type", ""); + RNA_def_enum(ot->srna, "type", prop_color_filter_types, COLOR_FILTER_HUE, "Filter Type", ""); RNA_def_float( - ot->srna, "strength", 1.0f, -10.0f, 10.0f, "Strength", "Filter Strength", -10.0f, 10.0f); + ot->srna, "strength", 1.0f, -10.0f, 10.0f, "Strength", "Filter strength", -10.0f, 10.0f); PropertyRNA *prop = RNA_def_float_color( ot->srna, "fill_color", 3, NULL, 0.0f, FLT_MAX, "Fill Color", "", 0.0f, 1.0f); diff --git a/source/blender/editors/sculpt_paint/sculpt_filter_mask.c b/source/blender/editors/sculpt_paint/sculpt_filter_mask.c index ddad6bef7fd..0297ed73dd4 100644 --- a/source/blender/editors/sculpt_paint/sculpt_filter_mask.c +++ b/source/blender/editors/sculpt_paint/sculpt_filter_mask.c @@ -80,12 +80,12 @@ static EnumPropertyItem prop_mask_filter_types[] = { {MASK_FILTER_CONTRAST_INCREASE, "CONTRAST_INCREASE", 0, - "Increase contrast", + "Increase Contrast", "Increase the contrast of the paint mask"}, {MASK_FILTER_CONTRAST_DECREASE, "CONTRAST_DECREASE", 0, - "Decrease contrast", + "Decrease Contrast", "Decrease the contrast of the paint mask"}, {0, NULL, 0, NULL, NULL}, }; diff --git a/source/blender/editors/sculpt_paint/sculpt_filter_mesh.c b/source/blender/editors/sculpt_paint/sculpt_filter_mesh.c index 02d4be20e1b..e11894a8c01 100644 --- a/source/blender/editors/sculpt_paint/sculpt_filter_mesh.c +++ b/source/blender/editors/sculpt_paint/sculpt_filter_mesh.c @@ -771,15 +771,15 @@ void SCULPT_OT_mesh_filter(struct wmOperatorType *ot) "type", prop_mesh_filter_types, MESH_FILTER_INFLATE, - "Filter type", + "Filter Type", "Operation that is going to be applied to the mesh"); RNA_def_float( - ot->srna, "strength", 1.0f, -10.0f, 10.0f, "Strength", "Filter Strength", -10.0f, 10.0f); + ot->srna, "strength", 1.0f, -10.0f, 10.0f, "Strength", "Filter strength", -10.0f, 10.0f); RNA_def_enum_flag(ot->srna, "deform_axis", prop_mesh_filter_deform_axis_items, MESH_FILTER_DEFORM_X | MESH_FILTER_DEFORM_Y | MESH_FILTER_DEFORM_Z, - "Deform axis", + "Deform Axis", "Apply the deformation in the selected axis"); RNA_def_enum(ot->srna, "orientation", diff --git a/source/blender/editors/space_action/action_select.c b/source/blender/editors/space_action/action_select.c index ab5f1e0ab22..98e39520e99 100644 --- a/source/blender/editors/space_action/action_select.c +++ b/source/blender/editors/space_action/action_select.c @@ -1325,8 +1325,8 @@ void ACTION_OT_select_less(wmOperatorType *ot) /* defines for left-right select tool */ static const EnumPropertyItem prop_actkeys_leftright_select_types[] = { {ACTKEYS_LRSEL_TEST, "CHECK", 0, "Check if Select Left or Right", ""}, - {ACTKEYS_LRSEL_LEFT, "LEFT", 0, "Before current frame", ""}, - {ACTKEYS_LRSEL_RIGHT, "RIGHT", 0, "After current frame", ""}, + {ACTKEYS_LRSEL_LEFT, "LEFT", 0, "Before Current Frame", ""}, + {ACTKEYS_LRSEL_RIGHT, "RIGHT", 0, "After Current Frame", ""}, {0, NULL, 0, NULL, NULL}, }; diff --git a/source/blender/editors/space_graph/graph_select.c b/source/blender/editors/space_graph/graph_select.c index 12035ab6b61..4ab4ef518fb 100644 --- a/source/blender/editors/space_graph/graph_select.c +++ b/source/blender/editors/space_graph/graph_select.c @@ -1288,8 +1288,8 @@ void GRAPH_OT_select_less(wmOperatorType *ot) /* defines for left-right select tool */ static const EnumPropertyItem prop_graphkeys_leftright_select_types[] = { {GRAPHKEYS_LRSEL_TEST, "CHECK", 0, "Check if Select Left or Right", ""}, - {GRAPHKEYS_LRSEL_LEFT, "LEFT", 0, "Before current frame", ""}, - {GRAPHKEYS_LRSEL_RIGHT, "RIGHT", 0, "After current frame", ""}, + {GRAPHKEYS_LRSEL_LEFT, "LEFT", 0, "Before Current Frame", ""}, + {GRAPHKEYS_LRSEL_RIGHT, "RIGHT", 0, "After Current Frame", ""}, {0, NULL, 0, NULL, NULL}, }; diff --git a/source/blender/editors/space_info/info_report.c b/source/blender/editors/space_info/info_report.c index 3ba088018c3..7dd8382c8ef 100644 --- a/source/blender/editors/space_info/info_report.c +++ b/source/blender/editors/space_info/info_report.c @@ -396,7 +396,7 @@ void INFO_OT_report_copy(wmOperatorType *ot) { /* identifiers */ ot->name = "Copy Reports to Clipboard"; - ot->description = "Copy selected reports to Clipboard"; + ot->description = "Copy selected reports to clipboard"; ot->idname = "INFO_OT_report_copy"; /* api callbacks */ diff --git a/source/blender/editors/space_node/node_view.c b/source/blender/editors/space_node/node_view.c index 3c861896d37..d2c88ed787c 100644 --- a/source/blender/editors/space_node/node_view.c +++ b/source/blender/editors/space_node/node_view.c @@ -283,7 +283,7 @@ void NODE_OT_backimage_move(wmOperatorType *ot) { /* identifiers */ ot->name = "Background Image Move"; - ot->description = "Move Node backdrop"; + ot->description = "Move node backdrop"; ot->idname = "NODE_OT_backimage_move"; /* api callbacks */ diff --git a/source/blender/editors/space_script/script_edit.c b/source/blender/editors/space_script/script_edit.c index bde7bdb77f1..50cfa2e71c7 100644 --- a/source/blender/editors/space_script/script_edit.c +++ b/source/blender/editors/space_script/script_edit.c @@ -152,7 +152,7 @@ void SCRIPT_OT_reload(wmOperatorType *ot) { /* identifiers */ ot->name = "Reload Scripts"; - ot->description = "Reload Scripts"; + ot->description = "Reload scripts"; ot->idname = "SCRIPT_OT_reload"; /* api callbacks */ diff --git a/source/blender/editors/uvedit/uvedit_smart_stitch.c b/source/blender/editors/uvedit/uvedit_smart_stitch.c index 6dac31794b4..c1d222c9368 100644 --- a/source/blender/editors/uvedit/uvedit_smart_stitch.c +++ b/source/blender/editors/uvedit/uvedit_smart_stitch.c @@ -2808,7 +2808,7 @@ void UV_OT_stitch(wmOperatorType *ot) RNA_def_boolean(ot->srna, "midpoint_snap", 0, - "Snap At Midpoint", + "Snap at Midpoint", "UVs are stitched at midpoint instead of at static island"); RNA_def_boolean(ot->srna, "clear_seams", 1, "Clear Seams", "Clear seams of stitched edges"); RNA_def_enum(ot->srna, -- cgit v1.2.3 From 6327771bc968c14440eb30f971916cc913e77977 Mon Sep 17 00:00:00 2001 From: Antonio Vazquez Date: Mon, 14 Dec 2020 10:25:37 +0100 Subject: Fix T83696: Add Additional menu to Effects panel This adds the missing options for the effects as it is done in modifiers. Reviewed By: HooglyBoogly Maniphest Tasks: T83696 Differential Revision: https://developer.blender.org/D9838 --- source/blender/editors/object/object_intern.h | 1 + source/blender/editors/object/object_ops.c | 1 + source/blender/editors/object/object_shader_fx.c | 54 ++++++++++++++++++++++++ 3 files changed, 56 insertions(+) (limited to 'source/blender/editors') diff --git a/source/blender/editors/object/object_intern.h b/source/blender/editors/object/object_intern.h index e6ef53a3d65..89ade5cc49d 100644 --- a/source/blender/editors/object/object_intern.h +++ b/source/blender/editors/object/object_intern.h @@ -206,6 +206,7 @@ void OBJECT_OT_gpencil_modifier_copy(struct wmOperatorType *ot); /* object_shader_fx.c */ void OBJECT_OT_shaderfx_add(struct wmOperatorType *ot); +void OBJECT_OT_shaderfx_copy(struct wmOperatorType *ot); void OBJECT_OT_shaderfx_remove(struct wmOperatorType *ot); void OBJECT_OT_shaderfx_move_up(struct wmOperatorType *ot); void OBJECT_OT_shaderfx_move_down(struct wmOperatorType *ot); diff --git a/source/blender/editors/object/object_ops.c b/source/blender/editors/object/object_ops.c index 8ba0ce5fd08..2e5a75ffa7d 100644 --- a/source/blender/editors/object/object_ops.c +++ b/source/blender/editors/object/object_ops.c @@ -166,6 +166,7 @@ void ED_operatortypes_object(void) WM_operatortype_append(OBJECT_OT_shaderfx_move_up); WM_operatortype_append(OBJECT_OT_shaderfx_move_down); WM_operatortype_append(OBJECT_OT_shaderfx_move_to_index); + WM_operatortype_append(OBJECT_OT_shaderfx_copy); WM_operatortype_append(OBJECT_OT_correctivesmooth_bind); WM_operatortype_append(OBJECT_OT_meshdeform_bind); diff --git a/source/blender/editors/object/object_shader_fx.c b/source/blender/editors/object/object_shader_fx.c index c5caee5ba08..2b1ac08ec2e 100644 --- a/source/blender/editors/object/object_shader_fx.c +++ b/source/blender/editors/object/object_shader_fx.c @@ -640,3 +640,57 @@ void OBJECT_OT_shaderfx_move_to_index(wmOperatorType *ot) RNA_def_int( ot->srna, "index", 0, 0, INT_MAX, "Index", "The index to move the effect to", 0, INT_MAX); } + +/************************ copy shader operator *********************/ + +static int shaderfx_copy_exec(bContext *C, wmOperator *op) +{ + Object *ob = ED_object_active_context(C); + ShaderFxData *fx = edit_shaderfx_property_get(op, ob, 0); + + ShaderFxData *nfx = BKE_shaderfx_new(fx->type); + if (!nfx) { + return OPERATOR_CANCELLED; + } + + BLI_strncpy(nfx->name, fx->name, sizeof(nfx->name)); + /* Make sure effect data has unique name. */ + BKE_shaderfx_unique_name(&ob->shader_fx, nfx); + + BKE_shaderfx_copydata(fx, nfx); + BLI_insertlinkafter(&ob->shader_fx, fx, nfx); + + DEG_id_tag_update(&ob->id, ID_RECALC_GEOMETRY); + WM_main_add_notifier(NC_OBJECT | ND_SHADERFX, ob); + + return OPERATOR_FINISHED; +} + +static int shaderfx_copy_invoke(bContext *C, wmOperator *op, const wmEvent *event) +{ + int retval; + if (edit_shaderfx_invoke_properties(C, op, event, &retval)) { + return shaderfx_copy_exec(C, op); + } + return retval; +} + +static bool shaderfx_copy_poll(bContext *C) +{ + return edit_shaderfx_poll_generic(C, &RNA_ShaderFx, 0); +} + +void OBJECT_OT_shaderfx_copy(wmOperatorType *ot) +{ + ot->name = "Copy Effect"; + ot->description = "Duplicate effect at the same position in the stack"; + ot->idname = "OBJECT_OT_shaderfx_copy"; + + ot->invoke = shaderfx_copy_invoke; + ot->exec = shaderfx_copy_exec; + ot->poll = shaderfx_copy_poll; + + /* flags */ + ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_INTERNAL; + edit_shaderfx_properties(ot); +} -- cgit v1.2.3 From 812ea9184221a8ca5785528bebc3ef342a8ecfb4 Mon Sep 17 00:00:00 2001 From: Julian Eisel Date: Fri, 11 Dec 2020 23:49:13 +0100 Subject: UI/Assets: Operator to load custom preview images for data-blocks No automatic preview generation will ever be good enough to cover all cases well. So custom preview images are a must for a preview driven data-block selection - like for asset browsing. The operator simply allows selecting an image file, which will then be read and copied into the data-blocks preview (resized if necessary). There's no UI for this currently and the operator won't be available in the search menu yet. It will later once the Asset Browser UI is merged. Reviewed as part of https://developer.blender.org/D9719. Reviewed by: Bastien Montagne, Brecht Van Lommel --- source/blender/editors/include/ED_util.h | 1 + source/blender/editors/render/render_preview.c | 2 +- source/blender/editors/screen/screen_ops.c | 1 + source/blender/editors/util/ed_util.c | 72 ++++++++++++++++++++++++++ 4 files changed, 75 insertions(+), 1 deletion(-) (limited to 'source/blender/editors') diff --git a/source/blender/editors/include/ED_util.h b/source/blender/editors/include/ED_util.h index 68ae3589064..d74a80045f1 100644 --- a/source/blender/editors/include/ED_util.h +++ b/source/blender/editors/include/ED_util.h @@ -53,6 +53,7 @@ void ED_spacedata_id_remap(struct ScrArea *area, struct ID *new_id); void ED_OT_flush_edits(struct wmOperatorType *ot); +void ED_OT_lib_id_load_custom_preview(struct wmOperatorType *ot); /* ************** XXX OLD CRUFT WARNING ************* */ diff --git a/source/blender/editors/render/render_preview.c b/source/blender/editors/render/render_preview.c index 095deccada0..d67113083a3 100644 --- a/source/blender/editors/render/render_preview.c +++ b/source/blender/editors/render/render_preview.c @@ -1304,7 +1304,7 @@ static void icon_preview_endjob(void *customdata) prv_img->tag &= ~PRV_TAG_DEFFERED_RENDERING; if (prv_img->tag & PRV_TAG_DEFFERED_DELETE) { BLI_assert(prv_img->tag & PRV_TAG_DEFFERED); - BKE_previewimg_cached_release_pointer(prv_img); + BKE_previewimg_deferred_release(prv_img); } } } diff --git a/source/blender/editors/screen/screen_ops.c b/source/blender/editors/screen/screen_ops.c index 649279f8e08..a0c5762c73c 100644 --- a/source/blender/editors/screen/screen_ops.c +++ b/source/blender/editors/screen/screen_ops.c @@ -5510,6 +5510,7 @@ void ED_operatortypes_screen(void) WM_operatortype_append(ED_OT_undo_history); WM_operatortype_append(ED_OT_flush_edits); + WM_operatortype_append(ED_OT_lib_id_load_custom_preview); } /** \} */ diff --git a/source/blender/editors/util/ed_util.c b/source/blender/editors/util/ed_util.c index 76c261c9cba..5e3f443ce9c 100644 --- a/source/blender/editors/util/ed_util.c +++ b/source/blender/editors/util/ed_util.c @@ -35,6 +35,7 @@ #include "DNA_screen_types.h" #include "DNA_space_types.h" +#include "BLI_fileops.h" #include "BLI_listbase.h" #include "BLI_path_util.h" #include "BLI_string.h" @@ -44,6 +45,7 @@ #include "BKE_context.h" #include "BKE_global.h" +#include "BKE_icons.h" #include "BKE_layer.h" #include "BKE_main.h" #include "BKE_material.h" @@ -51,6 +53,7 @@ #include "BKE_object.h" #include "BKE_packedFile.h" #include "BKE_paint.h" +#include "BKE_report.h" #include "BKE_screen.h" #include "BKE_undo_system.h" #include "BKE_workspace.h" @@ -501,3 +504,72 @@ void ED_OT_flush_edits(wmOperatorType *ot) /* flags */ ot->flag = OPTYPE_INTERNAL; } + +static bool lib_id_load_custom_preview_poll(bContext *C) +{ + const PointerRNA idptr = CTX_data_pointer_get(C, "active_id"); + BLI_assert(!idptr.data || RNA_struct_is_ID(idptr.type)); + + const ID *id = idptr.data; + if (!id) { + return false; + } + if (ID_IS_LINKED(id)) { + CTX_wm_operator_poll_msg_set(C, TIP_("Can't edit external library data")); + return false; + } + if (ID_IS_OVERRIDE_LIBRARY(id)) { + CTX_wm_operator_poll_msg_set(C, TIP_("Can't edit previews of overridden library data")); + return false; + } + if (!BKE_previewimg_id_get_p(id)) { + CTX_wm_operator_poll_msg_set(C, TIP_("Data-block does not support previews")); + return false; + } + + return true; +} + +static int lib_id_load_custom_preview_exec(bContext *C, wmOperator *op) +{ + char path[FILE_MAX]; + + RNA_string_get(op->ptr, "filepath", path); + + if (!BLI_is_file(path)) { + BKE_reportf(op->reports, RPT_ERROR, "File not found '%s'", path); + return OPERATOR_CANCELLED; + } + + PointerRNA idptr = CTX_data_pointer_get(C, "active_id"); + ID *id = idptr.data; + + BKE_previewimg_id_custom_set(id, path); + + // WM_event_add_notifier(C, NC_ASSET, NULL); + + return OPERATOR_FINISHED; +} + +void ED_OT_lib_id_load_custom_preview(wmOperatorType *ot) +{ + ot->name = "Load Custom Preview"; + ot->description = "Choose an image to help identify the data-block visually"; + ot->idname = "ED_OT_lib_id_load_custom_preview"; + + /* api callbacks */ + ot->poll = lib_id_load_custom_preview_poll; + ot->exec = lib_id_load_custom_preview_exec; + ot->invoke = WM_operator_filesel; + + /* flags */ + ot->flag = OPTYPE_INTERNAL; + + WM_operator_properties_filesel(ot, + FILE_TYPE_FOLDER | FILE_TYPE_IMAGE, + FILE_SPECIAL, + FILE_OPENFILE, + WM_FILESEL_FILEPATH, + FILE_DEFAULTDISPLAY, + FILE_SORT_DEFAULT); +} -- cgit v1.2.3 From 4b0396695c622d1ac8669600fa820e80b1f0979f Mon Sep 17 00:00:00 2001 From: Julian Eisel Date: Mon, 14 Dec 2020 12:48:16 +0100 Subject: UI/Assets: Support generating object preview images Object previews are really helpful for visual data-block selection, like asset browsing. Having them be generative should also be quite handy and should work well enough in many, if not most cases. What this does is simple: * Place the object (actually a deep copy of it, for thread safety) in a virtual .blend into an empty scene/view-layer. * Add a camera, point it towards the front of the object, assuming that means pointing towards its +Y axis. * Use "Camera Fit Frame to Selected" logic to put the object into frame. * Create a threaded off-screen render. Of course, such an automatic preview will not work in all situations. E.g. it currently does a bad job capturing a single plane. We could add options for more advanced automatic previews, but probably custom previews is more important, which I committed already (812ea9184221). Part of the first Asset Browser milestone. Check the #asset_browser_milestone_1 project milestone on developer.blender.org. Reviewed as part of https://developer.blender.org/D9719. Reviewed by: Bastien Montagne, Brecht Van Lommel --- source/blender/editors/include/ED_view3d.h | 5 + source/blender/editors/render/render_preview.c | 260 +++++++++++++++++---- source/blender/editors/space_view3d/view3d_utils.c | 35 +++ source/blender/editors/space_view3d/view3d_view.c | 28 +-- 4 files changed, 252 insertions(+), 76 deletions(-) (limited to 'source/blender/editors') diff --git a/source/blender/editors/include/ED_view3d.h b/source/blender/editors/include/ED_view3d.h index 596533406c3..13687bf0450 100644 --- a/source/blender/editors/include/ED_view3d.h +++ b/source/blender/editors/include/ED_view3d.h @@ -141,6 +141,11 @@ void ED_view3d_to_object(const struct Depsgraph *depsgraph, const float quat[4], const float dist); +bool ED_view3d_camera_to_view_selected(struct Main *bmain, + struct Depsgraph *depsgraph, + const struct Scene *scene, + struct Object *camera_ob); + void ED_view3d_lastview_store(struct RegionView3D *rv3d); /* Depth buffer */ diff --git a/source/blender/editors/render/render_preview.c b/source/blender/editors/render/render_preview.c index d67113083a3..4466d9f434d 100644 --- a/source/blender/editors/render/render_preview.c +++ b/source/blender/editors/render/render_preview.c @@ -68,6 +68,7 @@ #include "BKE_main.h" #include "BKE_material.h" #include "BKE_node.h" +#include "BKE_object.h" #include "BKE_scene.h" #include "BKE_texture.h" #include "BKE_world.h" @@ -94,12 +95,16 @@ #include "ED_datafiles.h" #include "ED_render.h" #include "ED_screen.h" +#include "ED_view3d.h" +#include "ED_view3d_offscreen.h" #ifndef NDEBUG /* Used for database init assert(). */ # include "BLI_threads.h" #endif +static void icon_copy_rect(ImBuf *ibuf, uint w, uint h, uint *rect); + ImBuf *get_brush_icon(Brush *brush) { static const int flags = IB_rect | IB_multilayer | IB_metadata; @@ -336,7 +341,7 @@ static World *preview_get_localized_world(ShaderPreview *sp, World *world) return sp->worldcopy; } -static ID *duplicate_ids(ID *id) +static ID *duplicate_ids(ID *id, const bool allow_failure) { if (id == NULL) { /* Non-ID preview render. */ @@ -344,6 +349,7 @@ static ID *duplicate_ids(ID *id) } switch (GS(id->name)) { + case ID_OB: case ID_MA: case ID_TE: case ID_LA: @@ -357,7 +363,9 @@ static ID *duplicate_ids(ID *id) case ID_SCR: return NULL; default: - BLI_assert(!"ID type preview not supported."); + if (!allow_failure) { + BLI_assert(!"ID type preview not supported."); + } return NULL; } } @@ -698,6 +706,132 @@ void ED_preview_draw(const bContext *C, void *idp, void *parentp, void *slotp, r } } +/* **************************** Object preview ****************** */ + +struct ObjectPreviewData { + /* The main for the preview, not of the current file. */ + Main *pr_main; + /* Copy of the object to create the preview for. The copy is for thread safety (and to insert it + * into an own main). */ + Object *object; + int sizex; + int sizey; +}; + +static Object *object_preview_camera_create( + Main *preview_main, ViewLayer *view_layer, Object *preview_object, int sizex, int sizey) +{ + Object *camera = BKE_object_add(preview_main, view_layer, OB_CAMERA, "Preview Camera"); + + float rotmat[3][3]; + float dummyscale[3]; + mat4_to_loc_rot_size(camera->loc, rotmat, dummyscale, preview_object->obmat); + + /* Camera is Y up, so needs additional 90deg rotation around X to match object's Z up. */ + float drotmat[3][3]; + axis_angle_to_mat3_single(drotmat, 'X', M_PI_2); + mul_m3_m3_post(rotmat, drotmat); + + camera->rotmode = ROT_MODE_QUAT; + mat3_to_quat(camera->quat, rotmat); + + /* shader_preview_render() does this too. */ + if (sizex > sizey) { + ((Camera *)camera->data)->lens *= (float)sizey / (float)sizex; + } + + return camera; +} + +static Scene *object_preview_scene_create(const struct ObjectPreviewData *preview_data, + Depsgraph **r_depsgraph) +{ + Scene *scene = BKE_scene_add(preview_data->pr_main, "Object preview scene"); + ViewLayer *view_layer = scene->view_layers.first; + Depsgraph *depsgraph = DEG_graph_new( + preview_data->pr_main, scene, view_layer, DAG_EVAL_VIEWPORT); + + BLI_assert(preview_data->object != NULL); + BLI_addtail(&preview_data->pr_main->objects, preview_data->object); + + BKE_collection_object_add(preview_data->pr_main, scene->master_collection, preview_data->object); + + Object *camera_object = object_preview_camera_create(preview_data->pr_main, + view_layer, + preview_data->object, + preview_data->sizex, + preview_data->sizey); + + scene->camera = camera_object; + scene->r.xsch = preview_data->sizex; + scene->r.ysch = preview_data->sizey; + scene->r.size = 100; + + Base *preview_base = BKE_view_layer_base_find(view_layer, preview_data->object); + /* For 'view selected' below. */ + preview_base->flag |= BASE_SELECTED; + + DEG_graph_build_from_view_layer(depsgraph); + DEG_evaluate_on_refresh(depsgraph); + + ED_view3d_camera_to_view_selected(preview_data->pr_main, depsgraph, scene, camera_object); + + BKE_scene_graph_update_tagged(depsgraph, preview_data->pr_main); + + *r_depsgraph = depsgraph; + return scene; +} + +static void object_preview_render(IconPreview *preview, IconPreviewSize *preview_sized) +{ + Main *preview_main = BKE_main_new(); + const float pixelsize_old = U.pixelsize; + char err_out[256] = "unknown"; + + BLI_assert(preview->id_copy && (preview->id_copy != preview->id)); + + struct ObjectPreviewData preview_data = { + .pr_main = preview_main, + /* Act on a copy. */ + .object = (Object *)preview->id_copy, + .sizex = preview_sized->sizex, + .sizey = preview_sized->sizey, + }; + Depsgraph *depsgraph; + Scene *scene = object_preview_scene_create(&preview_data, &depsgraph); + + /* Ownership is now ours. */ + preview->id_copy = NULL; + + U.pixelsize = 2.0f; + + ImBuf *ibuf = ED_view3d_draw_offscreen_imbuf_simple( + depsgraph, + DEG_get_evaluated_scene(depsgraph), + NULL, + OB_SOLID, + DEG_get_evaluated_object(depsgraph, scene->camera), + preview_sized->sizex, + preview_sized->sizey, + IB_rect, + V3D_OFSDRAW_NONE, + R_ALPHAPREMUL, + NULL, + NULL, + err_out); + /* TODO color-management? */ + + U.pixelsize = pixelsize_old; + + if (ibuf) { + icon_copy_rect(ibuf, preview_sized->sizex, preview_sized->sizey, preview_sized->rect); + IMB_freeImBuf(ibuf); + } + + DEG_graph_free(depsgraph); + BKE_main_free(preview_main); +} + /* **************************** new shader preview system ****************** */ /* inside thread, called by renderer, sets job update value */ @@ -1188,27 +1322,54 @@ static void common_preview_startjob(void *customdata, } } -/* exported functions */ - -static void icon_preview_add_size(IconPreview *ip, uint *rect, int sizex, int sizey) +/** + * Some ID types already have their own, more focused rendering (only objects right now). This is + * for the other ones, which all share #ShaderPreview and some functions. + */ +static void other_id_types_preview_render(IconPreview *ip, + IconPreviewSize *cur_size, + const bool is_deferred, + short *stop, + short *do_update, + float *progress) { - IconPreviewSize *cur_size = ip->sizes.first, *new_size; + ShaderPreview *sp = MEM_callocN(sizeof(ShaderPreview), "Icon ShaderPreview"); + const bool is_render = !is_deferred; + + /* These types don't use the ShaderPreview mess, they have their own types and functions. */ + BLI_assert(!ELEM(GS(ip->id->name), ID_OB)); + + /* construct shader preview from image size and previewcustomdata */ + sp->scene = ip->scene; + sp->owner = ip->owner; + sp->sizex = cur_size->sizex; + sp->sizey = cur_size->sizey; + sp->pr_method = is_render ? PR_ICON_RENDER : PR_ICON_DEFERRED; + sp->pr_rect = cur_size->rect; + sp->id = ip->id; + sp->id_copy = ip->id_copy; + sp->bmain = ip->bmain; + sp->own_id_copy = false; + Material *ma = NULL; - while (cur_size) { - if (cur_size->sizex == sizex && cur_size->sizey == sizey) { - /* requested size is already in list, no need to add it again */ - return; + if (is_render) { + BLI_assert(ip->id); + + /* grease pencil use its own preview file */ + if (GS(ip->id->name) == ID_MA) { + ma = (Material *)ip->id; } - cur_size = cur_size->next; + if ((ma == NULL) || (ma->gp_style == NULL)) { + sp->pr_main = G_pr_main; + } + else { + sp->pr_main = G_pr_main_grease_pencil; + } } - new_size = MEM_callocN(sizeof(IconPreviewSize), "IconPreviewSize"); - new_size->sizex = sizex; - new_size->sizey = sizey; - new_size->rect = rect; - - BLI_addtail(&ip->sizes, new_size); + common_preview_startjob(sp, stop, do_update, progress); + shader_preview_free(sp); } static void icon_preview_startjob_all_sizes(void *customdata, @@ -1235,41 +1396,36 @@ static void icon_preview_startjob_all_sizes(void *customdata, continue; } - ShaderPreview *sp = MEM_callocN(sizeof(ShaderPreview), "Icon ShaderPreview"); - const bool is_render = !(prv->tag & PRV_TAG_DEFFERED); - - /* construct shader preview from image size and previewcustomdata */ - sp->scene = ip->scene; - sp->owner = ip->owner; - sp->sizex = cur_size->sizex; - sp->sizey = cur_size->sizey; - sp->pr_method = is_render ? PR_ICON_RENDER : PR_ICON_DEFERRED; - sp->pr_rect = cur_size->rect; - sp->id = ip->id; - sp->id_copy = ip->id_copy; - sp->bmain = ip->bmain; - sp->own_id_copy = false; - Material *ma = NULL; - - if (is_render) { - BLI_assert(ip->id); - - /* grease pencil use its own preview file */ - if (GS(ip->id->name) == ID_MA) { - ma = (Material *)ip->id; - } + if (ELEM(GS(ip->id->name), ID_OB)) { + /* Much simpler than the ShaderPreview mess used for other ID types. */ + object_preview_render(ip, cur_size); + } + else { + other_id_types_preview_render( + ip, cur_size, (prv->tag & PRV_TAG_DEFFERED), stop, do_update, progress); + } + } +} - if ((ma == NULL) || (ma->gp_style == NULL)) { - sp->pr_main = G_pr_main; - } - else { - sp->pr_main = G_pr_main_grease_pencil; - } +static void icon_preview_add_size(IconPreview *ip, uint *rect, int sizex, int sizey) +{ + IconPreviewSize *cur_size = ip->sizes.first, *new_size; + + while (cur_size) { + if (cur_size->sizex == sizex && cur_size->sizey == sizey) { + /* requested size is already in list, no need to add it again */ + return; } - common_preview_startjob(sp, stop, do_update, progress); - shader_preview_free(sp); + cur_size = cur_size->next; } + + new_size = MEM_callocN(sizeof(IconPreviewSize), "IconPreviewSize"); + new_size->sizex = sizex; + new_size->sizey = sizey; + new_size->rect = rect; + + BLI_addtail(&ip->sizes, new_size); } static void icon_preview_endjob(void *customdata) @@ -1333,7 +1489,9 @@ void ED_preview_icon_render(Main *bmain, Scene *scene, ID *id, uint *rect, int s ip.scene = scene; ip.owner = BKE_previewimg_id_ensure(id); ip.id = id; - ip.id_copy = duplicate_ids(id); + /* Control isn't given back to the caller until the preview is done. So we don't need to copy + * the ID to avoid thread races. */ + ip.id_copy = duplicate_ids(id, true); icon_preview_add_size(&ip, rect, sizex, sizey); @@ -1376,7 +1534,7 @@ void ED_preview_icon_job( ip->scene = CTX_data_scene(C); ip->owner = owner; ip->id = id; - ip->id_copy = duplicate_ids(id); + ip->id_copy = duplicate_ids(id, false); icon_preview_add_size(ip, rect, sizex, sizey); @@ -1445,7 +1603,7 @@ void ED_preview_shader_job(const bContext *C, sp->sizey = sizey; sp->pr_method = method; sp->id = id; - sp->id_copy = duplicate_ids(id); + sp->id_copy = duplicate_ids(id, false); sp->own_id_copy = true; sp->parent = parent; sp->slot = slot; diff --git a/source/blender/editors/space_view3d/view3d_utils.c b/source/blender/editors/space_view3d/view3d_utils.c index 1be9bd27c7a..2b7b8255068 100644 --- a/source/blender/editors/space_view3d/view3d_utils.c +++ b/source/blender/editors/space_view3d/view3d_utils.c @@ -1620,6 +1620,41 @@ void ED_view3d_to_object(const Depsgraph *depsgraph, BKE_object_apply_mat4_ex(ob, mat, ob_eval->parent, ob_eval->parentinv, true); } +bool ED_view3d_camera_to_view_selected(struct Main *bmain, + Depsgraph *depsgraph, + const Scene *scene, + Object *camera_ob) +{ + Object *camera_ob_eval = DEG_get_evaluated_object(depsgraph, camera_ob); + float co[3]; /* the new location to apply */ + float scale; /* only for ortho cameras */ + + if (BKE_camera_view_frame_fit_to_scene(depsgraph, scene, camera_ob_eval, co, &scale)) { + ObjectTfmProtectedChannels obtfm; + float obmat_new[4][4]; + + if ((camera_ob_eval->type == OB_CAMERA) && + (((Camera *)camera_ob_eval->data)->type == CAM_ORTHO)) { + ((Camera *)camera_ob->data)->ortho_scale = scale; + } + + copy_m4_m4(obmat_new, camera_ob_eval->obmat); + copy_v3_v3(obmat_new[3], co); + + /* only touch location */ + BKE_object_tfm_protected_backup(camera_ob, &obtfm); + BKE_object_apply_mat4(camera_ob, obmat_new, true, true); + BKE_object_tfm_protected_restore(camera_ob, &obtfm, OB_LOCK_SCALE | OB_LOCK_ROT4D); + + /* notifiers */ + DEG_id_tag_update_ex(bmain, &camera_ob->id, ID_RECALC_TRANSFORM); + + return true; + } + + return false; +} + /** \} */ /* -------------------------------------------------------------------- */ diff --git a/source/blender/editors/space_view3d/view3d_view.c b/source/blender/editors/space_view3d/view3d_view.c index a24f59019f0..9d947384bf0 100644 --- a/source/blender/editors/space_view3d/view3d_view.c +++ b/source/blender/editors/space_view3d/view3d_view.c @@ -535,40 +535,18 @@ void VIEW3D_OT_camera_to_view(wmOperatorType *ot) * meant to take into account vertex/bone selection for eg. */ static int view3d_camera_to_view_selected_exec(bContext *C, wmOperator *op) { + Main *bmain = CTX_data_main(C); Depsgraph *depsgraph = CTX_data_ensure_evaluated_depsgraph(C); Scene *scene = CTX_data_scene(C); View3D *v3d = CTX_wm_view3d(C); /* can be NULL */ Object *camera_ob = v3d ? v3d->camera : scene->camera; - Object *camera_ob_eval = DEG_get_evaluated_object(depsgraph, camera_ob); - - float r_co[3]; /* the new location to apply */ - float r_scale; /* only for ortho cameras */ - if (camera_ob_eval == NULL) { + if (camera_ob == NULL) { BKE_report(op->reports, RPT_ERROR, "No active camera"); return OPERATOR_CANCELLED; } - /* this function does all the important stuff */ - if (BKE_camera_view_frame_fit_to_scene(depsgraph, scene, camera_ob_eval, r_co, &r_scale)) { - ObjectTfmProtectedChannels obtfm; - float obmat_new[4][4]; - - if ((camera_ob_eval->type == OB_CAMERA) && - (((Camera *)camera_ob_eval->data)->type == CAM_ORTHO)) { - ((Camera *)camera_ob->data)->ortho_scale = r_scale; - } - - copy_m4_m4(obmat_new, camera_ob_eval->obmat); - copy_v3_v3(obmat_new[3], r_co); - - /* only touch location */ - BKE_object_tfm_protected_backup(camera_ob, &obtfm); - BKE_object_apply_mat4(camera_ob, obmat_new, true, true); - BKE_object_tfm_protected_restore(camera_ob, &obtfm, OB_LOCK_SCALE | OB_LOCK_ROT4D); - - /* notifiers */ - DEG_id_tag_update(&camera_ob->id, ID_RECALC_TRANSFORM); + if (ED_view3d_camera_to_view_selected(bmain, depsgraph, scene, camera_ob)) { WM_event_add_notifier(C, NC_OBJECT | ND_TRANSFORM, camera_ob); return OPERATOR_FINISHED; } -- cgit v1.2.3 From 20bc1ab27578f1eec4962d0476de8380fed3e35a Mon Sep 17 00:00:00 2001 From: Hans Goudey Date: Mon, 14 Dec 2020 15:12:18 -0600 Subject: Fix incorrect RNA type warning Using the RNA type for regular modifiers instead of grease pencil modifiers caused a warning in context.c. --- source/blender/editors/object/object_gpencil_modifier.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source/blender/editors') diff --git a/source/blender/editors/object/object_gpencil_modifier.c b/source/blender/editors/object/object_gpencil_modifier.c index 9ea67df6daf..e5feb74df26 100644 --- a/source/blender/editors/object/object_gpencil_modifier.c +++ b/source/blender/editors/object/object_gpencil_modifier.c @@ -461,7 +461,7 @@ static bool gpencil_edit_modifier_poll(bContext *C) * (not only from added 'local' ones). */ static bool gpencil_edit_modifier_liboverride_allowed_poll(bContext *C) { - return gpencil_edit_modifier_poll_generic(C, &RNA_Modifier, 0, true); + return gpencil_edit_modifier_poll_generic(C, &RNA_GpencilModifier, 0, true); } static void gpencil_edit_modifier_properties(wmOperatorType *ot) -- cgit v1.2.3 From 04ca93ef9bcb3e2e0054c459f6b36ab43de24532 Mon Sep 17 00:00:00 2001 From: Wayde Moss Date: Mon, 14 Dec 2020 16:55:19 -0500 Subject: NLA: Fix context.selected_nla_strips PointerRNA The strips were given the wrong owner ID. This only caused issues for python based UI as far as I know. Property changes would not properly update the viewport. Reviewed By: lichtwerk Differential Revision: https://developer.blender.org/D9685 --- source/blender/editors/screen/screen_context.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source/blender/editors') diff --git a/source/blender/editors/screen/screen_context.c b/source/blender/editors/screen/screen_context.c index 244ebea5bbe..2061716f01f 100644 --- a/source/blender/editors/screen/screen_context.c +++ b/source/blender/editors/screen/screen_context.c @@ -663,7 +663,7 @@ static eContextResult screen_ctx_selected_nla_strips(const bContext *C, bContext NlaTrack *nlt = (NlaTrack *)ale->data; LISTBASE_FOREACH (NlaStrip *, strip, &nlt->strips) { if (strip->flag & NLASTRIP_FLAG_SELECT) { - CTX_data_list_add(result, &scene->id, &RNA_NlaStrip, strip); + CTX_data_list_add(result, ale->id, &RNA_NlaStrip, strip); } } } -- cgit v1.2.3 From 7470c10601d0fa871cdf1917da3b58af36af3225 Mon Sep 17 00:00:00 2001 From: Hans Goudey Date: Mon, 14 Dec 2020 17:19:43 -0600 Subject: Cleanup: Use LISTBASE_FOREACH macro, reduce variable scope --- source/blender/editors/space_node/node_edit.c | 344 ++++++++++---------------- 1 file changed, 136 insertions(+), 208 deletions(-) (limited to 'source/blender/editors') diff --git a/source/blender/editors/space_node/node_edit.c b/source/blender/editors/space_node/node_edit.c index 039ddad71ef..fdce5e3f30b 100644 --- a/source/blender/editors/space_node/node_edit.c +++ b/source/blender/editors/space_node/node_edit.c @@ -100,9 +100,7 @@ typedef struct CompoJob { static void compo_tag_output_nodes(bNodeTree *nodetree, int recalc_flags) { - bNode *node; - - for (node = nodetree->nodes.first; node; node = node->next) { + LISTBASE_FOREACH (bNode *, node, &nodetree->nodes) { if (node->type == CMP_NODE_COMPOSITE) { if (recalc_flags & COM_RECALC_COMPOSITE) { node->flag |= NODE_DO_OUTPUT_RECALC; @@ -124,14 +122,12 @@ static void compo_tag_output_nodes(bNodeTree *nodetree, int recalc_flags) static int compo_get_recalc_flags(const bContext *C) { wmWindowManager *wm = CTX_wm_manager(C); - wmWindow *win; int recalc_flags = 0; - for (win = wm->windows.first; win; win = win->next) { + LISTBASE_FOREACH (wmWindow *, win, &wm->windows) { const bScreen *screen = WM_window_get_active_screen(win); - ScrArea *area; - for (area = screen->areabase.first; area; area = area->next) { + LISTBASE_FOREACH (ScrArea *, area, &screen->areabase) { if (area->spacetype == SPACE_IMAGE) { SpaceImage *sima = area->spacedata.first; if (sima->image) { @@ -247,7 +243,6 @@ static void compo_startjob(void *cjv, CompoJob *cj = cjv; bNodeTree *ntree = cj->localtree; Scene *scene = cj->scene; - SceneRenderView *srv; if (scene->use_nodes == false) { return; @@ -280,7 +275,7 @@ static void compo_startjob(void *cjv, ""); } else { - for (srv = scene->r.views.first; srv; srv = srv->next) { + LISTBASE_FOREACH (SceneRenderView *, srv, &scene->r.views) { if (BKE_scene_multiview_is_render_view_active(&scene->r, srv) == false) { continue; } @@ -309,8 +304,6 @@ static void compo_startjob(void *cjv, */ void ED_node_composite_job(const bContext *C, struct bNodeTree *nodetree, Scene *scene_owner) { - wmJob *wm_job; - CompoJob *cj; Main *bmain = CTX_data_main(C); Scene *scene = CTX_data_scene(C); ViewLayer *view_layer = CTX_data_view_layer(C); @@ -327,13 +320,13 @@ void ED_node_composite_job(const bContext *C, struct bNodeTree *nodetree, Scene BKE_image_backup_render( scene, BKE_image_ensure_viewer(bmain, IMA_TYPE_R_RESULT, "Render Result"), false); - wm_job = WM_jobs_get(CTX_wm_manager(C), - CTX_wm_window(C), - scene_owner, - "Compositing", - WM_JOB_EXCL_RENDER | WM_JOB_PROGRESS, - WM_JOB_TYPE_COMPOSITE); - cj = MEM_callocN(sizeof(CompoJob), "compo job"); + wmJob *wm_job = WM_jobs_get(CTX_wm_manager(C), + CTX_wm_window(C), + scene_owner, + "Compositing", + WM_JOB_EXCL_RENDER | WM_JOB_PROGRESS, + WM_JOB_TYPE_COMPOSITE); + CompoJob *cj = MEM_callocN(sizeof(CompoJob), "compo job"); /* customdata for preview thread */ cj->bmain = bmain; @@ -524,9 +517,6 @@ void ED_node_shader_default(const bContext *C, ID *id) /* called from shading buttons or header */ void ED_node_composit_default(const bContext *C, struct Scene *sce) { - bNode *in, *out; - bNodeSocket *fromsock, *tosock; - /* but lets check it anyway */ if (sce->nodetree) { if (G.debug & G_DEBUG) { @@ -541,18 +531,18 @@ void ED_node_composit_default(const bContext *C, struct Scene *sce) sce->nodetree->edit_quality = NTREE_QUALITY_HIGH; sce->nodetree->render_quality = NTREE_QUALITY_HIGH; - out = nodeAddStaticNode(C, sce->nodetree, CMP_NODE_COMPOSITE); + bNode *out = nodeAddStaticNode(C, sce->nodetree, CMP_NODE_COMPOSITE); out->locx = 300.0f; out->locy = 400.0f; - in = nodeAddStaticNode(C, sce->nodetree, CMP_NODE_R_LAYERS); + bNode *in = nodeAddStaticNode(C, sce->nodetree, CMP_NODE_R_LAYERS); in->locx = 10.0f; in->locy = 400.0f; nodeSetActive(sce->nodetree, in); /* links from color to color */ - fromsock = in->outputs.first; - tosock = out->inputs.first; + bNodeSocket *fromsock = in->outputs.first; + bNodeSocket *tosock = out->inputs.first; nodeAddLink(sce->nodetree, in, fromsock, out, tosock); ntreeUpdateTree(CTX_data_main(C), sce->nodetree); @@ -562,9 +552,6 @@ void ED_node_composit_default(const bContext *C, struct Scene *sce) /* called from shading buttons or header */ void ED_node_texture_default(const bContext *C, Tex *tex) { - bNode *in, *out; - bNodeSocket *fromsock, *tosock; - /* but lets check it anyway */ if (tex->nodetree) { if (G.debug & G_DEBUG) { @@ -575,17 +562,17 @@ void ED_node_texture_default(const bContext *C, Tex *tex) tex->nodetree = ntreeAddTree(NULL, "Texture Nodetree", ntreeType_Texture->idname); - out = nodeAddStaticNode(C, tex->nodetree, TEX_NODE_OUTPUT); + bNode *out = nodeAddStaticNode(C, tex->nodetree, TEX_NODE_OUTPUT); out->locx = 300.0f; out->locy = 300.0f; - in = nodeAddStaticNode(C, tex->nodetree, TEX_NODE_CHECKER); + bNode *in = nodeAddStaticNode(C, tex->nodetree, TEX_NODE_CHECKER); in->locx = 10.0f; in->locy = 300.0f; nodeSetActive(tex->nodetree, in); - fromsock = in->outputs.first; - tosock = out->inputs.first; + bNodeSocket *fromsock = in->outputs.first; + bNodeSocket *tosock = out->inputs.first; nodeAddLink(tex->nodetree, in, fromsock, out, tosock); ntreeUpdateTree(CTX_data_main(C), tex->nodetree); @@ -634,15 +621,13 @@ void snode_set_context(const bContext *C) void snode_update(SpaceNode *snode, bNode *node) { - bNodeTreePath *path; - /* XXX this only updates nodes in the current node space tree path. * The function supposedly should update any potential group node linking to changed tree, * this really requires a working depsgraph ... */ /* update all edited group nodes */ - path = snode->treepath.last; + bNodeTreePath *path = snode->treepath.last; if (path) { bNodeTree *ngroup = path->nodetree; for (path = path->prev; path; path = path->prev) { @@ -671,10 +656,9 @@ void ED_node_set_active(Main *bmain, bNodeTree *ntree, bNode *node, bool *r_acti /* generic node group output: set node as active output */ if (node->type == NODE_GROUP_OUTPUT) { - bNode *tnode; - for (tnode = ntree->nodes.first; tnode; tnode = tnode->next) { - if (tnode->type == NODE_GROUP_OUTPUT) { - tnode->flag &= ~NODE_DO_OUTPUT; + LISTBASE_FOREACH (bNode *, node_iter, &ntree->nodes) { + if (node_iter->type == NODE_GROUP_OUTPUT) { + node_iter->flag &= ~NODE_DO_OUTPUT; } } @@ -696,11 +680,9 @@ void ED_node_set_active(Main *bmain, bNodeTree *ntree, bNode *node, bool *r_acti SH_NODE_OUTPUT_WORLD, SH_NODE_OUTPUT_LIGHT, SH_NODE_OUTPUT_LINESTYLE)) { - bNode *tnode; - - for (tnode = ntree->nodes.first; tnode; tnode = tnode->next) { - if (tnode->type == node->type) { - tnode->flag &= ~NODE_DO_OUTPUT; + LISTBASE_FOREACH (bNode *, node_iter, &ntree->nodes) { + if (node_iter->type == node->type) { + node_iter->flag &= ~NODE_DO_OUTPUT; } } @@ -715,16 +697,13 @@ void ED_node_set_active(Main *bmain, bNodeTree *ntree, bNode *node, bool *r_acti /* if active texture changed, free glsl materials */ if ((node->flag & NODE_ACTIVE_TEXTURE) && !was_active_texture) { - Material *ma; - World *wo; - - for (ma = bmain->materials.first; ma; ma = ma->id.next) { + LISTBASE_FOREACH (Material *, ma, &bmain->materials) { if (ma->nodetree && ma->use_nodes && ntreeHasTree(ma->nodetree, ntree)) { GPU_material_free(&ma->gpumaterial); } } - for (wo = bmain->worlds.first; wo; wo = wo->id.next) { + LISTBASE_FOREACH (World *, wo, &bmain->materials) { if (wo->nodetree && wo->use_nodes && ntreeHasTree(wo->nodetree, ntree)) { GPU_material_free(&wo->gpumaterial); } @@ -742,11 +721,9 @@ void ED_node_set_active(Main *bmain, bNodeTree *ntree, bNode *node, bool *r_acti else if (ntree->type == NTREE_COMPOSIT) { /* make active viewer, currently only 1 supported... */ if (ELEM(node->type, CMP_NODE_VIEWER, CMP_NODE_SPLITVIEWER)) { - bNode *tnode; - - for (tnode = ntree->nodes.first; tnode; tnode = tnode->next) { - if (ELEM(tnode->type, CMP_NODE_VIEWER, CMP_NODE_SPLITVIEWER)) { - tnode->flag &= ~NODE_DO_OUTPUT; + LISTBASE_FOREACH (bNode *, node_iter, &ntree->nodes) { + if (ELEM(node_iter->type, CMP_NODE_VIEWER, CMP_NODE_SPLITVIEWER)) { + node_iter->flag &= ~NODE_DO_OUTPUT; } } @@ -760,11 +737,9 @@ void ED_node_set_active(Main *bmain, bNodeTree *ntree, bNode *node, bool *r_acti } else if (node->type == CMP_NODE_COMPOSITE) { if (was_output == 0) { - bNode *tnode; - - for (tnode = ntree->nodes.first; tnode; tnode = tnode->next) { - if (tnode->type == CMP_NODE_COMPOSITE) { - tnode->flag &= ~NODE_DO_OUTPUT; + LISTBASE_FOREACH (bNode *, node_iter, &ntree->nodes) { + if (node_iter->type == CMP_NODE_COMPOSITE) { + node_iter->flag &= ~NODE_DO_OUTPUT; } } @@ -879,14 +854,12 @@ static void edit_node_properties_get( /* is rct in visible part of node? */ static bNode *visible_node(SpaceNode *snode, const rctf *rct) { - bNode *node; - - for (node = snode->edittree->nodes.last; node; node = node->prev) { + LISTBASE_FOREACH (bNode *, node, &snode->edittree->nodes) { if (BLI_rctf_isect(&node->totr, rct, NULL)) { - break; + return node; } } - return node; + return NULL; } /* ********************** size widget operator ******************** */ @@ -952,23 +925,19 @@ static int node_resize_modal(bContext *C, wmOperator *op, const wmEvent *event) ARegion *region = CTX_wm_region(C); bNode *node = nodeGetActive(snode->edittree); NodeSizeWidget *nsw = op->customdata; - float mx, my, dx, dy; switch (event->type) { - case MOUSEMOVE: - + case MOUSEMOVE: { + float mx, my; UI_view2d_region_to_view(®ion->v2d, event->mval[0], event->mval[1], &mx, &my); - dx = (mx - nsw->mxstart) / UI_DPI_FAC; - dy = (my - nsw->mystart) / UI_DPI_FAC; + float dx = (mx - nsw->mxstart) / UI_DPI_FAC; + float dy = (my - nsw->mystart) / UI_DPI_FAC; if (node) { - float *pwidth; - float oldwidth, widthmin, widthmax; - - pwidth = &node->width; - oldwidth = nsw->oldwidth; - widthmin = node->typeinfo->minwidth; - widthmax = node->typeinfo->maxwidth; + float *pwidth = &node->width; + float oldwidth = nsw->oldwidth; + float widthmin = node->typeinfo->minwidth; + float widthmax = node->typeinfo->maxwidth; { if (nsw->directions & NODE_RESIZE_RIGHT) { @@ -1026,23 +995,24 @@ static int node_resize_modal(bContext *C, wmOperator *op, const wmEvent *event) ED_region_tag_redraw(region); break; - + } case LEFTMOUSE: case MIDDLEMOUSE: - case RIGHTMOUSE: + case RIGHTMOUSE: { if (event->val == KM_RELEASE) { node_resize_exit(C, op, false); ED_node_post_apply_transform(C, snode->edittree); return OPERATOR_FINISHED; } - else if (event->val == KM_PRESS) { + if (event->val == KM_PRESS) { node_resize_exit(C, op, true); ED_region_tag_redraw(region); return OPERATOR_CANCELLED; } break; + } } return OPERATOR_RUNNING_MODAL; @@ -1095,14 +1065,12 @@ void NODE_OT_resize(wmOperatorType *ot) bool node_has_hidden_sockets(bNode *node) { - bNodeSocket *sock; - - for (sock = node->inputs.first; sock; sock = sock->next) { + LISTBASE_FOREACH (bNodeSocket *, sock, &node->inputs) { if (sock->flag & SOCK_HIDDEN) { return true; } } - for (sock = node->outputs.first; sock; sock = sock->next) { + LISTBASE_FOREACH (bNodeSocket *, sock, &node->outputs) { if (sock->flag & SOCK_HIDDEN) { return true; } @@ -1112,24 +1080,22 @@ bool node_has_hidden_sockets(bNode *node) void node_set_hidden_sockets(SpaceNode *snode, bNode *node, int set) { - bNodeSocket *sock; - if (set == 0) { - for (sock = node->inputs.first; sock; sock = sock->next) { + LISTBASE_FOREACH (bNodeSocket *, sock, &node->inputs) { sock->flag &= ~SOCK_HIDDEN; } - for (sock = node->outputs.first; sock; sock = sock->next) { + LISTBASE_FOREACH (bNodeSocket *, sock, &node->outputs) { sock->flag &= ~SOCK_HIDDEN; } } else { /* hide unused sockets */ - for (sock = node->inputs.first; sock; sock = sock->next) { + LISTBASE_FOREACH (bNodeSocket *, sock, &node->inputs) { if (sock->link == NULL) { sock->flag |= SOCK_HIDDEN; } } - for (sock = node->outputs.first; sock; sock = sock->next) { + LISTBASE_FOREACH (bNodeSocket *, sock, &node->outputs) { if (nodeCountSocketLinks(snode->edittree, sock) == 0) { sock->flag |= SOCK_HIDDEN; } @@ -1142,16 +1108,13 @@ void node_set_hidden_sockets(SpaceNode *snode, bNode *node, int set) int node_find_indicated_socket( SpaceNode *snode, bNode **nodep, bNodeSocket **sockp, float cursor[2], int in_out) { - bNode *node; - bNodeSocket *sock; rctf rect; *nodep = NULL; *sockp = NULL; /* check if we click in a socket */ - for (node = snode->edittree->nodes.first; node; node = node->next) { - + LISTBASE_FOREACH (bNode *, node, &snode->edittree->nodes) { BLI_rctf_init_pt_radius(&rect, cursor, NODE_SOCKSIZE + 4); if (!(node->flag & NODE_HIDDEN)) { @@ -1167,7 +1130,7 @@ int node_find_indicated_socket( } if (in_out & SOCK_IN) { - for (sock = node->inputs.first; sock; sock = sock->next) { + LISTBASE_FOREACH (bNodeSocket *, sock, &node->inputs) { if (!nodeSocketIsHidden(sock)) { if (BLI_rctf_isect_pt(&rect, sock->locx, sock->locy)) { if (node == visible_node(snode, &rect)) { @@ -1180,7 +1143,7 @@ int node_find_indicated_socket( } } if (in_out & SOCK_OUT) { - for (sock = node->outputs.first; sock; sock = sock->next) { + LISTBASE_FOREACH (bNodeSocket *, sock, &node->outputs) { if (!nodeSocketIsHidden(sock)) { if (BLI_rctf_isect_pt(&rect, sock->locx, sock->locy)) { if (node == visible_node(snode, &rect)) { @@ -1226,17 +1189,15 @@ static int node_duplicate_exec(bContext *C, wmOperator *op) Main *bmain = CTX_data_main(C); SpaceNode *snode = CTX_wm_space_node(C); bNodeTree *ntree = snode->edittree; - bNode *node, *newnode, *lastnode; - bNodeLink *link, *newlink, *lastlink; const bool keep_inputs = RNA_boolean_get(op->ptr, "keep_inputs"); bool do_tag_update = false; ED_preview_kill_jobs(CTX_wm_manager(C), bmain); - lastnode = ntree->nodes.last; - for (node = ntree->nodes.first; node; node = node->next) { + bNode *lastnode = ntree->nodes.last; + LISTBASE_FOREACH (bNode *, node, &ntree->nodes) { if (node->flag & SELECT) { - newnode = BKE_node_copy_store_new_pointers(ntree, node, LIB_ID_COPY_DEFAULT); + BKE_node_copy_store_new_pointers(ntree, node, LIB_ID_COPY_DEFAULT); /* to ensure redraws or rerenders happen */ ED_node_tag_update_id(snode->id); @@ -1251,14 +1212,14 @@ static int node_duplicate_exec(bContext *C, wmOperator *op) /* copy links between selected nodes * NB: this depends on correct node->new_node and sock->new_sock pointers from above copy! */ - lastlink = ntree->links.last; - for (link = ntree->links.first; link; link = link->next) { + bNodeLink *lastlink = ntree->links.last; + LISTBASE_FOREACH (bNodeLink *, link, &ntree->links) { /* This creates new links between copied nodes. * If keep_inputs is set, also copies input links from unselected (when fromnode==NULL)! */ if (link->tonode && (link->tonode->flag & NODE_SELECT) && (keep_inputs || (link->fromnode && (link->fromnode->flag & NODE_SELECT)))) { - newlink = MEM_callocN(sizeof(bNodeLink), "bNodeLink"); + bNodeLink *newlink = MEM_callocN(sizeof(bNodeLink), "bNodeLink"); newlink->flag = link->flag; newlink->tonode = link->tonode->new_node; newlink->tosock = link->tosock->new_sock; @@ -1282,11 +1243,11 @@ static int node_duplicate_exec(bContext *C, wmOperator *op) } /* clear flags for recursive depth-first iteration */ - for (node = ntree->nodes.first; node; node = node->next) { + LISTBASE_FOREACH (bNode *, node, &ntree->nodes) { node->flag &= ~NODE_TEST; } /* reparent copied nodes */ - for (node = ntree->nodes.first; node; node = node->next) { + LISTBASE_FOREACH (bNode *, node, &ntree->nodes) { if ((node->flag & SELECT) && !(node->flag & NODE_TEST)) { node_duplicate_reparent_recursive(node); } @@ -1298,10 +1259,10 @@ static int node_duplicate_exec(bContext *C, wmOperator *op) } /* deselect old nodes, select the copies instead */ - for (node = ntree->nodes.first; node; node = node->next) { + LISTBASE_FOREACH (bNode *, node, &ntree->nodes) { if (node->flag & SELECT) { /* has been set during copy above */ - newnode = node->new_node; + bNode *newnode = node->new_node; nodeSetSelected(node, false); node->flag &= ~(NODE_ACTIVE | NODE_ACTIVE_TEXTURE); @@ -1389,17 +1350,16 @@ static int node_read_viewlayers_exec(bContext *C, wmOperator *UNUSED(op)) { Main *bmain = CTX_data_main(C); SpaceNode *snode = CTX_wm_space_node(C); - Scene *curscene = CTX_data_scene(C), *scene; - bNode *node; + Scene *curscene = CTX_data_scene(C); ED_preview_kill_jobs(CTX_wm_manager(C), bmain); /* first tag scenes unread */ - for (scene = bmain->scenes.first; scene; scene = scene->id.next) { + LISTBASE_FOREACH (Scene *, scene, &bmain->scenes) { scene->id.tag |= LIB_TAG_DOIT; } - for (node = snode->edittree->nodes.first; node; node = node->next) { + LISTBASE_FOREACH (bNode *, node, &snode->edittree->nodes) { if (node->type == CMP_NODE_R_LAYERS) { ID *id = node->id; if (id->tag & LIB_TAG_DOIT) { @@ -1434,13 +1394,14 @@ void NODE_OT_read_viewlayers(wmOperatorType *ot) int node_render_changed_exec(bContext *C, wmOperator *UNUSED(op)) { Scene *sce = CTX_data_scene(C); - bNode *node; /* This is actually a test whether scene is used by the compositor or not. * All the nodes are using same render result, so there is no need to do * anything smart about check how exactly scene is used. */ - for (node = sce->nodetree->nodes.first; node; node = node->next) { - if (node->id == (ID *)sce) { + bNode *node = NULL; + LISTBASE_FOREACH (bNode *, node_iter, &sce->nodetree->nodes) { + if (node_iter->id == (ID *)sce) { + node = node_iter; break; } } @@ -1486,14 +1447,14 @@ void NODE_OT_render_changed(wmOperatorType *ot) static void node_flag_toggle_exec(SpaceNode *snode, int toggle_flag) { - bNode *node; int tot_eq = 0, tot_neq = 0; /* Toggles the flag on all selected nodes. * If the flag is set on all nodes it is unset. * If the flag is not set on all nodes, it is set. */ - for (node = snode->edittree->nodes.first; node; node = node->next) { + + LISTBASE_FOREACH (bNode *, node, &snode->edittree->nodes) { if (node->flag & SELECT) { if (toggle_flag == NODE_PREVIEW && (node->typeinfo->flag & NODE_PREVIEW) == 0) { @@ -1512,7 +1473,7 @@ static void node_flag_toggle_exec(SpaceNode *snode, int toggle_flag) } } } - for (node = snode->edittree->nodes.first; node; node = node->next) { + LISTBASE_FOREACH (bNode *, node, &snode->edittree->nodes) { if (node->flag & SELECT) { if (toggle_flag == NODE_PREVIEW && (node->typeinfo->flag & NODE_PREVIEW) == 0) { @@ -1631,8 +1592,6 @@ void NODE_OT_options_toggle(wmOperatorType *ot) static int node_socket_toggle_exec(bContext *C, wmOperator *UNUSED(op)) { SpaceNode *snode = CTX_wm_space_node(C); - bNode *node; - int hidden; /* sanity checking (poll callback checks this already) */ if ((snode == NULL) || (snode->edittree == NULL)) { @@ -1642,17 +1601,17 @@ static int node_socket_toggle_exec(bContext *C, wmOperator *UNUSED(op)) ED_preview_kill_jobs(CTX_wm_manager(C), CTX_data_main(C)); /* Toggle for all selected nodes */ - hidden = 0; - for (node = snode->edittree->nodes.first; node; node = node->next) { + bool hidden = false; + LISTBASE_FOREACH (bNode *, node, &snode->edittree->nodes) { if (node->flag & SELECT) { if (node_has_hidden_sockets(node)) { - hidden = 1; + hidden = true; break; } } } - for (node = snode->edittree->nodes.first; node; node = node->next) { + LISTBASE_FOREACH (bNode *, node, &snode->edittree->nodes) { if (node->flag & SELECT) { node_set_hidden_sockets(snode, node, !hidden); } @@ -1686,12 +1645,11 @@ static int node_mute_exec(bContext *C, wmOperator *UNUSED(op)) { Main *bmain = CTX_data_main(C); SpaceNode *snode = CTX_wm_space_node(C); - bNode *node; bool do_tag_update = false; ED_preview_kill_jobs(CTX_wm_manager(C), bmain); - for (node = snode->edittree->nodes.first; node; node = node->next) { + LISTBASE_FOREACH (bNode *, node, &snode->edittree->nodes) { /* Only allow muting of nodes having a mute func! */ if ((node->flag & SELECT) && node->typeinfo->update_internal_links) { node->flag ^= NODE_MUTED; @@ -1731,13 +1689,11 @@ static int node_delete_exec(bContext *C, wmOperator *UNUSED(op)) { Main *bmain = CTX_data_main(C); SpaceNode *snode = CTX_wm_space_node(C); - bNode *node, *next; bool do_tag_update = false; ED_preview_kill_jobs(CTX_wm_manager(C), bmain); - for (node = snode->edittree->nodes.first; node; node = next) { - next = node->next; + LISTBASE_FOREACH_MUTABLE (bNode *, node, &snode->edittree->nodes) { if (node->flag & SELECT) { do_tag_update |= (do_tag_update || node_connected_to_output(bmain, snode->edittree, node)); nodeRemoveNode(bmain, snode->edittree, node, true); @@ -1787,10 +1743,8 @@ static bool node_switch_view_poll(bContext *C) static int node_switch_view_exec(bContext *C, wmOperator *UNUSED(op)) { SpaceNode *snode = CTX_wm_space_node(C); - bNode *node, *next; - for (node = snode->edittree->nodes.first; node; node = next) { - next = node->next; + LISTBASE_FOREACH_MUTABLE (bNode *, node, &snode->edittree->nodes) { if (node->flag & SELECT) { /* call the update function from the Switch View node */ node->update = NODE_UPDATE_OPERATOR; @@ -1825,12 +1779,10 @@ static int node_delete_reconnect_exec(bContext *C, wmOperator *UNUSED(op)) { Main *bmain = CTX_data_main(C); SpaceNode *snode = CTX_wm_space_node(C); - bNode *node, *next; ED_preview_kill_jobs(CTX_wm_manager(C), CTX_data_main(C)); - for (node = snode->edittree->nodes.first; node; node = next) { - next = node->next; + LISTBASE_FOREACH_MUTABLE (bNode *, node, &snode->edittree->nodes) { if (node->flag & SELECT) { nodeInternalRelink(snode->edittree, node); nodeRemoveNode(bmain, snode->edittree, node, true); @@ -1963,9 +1915,6 @@ static int node_output_file_move_active_socket_exec(bContext *C, wmOperator *op) SpaceNode *snode = CTX_wm_space_node(C); PointerRNA ptr = CTX_data_pointer_get(C, "node"); bNode *node = NULL; - NodeImageMultiFile *nimf; - bNodeSocket *sock; - int direction; if (ptr.data) { node = ptr.data; @@ -1978,14 +1927,14 @@ static int node_output_file_move_active_socket_exec(bContext *C, wmOperator *op) return OPERATOR_CANCELLED; } - nimf = node->storage; + NodeImageMultiFile *nimf = node->storage; - sock = BLI_findlink(&node->inputs, nimf->active_input); + bNodeSocket *sock = BLI_findlink(&node->inputs, nimf->active_input); if (!sock) { return OPERATOR_CANCELLED; } - direction = RNA_enum_get(op->ptr, "direction"); + int direction = RNA_enum_get(op->ptr, "direction"); if (direction == 1) { bNodeSocket *before = sock->prev; @@ -2037,24 +1986,23 @@ static int node_copy_color_exec(bContext *C, wmOperator *UNUSED(op)) { SpaceNode *snode = CTX_wm_space_node(C); bNodeTree *ntree = snode->edittree; - bNode *node, *tnode; if (!ntree) { return OPERATOR_CANCELLED; } - node = nodeGetActive(ntree); + bNode *node = nodeGetActive(ntree); if (!node) { return OPERATOR_CANCELLED; } - for (tnode = ntree->nodes.first; tnode; tnode = tnode->next) { - if (tnode->flag & NODE_SELECT && tnode != node) { + LISTBASE_FOREACH (bNode *, node_iter, &ntree->nodes) { + if (node_iter->flag & NODE_SELECT && node_iter != node) { if (node->flag & NODE_CUSTOM_COLOR) { - tnode->flag |= NODE_CUSTOM_COLOR; - copy_v3_v3(tnode->color, node->color); + node_iter->flag |= NODE_CUSTOM_COLOR; + copy_v3_v3(node_iter->color, node->color); } else { - tnode->flag &= ~NODE_CUSTOM_COLOR; + node_iter->flag &= ~NODE_CUSTOM_COLOR; } } } @@ -2086,8 +2034,6 @@ static int node_clipboard_copy_exec(bContext *C, wmOperator *UNUSED(op)) { SpaceNode *snode = CTX_wm_space_node(C); bNodeTree *ntree = snode->edittree; - bNode *node; - bNodeLink *link, *newlink; ED_preview_kill_jobs(CTX_wm_manager(C), CTX_data_main(C)); @@ -2095,7 +2041,7 @@ static int node_clipboard_copy_exec(bContext *C, wmOperator *UNUSED(op)) BKE_node_clipboard_clear(); BKE_node_clipboard_init(ntree); - for (node = ntree->nodes.first; node; node = node->next) { + LISTBASE_FOREACH (bNode *, node, &ntree->nodes) { if (node->flag & SELECT) { /* No ID refcounting, this node is virtual, * detached from any actual Blender data currently. */ @@ -2105,7 +2051,7 @@ static int node_clipboard_copy_exec(bContext *C, wmOperator *UNUSED(op)) } } - for (node = ntree->nodes.first; node; node = node->next) { + LISTBASE_FOREACH (bNode *, node, &ntree->nodes) { if (node->flag & SELECT) { bNode *new_node = node->new_node; @@ -2126,11 +2072,11 @@ static int node_clipboard_copy_exec(bContext *C, wmOperator *UNUSED(op)) /* copy links between selected nodes * NB: this depends on correct node->new_node and sock->new_sock pointers from above copy! */ - for (link = ntree->links.first; link; link = link->next) { + LISTBASE_FOREACH (bNodeLink *, link, &ntree->links) { /* This creates new links between copied nodes. */ if (link->tonode && (link->tonode->flag & NODE_SELECT) && link->fromnode && (link->fromnode->flag & NODE_SELECT)) { - newlink = MEM_callocN(sizeof(bNodeLink), "bNodeLink"); + bNodeLink *newlink = MEM_callocN(sizeof(bNodeLink), "bNodeLink"); newlink->flag = link->flag; newlink->tonode = link->tonode->new_node; newlink->tosock = link->tosock->new_sock; @@ -2165,18 +2111,11 @@ static int node_clipboard_paste_exec(bContext *C, wmOperator *op) { SpaceNode *snode = CTX_wm_space_node(C); bNodeTree *ntree = snode->edittree; - const ListBase *clipboard_nodes_lb; - const ListBase *clipboard_links_lb; - bNode *node; - bNodeLink *link; - int num_nodes; - float center[2]; - bool is_clipboard_valid, all_nodes_valid; /* validate pointers in the clipboard */ - is_clipboard_valid = BKE_node_clipboard_validate(); - clipboard_nodes_lb = BKE_node_clipboard_get_nodes(); - clipboard_links_lb = BKE_node_clipboard_get_links(); + bool is_clipboard_valid = BKE_node_clipboard_validate(); + const ListBase *clipboard_nodes_lb = BKE_node_clipboard_get_nodes(); + const ListBase *clipboard_links_lb = BKE_node_clipboard_get_links(); if (BLI_listbase_is_empty(clipboard_nodes_lb)) { BKE_report(op->reports, RPT_ERROR, "Clipboard is empty"); @@ -2196,8 +2135,8 @@ static int node_clipboard_paste_exec(bContext *C, wmOperator *op) } /* make sure all clipboard nodes would be valid in the target tree */ - all_nodes_valid = true; - for (node = clipboard_nodes_lb->first; node; node = node->next) { + bool all_nodes_valid = true; + LISTBASE_FOREACH (bNode *, node, clipboard_nodes_lb) { if (!node->typeinfo->poll_instance || !node->typeinfo->poll_instance(node, ntree)) { all_nodes_valid = false; BKE_reportf(op->reports, @@ -2217,15 +2156,16 @@ static int node_clipboard_paste_exec(bContext *C, wmOperator *op) node_deselect_all(snode); /* calculate "barycenter" for placing on mouse cursor */ - zero_v2(center); - for (node = clipboard_nodes_lb->first, num_nodes = 0; node; node = node->next, num_nodes++) { + float center[2] = {0.0f, 0.0f}; + int num_nodes = 0; + LISTBASE_FOREACH_INDEX (bNode *, node, clipboard_nodes_lb, num_nodes) { center[0] += BLI_rctf_cent_x(&node->totr); center[1] += BLI_rctf_cent_y(&node->totr); } mul_v2_fl(center, 1.0 / num_nodes); /* copy nodes from clipboard */ - for (node = clipboard_nodes_lb->first; node; node = node->next) { + LISTBASE_FOREACH (bNode *, node, clipboard_nodes_lb) { bNode *new_node = BKE_node_copy_store_new_pointers(ntree, node, LIB_ID_COPY_DEFAULT); /* pasted nodes are selected */ @@ -2233,14 +2173,14 @@ static int node_clipboard_paste_exec(bContext *C, wmOperator *op) } /* reparent copied nodes */ - for (node = clipboard_nodes_lb->first; node; node = node->next) { + LISTBASE_FOREACH (bNode *, node, clipboard_nodes_lb) { bNode *new_node = node->new_node; if (new_node->parent) { new_node->parent = new_node->parent->new_node; } } - for (link = clipboard_links_lb->first; link; link = link->next) { + LISTBASE_FOREACH (bNodeLink *, link, clipboard_links_lb) { nodeAddLink(ntree, link->fromnode->new_node, link->fromsock->new_sock, @@ -2275,10 +2215,9 @@ void NODE_OT_clipboard_paste(wmOperatorType *ot) static bNodeSocket *ntree_get_active_interface_socket(ListBase *lb) { - bNodeSocket *sock; - for (sock = lb->first; sock; sock = sock->next) { - if (sock->flag & SELECT) { - return sock; + LISTBASE_FOREACH (bNodeSocket *, socket, lb) { + if (socket->flag & SELECT) { + return socket; } } return NULL; @@ -2289,12 +2228,12 @@ static int ntree_socket_add_exec(bContext *C, wmOperator *op) SpaceNode *snode = CTX_wm_space_node(C); bNodeTree *ntree = snode->edittree; int in_out = RNA_enum_get(op->ptr, "in_out"); - PointerRNA ntree_ptr; - bNodeSocket *sock, *tsock, *active_sock; - const char *default_name; + PointerRNA ntree_ptr; RNA_id_pointer_create((ID *)ntree, &ntree_ptr); + const char *default_name; + bNodeSocket *active_sock; if (in_out == SOCK_IN) { active_sock = ntree_get_active_interface_socket(&ntree->inputs); default_name = "Input"; @@ -2304,6 +2243,7 @@ static int ntree_socket_add_exec(bContext *C, wmOperator *op) default_name = "Output"; } + bNodeSocket *sock; if (active_sock) { /* insert a copy of the active socket right after it */ sock = ntreeInsertSocketInterface( @@ -2317,11 +2257,11 @@ static int ntree_socket_add_exec(bContext *C, wmOperator *op) } /* deactivate sockets (has to check both lists) */ - for (tsock = ntree->inputs.first; tsock; tsock = tsock->next) { - tsock->flag &= ~SELECT; + LISTBASE_FOREACH (bNodeSocket *, socket_iter, &ntree->inputs) { + socket_iter->flag &= ~SELECT; } - for (tsock = ntree->outputs.first; tsock; tsock = tsock->next) { - tsock->flag &= ~SELECT; + LISTBASE_FOREACH (bNodeSocket *, socket_iter, &ntree->outputs) { + socket_iter->flag &= ~SELECT; } /* make the new socket active */ sock->flag |= SELECT; @@ -2359,9 +2299,8 @@ static int ntree_socket_remove_exec(bContext *C, wmOperator *UNUSED(op)) { SpaceNode *snode = CTX_wm_space_node(C); bNodeTree *ntree = snode->edittree; - bNodeSocket *iosock, *active_sock; - iosock = ntree_get_active_interface_socket(&ntree->inputs); + bNodeSocket *iosock = ntree_get_active_interface_socket(&ntree->inputs); if (!iosock) { iosock = ntree_get_active_interface_socket(&ntree->outputs); } @@ -2370,7 +2309,7 @@ static int ntree_socket_remove_exec(bContext *C, wmOperator *UNUSED(op)) } /* preferably next socket becomes active, otherwise try previous socket */ - active_sock = (iosock->next ? iosock->next : iosock->prev); + bNodeSocket *active_sock = (iosock->next ? iosock->next : iosock->prev); ntreeRemoveSocketInterface(ntree, iosock); /* set active socket */ @@ -2416,11 +2355,9 @@ static int ntree_socket_move_exec(bContext *C, wmOperator *op) SpaceNode *snode = CTX_wm_space_node(C); bNodeTree *ntree = snode->edittree; int direction = RNA_enum_get(op->ptr, "direction"); - bNodeSocket *iosock; - ListBase *lb; - lb = &ntree->inputs; - iosock = ntree_get_active_interface_socket(lb); + ListBase *lb = &ntree->inputs; + bNodeSocket *iosock = ntree_get_active_interface_socket(lb); if (!iosock) { lb = &ntree->outputs; iosock = ntree_get_active_interface_socket(lb); @@ -2489,8 +2426,6 @@ static bool node_shader_script_update_poll(bContext *C) Scene *scene = CTX_data_scene(C); const RenderEngineType *type = RE_engines_find(scene->r.engine); SpaceNode *snode = CTX_wm_space_node(C); - bNode *node; - Text *text; /* test if we have a render engine that supports shaders scripts */ if (!(type && type->update_script_node)) { @@ -2498,7 +2433,7 @@ static bool node_shader_script_update_poll(bContext *C) } /* see if we have a shader script node in context */ - node = CTX_data_pointer_get_type(C, "node", &RNA_ShaderNodeScript).data; + bNode *node = CTX_data_pointer_get_type(C, "node", &RNA_ShaderNodeScript).data; if (!node && snode && snode->edittree) { node = nodeGetActive(snode->edittree); @@ -2513,7 +2448,7 @@ static bool node_shader_script_update_poll(bContext *C) } /* see if we have a text datablock in context */ - text = CTX_data_pointer_get_type(C, "edit_text", &RNA_Text).data; + Text *text = CTX_data_pointer_get_type(C, "edit_text", &RNA_Text).data; if (text) { return 1; } @@ -2530,12 +2465,11 @@ static bool node_shader_script_update_text_recursive(RenderEngine *engine, Text *text) { bool found = false; - bNode *node; ntree->done = true; /* update each script that is using this text datablock */ - for (node = ntree->nodes.first; node; node = node->next) { + LISTBASE_FOREACH (bNode *, node, &ntree->nodes) { if (node->type == NODE_GROUP) { bNodeTree *ngroup = (bNodeTree *)node->id; if (ngroup && !ngroup->done) { @@ -2557,18 +2491,16 @@ static int node_shader_script_update_exec(bContext *C, wmOperator *op) Scene *scene = CTX_data_scene(C); SpaceNode *snode = CTX_wm_space_node(C); PointerRNA nodeptr = CTX_data_pointer_get_type(C, "node", &RNA_ShaderNodeScript); - bNodeTree *ntree_base = NULL; - bNode *node = NULL; - RenderEngine *engine; - RenderEngineType *type; bool found = false; /* setup render engine */ - type = RE_engines_find(scene->r.engine); - engine = RE_engine_create(type); + RenderEngineType *type = RE_engines_find(scene->r.engine); + RenderEngine *engine = RE_engine_create(type); engine->reports = op->reports; /* get node */ + bNodeTree *ntree_base = NULL; + bNode *node = NULL; if (nodeptr.data) { ntree_base = (bNodeTree *)nodeptr.owner_id; node = nodeptr.data; @@ -2643,10 +2575,8 @@ static void viewer_border_corner_to_backdrop(SpaceNode *snode, float *fx, float *fy) { - float bufx, bufy; - - bufx = backdrop_width * snode->zoom; - bufy = backdrop_height * snode->zoom; + float bufx = backdrop_width * snode->zoom; + float bufy = backdrop_height * snode->zoom; *fx = (bufx > 0.0f ? ((float)x - 0.5f * region->winx - snode->xof) / bufx + 0.5f : 0.0f); *fy = (bufy > 0.0f ? ((float)y - 0.5f * region->winy - snode->yof) / bufy + 0.5f : 0.0f); @@ -2655,14 +2585,12 @@ static void viewer_border_corner_to_backdrop(SpaceNode *snode, static int viewer_border_exec(bContext *C, wmOperator *op) { Main *bmain = CTX_data_main(C); - Image *ima; void *lock; - ImBuf *ibuf; ED_preview_kill_jobs(CTX_wm_manager(C), bmain); - ima = BKE_image_ensure_viewer(bmain, IMA_TYPE_COMPOSITE, "Viewer Node"); - ibuf = BKE_image_acquire_ibuf(ima, NULL, &lock); + Image *ima = BKE_image_ensure_viewer(bmain, IMA_TYPE_COMPOSITE, "Viewer Node"); + ImBuf *ibuf = BKE_image_acquire_ibuf(ima, NULL, &lock); if (ibuf) { ARegion *region = CTX_wm_region(C); -- cgit v1.2.3 From 15f2f69694cb23d04989d3faea4853468a3b140a Mon Sep 17 00:00:00 2001 From: Hans Goudey Date: Mon, 14 Dec 2020 17:48:57 -0600 Subject: Cleanup: Reduce variable scope --- source/blender/editors/space_node/node_draw.c | 61 +++++++++++++-------------- 1 file changed, 29 insertions(+), 32 deletions(-) (limited to 'source/blender/editors') diff --git a/source/blender/editors/space_node/node_draw.c b/source/blender/editors/space_node/node_draw.c index fc7fa3a6caa..5a2eb0cc3a0 100644 --- a/source/blender/editors/space_node/node_draw.c +++ b/source/blender/editors/space_node/node_draw.c @@ -344,8 +344,6 @@ void node_from_view(struct bNode *node, float x, float y, float *rx, float *ry) /* based on settings in node, sets drawing rect info. each redraw! */ static void node_update_basis(const bContext *C, bNodeTree *ntree, bNode *node) { - uiLayout *layout, *row; - PointerRNA nodeptr; RNA_pointer_create(&ntree->id, &RNA_Node, node, &nodeptr); @@ -374,15 +372,15 @@ static void node_update_basis(const bContext *C, bNodeTree *ntree, bNode *node) PointerRNA sockptr; RNA_pointer_create(&ntree->id, &RNA_NodeSocket, nsock, &sockptr); - layout = UI_block_layout(node->block, - UI_LAYOUT_VERTICAL, - UI_LAYOUT_PANEL, - locx + NODE_DYS, - dy, - NODE_WIDTH(node) - NODE_DY, - NODE_DY, - 0, - UI_style_get_dpi()); + uiLayout *layout = UI_block_layout(node->block, + UI_LAYOUT_VERTICAL, + UI_LAYOUT_PANEL, + locx + NODE_DYS, + dy, + NODE_WIDTH(node) - NODE_DY, + NODE_DY, + 0, + UI_style_get_dpi()); if (node->flag & NODE_MUTED) { uiLayoutSetActive(layout, false); @@ -393,7 +391,7 @@ static void node_update_basis(const bContext *C, bNodeTree *ntree, bNode *node) uiLayoutSetContextPointer(layout, "socket", &sockptr); /* align output buttons to the right */ - row = uiLayoutRow(layout, 1); + uiLayout *row = uiLayoutRow(layout, true); uiLayoutSetAlignment(row, UI_LAYOUT_ALIGN_RIGHT); const char *socket_label = nodeSocketLabel(nsock); nsock->typeinfo->draw((bContext *)C, row, &sockptr, &nodeptr, IFACE_(socket_label)); @@ -469,15 +467,15 @@ static void node_update_basis(const bContext *C, bNodeTree *ntree, bNode *node) node->butr.ymin = 0; node->butr.ymax = 0; - layout = UI_block_layout(node->block, - UI_LAYOUT_VERTICAL, - UI_LAYOUT_PANEL, - locx + NODE_DYS, - dy, - node->butr.xmax, - 0, - 0, - UI_style_get_dpi()); + uiLayout *layout = UI_block_layout(node->block, + UI_LAYOUT_VERTICAL, + UI_LAYOUT_PANEL, + locx + NODE_DYS, + dy, + node->butr.xmax, + 0, + 0, + UI_style_get_dpi()); if (node->flag & NODE_MUTED) { uiLayoutSetActive(layout, false); @@ -502,15 +500,15 @@ static void node_update_basis(const bContext *C, bNodeTree *ntree, bNode *node) PointerRNA sockptr; RNA_pointer_create(&ntree->id, &RNA_NodeSocket, nsock, &sockptr); - layout = UI_block_layout(node->block, - UI_LAYOUT_VERTICAL, - UI_LAYOUT_PANEL, - locx + NODE_DYS, - dy, - NODE_WIDTH(node) - NODE_DY, - NODE_DY, - 0, - UI_style_get_dpi()); + uiLayout *layout = UI_block_layout(node->block, + UI_LAYOUT_VERTICAL, + UI_LAYOUT_PANEL, + locx + NODE_DYS, + dy, + NODE_WIDTH(node) - NODE_DY, + NODE_DY, + 0, + UI_style_get_dpi()); if (node->flag & NODE_MUTED) { uiLayoutSetActive(layout, false); @@ -520,7 +518,7 @@ static void node_update_basis(const bContext *C, bNodeTree *ntree, bNode *node) uiLayoutSetContextPointer(layout, "node", &nodeptr); uiLayoutSetContextPointer(layout, "socket", &sockptr); - row = uiLayoutRow(layout, 1); + uiLayout *row = uiLayoutRow(layout, true); const char *socket_label = nodeSocketLabel(nsock); nsock->typeinfo->draw((bContext *)C, row, &sockptr, &nodeptr, IFACE_(socket_label)); @@ -771,7 +769,6 @@ void node_socket_color_get( bContext *C, bNodeTree *ntree, PointerRNA *node_ptr, bNodeSocket *sock, float r_color[4]) { PointerRNA ptr; - BLI_assert(RNA_struct_is_a(node_ptr->type, &RNA_Node)); RNA_pointer_create((ID *)ntree, &RNA_NodeSocket, sock, &ptr); -- cgit v1.2.3 From 525364be31aafa547f4b17b9947074ed5a5b2570 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Tue, 15 Dec 2020 10:47:58 +1100 Subject: Cleanup: reduce indirect DNA header inclusion Remove DNA headers, using forward declarations where possible. Also removed duplicate header, header including it's self and unnecessary inclusion of libc system headers from BKE header. --- source/blender/editors/armature/editarmature_undo.c | 2 ++ source/blender/editors/gpencil/drawgpencil.c | 1 + source/blender/editors/gpencil/gpencil_add_monkey.c | 1 + source/blender/editors/gpencil/gpencil_add_stroke.c | 1 + source/blender/editors/gpencil/gpencil_convert.c | 1 + source/blender/editors/gpencil/gpencil_data.c | 1 + source/blender/editors/gpencil/gpencil_edit.c | 1 + source/blender/editors/gpencil/gpencil_fill.c | 1 + source/blender/editors/gpencil/gpencil_merge.c | 1 + source/blender/editors/gpencil/gpencil_ops_versioning.c | 1 + source/blender/editors/gpencil/gpencil_sculpt_paint.c | 1 + source/blender/editors/gpencil/gpencil_select.c | 1 + source/blender/editors/gpencil/gpencil_utils.c | 2 ++ source/blender/editors/gpencil/gpencil_vertex_ops.c | 1 + source/blender/editors/gpencil/gpencil_vertex_paint.c | 1 + source/blender/editors/include/ED_info.h | 8 ++++++-- source/blender/editors/include/ED_uvedit.h | 8 +++++--- .../editors/interface/interface_eyedropper_gpencil_color.c | 1 + source/blender/editors/mesh/editmesh_select_similar.c | 1 + source/blender/editors/mesh/editmesh_undo.c | 1 + source/blender/editors/metaball/editmball_undo.c | 2 ++ source/blender/editors/object/object_bake.c | 1 + source/blender/editors/physics/rigidbody_constraint.c | 1 + source/blender/editors/physics/rigidbody_object.c | 1 + source/blender/editors/sculpt_paint/paint_image.c | 1 + .../blender/editors/space_outliner/tree/tree_display_libraries.cc | 2 ++ .../editors/space_outliner/tree/tree_display_view_layer.cc | 1 + source/blender/editors/undo/memfile_undo.c | 1 + 28 files changed, 41 insertions(+), 5 deletions(-) (limited to 'source/blender/editors') diff --git a/source/blender/editors/armature/editarmature_undo.c b/source/blender/editors/armature/editarmature_undo.c index c217b615db6..7c11c5e537e 100644 --- a/source/blender/editors/armature/editarmature_undo.c +++ b/source/blender/editors/armature/editarmature_undo.c @@ -26,7 +26,9 @@ #include "CLG_log.h" #include "DNA_armature_types.h" +#include "DNA_layer_types.h" #include "DNA_object_types.h" +#include "DNA_scene_types.h" #include "BLI_array_utils.h" #include "BLI_listbase.h" diff --git a/source/blender/editors/gpencil/drawgpencil.c b/source/blender/editors/gpencil/drawgpencil.c index 93767127cc7..4e2951c3571 100644 --- a/source/blender/editors/gpencil/drawgpencil.c +++ b/source/blender/editors/gpencil/drawgpencil.c @@ -41,6 +41,7 @@ #include "DNA_brush_types.h" #include "DNA_gpencil_types.h" +#include "DNA_material_types.h" #include "DNA_object_types.h" #include "DNA_scene_types.h" #include "DNA_screen_types.h" diff --git a/source/blender/editors/gpencil/gpencil_add_monkey.c b/source/blender/editors/gpencil/gpencil_add_monkey.c index 315b3c281da..65141442237 100644 --- a/source/blender/editors/gpencil/gpencil_add_monkey.c +++ b/source/blender/editors/gpencil/gpencil_add_monkey.c @@ -25,6 +25,7 @@ #include "BLI_utildefines.h" #include "DNA_gpencil_types.h" +#include "DNA_material_types.h" #include "DNA_object_types.h" #include "DNA_scene_types.h" diff --git a/source/blender/editors/gpencil/gpencil_add_stroke.c b/source/blender/editors/gpencil/gpencil_add_stroke.c index f26fd936d40..0c8cc621a3b 100644 --- a/source/blender/editors/gpencil/gpencil_add_stroke.c +++ b/source/blender/editors/gpencil/gpencil_add_stroke.c @@ -25,6 +25,7 @@ #include "BLI_utildefines.h" #include "DNA_gpencil_types.h" +#include "DNA_material_types.h" #include "DNA_object_types.h" #include "DNA_scene_types.h" diff --git a/source/blender/editors/gpencil/gpencil_convert.c b/source/blender/editors/gpencil/gpencil_convert.c index 63aa242275a..09b57029350 100644 --- a/source/blender/editors/gpencil/gpencil_convert.c +++ b/source/blender/editors/gpencil/gpencil_convert.c @@ -41,6 +41,7 @@ #include "DNA_collection_types.h" #include "DNA_curve_types.h" #include "DNA_gpencil_types.h" +#include "DNA_material_types.h" #include "DNA_node_types.h" #include "DNA_object_types.h" #include "DNA_scene_types.h" diff --git a/source/blender/editors/gpencil/gpencil_data.c b/source/blender/editors/gpencil/gpencil_data.c index 203e86e9e15..093f1fa89c7 100644 --- a/source/blender/editors/gpencil/gpencil_data.c +++ b/source/blender/editors/gpencil/gpencil_data.c @@ -42,6 +42,7 @@ #include "DNA_anim_types.h" #include "DNA_brush_types.h" #include "DNA_gpencil_types.h" +#include "DNA_material_types.h" #include "DNA_meshdata_types.h" #include "DNA_modifier_types.h" #include "DNA_object_types.h" diff --git a/source/blender/editors/gpencil/gpencil_edit.c b/source/blender/editors/gpencil/gpencil_edit.c index 95c94f8cfed..36e383cf3c2 100644 --- a/source/blender/editors/gpencil/gpencil_edit.c +++ b/source/blender/editors/gpencil/gpencil_edit.c @@ -41,6 +41,7 @@ #include "DNA_gpencil_modifier_types.h" #include "DNA_gpencil_types.h" +#include "DNA_material_types.h" #include "DNA_meshdata_types.h" #include "DNA_object_types.h" #include "DNA_scene_types.h" diff --git a/source/blender/editors/gpencil/gpencil_fill.c b/source/blender/editors/gpencil/gpencil_fill.c index 93941ea3766..39968aac9fa 100644 --- a/source/blender/editors/gpencil/gpencil_fill.c +++ b/source/blender/editors/gpencil/gpencil_fill.c @@ -35,6 +35,7 @@ #include "DNA_brush_types.h" #include "DNA_gpencil_types.h" #include "DNA_image_types.h" +#include "DNA_material_types.h" #include "DNA_meshdata_types.h" #include "DNA_object_types.h" #include "DNA_windowmanager_types.h" diff --git a/source/blender/editors/gpencil/gpencil_merge.c b/source/blender/editors/gpencil/gpencil_merge.c index 9f2bf3818a4..272dff56291 100644 --- a/source/blender/editors/gpencil/gpencil_merge.c +++ b/source/blender/editors/gpencil/gpencil_merge.c @@ -31,6 +31,7 @@ #include "BLI_math.h" #include "DNA_gpencil_types.h" +#include "DNA_material_types.h" #include "BKE_brush.h" #include "BKE_context.h" diff --git a/source/blender/editors/gpencil/gpencil_ops_versioning.c b/source/blender/editors/gpencil/gpencil_ops_versioning.c index 4721736489e..815bbbaa254 100644 --- a/source/blender/editors/gpencil/gpencil_ops_versioning.c +++ b/source/blender/editors/gpencil/gpencil_ops_versioning.c @@ -33,6 +33,7 @@ #include "BLI_math.h" #include "DNA_gpencil_types.h" +#include "DNA_material_types.h" #include "DNA_meshdata_types.h" #include "DNA_object_types.h" #include "DNA_scene_types.h" diff --git a/source/blender/editors/gpencil/gpencil_sculpt_paint.c b/source/blender/editors/gpencil/gpencil_sculpt_paint.c index ed18c2eed5d..bb9dd8cac5d 100644 --- a/source/blender/editors/gpencil/gpencil_sculpt_paint.c +++ b/source/blender/editors/gpencil/gpencil_sculpt_paint.c @@ -41,6 +41,7 @@ #include "BLT_translation.h" #include "DNA_gpencil_types.h" +#include "DNA_material_types.h" #include "DNA_meshdata_types.h" #include "DNA_object_types.h" #include "DNA_scene_types.h" diff --git a/source/blender/editors/gpencil/gpencil_select.c b/source/blender/editors/gpencil/gpencil_select.c index 2c0b9534141..281ab8c5adc 100644 --- a/source/blender/editors/gpencil/gpencil_select.c +++ b/source/blender/editors/gpencil/gpencil_select.c @@ -36,6 +36,7 @@ #include "BLI_utildefines.h" #include "DNA_gpencil_types.h" +#include "DNA_material_types.h" #include "DNA_object_types.h" #include "DNA_scene_types.h" #include "DNA_screen_types.h" diff --git a/source/blender/editors/gpencil/gpencil_utils.c b/source/blender/editors/gpencil/gpencil_utils.c index e8e25a55796..c3ac33063af 100644 --- a/source/blender/editors/gpencil/gpencil_utils.c +++ b/source/blender/editors/gpencil/gpencil_utils.c @@ -40,7 +40,9 @@ #include "PIL_time.h" #include "DNA_brush_types.h" +#include "DNA_collection_types.h" #include "DNA_gpencil_types.h" +#include "DNA_material_types.h" #include "DNA_meshdata_types.h" #include "DNA_object_types.h" #include "DNA_scene_types.h" diff --git a/source/blender/editors/gpencil/gpencil_vertex_ops.c b/source/blender/editors/gpencil/gpencil_vertex_ops.c index c3fd8d10b64..90b2c1c3895 100644 --- a/source/blender/editors/gpencil/gpencil_vertex_ops.c +++ b/source/blender/editors/gpencil/gpencil_vertex_ops.c @@ -32,6 +32,7 @@ #include "DNA_brush_types.h" #include "DNA_gpencil_types.h" +#include "DNA_material_types.h" #include "BKE_colortools.h" #include "BKE_context.h" diff --git a/source/blender/editors/gpencil/gpencil_vertex_paint.c b/source/blender/editors/gpencil/gpencil_vertex_paint.c index a4dc677f0dc..3afff897734 100644 --- a/source/blender/editors/gpencil/gpencil_vertex_paint.c +++ b/source/blender/editors/gpencil/gpencil_vertex_paint.c @@ -31,6 +31,7 @@ #include "DNA_brush_types.h" #include "DNA_gpencil_types.h" +#include "DNA_material_types.h" #include "BKE_brush.h" #include "BKE_colortools.h" diff --git a/source/blender/editors/include/ED_info.h b/source/blender/editors/include/ED_info.h index e3ce494e09a..9ac6b6c1085 100644 --- a/source/blender/editors/include/ED_info.h +++ b/source/blender/editors/include/ED_info.h @@ -38,8 +38,12 @@ const char *ED_info_statistics_string(struct Main *bmain, struct Scene *scene, struct ViewLayer *view_layer); -void ED_info_draw_stats( - struct Main *bmain, Scene *scene, ViewLayer *view_layer, int x, int *y, int height); +void ED_info_draw_stats(struct Main *bmain, + struct Scene *scene, + struct ViewLayer *view_layer, + int x, + int *y, + int height); #ifdef __cplusplus } diff --git a/source/blender/editors/include/ED_uvedit.h b/source/blender/editors/include/ED_uvedit.h index 2066d7da511..d08bc0b0b3d 100644 --- a/source/blender/editors/include/ED_uvedit.h +++ b/source/blender/editors/include/ED_uvedit.h @@ -217,8 +217,10 @@ struct BMLoop *ED_uvedit_active_vert_loop_get(struct BMesh *bm); void ED_uvedit_active_edge_loop_set(struct BMesh *bm, struct BMLoop *l); struct BMLoop *ED_uvedit_active_edge_loop_get(struct BMesh *bm); -char ED_uvedit_select_mode_get(const Scene *scene); -void ED_uvedit_select_sync_flush(const ToolSettings *ts, struct BMEditMesh *em, const bool select); +char ED_uvedit_select_mode_get(const struct Scene *scene); +void ED_uvedit_select_sync_flush(const struct ToolSettings *ts, + struct BMEditMesh *em, + const bool select); /* uvedit_unwrap_ops.c */ void ED_uvedit_live_unwrap_begin(struct Scene *scene, struct Object *obedit); @@ -244,7 +246,7 @@ struct UVPackIsland_Params { uint use_seams : 1; uint correct_aspect : 1; }; -void ED_uvedit_pack_islands_multi(const Scene *scene, +void ED_uvedit_pack_islands_multi(const struct Scene *scene, Object **objects, const uint objects_len, const struct UVPackIsland_Params *params); diff --git a/source/blender/editors/interface/interface_eyedropper_gpencil_color.c b/source/blender/editors/interface/interface_eyedropper_gpencil_color.c index 7f735a0e789..f2899fc0098 100644 --- a/source/blender/editors/interface/interface_eyedropper_gpencil_color.c +++ b/source/blender/editors/interface/interface_eyedropper_gpencil_color.c @@ -34,6 +34,7 @@ #include "BLT_translation.h" #include "DNA_gpencil_types.h" +#include "DNA_material_types.h" #include "DNA_space_types.h" #include "BKE_context.h" diff --git a/source/blender/editors/mesh/editmesh_select_similar.c b/source/blender/editors/mesh/editmesh_select_similar.c index 00349983c57..d762eede079 100644 --- a/source/blender/editors/mesh/editmesh_select_similar.c +++ b/source/blender/editors/mesh/editmesh_select_similar.c @@ -34,6 +34,7 @@ #include "BKE_material.h" #include "BKE_report.h" +#include "DNA_material_types.h" #include "DNA_meshdata_types.h" #include "WM_api.h" diff --git a/source/blender/editors/mesh/editmesh_undo.c b/source/blender/editors/mesh/editmesh_undo.c index 43cad2db185..cff5414da75 100644 --- a/source/blender/editors/mesh/editmesh_undo.c +++ b/source/blender/editors/mesh/editmesh_undo.c @@ -27,6 +27,7 @@ #include "DNA_mesh_types.h" #include "DNA_meshdata_types.h" #include "DNA_object_types.h" +#include "DNA_scene_types.h" #include "BLI_array_utils.h" #include "BLI_listbase.h" diff --git a/source/blender/editors/metaball/editmball_undo.c b/source/blender/editors/metaball/editmball_undo.c index 552e459acb1..b4030ad269b 100644 --- a/source/blender/editors/metaball/editmball_undo.c +++ b/source/blender/editors/metaball/editmball_undo.c @@ -30,8 +30,10 @@ #include "BLI_utildefines.h" #include "DNA_defs.h" +#include "DNA_layer_types.h" #include "DNA_meta_types.h" #include "DNA_object_types.h" +#include "DNA_scene_types.h" #include "BKE_context.h" #include "BKE_layer.h" diff --git a/source/blender/editors/object/object_bake.c b/source/blender/editors/object/object_bake.c index 008498a1735..9618774eea8 100644 --- a/source/blender/editors/object/object_bake.c +++ b/source/blender/editors/object/object_bake.c @@ -25,6 +25,7 @@ #include "MEM_guardedalloc.h" +#include "DNA_material_types.h" #include "DNA_mesh_types.h" #include "DNA_meshdata_types.h" #include "DNA_object_types.h" diff --git a/source/blender/editors/physics/rigidbody_constraint.c b/source/blender/editors/physics/rigidbody_constraint.c index 4939bf0086b..cb7ca5bd5d1 100644 --- a/source/blender/editors/physics/rigidbody_constraint.c +++ b/source/blender/editors/physics/rigidbody_constraint.c @@ -25,6 +25,7 @@ #include #include +#include "DNA_collection_types.h" #include "DNA_object_types.h" #include "DNA_rigidbody_types.h" #include "DNA_scene_types.h" diff --git a/source/blender/editors/physics/rigidbody_object.c b/source/blender/editors/physics/rigidbody_object.c index cb25363d2b2..4fd304ea71d 100644 --- a/source/blender/editors/physics/rigidbody_object.c +++ b/source/blender/editors/physics/rigidbody_object.c @@ -25,6 +25,7 @@ #include #include +#include "DNA_collection_types.h" #include "DNA_object_types.h" #include "DNA_rigidbody_types.h" #include "DNA_scene_types.h" diff --git a/source/blender/editors/sculpt_paint/paint_image.c b/source/blender/editors/sculpt_paint/paint_image.c index 999d364a3cd..324fd5d3075 100644 --- a/source/blender/editors/sculpt_paint/paint_image.c +++ b/source/blender/editors/sculpt_paint/paint_image.c @@ -40,6 +40,7 @@ #include "IMB_imbuf_types.h" #include "DNA_brush_types.h" +#include "DNA_material_types.h" #include "DNA_mesh_types.h" #include "DNA_node_types.h" #include "DNA_object_types.h" diff --git a/source/blender/editors/space_outliner/tree/tree_display_libraries.cc b/source/blender/editors/space_outliner/tree/tree_display_libraries.cc index bd0870c837c..cb5f42f08e1 100644 --- a/source/blender/editors/space_outliner/tree/tree_display_libraries.cc +++ b/source/blender/editors/space_outliner/tree/tree_display_libraries.cc @@ -24,6 +24,8 @@ #include "BKE_collection.h" #include "BKE_main.h" +#include "DNA_collection_types.h" + #include "BLT_translation.h" #include "../outliner_intern.h" diff --git a/source/blender/editors/space_outliner/tree/tree_display_view_layer.cc b/source/blender/editors/space_outliner/tree/tree_display_view_layer.cc index c88eb957dd1..f7740f4648f 100644 --- a/source/blender/editors/space_outliner/tree/tree_display_view_layer.cc +++ b/source/blender/editors/space_outliner/tree/tree_display_view_layer.cc @@ -20,6 +20,7 @@ #include +#include "DNA_collection_types.h" #include "DNA_scene_types.h" #include "BKE_layer.h" diff --git a/source/blender/editors/undo/memfile_undo.c b/source/blender/editors/undo/memfile_undo.c index 49417a54472..4fded419b5b 100644 --- a/source/blender/editors/undo/memfile_undo.c +++ b/source/blender/editors/undo/memfile_undo.c @@ -27,6 +27,7 @@ #include "BLI_listbase.h" #include "DNA_ID.h" +#include "DNA_collection_types.h" #include "DNA_node_types.h" #include "DNA_object_enums.h" #include "DNA_object_types.h" -- cgit v1.2.3 From e995296acbd9587efbed0b7f2cbb7bde28ea00f1 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Tue, 15 Dec 2020 12:23:37 +1100 Subject: Cleanup: unused variables --- source/blender/editors/screen/screen_context.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'source/blender/editors') diff --git a/source/blender/editors/screen/screen_context.c b/source/blender/editors/screen/screen_context.c index 2061716f01f..fb7606d1fe5 100644 --- a/source/blender/editors/screen/screen_context.c +++ b/source/blender/editors/screen/screen_context.c @@ -649,8 +649,6 @@ static eContextResult screen_ctx_selected_editable_sequences(const bContext *C, } static eContextResult screen_ctx_selected_nla_strips(const bContext *C, bContextDataResult *result) { - wmWindow *win = CTX_wm_window(C); - Scene *scene = WM_window_get_active_scene(win); bAnimContext ac; if (ANIM_animdata_get_context(C, &ac) != 0) { ListBase anim_data = {NULL, NULL}; -- cgit v1.2.3 From 001f2c5d50b496708ef12de2c083686996b678d9 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Tue, 15 Dec 2020 12:27:16 +1100 Subject: Cleanup: spelling --- source/blender/editors/gpencil/gpencil_data.c | 4 ++-- source/blender/editors/interface/interface_templates.c | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) (limited to 'source/blender/editors') diff --git a/source/blender/editors/gpencil/gpencil_data.c b/source/blender/editors/gpencil/gpencil_data.c index 093f1fa89c7..aff109eb98e 100644 --- a/source/blender/editors/gpencil/gpencil_data.c +++ b/source/blender/editors/gpencil/gpencil_data.c @@ -1332,8 +1332,8 @@ static int gpencil_merge_layer_exec(bContext *C, wmOperator *op) } /* Read all frames from merge layer and add any missing in destination layer, - * copying all previous strokes to keep the image equals. Need to do it in a separated - * loop to avoid strokes acumulation. */ + * copying all previous strokes to keep the image equals. + * Need to do it in a separated loop to avoid strokes accumulation. */ LISTBASE_FOREACH (bGPDframe *, gpf_src, &gpl_src->frames) { /* Try to find frame in destination layer hash table. */ bGPDframe *gpf_dst = BLI_ghash_lookup(gh_frames_dst, POINTER_FROM_INT(gpf_src->framenum)); diff --git a/source/blender/editors/interface/interface_templates.c b/source/blender/editors/interface/interface_templates.c index 352afe72e76..dec2312b549 100644 --- a/source/blender/editors/interface/interface_templates.c +++ b/source/blender/editors/interface/interface_templates.c @@ -6173,7 +6173,7 @@ void uiTemplateList(uiLayout *layout, org_i, flt_flag); - /* Items should be able to set context pointers for the layout. But the listrow button + /* Items should be able to set context pointers for the layout. But the list-row button * swallows events, so it needs the context storage too for handlers to see it. */ but->context = uiLayoutGetContextStore(sub); -- cgit v1.2.3 From 612598acd7b8d6a75dfb60ed3487bf5342b4f586 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Tue, 15 Dec 2020 12:30:00 +1100 Subject: Cleanup: doxy comments (use colon after parameter name) Also remove colon after `\note`. --- source/blender/editors/interface/interface_templates.c | 2 +- source/blender/editors/space_outliner/outliner_tree.c | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) (limited to 'source/blender/editors') diff --git a/source/blender/editors/interface/interface_templates.c b/source/blender/editors/interface/interface_templates.c index dec2312b549..b895f1702f4 100644 --- a/source/blender/editors/interface/interface_templates.c +++ b/source/blender/editors/interface/interface_templates.c @@ -2014,7 +2014,7 @@ static void set_constraint_expand_flag(const bContext *UNUSED(C), Panel *panel, /** * Function with void * argument for #uiListPanelIDFromDataFunc. * - * \note: Constraint panel types are assumed to be named with the struct name field + * \note Constraint panel types are assumed to be named with the struct name field * concatenated to the defined prefix. */ static void object_constraint_panel_id(void *md_link, char *r_name) diff --git a/source/blender/editors/space_outliner/outliner_tree.c b/source/blender/editors/space_outliner/outliner_tree.c index 7308b161d18..56eedcd3748 100644 --- a/source/blender/editors/space_outliner/outliner_tree.c +++ b/source/blender/editors/space_outliner/outliner_tree.c @@ -908,9 +908,9 @@ static void outliner_add_id_contents(SpaceOutliner *space_outliner, /** * TODO: this function needs to be split up! It's getting a bit too large... * - * \note: "ID" is not always a real ID - * \note: If child items are only added to the tree if the item is open, the TSE_ type _must_ be - * added to #outliner_element_needs_rebuild_on_open_change(). + * \note "ID" is not always a real ID. + * \note If child items are only added to the tree if the item is open, + * the `TSE_` type _must_ be added to #outliner_element_needs_rebuild_on_open_change(). */ TreeElement *outliner_add_element(SpaceOutliner *space_outliner, ListBase *lb, -- cgit v1.2.3 From e035d7301c8c6fc1bb42110054101b00d190d1f9 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Tue, 15 Dec 2020 16:11:41 +1100 Subject: Fix crash sliding effect sequence strips Off by one error in array access. --- source/blender/editors/space_sequencer/sequencer_edit.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) (limited to 'source/blender/editors') diff --git a/source/blender/editors/space_sequencer/sequencer_edit.c b/source/blender/editors/space_sequencer/sequencer_edit.c index 93b17830c0f..953a77d22a6 100644 --- a/source/blender/editors/space_sequencer/sequencer_edit.c +++ b/source/blender/editors/space_sequencer/sequencer_edit.c @@ -537,7 +537,7 @@ static int slip_add_sequences_recursive( for (seq = seqbasep->first; seq; seq = seq->next) { if (!do_trim || (!(seq->type & SEQ_TYPE_EFFECT) && (seq->flag & SELECT))) { seq_array[offset + num_items] = seq; - trim[offset + num_items] = do_trim; + trim[offset + num_items] = do_trim && ((seq->type & SEQ_TYPE_EFFECT) == 0); num_items++; if (seq->type == SEQ_TYPE_META) { @@ -545,9 +545,6 @@ static int slip_add_sequences_recursive( num_items += slip_add_sequences_recursive( &seq->seqbase, seq_array, trim, num_items + offset, false); } - else if (seq->type & SEQ_TYPE_EFFECT) { - trim[offset + num_items] = false; - } } } -- cgit v1.2.3 From 12792ee70cd87ce4495a62cb89fd37b95be11917 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Tue, 15 Dec 2020 18:07:12 +1100 Subject: Fix T83788: Topology mirror crashes for vertices aren't mirrored Caused by da8dc204bd062b2712869cf2709d2530915249b5 --- source/blender/editors/mesh/editmesh_utils.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'source/blender/editors') diff --git a/source/blender/editors/mesh/editmesh_utils.c b/source/blender/editors/mesh/editmesh_utils.c index 6467df0e87b..94f386e08d5 100644 --- a/source/blender/editors/mesh/editmesh_utils.c +++ b/source/blender/editors/mesh/editmesh_utils.c @@ -1139,8 +1139,10 @@ void EDBM_verts_mirror_cache_begin_ex(BMEditMesh *em, if (use_topology) { v_mirr = cache_mirr_intptr_as_bmvert(mesh_topo_store.index_lookup, i); - if (respecthide && BM_elem_flag_test(v_mirr, BM_ELEM_HIDDEN)) { - v_mirr = NULL; + if (v_mirr != NULL) { + if (respecthide && BM_elem_flag_test(v_mirr, BM_ELEM_HIDDEN)) { + v_mirr = NULL; + } } } else { -- cgit v1.2.3 From ef2151d73de87b3e7be631b6712283a727f8d4a6 Mon Sep 17 00:00:00 2001 From: Julian Eisel Date: Tue, 15 Dec 2020 12:02:22 +0100 Subject: Fix T83776: Crashes with add-on's icon preview in menus Apparently the ID pointer can be NULL, which most code here assumes is not the case. But it's very fragile & finicky, there is one code path were it's allowed to be NULL. Add necessary NULL-checks, an assert as sanity check and a comment to note the possibility of NULL. --- source/blender/editors/render/render_preview.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) (limited to 'source/blender/editors') diff --git a/source/blender/editors/render/render_preview.c b/source/blender/editors/render/render_preview.c index 4466d9f434d..3c103f28d93 100644 --- a/source/blender/editors/render/render_preview.c +++ b/source/blender/editors/render/render_preview.c @@ -189,7 +189,7 @@ typedef struct IconPreview { Main *bmain; Scene *scene; void *owner; - ID *id, *id_copy; + ID *id, *id_copy; /* May be NULL! (see ICON_TYPE_PREVIEW case in #ui_icon_ensure_deferred()) */ ListBase sizes; } IconPreview; @@ -1235,6 +1235,8 @@ static void icon_preview_startjob(void *customdata, short *stop, short *do_updat ID *id = sp->id; short idtype = GS(id->name); + BLI_assert(id != NULL); + if (idtype == ID_IM) { Image *ima = (Image *)id; ImBuf *ibuf = NULL; @@ -1337,7 +1339,7 @@ static void other_id_types_preview_render(IconPreview *ip, const bool is_render = !is_deferred; /* These types don't use the ShaderPreview mess, they have their own types and functions. */ - BLI_assert(!ELEM(GS(ip->id->name), ID_OB)); + BLI_assert(!ip->id || !ELEM(GS(ip->id->name), ID_OB)); /* construct shader preview from image size and previewcustomdata */ sp->scene = ip->scene; @@ -1396,7 +1398,7 @@ static void icon_preview_startjob_all_sizes(void *customdata, continue; } - if (ELEM(GS(ip->id->name), ID_OB)) { + if (ip->id && ELEM(GS(ip->id->name), ID_OB)) { /* Much simpler than the ShaderPreview mess used for other ID types. */ object_preview_render(ip, cur_size); } -- cgit v1.2.3 From 82645ff739687e4d58715869778c8860e832513c Mon Sep 17 00:00:00 2001 From: Dalai Felinto Date: Tue, 15 Dec 2020 13:07:02 +0100 Subject: Move Point Cloud object back to Experimental Features The geometry-nodes features no longer depend on the point cloud object. Therefore the point cloud object, although important in the future, can be postponed until we have render and edit mode fully working. This reverts commits: * ea74ed5a7a2031b614d401e394f2e0146fc90155. * dc614c68ef2c8ca8b076a000974b5a20a4145a42. --- source/blender/editors/object/CMakeLists.txt | 1 + source/blender/editors/object/object_add.c | 9 +++++++++ source/blender/editors/space_buttons/CMakeLists.txt | 1 + source/blender/editors/space_buttons/buttons_context.c | 6 ++++++ 4 files changed, 17 insertions(+) (limited to 'source/blender/editors') diff --git a/source/blender/editors/object/CMakeLists.txt b/source/blender/editors/object/CMakeLists.txt index d872511ae03..77b5379ddd4 100644 --- a/source/blender/editors/object/CMakeLists.txt +++ b/source/blender/editors/object/CMakeLists.txt @@ -88,6 +88,7 @@ endif() if(WITH_EXPERIMENTAL_FEATURES) add_definitions(-DWITH_GEOMETRY_NODES) + add_definitions(-DWITH_POINT_CLOUD) add_definitions(-DWITH_HAIR_NODES) endif() diff --git a/source/blender/editors/object/object_add.c b/source/blender/editors/object/object_add.c index bbfdfb2532d..a64033bc63a 100644 --- a/source/blender/editors/object/object_add.c +++ b/source/blender/editors/object/object_add.c @@ -1714,6 +1714,9 @@ void OBJECT_OT_hair_add(wmOperatorType *ot) static bool object_pointcloud_add_poll(bContext *C) { + if (!U.experimental.use_new_point_cloud_type) { + return false; + } return ED_operator_objectmode(C); } @@ -2316,17 +2319,23 @@ static const EnumPropertyItem convert_target_items[] = { "MESH", ICON_OUTLINER_OB_MESH, "Mesh", +#ifdef WITH_POINT_CLOUD "Mesh from Curve, Surface, Metaball, Text, or Pointcloud objects"}, +#else + "Mesh from Curve, Surface, Metaball, or Text objects"}, +#endif {OB_GPENCIL, "GPENCIL", ICON_OUTLINER_OB_GREASEPENCIL, "Grease Pencil", "Grease Pencil from Curve or Mesh objects"}, +#ifdef WITH_POINT_CLOUD {OB_POINTCLOUD, "POINTCLOUD", ICON_OUTLINER_OB_POINTCLOUD, "Pointcloud", "Pointcloud from Mesh objects"}, +#endif {0, NULL, 0, NULL, NULL}, }; diff --git a/source/blender/editors/space_buttons/CMakeLists.txt b/source/blender/editors/space_buttons/CMakeLists.txt index fa3e6a51036..c71e5e49d8d 100644 --- a/source/blender/editors/space_buttons/CMakeLists.txt +++ b/source/blender/editors/space_buttons/CMakeLists.txt @@ -51,6 +51,7 @@ endif() if(WITH_EXPERIMENTAL_FEATURES) add_definitions(-DWITH_GEOMETRY_NODES) + add_definitions(-DWITH_POINT_CLOUD) add_definitions(-DWITH_HAIR_NODES) endif() diff --git a/source/blender/editors/space_buttons/buttons_context.c b/source/blender/editors/space_buttons/buttons_context.c index 8b39995a5c9..3a2b8cf0115 100644 --- a/source/blender/editors/space_buttons/buttons_context.c +++ b/source/blender/editors/space_buttons/buttons_context.c @@ -246,9 +246,11 @@ static bool buttons_context_path_data(ButsContextPath *path, int type) return true; } #endif +#ifdef WITH_POINT_CLOUD if (RNA_struct_is_a(ptr->type, &RNA_PointCloud) && (type == -1 || type == OB_POINTCLOUD)) { return true; } +#endif if (RNA_struct_is_a(ptr->type, &RNA_Volume) && (type == -1 || type == OB_VOLUME)) { return true; } @@ -812,7 +814,9 @@ const char *buttons_context_dir[] = { #ifdef WITH_HAIR_NODES "hair", #endif +#ifdef WITH_POINT_CLOUD "pointcloud", +#endif "volume", NULL, }; @@ -899,10 +903,12 @@ int /*eContextResult*/ buttons_context(const bContext *C, return CTX_RESULT_OK; } #endif +#ifdef WITH_POINT_CLOUD if (CTX_data_equals(member, "pointcloud")) { set_pointer_type(path, result, &RNA_PointCloud); return CTX_RESULT_OK; } +#endif if (CTX_data_equals(member, "volume")) { set_pointer_type(path, result, &RNA_Volume); return CTX_RESULT_OK; -- cgit v1.2.3 From c25e0310497f5228bd04992d6bcd84481d0b0c5b Mon Sep 17 00:00:00 2001 From: Julian Eisel Date: Fri, 11 Dec 2020 23:16:29 +0100 Subject: Asset System: "Mark Asset" & "Clear Asset" operators and UI integration This makes it possible to turn data-blocks into assets and back into normal data-blocks. A core design decision made for the asset system is that not every data-block should be an asset, because not every data-block is made for reuse. Users have to explicitly mark data-blocks as assets. Exposes "Mark Asset" and "Clear Asset" in Outliner context menus (currently ID Data submenu) and button context menus. We are still not too happy with the names, they may change. This uses the new context members to pass data-blocks to operators, added in af008f553293 and 0c1d4769235c. Part of the first Asset Browser milestone. Check the #asset_browser_milestone_1 project milestone on developer.blender.org. Differential Revision: https://developer.blender.org/D9717 Reviewed by: Brecht Van Lommel --- source/blender/editors/CMakeLists.txt | 1 + source/blender/editors/asset/CMakeLists.txt | 39 ++++ source/blender/editors/asset/asset_edit.c | 69 ++++++ source/blender/editors/asset/asset_ops.c | 238 +++++++++++++++++++++ source/blender/editors/include/ED_asset.h | 39 ++++ .../editors/interface/interface_context_menu.c | 17 ++ source/blender/editors/space_api/spacetypes.c | 2 + .../editors/space_outliner/outliner_tools.c | 12 ++ source/blender/editors/util/CMakeLists.txt | 1 + 9 files changed, 418 insertions(+) create mode 100644 source/blender/editors/asset/CMakeLists.txt create mode 100644 source/blender/editors/asset/asset_edit.c create mode 100644 source/blender/editors/asset/asset_ops.c create mode 100644 source/blender/editors/include/ED_asset.h (limited to 'source/blender/editors') diff --git a/source/blender/editors/CMakeLists.txt b/source/blender/editors/CMakeLists.txt index 1f5dc73f732..a2ae350ce4b 100644 --- a/source/blender/editors/CMakeLists.txt +++ b/source/blender/editors/CMakeLists.txt @@ -22,6 +22,7 @@ if(WITH_BLENDER) add_subdirectory(animation) add_subdirectory(armature) + add_subdirectory(asset) add_subdirectory(curve) add_subdirectory(geometry) add_subdirectory(gizmo_library) diff --git a/source/blender/editors/asset/CMakeLists.txt b/source/blender/editors/asset/CMakeLists.txt new file mode 100644 index 00000000000..63a1761b264 --- /dev/null +++ b/source/blender/editors/asset/CMakeLists.txt @@ -0,0 +1,39 @@ +# ***** BEGIN GPL LICENSE BLOCK ***** +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software Foundation, +# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +# ***** END GPL LICENSE BLOCK ***** + +set(INC + ../include + ../../blenlib + ../../blenkernel + ../../makesdna + ../../makesrna + ../../windowmanager + ../../../../intern/guardedalloc +) + +set(INC_SYS +) + +set(SRC + asset_edit.c + asset_ops.c +) + +set(LIB +) + +blender_add_lib(bf_editor_asset "${SRC}" "${INC}" "${INC_SYS}" "${LIB}") diff --git a/source/blender/editors/asset/asset_edit.c b/source/blender/editors/asset/asset_edit.c new file mode 100644 index 00000000000..5333c08c66a --- /dev/null +++ b/source/blender/editors/asset/asset_edit.c @@ -0,0 +1,69 @@ +/* + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +/** \file + * \ingroup edasset + */ + +#include "BKE_asset.h" +#include "BKE_context.h" +#include "BKE_idtype.h" +#include "BKE_lib_id.h" + +#include "DNA_ID.h" +#include "DNA_asset_types.h" + +#include "UI_interface_icons.h" + +#include "RNA_access.h" + +#include "ED_asset.h" + +bool ED_asset_mark_id(const bContext *C, ID *id) +{ + if (id->asset_data) { + return false; + } + if (!BKE_id_can_be_asset(id)) { + return false; + } + + id_fake_user_set(id); + + id->asset_data = BKE_asset_metadata_create(); + + UI_icon_render_id(C, NULL, id, true, true); + + return true; +} + +bool ED_asset_clear_id(ID *id) +{ + if (!id->asset_data) { + return false; + } + BKE_asset_metadata_free(&id->asset_data); + /* Don't clear fake user here, there's no guarantee that it was actually set by + * #ED_asset_mark_id(), it might have been something/someone else. */ + + return true; +} + +bool ED_asset_can_make_single_from_context(const bContext *C) +{ + /* Context needs a "id" pointer to be set for #ASSET_OT_mark()/#ASSET_OT_clear() to use. */ + return CTX_data_pointer_get_type_silent(C, "id", &RNA_ID).data != NULL; +} diff --git a/source/blender/editors/asset/asset_ops.c b/source/blender/editors/asset/asset_ops.c new file mode 100644 index 00000000000..929d49e19fa --- /dev/null +++ b/source/blender/editors/asset/asset_ops.c @@ -0,0 +1,238 @@ +/* + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +/** \file + * \ingroup edasset + */ + +#include + +#include "BKE_asset.h" +#include "BKE_context.h" +#include "BKE_report.h" + +#include "BLI_listbase.h" +#include "BLI_string_utils.h" + +#include "DNA_asset_types.h" + +#include "ED_asset.h" + +#include "MEM_guardedalloc.h" + +#include "RNA_access.h" +#include "RNA_define.h" + +#include "WM_api.h" +#include "WM_types.h" + +/* -------------------------------------------------------------------- */ + +struct AssetMarkResultStats { + int tot_created; + int tot_already_asset; + ID *last_id; +}; + +/** + * Return the IDs to operate on as list of #CollectionPointerLink links. Needs freeing. + */ +static ListBase /* CollectionPointerLink */ asset_operation_get_ids_from_context(const bContext *C) +{ + ListBase list = {0}; + + PointerRNA idptr = CTX_data_pointer_get_type(C, "id", &RNA_ID); + + if (idptr.data) { + CollectionPointerLink *ctx_link = MEM_callocN(sizeof(*ctx_link), __func__); + ctx_link->ptr = idptr; + BLI_addtail(&list, ctx_link); + } + else { + CTX_data_selected_ids(C, &list); + } + + return list; +} + +static void asset_mark_for_idptr_list(const bContext *C, + const ListBase /* CollectionPointerLink */ *ids, + struct AssetMarkResultStats *r_stats) +{ + memset(r_stats, 0, sizeof(*r_stats)); + + LISTBASE_FOREACH (CollectionPointerLink *, ctx_id, ids) { + BLI_assert(RNA_struct_is_ID(ctx_id->ptr.type)); + + ID *id = ctx_id->ptr.data; + if (id->asset_data) { + r_stats->tot_already_asset++; + continue; + } + + if (ED_asset_mark_id(C, id)) { + r_stats->last_id = id; + r_stats->tot_created++; + } + } +} + +static bool asset_mark_results_report(const struct AssetMarkResultStats *stats, + ReportList *reports) +{ + /* User feedback on failure. */ + if ((stats->tot_created < 1) && (stats->tot_already_asset > 0)) { + BKE_report(reports, + RPT_ERROR, + "Selected data-blocks are already assets (or do not support use as assets)"); + return false; + } + if (stats->tot_created < 1) { + BKE_report(reports, + RPT_ERROR, + "No data-blocks to create assets for found (or do not support use as assets)"); + return false; + } + + /* User feedback on success. */ + if (stats->tot_created == 1) { + /* If only one data-block: Give more useful message by printing asset name. */ + BKE_reportf(reports, RPT_INFO, "Data-block '%s' is now an asset", stats->last_id->name + 2); + } + else { + BKE_reportf(reports, RPT_INFO, "%i data-blocks are now assets", stats->tot_created); + } + + return true; +} + +static int asset_mark_exec(bContext *C, wmOperator *op) +{ + ListBase ids = asset_operation_get_ids_from_context(C); + + struct AssetMarkResultStats stats; + asset_mark_for_idptr_list(C, &ids, &stats); + BLI_freelistN(&ids); + + if (!asset_mark_results_report(&stats, op->reports)) { + return OPERATOR_CANCELLED; + } + + WM_main_add_notifier(NC_ID | NA_EDITED, NULL); + WM_main_add_notifier(NC_ASSET | NA_ADDED, NULL); + + return OPERATOR_FINISHED; +} + +static void ASSET_OT_mark(wmOperatorType *ot) +{ + ot->name = "Mark Asset"; + ot->description = + "Enable easier reuse of selected data-blocks through the Asset Browser, with the help of " + "customizable metadata (like previews, descriptions and tags)"; + ot->idname = "ASSET_OT_mark"; + + ot->exec = asset_mark_exec; + + ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; +} + +/* -------------------------------------------------------------------- */ + +struct AssetClearResultStats { + int tot_removed; + ID *last_id; +}; + +static void asset_clear_from_idptr_list(const ListBase /* CollectionPointerLink */ *ids, + struct AssetClearResultStats *r_stats) +{ + memset(r_stats, 0, sizeof(*r_stats)); + + LISTBASE_FOREACH (CollectionPointerLink *, ctx_id, ids) { + BLI_assert(RNA_struct_is_ID(ctx_id->ptr.type)); + + ID *id = ctx_id->ptr.data; + if (!id->asset_data) { + continue; + } + + if (ED_asset_clear_id(id)) { + r_stats->tot_removed++; + r_stats->last_id = id; + } + } +} + +static bool asset_clear_result_report(const struct AssetClearResultStats *stats, + ReportList *reports) + +{ + if (stats->tot_removed < 1) { + BKE_report(reports, RPT_ERROR, "No asset data-blocks selected/focused"); + return false; + } + + if (stats->tot_removed == 1) { + /* If only one data-block: Give more useful message by printing asset name. */ + BKE_reportf( + reports, RPT_INFO, "Data-block '%s' is no asset anymore", stats->last_id->name + 2); + } + else { + BKE_reportf(reports, RPT_INFO, "%i data-blocks are no assets anymore", stats->tot_removed); + } + + return true; +} + +static int asset_clear_exec(bContext *C, wmOperator *op) +{ + ListBase ids = asset_operation_get_ids_from_context(C); + + struct AssetClearResultStats stats; + asset_clear_from_idptr_list(&ids, &stats); + BLI_freelistN(&ids); + + if (!asset_clear_result_report(&stats, op->reports)) { + return OPERATOR_CANCELLED; + } + + WM_main_add_notifier(NC_ID | NA_EDITED, NULL); + WM_main_add_notifier(NC_ASSET | NA_REMOVED, NULL); + + return OPERATOR_FINISHED; +} + +static void ASSET_OT_clear(wmOperatorType *ot) +{ + ot->name = "Clear Asset"; + ot->description = + "Delete all asset metadata and turn the selected asset data-blocks back into normal " + "data-blocks"; + ot->idname = "ASSET_OT_clear"; + + ot->exec = asset_clear_exec; + + ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; +} + +/* -------------------------------------------------------------------- */ + +void ED_operatortypes_asset(void) +{ + WM_operatortype_append(ASSET_OT_mark); + WM_operatortype_append(ASSET_OT_clear); +} diff --git a/source/blender/editors/include/ED_asset.h b/source/blender/editors/include/ED_asset.h new file mode 100644 index 00000000000..6fe50528cc5 --- /dev/null +++ b/source/blender/editors/include/ED_asset.h @@ -0,0 +1,39 @@ +/* + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +/** \file + * \ingroup editors + */ + +#ifndef __ED_ASSET_H__ +#define __ED_ASSET_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +bool ED_asset_mark_id(const struct bContext *C, struct ID *id); +bool ED_asset_clear_id(struct ID *id); + +bool ED_asset_can_make_single_from_context(const struct bContext *C); + +void ED_operatortypes_asset(void); + +#ifdef __cplusplus +} +#endif + +#endif /* __ED_ASSET_H__ */ diff --git a/source/blender/editors/interface/interface_context_menu.c b/source/blender/editors/interface/interface_context_menu.c index 3e76cd1cde4..870c3a2a13f 100644 --- a/source/blender/editors/interface/interface_context_menu.c +++ b/source/blender/editors/interface/interface_context_menu.c @@ -38,6 +38,7 @@ #include "BKE_idprop.h" #include "BKE_screen.h" +#include "ED_asset.h" #include "ED_keyframing.h" #include "ED_screen.h" @@ -952,6 +953,22 @@ bool ui_popup_context_menu_for_button(bContext *C, uiBut *but) } } + /* If the button reprents an id, it can set the "id" context pointer. */ + if (ED_asset_can_make_single_from_context(C)) { + ID *id = CTX_data_pointer_get_type(C, "id", &RNA_ID).data; + + /* Gray out items depending on if data-block is an asset. Preferably this could be done via + * operator poll, but that doesn't work since the operator also works with "selected_ids", + * which isn't cheap to check. */ + uiLayout *sub = uiLayoutColumn(layout, true); + uiLayoutSetEnabled(sub, !id->asset_data); + uiItemO(sub, NULL, ICON_NONE, "ASSET_OT_mark"); + sub = uiLayoutColumn(layout, true); + uiLayoutSetEnabled(sub, id->asset_data); + uiItemO(sub, NULL, ICON_NONE, "ASSET_OT_clear"); + uiItemS(layout); + } + /* Pointer properties and string properties with * prop_search support jumping to target object/bone. */ if (but->rnapoin.data && but->rnaprop) { diff --git a/source/blender/editors/space_api/spacetypes.c b/source/blender/editors/space_api/spacetypes.c index 10ce7b81954..0fe94ec382c 100644 --- a/source/blender/editors/space_api/spacetypes.c +++ b/source/blender/editors/space_api/spacetypes.c @@ -40,6 +40,7 @@ #include "ED_anim_api.h" #include "ED_armature.h" +#include "ED_asset.h" #include "ED_clip.h" #include "ED_curve.h" #include "ED_fileselect.h" @@ -105,6 +106,7 @@ void ED_spacetypes_init(void) ED_operatortypes_screen(); ED_operatortypes_anim(); ED_operatortypes_animchannels(); + ED_operatortypes_asset(); ED_operatortypes_gpencil(); ED_operatortypes_object(); ED_operatortypes_lattice(); diff --git a/source/blender/editors/space_outliner/outliner_tools.c b/source/blender/editors/space_outliner/outliner_tools.c index 098a0edb614..e4c3ebfdff5 100644 --- a/source/blender/editors/space_outliner/outliner_tools.c +++ b/source/blender/editors/space_outliner/outliner_tools.c @@ -1685,6 +1685,8 @@ typedef enum eOutlinerIdOpTypes { OUTLINER_IDOP_INVALID = 0, OUTLINER_IDOP_UNLINK, + OUTLINER_IDOP_MARK_ASSET, + OUTLINER_IDOP_CLEAR_ASSET, OUTLINER_IDOP_LOCAL, OUTLINER_IDOP_OVERRIDE_LIBRARY_CREATE, OUTLINER_IDOP_OVERRIDE_LIBRARY_CREATE_HIERARCHY, @@ -1710,6 +1712,8 @@ typedef enum eOutlinerIdOpTypes { /* TODO: implement support for changing the ID-block used. */ static const EnumPropertyItem prop_id_op_types[] = { {OUTLINER_IDOP_UNLINK, "UNLINK", 0, "Unlink", ""}, + {OUTLINER_IDOP_MARK_ASSET, "MARK_ASSET", 0, "Mark Asset", ""}, + {OUTLINER_IDOP_CLEAR_ASSET, "CLEAR_ASSET", 0, "Clear Asset", ""}, {OUTLINER_IDOP_LOCAL, "LOCAL", 0, "Make Local", ""}, {OUTLINER_IDOP_SINGLE, "SINGLE", 0, "Make Single User", ""}, {OUTLINER_IDOP_DELETE, "DELETE", ICON_X, "Delete", ""}, @@ -1915,6 +1919,14 @@ static int outliner_id_operation_exec(bContext *C, wmOperator *op) } break; } + case OUTLINER_IDOP_MARK_ASSET: { + WM_operator_name_call(C, "ASSET_OT_mark", WM_OP_EXEC_DEFAULT, NULL); + break; + } + case OUTLINER_IDOP_CLEAR_ASSET: { + WM_operator_name_call(C, "ASSET_OT_clear", WM_OP_EXEC_DEFAULT, NULL); + break; + } case OUTLINER_IDOP_LOCAL: { /* make local */ outliner_do_libdata_operation( diff --git a/source/blender/editors/util/CMakeLists.txt b/source/blender/editors/util/CMakeLists.txt index c88169778f7..bbaf5d5475a 100644 --- a/source/blender/editors/util/CMakeLists.txt +++ b/source/blender/editors/util/CMakeLists.txt @@ -47,6 +47,7 @@ set(SRC ../include/BIF_glutil.h ../include/ED_anim_api.h ../include/ED_armature.h + ../include/ED_asset.h ../include/ED_buttons.h ../include/ED_clip.h ../include/ED_curve.h -- cgit v1.2.3 From 9363132c8601ebca6d89168e09bb10f81d6cb03a Mon Sep 17 00:00:00 2001 From: Julian Eisel Date: Mon, 14 Dec 2020 13:21:58 +0100 Subject: Asset System: Various changes to previews in preparation for Asset Browser * Support defining (not necessarily rendering) icons in threads. Needed so the File Browser can expose file previews with an icon-id to scripts. ** For that, ported `icons.c` to C++, to be able to use scope based mutex locks (cleaner & safer code). Had to do some cleanups and minor refactoring for that. * Added support for ImBuf icons, as a decent way for icons to hold the file preview buffers. * Tag previews as "unfinished" while they render in a thread, for the File Browser to dynamically load previews as they get finished. * Better handle cases where threaded preview generation is requested, but the ID type doesn't support it (fallback to single threaded). This is for general sanity of the code (as in, safety and cleanness) * Enabled asset notifier for custom preview loading operator, was just disabled because `NC_ASSET` wasn't defined in master yet. Part of the first Asset Browser milestone. Check the #asset_browser_milestone_1 project milestone on developer.blender.org. Differential Revision: https://developer.blender.org/D9719 Reviewed by: Bastien Montagne, Brecht Van Lommel --- source/blender/editors/interface/interface_icons.c | 45 ++++++++++++++-------- source/blender/editors/render/render_preview.c | 37 +++++++++++++++++- source/blender/editors/util/ed_util.c | 2 +- 3 files changed, 66 insertions(+), 18 deletions(-) (limited to 'source/blender/editors') diff --git a/source/blender/editors/interface/interface_icons.c b/source/blender/editors/interface/interface_icons.c index 90f5172f6ec..1c09dc6f4df 100644 --- a/source/blender/editors/interface/interface_icons.c +++ b/source/blender/editors/interface/interface_icons.c @@ -100,11 +100,12 @@ typedef void (*VectorDrawFunc)(int x, int y, int w, int h, float alpha); #define ICON_TYPE_COLOR_TEXTURE 1 #define ICON_TYPE_MONO_TEXTURE 2 #define ICON_TYPE_BUFFER 3 -#define ICON_TYPE_VECTOR 4 -#define ICON_TYPE_GEOM 5 -#define ICON_TYPE_EVENT 6 /* draw keymap entries using custom renderer. */ -#define ICON_TYPE_GPLAYER 7 -#define ICON_TYPE_BLANK 8 +#define ICON_TYPE_IMBUF 4 +#define ICON_TYPE_VECTOR 5 +#define ICON_TYPE_GEOM 6 +#define ICON_TYPE_EVENT 7 /* draw keymap entries using custom renderer. */ +#define ICON_TYPE_GPLAYER 8 +#define ICON_TYPE_BLANK 9 typedef struct DrawInfo { int type; @@ -1147,6 +1148,9 @@ static DrawInfo *icon_create_drawinfo(Icon *icon) if (ELEM(icon_data_type, ICON_DATA_ID, ICON_DATA_PREVIEW)) { di->type = ICON_TYPE_PREVIEW; } + else if (icon_data_type == ICON_DATA_IMBUF) { + di->type = ICON_TYPE_IMBUF; + } else if (icon_data_type == ICON_DATA_GEOM) { di->type = ICON_TYPE_GEOM; } @@ -1262,7 +1266,7 @@ static void icon_create_rect(struct PreviewImage *prv_img, enum eIconSizes size) else if (!prv_img->rect[size]) { prv_img->w[size] = render_size; prv_img->h[size] = render_size; - prv_img->flag[size] |= PRV_CHANGED; + prv_img->flag[size] |= (PRV_CHANGED | PRV_UNFINISHED); prv_img->changed_timestamp[size] = 0; prv_img->rect[size] = MEM_callocN(render_size * render_size * sizeof(uint), "prv_rect"); } @@ -1384,8 +1388,12 @@ void ui_icon_ensure_deferred(const bContext *C, const int icon_id, const bool bi } } -/* only called when icon has changed */ -/* only call with valid pointer from UI_icon_draw */ +/** + * * Only call with valid pointer from UI_icon_draw. + * * Only called when icon has changed. + * + * Note that if an ID doesn't support jobs for preview creation, \a use_job will be ignored. + */ static void icon_set_image(const bContext *C, Scene *scene, ID *id, @@ -1408,7 +1416,7 @@ static void icon_set_image(const bContext *C, const bool delay = prv_img->rect[size] != NULL; icon_create_rect(prv_img, size); - if (use_job) { + if (use_job && BKE_previewimg_id_supports_jobs(id)) { /* Job (background) version */ ED_preview_icon_job( C, prv_img, id, prv_img->rect[size], prv_img->w[size], prv_img->h[size], delay); @@ -1790,7 +1798,14 @@ static void icon_draw_size(float x, /* We need to flush widget base first to ensure correct ordering. */ UI_widgetbase_draw_cache_flush(); - if (di->type == ICON_TYPE_VECTOR) { + if (di->type == ICON_TYPE_IMBUF) { + ImBuf *ibuf = icon->obj; + + GPU_blend(GPU_BLEND_ALPHA_PREMULT); + icon_draw_rect(x, y, w, h, aspect, ibuf->x, ibuf->y, ibuf->rect, alpha, desaturate); + GPU_blend(GPU_BLEND_ALPHA); + } + else if (di->type == ICON_TYPE_VECTOR) { /* vector icons use the uiBlock transformation, they are not drawn * with untransformed coordinates like the other icons */ di->data.vector.func((int)x, (int)y, w, h, 1.0f); @@ -1937,6 +1952,9 @@ static void ui_id_preview_image_render_size( } } +/** + * Note that if an ID doesn't support jobs for preview creation, \a use_job will be ignored. + */ void UI_icon_render_id(const bContext *C, Scene *scene, ID *id, const bool big, const bool use_job) { PreviewImage *pi = BKE_previewimg_id_ensure(id); @@ -1964,12 +1982,7 @@ static void ui_id_icon_render(const bContext *C, ID *id, bool use_jobs) } for (enum eIconSizes i = 0; i < NUM_ICON_SIZES; i++) { - /* check if rect needs to be created; changed - * only set by dynamic icons */ - if (((pi->flag[i] & PRV_CHANGED) || !pi->rect[i])) { - icon_set_image(C, NULL, id, pi, i, use_jobs); - pi->flag[i] &= ~PRV_CHANGED; - } + ui_id_preview_image_render_size(C, NULL, id, pi, i, use_jobs); } } diff --git a/source/blender/editors/render/render_preview.c b/source/blender/editors/render/render_preview.c index 3c103f28d93..579fd86077e 100644 --- a/source/blender/editors/render/render_preview.c +++ b/source/blender/editors/render/render_preview.c @@ -354,13 +354,15 @@ static ID *duplicate_ids(ID *id, const bool allow_failure) case ID_TE: case ID_LA: case ID_WO: { + BLI_assert(BKE_previewimg_id_supports_jobs(id)); ID *id_copy = BKE_id_copy_ex( NULL, id, NULL, LIB_ID_CREATE_LOCAL | LIB_ID_COPY_LOCALIZE | LIB_ID_COPY_NO_ANIMDATA); return id_copy; } + /* These support threading, but don't need duplicating. */ case ID_IM: case ID_BR: - case ID_SCR: + BLI_assert(BKE_previewimg_id_supports_jobs(id)); return NULL; default: if (!allow_failure) { @@ -1374,6 +1376,24 @@ static void other_id_types_preview_render(IconPreview *ip, shader_preview_free(sp); } +/* exported functions */ + +/** + * Find the index to map \a icon_size to data in \a preview_image. + */ +static int icon_previewimg_size_index_get(const IconPreviewSize *icon_size, + const PreviewImage *preview_image) +{ + for (int i = 0; i < NUM_ICON_SIZES; i++) { + if ((preview_image->w[i] == icon_size->sizex) && (preview_image->h[i] == icon_size->sizey)) { + return i; + } + } + + BLI_assert(!"The searched icon size does not match any in the preview image"); + return -1; +} + static void icon_preview_startjob_all_sizes(void *customdata, short *stop, short *do_update, @@ -1398,6 +1418,13 @@ static void icon_preview_startjob_all_sizes(void *customdata, continue; } +#ifndef NDEBUG + { + int size_index = icon_previewimg_size_index_get(cur_size, prv); + BLI_assert(!BKE_previewimg_is_finished(prv, size_index)); + } +#endif + if (ip->id && ELEM(GS(ip->id->name), ID_OB)) { /* Much simpler than the ShaderPreview mess used for other ID types. */ object_preview_render(ip, cur_size); @@ -1460,6 +1487,12 @@ static void icon_preview_endjob(void *customdata) if (ip->owner) { PreviewImage *prv_img = ip->owner; prv_img->tag &= ~PRV_TAG_DEFFERED_RENDERING; + + LISTBASE_FOREACH (IconPreviewSize *, icon_size, &ip->sizes) { + int size_index = icon_previewimg_size_index_get(icon_size, prv_img); + BKE_previewimg_finish(prv_img, size_index); + } + if (prv_img->tag & PRV_TAG_DEFFERED_DELETE) { BLI_assert(prv_img->tag & PRV_TAG_DEFFERED); BKE_previewimg_deferred_release(prv_img); @@ -1576,6 +1609,8 @@ void ED_preview_shader_job(const bContext *C, Scene *scene = CTX_data_scene(C); short id_type = GS(id->name); + BLI_assert(BKE_previewimg_id_supports_jobs(id)); + /* Use workspace render only for buttons Window, * since the other previews are related to the datablock. */ diff --git a/source/blender/editors/util/ed_util.c b/source/blender/editors/util/ed_util.c index 5e3f443ce9c..6547e42f410 100644 --- a/source/blender/editors/util/ed_util.c +++ b/source/blender/editors/util/ed_util.c @@ -546,7 +546,7 @@ static int lib_id_load_custom_preview_exec(bContext *C, wmOperator *op) BKE_previewimg_id_custom_set(id, path); - // WM_event_add_notifier(C, NC_ASSET, NULL); + WM_event_add_notifier(C, NC_ASSET, NULL); return OPERATOR_FINISHED; } -- cgit v1.2.3 From b5d778a7d4072bfb091198a2094890157a6d017b Mon Sep 17 00:00:00 2001 From: Julian Eisel Date: Mon, 14 Dec 2020 13:31:55 +0100 Subject: Asset System: Support dragging assets and appending on drop For the Asset Browser, it needs to be possible to drag assets into various editors, which may not come from the current .blend file. In other words, the dragging needs to work with just the asset metadata, without direct access to the data-block itself. Idea is simple: When dragging an asset, store the source file-path and data-block name and when dropping, append the data-block. It uses existing drop operators, but the function to get the dropped data-block is replaced with one that returns the local data-block, or, in case of an external asset, appends the data-block first. The drop operators need to be adjusted to use this new function that respects assets. With this patch it only works for dragging assets into the 3D view. Note that I expect this to be a short-lived change. A refactor like D4071 is needed to make the drag & drop system more future proof for assets and other use cases. Part of the first Asset Browser milestone. Check the #asset_browser_milestone_1 project milestone on developer.blender.org. Differential Revision: https://developer.blender.org/D9721 Reviewed by: Bastien Montagne, Brecht Van Lommel --- source/blender/editors/include/UI_interface.h | 7 ++++ source/blender/editors/interface/interface.c | 37 ++++++++++++++++++---- .../blender/editors/interface/interface_handlers.c | 5 ++- .../blender/editors/space_console/space_console.c | 4 +-- source/blender/editors/space_node/space_node.c | 8 ++--- .../editors/space_outliner/outliner_dragdrop.c | 18 +++++------ source/blender/editors/space_text/space_text.c | 2 +- source/blender/editors/space_view3d/space_view3d.c | 26 ++++++++++----- 8 files changed, 76 insertions(+), 31 deletions(-) (limited to 'source/blender/editors') diff --git a/source/blender/editors/include/UI_interface.h b/source/blender/editors/include/UI_interface.h index 352c58032f5..83e94664c0b 100644 --- a/source/blender/editors/include/UI_interface.h +++ b/source/blender/editors/include/UI_interface.h @@ -727,6 +727,13 @@ void UI_block_translate(uiBlock *block, int x, int y); int UI_but_return_value_get(uiBut *but); void UI_but_drag_set_id(uiBut *but, struct ID *id); +void UI_but_drag_set_asset(uiBut *but, + const char *name, + const char *path, + int id_type, + int icon, + struct ImBuf *imb, + float scale); void UI_but_drag_set_rna(uiBut *but, struct PointerRNA *ptr); void UI_but_drag_set_path(uiBut *but, const char *path, const bool use_free); void UI_but_drag_set_name(uiBut *but, const char *name); diff --git a/source/blender/editors/interface/interface.c b/source/blender/editors/interface/interface.c index 254d0909367..c5c2f0e55c4 100644 --- a/source/blender/editors/interface/interface.c +++ b/source/blender/editors/interface/interface.c @@ -3352,7 +3352,7 @@ static void ui_but_free(const bContext *C, uiBut *but) } if (but->dragpoin && (but->dragflag & UI_BUT_DRAGPOIN_FREE)) { - MEM_freeN(but->dragpoin); + WM_drag_data_free(but->dragtype, but->dragpoin); } ui_but_extra_operator_icons_free(but); @@ -6098,17 +6098,42 @@ void UI_but_drag_set_id(uiBut *but, ID *id) { but->dragtype = WM_DRAG_ID; if ((but->dragflag & UI_BUT_DRAGPOIN_FREE)) { - MEM_SAFE_FREE(but->dragpoin); + WM_drag_data_free(but->dragtype, but->dragpoin); but->dragflag &= ~UI_BUT_DRAGPOIN_FREE; } but->dragpoin = (void *)id; } +void UI_but_drag_set_asset(uiBut *but, + const char *name, + const char *path, + int id_type, + int icon, + struct ImBuf *imb, + float scale) +{ + wmDragAsset *asset_drag = MEM_mallocN(sizeof(*asset_drag), "wmDragAsset"); + + BLI_strncpy(asset_drag->name, name, sizeof(asset_drag->name)); + asset_drag->path = path; + asset_drag->id_type = id_type; + + but->dragtype = WM_DRAG_ASSET; + ui_def_but_icon(but, icon, 0); /* no flag UI_HAS_ICON, so icon doesn't draw in button */ + if ((but->dragflag & UI_BUT_DRAGPOIN_FREE)) { + WM_drag_data_free(but->dragtype, but->dragpoin); + } + but->dragpoin = asset_drag; + but->dragflag |= UI_BUT_DRAGPOIN_FREE; + but->imb = imb; + but->imb_scale = scale; +} + void UI_but_drag_set_rna(uiBut *but, PointerRNA *ptr) { but->dragtype = WM_DRAG_RNA; if ((but->dragflag & UI_BUT_DRAGPOIN_FREE)) { - MEM_SAFE_FREE(but->dragpoin); + WM_drag_data_free(but->dragtype, but->dragpoin); but->dragflag &= ~UI_BUT_DRAGPOIN_FREE; } but->dragpoin = (void *)ptr; @@ -6118,7 +6143,7 @@ void UI_but_drag_set_path(uiBut *but, const char *path, const bool use_free) { but->dragtype = WM_DRAG_PATH; if ((but->dragflag & UI_BUT_DRAGPOIN_FREE)) { - MEM_SAFE_FREE(but->dragpoin); + WM_drag_data_free(but->dragtype, but->dragpoin); but->dragflag &= ~UI_BUT_DRAGPOIN_FREE; } but->dragpoin = (void *)path; @@ -6131,7 +6156,7 @@ void UI_but_drag_set_name(uiBut *but, const char *name) { but->dragtype = WM_DRAG_NAME; if ((but->dragflag & UI_BUT_DRAGPOIN_FREE)) { - MEM_SAFE_FREE(but->dragpoin); + WM_drag_data_free(but->dragtype, but->dragpoin); but->dragflag &= ~UI_BUT_DRAGPOIN_FREE; } but->dragpoin = (void *)name; @@ -6149,7 +6174,7 @@ void UI_but_drag_set_image( but->dragtype = WM_DRAG_PATH; ui_def_but_icon(but, icon, 0); /* no flag UI_HAS_ICON, so icon doesn't draw in button */ if ((but->dragflag & UI_BUT_DRAGPOIN_FREE)) { - MEM_SAFE_FREE(but->dragpoin); + WM_drag_data_free(but->dragtype, but->dragpoin); but->dragflag &= ~UI_BUT_DRAGPOIN_FREE; } but->dragpoin = (void *)path; diff --git a/source/blender/editors/interface/interface_handlers.c b/source/blender/editors/interface/interface_handlers.c index bcb79743b12..f39ad4c4ed5 100644 --- a/source/blender/editors/interface/interface_handlers.c +++ b/source/blender/editors/interface/interface_handlers.c @@ -1987,6 +1987,8 @@ static bool ui_but_drag_init(bContext *C, else { wmDrag *drag = WM_event_start_drag( C, but->icon, but->dragtype, but->dragpoin, ui_but_value_get(but), WM_DRAG_NOP); + /* wmDrag has ownership over dragpoin now, stop messing with it. */ + but->dragpoin = NULL; if (but->imb) { WM_event_drag_image(drag, @@ -2259,10 +2261,11 @@ static void ui_but_drop(bContext *C, const wmEvent *event, uiBut *but, uiHandleB ListBase *drags = event->customdata; /* drop event type has listbase customdata by default */ LISTBASE_FOREACH (wmDrag *, wmd, drags) { + /* TODO asset dropping. */ if (wmd->type == WM_DRAG_ID) { /* align these types with UI_but_active_drop_name */ if (ELEM(but->type, UI_BTYPE_TEXT, UI_BTYPE_SEARCH_MENU)) { - ID *id = WM_drag_ID(wmd, 0); + ID *id = WM_drag_get_local_ID(wmd, 0); button_activate_state(C, but, BUTTON_STATE_TEXT_EDITING); diff --git a/source/blender/editors/space_console/space_console.c b/source/blender/editors/space_console/space_console.c index a54faa41122..9b8e9e0e871 100644 --- a/source/blender/editors/space_console/space_console.c +++ b/source/blender/editors/space_console/space_console.c @@ -164,12 +164,12 @@ static bool id_drop_poll(bContext *UNUSED(C), const wmEvent *UNUSED(event), const char **UNUSED(tooltip)) { - return WM_drag_ID(drag, 0) != NULL; + return WM_drag_get_local_ID(drag, 0) != NULL; } static void id_drop_copy(wmDrag *drag, wmDropBox *drop) { - ID *id = WM_drag_ID(drag, 0); + ID *id = WM_drag_get_local_ID(drag, 0); /* copy drag path to properties */ char *text = RNA_path_full_ID_py(G_MAIN, id); diff --git a/source/blender/editors/space_node/space_node.c b/source/blender/editors/space_node/space_node.c index afc1a963f4f..ad7632377a3 100644 --- a/source/blender/editors/space_node/space_node.c +++ b/source/blender/editors/space_node/space_node.c @@ -645,7 +645,7 @@ static bool node_ima_drop_poll(bContext *UNUSED(C), /* rule might not work? */ return (ELEM(drag->icon, 0, ICON_FILE_IMAGE, ICON_FILE_MOVIE)); } - return WM_drag_ID(drag, ID_IM) != NULL; + return WM_drag_get_local_ID(drag, ID_IM) != NULL; } static bool node_mask_drop_poll(bContext *UNUSED(C), @@ -653,19 +653,19 @@ static bool node_mask_drop_poll(bContext *UNUSED(C), const wmEvent *UNUSED(event), const char **UNUSED(r_tooltip)) { - return WM_drag_ID(drag, ID_MSK) != NULL; + return WM_drag_get_local_ID(drag, ID_MSK) != NULL; } static void node_id_drop_copy(wmDrag *drag, wmDropBox *drop) { - ID *id = WM_drag_ID(drag, 0); + ID *id = WM_drag_get_local_ID(drag, 0); RNA_string_set(drop->ptr, "name", id->name + 2); } static void node_id_path_drop_copy(wmDrag *drag, wmDropBox *drop) { - ID *id = WM_drag_ID(drag, 0); + ID *id = WM_drag_get_local_ID(drag, 0); if (id) { RNA_string_set(drop->ptr, "name", id->name + 2); diff --git a/source/blender/editors/space_outliner/outliner_dragdrop.c b/source/blender/editors/space_outliner/outliner_dragdrop.c index dcb8ef9c954..152bbc96281 100644 --- a/source/blender/editors/space_outliner/outliner_dragdrop.c +++ b/source/blender/editors/space_outliner/outliner_dragdrop.c @@ -333,7 +333,7 @@ static bool parent_drop_poll(bContext *C, ED_region_tag_redraw_no_rebuild(CTX_wm_region(C)); } - Object *potential_child = (Object *)WM_drag_ID(drag, ID_OB); + Object *potential_child = (Object *)WM_drag_get_local_ID(drag, ID_OB); if (!potential_child) { return false; } @@ -421,7 +421,7 @@ static int parent_drop_invoke(bContext *C, wmOperator *op, const wmEvent *event) } Object *par = (Object *)tselem->id; - Object *ob = (Object *)WM_drag_ID_from_event(event, ID_OB); + Object *ob = (Object *)WM_drag_get_local_ID_from_event(event, ID_OB); if (ELEM(NULL, ob, par)) { return OPERATOR_CANCELLED; @@ -473,7 +473,7 @@ static bool parent_clear_poll(bContext *C, } } - Object *ob = (Object *)WM_drag_ID(drag, ID_OB); + Object *ob = (Object *)WM_drag_get_local_ID(drag, ID_OB); if (!ob) { return false; } @@ -552,7 +552,7 @@ static bool scene_drop_poll(bContext *C, const char **UNUSED(r_tooltip)) { /* Ensure item under cursor is valid drop target */ - Object *ob = (Object *)WM_drag_ID(drag, ID_OB); + Object *ob = (Object *)WM_drag_get_local_ID(drag, ID_OB); return (ob && (outliner_ID_drop_find(C, event, ID_SCE) != NULL)); } @@ -560,7 +560,7 @@ static int scene_drop_invoke(bContext *C, wmOperator *UNUSED(op), const wmEvent { Main *bmain = CTX_data_main(C); Scene *scene = (Scene *)outliner_ID_drop_find(C, event, ID_SCE); - Object *ob = (Object *)WM_drag_ID_from_event(event, ID_OB); + Object *ob = (Object *)WM_drag_get_local_ID_from_event(event, ID_OB); if (ELEM(NULL, ob, scene) || ID_IS_LINKED(scene)) { return OPERATOR_CANCELLED; @@ -620,7 +620,7 @@ static bool material_drop_poll(bContext *C, const char **UNUSED(r_tooltip)) { /* Ensure item under cursor is valid drop target */ - Material *ma = (Material *)WM_drag_ID(drag, ID_MA); + Material *ma = (Material *)WM_drag_get_local_ID(drag, ID_MA); return (ma && (outliner_ID_drop_find(C, event, ID_OB) != NULL)); } @@ -628,7 +628,7 @@ static int material_drop_invoke(bContext *C, wmOperator *UNUSED(op), const wmEve { Main *bmain = CTX_data_main(C); Object *ob = (Object *)outliner_ID_drop_find(C, event, ID_OB); - Material *ma = (Material *)WM_drag_ID_from_event(event, ID_MA); + Material *ma = (Material *)WM_drag_get_local_ID_from_event(event, ID_MA); if (ELEM(NULL, ob, ma)) { return OPERATOR_CANCELLED; @@ -1461,14 +1461,14 @@ static int outliner_item_drag_drop_invoke(bContext *C, parent = scene->master_collection; } - WM_drag_add_ID(drag, id, &parent->id); + WM_drag_add_local_ID(drag, id, &parent->id); } BLI_freelistN(&selected.selected_array); } else { /* Add single ID. */ - WM_drag_add_ID(drag, data.drag_id, data.drag_parent); + WM_drag_add_local_ID(drag, data.drag_id, data.drag_parent); } ED_outliner_select_sync_from_outliner(C, space_outliner); diff --git a/source/blender/editors/space_text/space_text.c b/source/blender/editors/space_text/space_text.c index bb71a9b11be..0f5ac5abe1d 100644 --- a/source/blender/editors/space_text/space_text.c +++ b/source/blender/editors/space_text/space_text.c @@ -357,7 +357,7 @@ static bool text_drop_paste_poll(bContext *UNUSED(C), static void text_drop_paste(wmDrag *drag, wmDropBox *drop) { char *text; - ID *id = WM_drag_ID(drag, 0); + ID *id = WM_drag_get_local_ID(drag, 0); /* copy drag path to properties */ text = RNA_path_full_ID_py(G_MAIN, id); diff --git a/source/blender/editors/space_view3d/space_view3d.c b/source/blender/editors/space_view3d/space_view3d.c index 9f31e7a411d..3761f4ad7c6 100644 --- a/source/blender/editors/space_view3d/space_view3d.c +++ b/source/blender/editors/space_view3d/space_view3d.c @@ -461,6 +461,12 @@ static void view3d_main_region_exit(wmWindowManager *wm, ARegion *region) ED_view3d_stop_render_preview(wm, region); } +static bool view3d_drop_in_main_region_poll(bContext *C, const wmEvent *event) +{ + ScrArea *area = CTX_wm_area(C); + return ED_region_overlap_isect_any_xy(area, &event->x) == false; +} + static ID *view3d_drop_id_in_main_region_poll_id(bContext *C, wmDrag *drag, const wmEvent *event, @@ -470,7 +476,7 @@ static ID *view3d_drop_id_in_main_region_poll_id(bContext *C, if (ED_region_overlap_isect_any_xy(area, &event->x)) { return NULL; } - return WM_drag_ID(drag, id_type); + return view3d_drop_in_main_region_poll(C, event) ? WM_drag_get_local_ID(drag, id_type) : NULL; } static bool view3d_drop_id_in_main_region_poll(bContext *C, @@ -478,7 +484,11 @@ static bool view3d_drop_id_in_main_region_poll(bContext *C, const wmEvent *event, ID_Type id_type) { - return (view3d_drop_id_in_main_region_poll_id(C, drag, event, id_type) != NULL); + if (!view3d_drop_in_main_region_poll(C, event)) { + return false; + } + + return WM_drag_get_local_ID(drag, id_type) || WM_drag_get_asset_data(drag, id_type); } static bool view3d_ob_drop_poll(bContext *C, @@ -533,7 +543,7 @@ static bool view3d_ima_drop_poll(bContext *C, return (ELEM(drag->icon, 0, ICON_FILE_IMAGE, ICON_FILE_MOVIE)); } - return WM_drag_ID(drag, ID_IM) != NULL; + return WM_drag_get_local_ID(drag, ID_IM) || WM_drag_get_asset_data(drag, ID_IM); } static bool view3d_ima_bg_is_camera_view(bContext *C) @@ -596,14 +606,14 @@ static bool view3d_volume_drop_poll(bContext *UNUSED(C), static void view3d_ob_drop_copy(wmDrag *drag, wmDropBox *drop) { - ID *id = WM_drag_ID(drag, ID_OB); + ID *id = WM_drag_get_local_ID_or_import_from_asset(drag, ID_OB); RNA_string_set(drop->ptr, "name", id->name + 2); } static void view3d_collection_drop_copy(wmDrag *drag, wmDropBox *drop) { - ID *id = WM_drag_ID(drag, ID_GR); + ID *id = WM_drag_get_local_ID_or_import_from_asset(drag, ID_GR); drop->opcontext = WM_OP_EXEC_DEFAULT; RNA_string_set(drop->ptr, "name", id->name + 2); @@ -611,14 +621,14 @@ static void view3d_collection_drop_copy(wmDrag *drag, wmDropBox *drop) static void view3d_id_drop_copy(wmDrag *drag, wmDropBox *drop) { - ID *id = WM_drag_ID(drag, 0); + ID *id = WM_drag_get_local_ID_or_import_from_asset(drag, 0); RNA_string_set(drop->ptr, "name", id->name + 2); } static void view3d_id_drop_copy_with_type(wmDrag *drag, wmDropBox *drop) { - ID *id = WM_drag_ID(drag, 0); + ID *id = WM_drag_get_local_ID(drag, 0); RNA_string_set(drop->ptr, "name", id->name + 2); RNA_enum_set(drop->ptr, "type", GS(id->name)); @@ -626,7 +636,7 @@ static void view3d_id_drop_copy_with_type(wmDrag *drag, wmDropBox *drop) static void view3d_id_path_drop_copy(wmDrag *drag, wmDropBox *drop) { - ID *id = WM_drag_ID(drag, 0); + ID *id = WM_drag_get_local_ID_or_import_from_asset(drag, 0); if (id) { RNA_string_set(drop->ptr, "name", id->name + 2); -- cgit v1.2.3 From e413c80371c1714d80262034d0e83b4e10e6cbe5 Mon Sep 17 00:00:00 2001 From: Julian Eisel Date: Mon, 14 Dec 2020 13:39:41 +0100 Subject: Asset System: Support custom asset library paths through Preferences One of the core design aspects of the Asset Browser is that users can "mount" custom asset libraries via the Preferences. Currently an asset library is just a directory with one or more .blend files in it. We could easily support a single .blend file as asset library as well (rather than a directory). It's just disabled currently. Note that in earlier designs, asset libraries were called repositories. Idea is simple: In Preferences > File Paths, you can create custom libraries, by setting a name and selecting a path. The name is ensured to be unique. If the name or path are empty, the Asset Browser will not show it in the list of available asset libraries. The library path is not checked for validity, the Asset Browser will allow selecting invalid libraries, but show a message instead of the file list, to help the user understand what's going on. Of course the actual Asset Browser UI is not part of this commit, it's in one of the following ones. {F9497950} Part of the first Asset Browser milestone. Check the #asset_browser_milestone_1 project milestone on developer.blender.org. Differential Revision: https://developer.blender.org/D9722 Reviewed by: Brecht Van Lommel, Hans Goudey --- .../blender/editors/interface/interface_handlers.c | 6 ++- source/blender/editors/space_buttons/buttons_ops.c | 2 +- .../blender/editors/space_userpref/userpref_ops.c | 61 ++++++++++++++++++++++ 3 files changed, 67 insertions(+), 2 deletions(-) (limited to 'source/blender/editors') diff --git a/source/blender/editors/interface/interface_handlers.c b/source/blender/editors/interface/interface_handlers.c index f39ad4c4ed5..72ed2cc0933 100644 --- a/source/blender/editors/interface/interface_handlers.c +++ b/source/blender/editors/interface/interface_handlers.c @@ -626,7 +626,11 @@ static bool ui_rna_is_userdef(PointerRNA *ptr, PropertyRNA *prop) if (base == NULL) { base = ptr->type; } - if (ELEM(base, &RNA_AddonPreferences, &RNA_KeyConfigPreferences, &RNA_KeyMapItem)) { + if (ELEM(base, + &RNA_AddonPreferences, + &RNA_KeyConfigPreferences, + &RNA_KeyMapItem, + &RNA_UserAssetLibrary)) { tag = true; } } diff --git a/source/blender/editors/space_buttons/buttons_ops.c b/source/blender/editors/space_buttons/buttons_ops.c index 8bdc2ed993f..8f57abf83ae 100644 --- a/source/blender/editors/space_buttons/buttons_ops.c +++ b/source/blender/editors/space_buttons/buttons_ops.c @@ -338,7 +338,7 @@ static int file_browse_invoke(bContext *C, wmOperator *op, const wmEvent *event) is_relative = BLI_path_is_rel(str); } - if (UNLIKELY(ptr.data == &U)) { + if (UNLIKELY(ptr.data == &U || is_userdef)) { is_relative = false; } diff --git a/source/blender/editors/space_userpref/userpref_ops.c b/source/blender/editors/space_userpref/userpref_ops.c index d823530fd89..9cc8cc6ddaa 100644 --- a/source/blender/editors/space_userpref/userpref_ops.c +++ b/source/blender/editors/space_userpref/userpref_ops.c @@ -30,6 +30,7 @@ #include "BKE_context.h" #include "BKE_global.h" #include "BKE_main.h" +#include "BKE_preferences.h" #include "BKE_report.h" #include "RNA_access.h" @@ -133,9 +134,69 @@ static void PREFERENCES_OT_autoexec_path_remove(wmOperatorType *ot) /** \} */ +/* -------------------------------------------------------------------- */ +/** \name Add Asset Library Operator + * \{ */ + +static int preferences_asset_library_add_exec(bContext *UNUSED(C), wmOperator *UNUSED(op)) +{ + BKE_preferences_asset_library_add(&U, NULL, NULL); + U.runtime.is_dirty = true; + return OPERATOR_FINISHED; +} + +static void PREFERENCES_OT_asset_library_add(wmOperatorType *ot) +{ + ot->name = "Add Asset Library"; + ot->idname = "PREFERENCES_OT_asset_library_add"; + ot->description = + "Add a path to a .blend file to be used by the Asset Browser as source of assets"; + + ot->exec = preferences_asset_library_add_exec; + + ot->flag = OPTYPE_INTERNAL; +} + +/** \} */ + +/* -------------------------------------------------------------------- */ +/** \name Remove Asset Library Operator + * \{ */ + +static int preferences_asset_library_remove_exec(bContext *UNUSED(C), wmOperator *op) +{ + const int index = RNA_int_get(op->ptr, "index"); + bUserAssetLibrary *library = BLI_findlink(&U.asset_libraries, index); + if (library) { + BKE_preferences_asset_library_remove(&U, library); + U.runtime.is_dirty = true; + } + return OPERATOR_FINISHED; +} + +static void PREFERENCES_OT_asset_library_remove(wmOperatorType *ot) +{ + ot->name = "Remove Asset Library"; + ot->idname = "PREFERENCES_OT_asset_library_remove"; + ot->description = + "Remove a path to a .blend file, so the Asset Browser will not attempt to show it anymore"; + + ot->exec = preferences_asset_library_remove_exec; + + ot->flag = OPTYPE_INTERNAL; + + RNA_def_int(ot->srna, "index", 0, 0, INT_MAX, "Index", "", 0, 1000); +} + +/** \} */ + void ED_operatortypes_userpref(void) { WM_operatortype_append(PREFERENCES_OT_reset_default_theme); + WM_operatortype_append(PREFERENCES_OT_autoexec_path_add); WM_operatortype_append(PREFERENCES_OT_autoexec_path_remove); + + WM_operatortype_append(PREFERENCES_OT_asset_library_add); + WM_operatortype_append(PREFERENCES_OT_asset_library_remove); } -- cgit v1.2.3 From 70474e1a7cc45a1b1cc08d39b3e472c88c8d3225 Mon Sep 17 00:00:00 2001 From: Julian Eisel Date: Mon, 14 Dec 2020 13:50:36 +0100 Subject: Asset System: Prepare File Browser backend for the Asset Browser The Asset Browser will be a sub-editor of the File Browser. This prepares the File Browser code for that. **File-Lists** * Support loading assets with metadata read from external files into the file-list. * New main based file-list type, for the "Current File" asset library. * Refresh file-list when switching between browse modes or asset libraries. * Support empty file-lists (asset library with no assets). * Store file previews as icons, so scripts can reference them via icon-id. See previous commit. **Space Data** * Introduce "browse mode" to differeniate between file and asset browsing. * Add `FileAssetSelectParams` to `SpaceFile`, with `FileSelectParams` as base. Makes sure data is separated between asset and file browsing when switching between them. The active params can be obtained through `ED_fileselect_get_active_params()`. * `FileAssetSelectParams` stores the currently visible asset library ID. * Introduce file history abstraction so file and asset browsing can keep a separate history (previous and next directories). **General** * Option to only show asset data-blocks while file browsing (not exposed here). * Add "active_file" context member, so scripts can get and display info about the active file. * Add "active_id" context member, so `ED_OT_lib_id_load_custom_preview` can set a custom ID preview. (Only for "Current File" asset library) * Expose some of `FileDirEntry` in RNA as (non-editable). That way scripts can obtain name, preview icon and asset-data. Part of the first Asset Browser milestone. Check the #asset_browser_milestone_1 project milestone on developer.blender.org. Differential Revision: https://developer.blender.org/D9724 Reviewed by: Bastien Montagne --- source/blender/editors/include/ED_fileselect.h | 7 +- source/blender/editors/space_file/file_intern.h | 1 + source/blender/editors/space_file/file_ops.c | 9 +- source/blender/editors/space_file/filelist.c | 655 ++++++++++++++++++------ source/blender/editors/space_file/filelist.h | 19 +- source/blender/editors/space_file/filesel.c | 188 +++++-- source/blender/editors/space_file/space_file.c | 139 +++-- 7 files changed, 789 insertions(+), 229 deletions(-) (limited to 'source/blender/editors') diff --git a/source/blender/editors/include/ED_fileselect.h b/source/blender/editors/include/ED_fileselect.h index a5a8df916d6..3288cf11cb0 100644 --- a/source/blender/editors/include/ED_fileselect.h +++ b/source/blender/editors/include/ED_fileselect.h @@ -29,6 +29,7 @@ extern "C" { struct ARegion; struct FileSelectParams; +struct FileAssetSelectParams; struct Scene; struct ScrArea; struct SpaceFile; @@ -103,14 +104,14 @@ struct rcti; struct FileSelectParams *ED_fileselect_ensure_active_params(struct SpaceFile *sfile); struct FileSelectParams *ED_fileselect_get_active_params(const struct SpaceFile *sfile); +struct FileSelectParams *ED_fileselect_get_file_params(const struct SpaceFile *sfile); +struct FileAssetSelectParams *ED_fileselect_get_asset_params(const struct SpaceFile *sfile); void ED_fileselect_set_params_from_userdef(struct SpaceFile *sfile); void ED_fileselect_params_to_userdef(struct SpaceFile *sfile, const int temp_win_size[], const bool is_maximized); -void ED_fileselect_reset_params(struct SpaceFile *sfile); - void ED_fileselect_init_layout(struct SpaceFile *sfile, struct ARegion *region); FileLayout *ED_fileselect_get_layout(struct SpaceFile *sfile, struct ARegion *region); @@ -142,6 +143,8 @@ void ED_fileselect_exit(struct wmWindowManager *wm, struct Scene *owner_scene, struct SpaceFile *sfile); +bool ED_fileselect_is_asset_browser(const struct SpaceFile *sfile); + void ED_fileselect_window_params_get(const struct wmWindow *win, int win_size[2], bool *is_maximized); diff --git a/source/blender/editors/space_file/file_intern.h b/source/blender/editors/space_file/file_intern.h index b459c02d9e5..a0e02681e0e 100644 --- a/source/blender/editors/space_file/file_intern.h +++ b/source/blender/editors/space_file/file_intern.h @@ -90,6 +90,7 @@ void file_sfile_to_operator(struct Main *bmain, struct wmOperator *op, struct Sp void file_operator_to_sfile(struct Main *bmain, struct SpaceFile *sfile, struct wmOperator *op); /* filesel.c */ +void fileselect_refresh_params(struct SpaceFile *sfile); void fileselect_file_set(SpaceFile *sfile, const int index); bool file_attribute_column_type_enabled(const FileSelectParams *params, FileAttributeColumnType column); diff --git a/source/blender/editors/space_file/file_ops.c b/source/blender/editors/space_file/file_ops.c index b98348307f3..8af84f65ced 100644 --- a/source/blender/editors/space_file/file_ops.c +++ b/source/blender/editors/space_file/file_ops.c @@ -930,6 +930,7 @@ void FILE_OT_select_all(wmOperatorType *ot) /* Note we could get rid of this one, but it's used by some addon so... * Does not hurt keeping it around for now. */ +/* TODO disallow bookmark editing in assets mode? */ static int bookmark_select_exec(bContext *C, wmOperator *op) { Main *bmain = CTX_data_main(C); @@ -1836,10 +1837,6 @@ static int file_previous_exec(bContext *C, wmOperator *UNUSED(op)) FileSelectParams *params = ED_fileselect_get_active_params(sfile); if (params) { - if (!sfile->folders_next) { - sfile->folders_next = folderlist_new(); - } - folderlist_pushdir(sfile->folders_next, params->dir); folderlist_popdir(sfile->folders_prev, params->dir); folderlist_pushdir(sfile->folders_next, params->dir); @@ -1874,10 +1871,6 @@ static int file_next_exec(bContext *C, wmOperator *UNUSED(unused)) SpaceFile *sfile = CTX_wm_space_file(C); FileSelectParams *params = ED_fileselect_get_active_params(sfile); if (params) { - if (!sfile->folders_next) { - sfile->folders_next = folderlist_new(); - } - folderlist_pushdir(sfile->folders_prev, params->dir); folderlist_popdir(sfile->folders_next, params->dir); diff --git a/source/blender/editors/space_file/filelist.c b/source/blender/editors/space_file/filelist.c index e87142a7096..5dc5f741ac3 100644 --- a/source/blender/editors/space_file/filelist.c +++ b/source/blender/editors/space_file/filelist.c @@ -53,13 +53,17 @@ # include "BLI_winstuff.h" #endif +#include "BKE_asset.h" #include "BKE_context.h" #include "BKE_global.h" #include "BKE_icons.h" #include "BKE_idtype.h" +#include "BKE_lib_id.h" #include "BKE_main.h" +#include "BKE_main_idmap.h" #include "BLO_readfile.h" +#include "DNA_asset_types.h" #include "DNA_space_types.h" #include "ED_datafiles.h" @@ -82,6 +86,8 @@ #include "filelist.h" +#define FILEDIR_NBR_ENTRIES_UNSET -1 + /* ----------------- FOLDERLIST (previous/next) -------------- */ typedef struct FolderList { @@ -89,12 +95,6 @@ typedef struct FolderList { char *foldername; } FolderList; -ListBase *folderlist_new(void) -{ - ListBase *p = MEM_callocN(sizeof(*p), __func__); - return p; -} - void folderlist_popdir(struct ListBase *folderlist, char *dir) { const char *prev_dir; @@ -117,6 +117,10 @@ void folderlist_popdir(struct ListBase *folderlist, char *dir) void folderlist_pushdir(ListBase *folderlist, const char *dir) { + if (!dir[0]) { + return; + } + struct FolderList *folder, *previous_folder; previous_folder = folderlist->last; @@ -153,7 +157,7 @@ int folderlist_clear_next(struct SpaceFile *sfile) struct FolderList *folder; /* if there is no folder_next there is nothing we can clear */ - if (!sfile->folders_next) { + if (BLI_listbase_is_empty(sfile->folders_next)) { return 0; } @@ -180,23 +184,79 @@ void folderlist_free(ListBase *folderlist) } } -ListBase *folderlist_duplicate(ListBase *folderlist) +static ListBase folderlist_duplicate(ListBase *folderlist) { + ListBase folderlistn = {NULL}; - if (folderlist) { - ListBase *folderlistn = MEM_callocN(sizeof(*folderlistn), __func__); - FolderList *folder; + BLI_duplicatelist(&folderlistn, folderlist); + + for (FolderList *folder = folderlistn.first; folder; folder = folder->next) { + folder->foldername = MEM_dupallocN(folder->foldername); + } + return folderlistn; +} - BLI_duplicatelist(folderlistn, folderlist); +/* ----------------- Folder-History (wraps/owns file list above) -------------- */ - for (folder = folderlistn->first; folder; folder = folder->next) { - folder->foldername = MEM_dupallocN(folder->foldername); +static FileFolderHistory *folder_history_find(const SpaceFile *sfile, eFileBrowse_Mode browse_mode) +{ + LISTBASE_FOREACH (FileFolderHistory *, history, &sfile->folder_histories) { + if (history->browse_mode == browse_mode) { + return history; } - return folderlistn; } + return NULL; } +void folder_history_list_ensure_for_active_browse_mode(SpaceFile *sfile) +{ + FileFolderHistory *history = folder_history_find(sfile, sfile->browse_mode); + + if (!history) { + history = MEM_callocN(sizeof(*history), __func__); + history->browse_mode = sfile->browse_mode; + BLI_addtail(&sfile->folder_histories, history); + } + + sfile->folders_next = &history->folders_next; + sfile->folders_prev = &history->folders_prev; +} + +static void folder_history_entry_free(SpaceFile *sfile, FileFolderHistory *history) +{ + if (sfile->folders_prev == &history->folders_prev) { + sfile->folders_prev = NULL; + } + if (sfile->folders_next == &history->folders_next) { + sfile->folders_next = NULL; + } + folderlist_free(&history->folders_prev); + folderlist_free(&history->folders_next); + BLI_freelinkN(&sfile->folder_histories, history); +} + +void folder_history_list_free(SpaceFile *sfile) +{ + LISTBASE_FOREACH_MUTABLE (FileFolderHistory *, history, &sfile->folder_histories) { + folder_history_entry_free(sfile, history); + } +} + +ListBase folder_history_list_duplicate(ListBase *listbase) +{ + ListBase histories = {NULL}; + + LISTBASE_FOREACH (FileFolderHistory *, history, listbase) { + FileFolderHistory *history_new = MEM_dupallocN(history); + history_new->folders_prev = folderlist_duplicate(&history->folders_prev); + history_new->folders_next = folderlist_duplicate(&history->folders_next); + BLI_addtail(&histories, history_new); + } + + return histories; +} + /* ------------------FILELIST------------------------ */ typedef struct FileListInternEntry { @@ -216,6 +276,24 @@ typedef struct FileListInternEntry { /** not strictly needed, but used during sorting, avoids to have to recompute it there... */ char *name; + /** + * This is data from the current main, represented by this file. It's crucial that this is + * updated correctly on undo, redo and file reading (without UI). The space is responsible to + * take care of that. + */ + struct { + /** When showing local IDs (FILE_MAIN, FILE_MAIN_ASSET), the ID this file entry represents. */ + ID *id; + + /* For the few file types that have the preview already in memory. For others, there's delayed + * preview reading from disk. Non-owning pointer. */ + PreviewImage *preview_image; + } local_data; + + /** When the file represents an asset read from another file, it is stored here. + * Owning pointer. */ + AssetMetaData *imported_asset_data; + /** Defined in BLI_fileops.h */ eFileAttributes attributes; BLI_stat_t st; @@ -267,7 +345,11 @@ typedef struct FileListEntryPreview { char path[FILE_MAX]; uint flags; int index; - ImBuf *img; + /* Some file types load the memory from runtime data, not from disk. We just wait until it's done + * generating (BKE_previewimg_is_finished()). */ + PreviewImage *in_memory_preview; + + int icon_id; } FileListEntryPreview; /* Dummy wrapper around FileListEntryPreview to ensure we do not access freed memory when freeing @@ -290,11 +372,16 @@ enum { FLF_HIDE_DOT = 1 << 1, FLF_HIDE_PARENT = 1 << 2, FLF_HIDE_LIB_DIR = 1 << 3, + FLF_ASSETS_ONLY = 1 << 4, }; typedef struct FileList { FileDirEntryArr filelist; + eFileSelectType type; + /* The library this list was created for. Stored here so we know when to re-read. */ + FileSelectAssetLibraryUID *asset_library; + short flags; short sort; @@ -324,10 +411,13 @@ typedef struct FileList { bool (*checkdirf)(struct FileList *, char *, const bool); /* Fill filelist (to be called by read job). */ - void (*read_jobf)(struct FileList *, const char *, short *, short *, float *, ThreadMutex *); + void (*read_jobf)( + Main *, struct FileList *, const char *, short *, short *, float *, ThreadMutex *); /* Filter an entry of current filelist. */ bool (*filterf)(struct FileListInternEntry *, const char *, FileListFilter *); + + short tags; /* FileListTags */ } FileList; /* FileList.flags */ @@ -340,6 +430,14 @@ enum { FL_SORT_INVERT = 1 << 5, }; +/* FileList.tags */ +enum FileListTags { + /** The file list has references to main data (IDs) and needs special care. */ + FILELIST_TAGS_USES_MAIN_DATA = (1 << 0), + /** The file list type is not thread-safe. */ + FILELIST_TAGS_NO_THREADS = (1 << 2), +}; + #define SPECIAL_IMG_SIZE 256 #define SPECIAL_IMG_ROWS 1 #define SPECIAL_IMG_COLS 7 @@ -357,24 +455,34 @@ enum { static ImBuf *gSpecialFileImages[SPECIAL_IMG_MAX]; -static void filelist_readjob_main(FileList *filelist, +static void filelist_readjob_main(Main *current_main, + FileList *filelist, const char *main_name, short *stop, short *do_update, float *progress, ThreadMutex *lock); -static void filelist_readjob_lib(FileList *filelist, +static void filelist_readjob_lib(Main *current_main, + FileList *filelist, const char *main_name, short *stop, short *do_update, float *progress, ThreadMutex *lock); -static void filelist_readjob_dir(FileList *filelist, +static void filelist_readjob_dir(Main *current_main, + FileList *filelist, const char *main_name, short *stop, short *do_update, float *progress, ThreadMutex *lock); +static void filelist_readjob_main_assets(Main *current_main, + FileList *filelist, + const char *main_name, + short *stop, + short *do_update, + float *progress, + ThreadMutex *lock); /* helper, could probably go in BKE actually? */ static int groupname_to_code(const char *group); @@ -694,6 +802,11 @@ static bool is_filtered_hidden(const char *filename, return true; } #endif + /* For data-blocks (but not the group directories), check the asset-only filter. */ + if (!(file->typeflag & FILE_TYPE_DIR) && (file->typeflag & FILE_TYPE_BLENDERLIB) && + (filter->flags & FLF_ASSETS_ONLY) && !(file->typeflag & FILE_TYPE_ASSET)) { + return true; + } return false; } @@ -737,51 +850,61 @@ static bool is_filtered_file(FileListInternEntry *file, return is_filtered; } -static bool is_filtered_lib(FileListInternEntry *file, const char *root, FileListFilter *filter) +static bool is_filtered_id_file(const FileListInternEntry *file, + const char *id_group, + const char *name, + const FileListFilter *filter) { - bool is_filtered; - char path[FILE_MAX_LIBEXTRA], dir[FILE_MAX_LIBEXTRA], *group, *name; - - BLI_join_dirfile(path, sizeof(path), root, file->relpath); - - if (BLO_library_path_explode(path, dir, &group, &name)) { - is_filtered = !is_filtered_hidden(file->relpath, filter, file); - if (is_filtered && !FILENAME_IS_CURRPAR(file->relpath)) { - /* We only check for types if some type are enabled in filtering. */ - if ((filter->filter || filter->filter_id) && (filter->flags & FLF_DO_FILTER)) { - if (file->typeflag & FILE_TYPE_DIR) { - if (file->typeflag & - (FILE_TYPE_BLENDERLIB | FILE_TYPE_BLENDER | FILE_TYPE_BLENDER_BACKUP)) { - if (!(filter->filter & (FILE_TYPE_BLENDER | FILE_TYPE_BLENDER_BACKUP))) { - is_filtered = false; - } - } - else { - if (!(filter->filter & FILE_TYPE_FOLDER)) { - is_filtered = false; - } + bool is_filtered = !is_filtered_hidden(file->relpath, filter, file); + if (is_filtered && !FILENAME_IS_CURRPAR(file->relpath)) { + /* We only check for types if some type are enabled in filtering. */ + if ((filter->filter || filter->filter_id) && (filter->flags & FLF_DO_FILTER)) { + if (file->typeflag & FILE_TYPE_DIR) { + if (file->typeflag & + (FILE_TYPE_BLENDERLIB | FILE_TYPE_BLENDER | FILE_TYPE_BLENDER_BACKUP)) { + if (!(filter->filter & (FILE_TYPE_BLENDER | FILE_TYPE_BLENDER_BACKUP))) { + is_filtered = false; } } - if (is_filtered && group) { - if (!name && (filter->flags & FLF_HIDE_LIB_DIR)) { + else { + if (!(filter->filter & FILE_TYPE_FOLDER)) { is_filtered = false; } - else { - uint64_t filter_id = groupname_to_filter_id(group); - if (!(filter_id & filter->filter_id)) { - is_filtered = false; - } - } } } - /* If there's a filter string, apply it as filter even if FLF_DO_FILTER is not set. */ - if (is_filtered && (filter->filter_search[0] != '\0')) { - if (fnmatch(filter->filter_search, file->relpath, FNM_CASEFOLD) != 0) { + if (is_filtered && id_group) { + if (!name && (filter->flags & FLF_HIDE_LIB_DIR)) { is_filtered = false; } + else { + uint64_t filter_id = groupname_to_filter_id(id_group); + if (!(filter_id & filter->filter_id)) { + is_filtered = false; + } + } + } + } + /* If there's a filter string, apply it as filter even if FLF_DO_FILTER is not set. */ + if (is_filtered && (filter->filter_search[0] != '\0')) { + if (fnmatch(filter->filter_search, file->relpath, FNM_CASEFOLD) != 0) { + is_filtered = false; } } } + + return is_filtered; +} + +static bool is_filtered_lib(FileListInternEntry *file, const char *root, FileListFilter *filter) +{ + bool is_filtered; + char path[FILE_MAX_LIBEXTRA], dir[FILE_MAX_LIBEXTRA], *group, *name; + + BLI_join_dirfile(path, sizeof(path), root, file->relpath); + + if (BLO_library_path_explode(path, dir, &group, &name)) { + is_filtered = is_filtered_id_file(file, group, name, filter); + } else { is_filtered = is_filtered_file(file, root, filter); } @@ -796,6 +919,14 @@ static bool is_filtered_main(FileListInternEntry *file, return !is_filtered_hidden(file->relpath, filter, file); } +static bool is_filtered_main_assets(FileListInternEntry *file, + const char *UNUSED(dir), + FileListFilter *filter) +{ + /* "Filtered" means *not* being filtered out... So return true if the file should be visible. */ + return is_filtered_id_file(file, file->relpath, file->name, filter); +} + static void filelist_filter_clear(FileList *filelist) { filelist->flags |= FL_NEED_FILTERING; @@ -807,7 +938,7 @@ void filelist_filter(FileList *filelist) const int num_files = filelist->filelist.nbr_entries; FileListInternEntry **filtered_tmp, *file; - if (filelist->filelist.nbr_entries == 0) { + if (ELEM(filelist->filelist.nbr_entries, FILEDIR_NBR_ENTRIES_UNSET, 0)) { return; } @@ -858,6 +989,7 @@ void filelist_setfilter_options(FileList *filelist, const bool hide_parent, const uint64_t filter, const uint64_t filter_id, + const bool filter_assets_only, const char *filter_glob, const char *filter_search) { @@ -875,6 +1007,10 @@ void filelist_setfilter_options(FileList *filelist, filelist->filter_data.flags ^= FLF_HIDE_PARENT; update = true; } + if (((filelist->filter_data.flags & FLF_ASSETS_ONLY) != 0) != (filter_assets_only != 0)) { + filelist->filter_data.flags ^= FLF_ASSETS_ONLY; + update = true; + } if (filelist->filter_data.filter != filter) { filelist->filter_data.filter = filter; update = true; @@ -903,6 +1039,50 @@ void filelist_setfilter_options(FileList *filelist, } } +/** + * Checks two libraries for equality. + * \return True if the libraries match. + */ +static bool filelist_compare_asset_libraries(const FileSelectAssetLibraryUID *library_a, + const FileSelectAssetLibraryUID *library_b) +{ + if (library_a->type != library_b->type) { + return false; + } + if (library_a->type == FILE_ASSET_LIBRARY_CUSTOM) { + return STREQ(library_a->custom_library_identifier, library_b->custom_library_identifier); + } + + return true; +} + +/** + * \param asset_library: May be NULL to unset the library. + */ +void filelist_setlibrary(FileList *filelist, const FileSelectAssetLibraryUID *asset_library) +{ + /* Unset if needed. */ + if (!asset_library) { + if (filelist->asset_library) { + MEM_SAFE_FREE(filelist->asset_library); + filelist->flags |= FL_FORCE_RESET; + } + return; + } + + if (!filelist->asset_library) { + filelist->asset_library = MEM_mallocN(sizeof(*filelist->asset_library), + "filelist asset library"); + *filelist->asset_library = *asset_library; + + filelist->flags |= FL_FORCE_RESET; + } + else if (!filelist_compare_asset_libraries(filelist->asset_library, asset_library)) { + *filelist->asset_library = *asset_library; + filelist->flags |= FL_FORCE_RESET; + } +} + /* ********** Icon/image helpers ********** */ void filelist_init_icons(void) @@ -960,7 +1140,12 @@ ImBuf *filelist_getimage(struct FileList *filelist, const int index) { FileDirEntry *file = filelist_geticon_get_file(filelist, index); - return file->image; + return file->preview_icon_id ? BKE_icon_imbuf_get_buffer(file->preview_icon_id) : NULL; +} + +ImBuf *filelist_file_getimage(const FileDirEntry *file) +{ + return file->preview_icon_id ? BKE_icon_imbuf_get_buffer(file->preview_icon_id) : NULL; } static ImBuf *filelist_geticon_image_ex(FileDirEntry *file) @@ -993,7 +1178,7 @@ static int filelist_geticon_ex(FileDirEntry *file, const bool is_main, const bool ignore_libdir) { - const int typeflag = file->typeflag; + const eFileSel_File_Types typeflag = file->typeflag; if ((typeflag & FILE_TYPE_DIR) && !(ignore_libdir && (typeflag & (FILE_TYPE_BLENDERLIB | FILE_TYPE_BLENDER)))) { @@ -1160,6 +1345,14 @@ static bool filelist_checkdir_main(struct FileList *filelist, char *r_dir, const return filelist_checkdir_lib(filelist, r_dir, do_change); } +static bool filelist_checkdir_main_assets(struct FileList *UNUSED(filelist), + char *UNUSED(r_dir), + const bool UNUSED(do_change)) +{ + /* Main is always valid. */ + return true; +} + static void filelist_entry_clear(FileDirEntry *entry) { if (entry->name) { @@ -1174,8 +1367,9 @@ static void filelist_entry_clear(FileDirEntry *entry) if (entry->redirection_path) { MEM_freeN(entry->redirection_path); } - if (entry->image) { - IMB_freeImBuf(entry->image); + if (entry->preview_icon_id) { + BKE_icon_delete(entry->preview_icon_id); + entry->preview_icon_id = 0; } /* For now, consider FileDirEntryRevision::poin as not owned here, * so no need to do anything about it */ @@ -1232,8 +1426,8 @@ static void filelist_direntryarr_free(FileDirEntryArr *array) #else BLI_assert(BLI_listbase_is_empty(&array->entries)); #endif - array->nbr_entries = 0; - array->nbr_entries_filtered = -1; + array->nbr_entries = FILEDIR_NBR_ENTRIES_UNSET; + array->nbr_entries_filtered = FILEDIR_NBR_ENTRIES_UNSET; array->entry_idx_start = -1; array->entry_idx_end = -1; } @@ -1249,6 +1443,10 @@ static void filelist_intern_entry_free(FileListInternEntry *entry) if (entry->name) { MEM_freeN(entry->name); } + /* If we own the asset-data (it was generated from external file data), free it. */ + if (entry->imported_asset_data) { + BKE_asset_metadata_free(&entry->imported_asset_data); + } MEM_freeN(entry); } @@ -1272,37 +1470,52 @@ static void filelist_cache_preview_runf(TaskPool *__restrict pool, void *taskdat FileListEntryPreview *preview = preview_taskdata->preview; ThumbSource source = 0; + bool done = false; // printf("%s: Start (%d)...\n", __func__, threadid); - // printf("%s: %d - %s - %p\n", __func__, preview->index, preview->path, preview->img); - BLI_assert(preview->flags & - (FILE_TYPE_IMAGE | FILE_TYPE_MOVIE | FILE_TYPE_FTFONT | FILE_TYPE_BLENDER | - FILE_TYPE_BLENDER_BACKUP | FILE_TYPE_BLENDERLIB)); - - if (preview->flags & FILE_TYPE_IMAGE) { - source = THB_SOURCE_IMAGE; - } - else if (preview->flags & - (FILE_TYPE_BLENDER | FILE_TYPE_BLENDER_BACKUP | FILE_TYPE_BLENDERLIB)) { - source = THB_SOURCE_BLEND; - } - else if (preview->flags & FILE_TYPE_MOVIE) { - source = THB_SOURCE_MOVIE; - } - else if (preview->flags & FILE_TYPE_FTFONT) { - source = THB_SOURCE_FONT; + if (preview->in_memory_preview) { + if (BKE_previewimg_is_finished(preview->in_memory_preview, ICON_SIZE_PREVIEW)) { + ImBuf *imbuf = BKE_previewimg_to_imbuf(preview->in_memory_preview, ICON_SIZE_PREVIEW); + preview->icon_id = BKE_icon_imbuf_create(imbuf); + done = true; + } } + else { + // printf("%s: %d - %s - %p\n", __func__, preview->index, preview->path, preview->img); + BLI_assert(preview->flags & + (FILE_TYPE_IMAGE | FILE_TYPE_MOVIE | FILE_TYPE_FTFONT | FILE_TYPE_BLENDER | + FILE_TYPE_BLENDER_BACKUP | FILE_TYPE_BLENDERLIB)); - IMB_thumb_path_lock(preview->path); - /* Always generate biggest preview size for now, it's simpler and avoids having to re-generate in - * case user switch to a bigger preview size. */ - preview->img = IMB_thumb_manage(preview->path, THB_LARGE, source); - IMB_thumb_path_unlock(preview->path); + if (preview->flags & FILE_TYPE_IMAGE) { + source = THB_SOURCE_IMAGE; + } + else if (preview->flags & + (FILE_TYPE_BLENDER | FILE_TYPE_BLENDER_BACKUP | FILE_TYPE_BLENDERLIB)) { + source = THB_SOURCE_BLEND; + } + else if (preview->flags & FILE_TYPE_MOVIE) { + source = THB_SOURCE_MOVIE; + } + else if (preview->flags & FILE_TYPE_FTFONT) { + source = THB_SOURCE_FONT; + } + + IMB_thumb_path_lock(preview->path); + /* Always generate biggest preview size for now, it's simpler and avoids having to re-generate + * in case user switch to a bigger preview size. */ + ImBuf *imbuf = IMB_thumb_manage(preview->path, THB_LARGE, source); + IMB_thumb_path_unlock(preview->path); + preview->icon_id = BKE_icon_imbuf_create(imbuf); - /* That way task freeing function won't free th preview, since it does not own it anymore. */ - atomic_cas_ptr((void **)&preview_taskdata->preview, preview, NULL); - BLI_thread_queue_push(cache->previews_done, preview); + done = true; + } + + if (done) { + /* That way task freeing function won't free th preview, since it does not own it anymore. */ + atomic_cas_ptr((void **)&preview_taskdata->preview, preview, NULL); + BLI_thread_queue_push(cache->previews_done, preview); + } // printf("%s: End (%d)...\n", __func__, threadid); } @@ -1315,8 +1528,8 @@ static void filelist_cache_preview_freef(TaskPool *__restrict UNUSED(pool), void /* preview_taskdata->preview is atomically set to NULL once preview has been processed and sent * to previews_done queue. */ if (preview != NULL) { - if (preview->img) { - IMB_freeImBuf(preview->img); + if (preview->icon_id) { + BKE_icon_delete(preview->icon_id); } MEM_freeN(preview); } @@ -1342,8 +1555,8 @@ static void filelist_cache_previews_clear(FileListEntryCache *cache) while ((preview = BLI_thread_queue_pop_timeout(cache->previews_done, 0))) { // printf("%s: DONE %d - %s - %p\n", __func__, preview->index, preview->path, // preview->img); - if (preview->img) { - IMB_freeImBuf(preview->img); + if (preview->icon_id) { + BKE_icon_delete(preview->icon_id); } MEM_freeN(preview); } @@ -1374,10 +1587,11 @@ static void filelist_cache_previews_push(FileList *filelist, FileDirEntry *entry BLI_assert(cache->flags & FLC_PREVIEWS_ACTIVE); - if (!entry->image && !(entry->flags & FILE_ENTRY_INVALID_PREVIEW) && + if (!entry->preview_icon_id && !(entry->flags & FILE_ENTRY_INVALID_PREVIEW) && (entry->typeflag & (FILE_TYPE_IMAGE | FILE_TYPE_MOVIE | FILE_TYPE_FTFONT | FILE_TYPE_BLENDER | FILE_TYPE_BLENDER_BACKUP | FILE_TYPE_BLENDERLIB))) { FileListEntryPreview *preview = MEM_mallocN(sizeof(*preview), __func__); + FileListInternEntry *intern_entry = filelist->filelist_intern.filtered[index]; if (entry->redirection_path) { BLI_strncpy(preview->path, entry->redirection_path, FILE_MAXDIR); @@ -1389,7 +1603,8 @@ static void filelist_cache_previews_push(FileList *filelist, FileDirEntry *entry preview->index = index; preview->flags = entry->typeflag; - preview->img = NULL; + preview->in_memory_preview = intern_entry->local_data.preview_image; + preview->icon_id = 0; // printf("%s: %d - %s - %p\n", __func__, preview->index, preview->path, preview->img); filelist_cache_preview_ensure_running(cache); @@ -1497,25 +1712,45 @@ FileList *filelist_new(short type) p->selection_state = BLI_ghash_new( BLI_ghashutil_uinthash_v4_p, BLI_ghashutil_uinthash_v4_cmp, __func__); + p->filelist.nbr_entries = FILEDIR_NBR_ENTRIES_UNSET; + filelist_settype(p, type); - switch (type) { + return p; +} + +void filelist_settype(FileList *filelist, short type) +{ + if (filelist->type == type) { + return; + } + + filelist->type = type; + filelist->tags = 0; + switch (filelist->type) { case FILE_MAIN: - p->checkdirf = filelist_checkdir_main; - p->read_jobf = filelist_readjob_main; - p->filterf = is_filtered_main; + filelist->checkdirf = filelist_checkdir_main; + filelist->read_jobf = filelist_readjob_main; + filelist->filterf = is_filtered_main; break; case FILE_LOADLIB: - p->checkdirf = filelist_checkdir_lib; - p->read_jobf = filelist_readjob_lib; - p->filterf = is_filtered_lib; + filelist->checkdirf = filelist_checkdir_lib; + filelist->read_jobf = filelist_readjob_lib; + filelist->filterf = is_filtered_lib; + break; + case FILE_MAIN_ASSET: + filelist->checkdirf = filelist_checkdir_main_assets; + filelist->read_jobf = filelist_readjob_main_assets; + filelist->filterf = is_filtered_main_assets; + filelist->tags |= FILELIST_TAGS_USES_MAIN_DATA | FILELIST_TAGS_NO_THREADS; break; default: - p->checkdirf = filelist_checkdir_dir; - p->read_jobf = filelist_readjob_dir; - p->filterf = is_filtered_file; + filelist->checkdirf = filelist_checkdir_dir; + filelist->read_jobf = filelist_readjob_dir; + filelist->filterf = is_filtered_file; break; } - return p; + + filelist->flags |= FL_FORCE_RESET; } void filelist_clear_ex(struct FileList *filelist, const bool do_cache, const bool do_selection) @@ -1560,6 +1795,8 @@ void filelist_free(struct FileList *filelist) filelist->selection_state = NULL; } + MEM_SAFE_FREE(filelist->asset_library); + memset(&filelist->filter_data, 0, sizeof(filelist->filter_data)); filelist->flags &= ~(FL_NEED_SORTING | FL_NEED_FILTERING); @@ -1580,7 +1817,7 @@ BlendHandle *filelist_lib(struct FileList *filelist) static const char *fileentry_uiname(const char *root, const char *relpath, - const int typeflag, + const eFileSel_File_Types typeflag, char *buff) { char *name = NULL; @@ -1624,11 +1861,12 @@ bool filelist_is_dir(struct FileList *filelist, const char *path) */ void filelist_setdir(struct FileList *filelist, char *r_dir) { + const bool allow_invalid = filelist->asset_library != NULL; BLI_assert(strlen(r_dir) < FILE_MAX_LIBEXTRA); BLI_path_normalize_dir(BKE_main_blendfile_path_from_global(), r_dir); - const bool is_valid_path = filelist->checkdirf(filelist, r_dir, true); - BLI_assert(is_valid_path); + const bool is_valid_path = filelist->checkdirf(filelist, r_dir, !allow_invalid); + BLI_assert(is_valid_path || allow_invalid); UNUSED_VARS_NDEBUG(is_valid_path); if (!STREQ(filelist->filelist.root, r_dir)) { @@ -1645,11 +1883,16 @@ void filelist_setrecursion(struct FileList *filelist, const int recursion_level) } } -bool filelist_force_reset(struct FileList *filelist) +bool filelist_needs_force_reset(FileList *filelist) { return (filelist->flags & FL_FORCE_RESET) != 0; } +void filelist_tag_force_reset(FileList *filelist) +{ + filelist->flags |= FL_FORCE_RESET; +} + bool filelist_is_ready(struct FileList *filelist) { return (filelist->flags & FL_IS_READY) != 0; @@ -1660,6 +1903,11 @@ bool filelist_pending(struct FileList *filelist) return (filelist->flags & FL_IS_PENDING) != 0; } +bool filelist_needs_reset_on_main_changes(const FileList *filelist) +{ + return (filelist->tags & FILELIST_TAGS_USES_MAIN_DATA) != 0; +} + /** * Limited version of full update done by space_file's file_refresh(), * to be used by operators and such. @@ -1668,7 +1916,7 @@ bool filelist_pending(struct FileList *filelist) */ int filelist_files_ensure(FileList *filelist) { - if (!filelist_force_reset(filelist) || !filelist_empty(filelist)) { + if (!filelist_needs_force_reset(filelist) || !filelist_needs_reading(filelist)) { filelist_sort(filelist); filelist_filter(filelist); } @@ -1701,6 +1949,17 @@ static FileDirEntry *filelist_file_create_entry(FileList *filelist, const int in if (entry->redirection_path) { ret->redirection_path = BLI_strdup(entry->redirection_path); } + ret->id = entry->local_data.id; + ret->asset_data = entry->imported_asset_data ? entry->imported_asset_data : NULL; + if (ret->id && (ret->asset_data == NULL)) { + ret->asset_data = ret->id->asset_data; + } + /* For some file types the preview is already available. */ + if (entry->local_data.preview_image && + BKE_previewimg_is_finished(entry->local_data.preview_image, ICON_SIZE_PREVIEW)) { + ImBuf *ibuf = BKE_previewimg_to_imbuf(entry->local_data.preview_image, ICON_SIZE_PREVIEW); + ret->preview_icon_id = BKE_icon_imbuf_create(ibuf); + } BLI_addtail(&cache->cached_entries, ret); return ret; } @@ -1770,7 +2029,7 @@ int filelist_file_findpath(struct FileList *filelist, const char *filename) { int fidx = -1; - if (filelist->filelist.nbr_entries_filtered < 0) { + if (filelist->filelist.nbr_entries_filtered == FILEDIR_NBR_ENTRIES_UNSET) { return fidx; } @@ -1788,9 +2047,17 @@ int filelist_file_findpath(struct FileList *filelist, const char *filename) return -1; } +/** + * Get the ID a file represents (if any). For #FILE_MAIN, #FILE_MAIN_ASSET. + */ +ID *filelist_file_get_id(const FileDirEntry *file) +{ + return file->id; +} + FileDirEntry *filelist_entry_find_uuid(struct FileList *filelist, const int uuid[4]) { - if (filelist->filelist.nbr_entries_filtered < 0) { + if (filelist->filelist.nbr_entries_filtered == FILEDIR_NBR_ENTRIES_UNSET) { return NULL; } @@ -2147,15 +2414,17 @@ bool filelist_cache_previews_update(FileList *filelist) // printf("%s: %d - %s - %p\n", __func__, preview->index, preview->path, preview->img); - if (preview->img) { + if (preview->icon_id) { /* Due to asynchronous process, a preview for a given image may be generated several times, * i.e. entry->image may already be set at this point. */ - if (entry && !entry->image) { - entry->image = preview->img; + if (entry && !entry->preview_icon_id) { + /* Move ownership over icon. */ + entry->preview_icon_id = preview->icon_id; + preview->icon_id = 0; changed = true; } else { - IMB_freeImBuf(preview->img); + BKE_icon_delete(preview->icon_id); } } else if (entry) { @@ -2313,9 +2582,9 @@ int ED_file_extension_icon(const char *path) } } -int filelist_empty(struct FileList *filelist) +int filelist_needs_reading(struct FileList *filelist) { - return (filelist->filelist.nbr_entries == 0); + return (filelist->filelist.nbr_entries == FILEDIR_NBR_ENTRIES_UNSET); } uint filelist_entry_select_set(const FileList *filelist, @@ -2564,8 +2833,8 @@ static int filelist_readjob_list_dir(const char *root, static int filelist_readjob_list_lib(const char *root, ListBase *entries, const bool skip_currpar) { FileListInternEntry *entry; - LinkNode *ln, *names; - int i, nnames, idcode = 0, nbr_entries = 0; + LinkNode *ln, *names = NULL, *datablock_infos = NULL; + int i, nitems, idcode = 0, nbr_entries = 0; char dir[FILE_MAX_LIBEXTRA], *group; bool ok; @@ -2587,11 +2856,11 @@ static int filelist_readjob_list_lib(const char *root, ListBase *entries, const * and freed in filelist_entry_free. */ if (group) { idcode = groupname_to_code(group); - names = BLO_blendhandle_get_datablock_names(libfiledata, idcode, &nnames); + datablock_infos = BLO_blendhandle_get_datablock_info(libfiledata, idcode, &nitems); } else { names = BLO_blendhandle_get_linkable_groups(libfiledata); - nnames = BLI_linklist_count(names); + nitems = BLI_linklist_count(names); } BLO_blendhandle_close(libfiledata); @@ -2604,12 +2873,18 @@ static int filelist_readjob_list_lib(const char *root, ListBase *entries, const nbr_entries++; } - for (i = 0, ln = names; i < nnames; i++, ln = ln->next) { - const char *blockname = ln->link; + for (i = 0, ln = (datablock_infos ? datablock_infos : names); i < nitems; i++, ln = ln->next) { + struct BLODataBlockInfo *info = datablock_infos ? ln->link : NULL; + const char *blockname = info ? info->name : ln->link; entry = MEM_callocN(sizeof(*entry), __func__); entry->relpath = BLI_strdup(blockname); entry->typeflag |= FILE_TYPE_BLENDERLIB; + if (info && info->asset_data) { + entry->typeflag |= FILE_TYPE_ASSET; + /* Moves ownership! */ + entry->imported_asset_data = info->asset_data; + } if (!(group && idcode)) { entry->typeflag |= FILE_TYPE_DIR; entry->blentype = groupname_to_code(blockname); @@ -2621,7 +2896,7 @@ static int filelist_readjob_list_lib(const char *root, ListBase *entries, const nbr_entries++; } - BLI_linklist_freeN(names); + BLI_linklist_freeN(datablock_infos ? datablock_infos : names); return nbr_entries; } @@ -2820,7 +3095,10 @@ static void filelist_readjob_do(const bool do_lib, // BLI_assert(filelist->filtered == NULL); BLI_assert(BLI_listbase_is_empty(&filelist->filelist.entries) && - (filelist->filelist.nbr_entries == 0)); + (filelist->filelist.nbr_entries == FILEDIR_NBR_ENTRIES_UNSET)); + + /* A valid, but empty directory from now. */ + filelist->filelist.nbr_entries = 0; todo_dirs = BLI_stack_new(sizeof(*td_dir), __func__); td_dir = BLI_stack_push_r(todo_dirs); @@ -2932,7 +3210,8 @@ static void filelist_readjob_do(const bool do_lib, BLI_stack_free(todo_dirs); } -static void filelist_readjob_dir(FileList *filelist, +static void filelist_readjob_dir(Main *UNUSED(current_main), + FileList *filelist, const char *main_name, short *stop, short *do_update, @@ -2942,7 +3221,8 @@ static void filelist_readjob_dir(FileList *filelist, filelist_readjob_do(false, filelist, main_name, stop, do_update, progress, lock); } -static void filelist_readjob_lib(FileList *filelist, +static void filelist_readjob_lib(Main *UNUSED(current_main), + FileList *filelist, const char *main_name, short *stop, short *do_update, @@ -2952,7 +3232,8 @@ static void filelist_readjob_lib(FileList *filelist, filelist_readjob_do(true, filelist, main_name, stop, do_update, progress, lock); } -static void filelist_readjob_main(FileList *filelist, +static void filelist_readjob_main(Main *current_main, + FileList *filelist, const char *main_name, short *stop, short *do_update, @@ -2960,12 +3241,67 @@ static void filelist_readjob_main(FileList *filelist, ThreadMutex *lock) { /* TODO! */ - filelist_readjob_dir(filelist, main_name, stop, do_update, progress, lock); + filelist_readjob_dir(current_main, filelist, main_name, stop, do_update, progress, lock); +} + +/** + * \warning Acts on main, so NOT thread-safe! + */ +static void filelist_readjob_main_assets(Main *current_main, + FileList *filelist, + const char *UNUSED(main_name), + short *UNUSED(stop), + short *do_update, + float *UNUSED(progress), + ThreadMutex *UNUSED(lock)) +{ + BLI_assert(BLI_listbase_is_empty(&filelist->filelist.entries) && + (filelist->filelist.nbr_entries == FILEDIR_NBR_ENTRIES_UNSET)); + + /* A valid, but empty directory from now. */ + filelist->filelist.nbr_entries = 0; + + FileListInternEntry *entry; + ListBase tmp_entries = {0}; + ID *id_iter; + int nbr_entries = 0; + + FOREACH_MAIN_ID_BEGIN (current_main, id_iter) { + if (!id_iter->asset_data) { + continue; + } + + const char *id_code_name = BKE_idtype_idcode_to_name(GS(id_iter->name)); + + entry = MEM_callocN(sizeof(*entry), __func__); + entry->relpath = BLI_strdup(id_code_name); + entry->name = BLI_strdup(id_iter->name + 2); + entry->typeflag |= FILE_TYPE_BLENDERLIB | FILE_TYPE_ASSET; + entry->blentype = GS(id_iter->name); + *((uint32_t *)entry->uuid) = atomic_add_and_fetch_uint32( + (uint32_t *)filelist->filelist_intern.curr_uuid, 1); + entry->local_data.preview_image = BKE_asset_metadata_preview_get_from_id(id_iter->asset_data, + id_iter); + entry->local_data.id = id_iter; + nbr_entries++; + BLI_addtail(&tmp_entries, entry); + } + FOREACH_MAIN_ID_END; + + if (nbr_entries) { + *do_update = true; + + BLI_movelisttolist(&filelist->filelist.entries, &tmp_entries); + filelist->filelist.nbr_entries += nbr_entries; + filelist->filelist.nbr_entries_filtered = filelist->filelist.entry_idx_start = + filelist->filelist.entry_idx_end = -1; + } } typedef struct FileListReadJob { ThreadMutex lock; char main_name[FILE_MAX]; + Main *current_main; struct FileList *filelist; /** XXX We may use a simpler struct here... just a linked list and root path? */ struct FileList *tmp_filelist; @@ -2985,7 +3321,7 @@ static void filelist_readjob_startjob(void *flrjv, short *stop, short *do_update flrj->tmp_filelist = MEM_dupallocN(flrj->filelist); BLI_listbase_clear(&flrj->tmp_filelist->filelist.entries); - flrj->tmp_filelist->filelist.nbr_entries = 0; + flrj->tmp_filelist->filelist.nbr_entries = FILEDIR_NBR_ENTRIES_UNSET; flrj->tmp_filelist->filelist_intern.filtered = NULL; BLI_listbase_clear(&flrj->tmp_filelist->filelist_intern.entries); @@ -2996,11 +3332,17 @@ static void filelist_readjob_startjob(void *flrjv, short *stop, short *do_update flrj->tmp_filelist->libfiledata = NULL; memset(&flrj->tmp_filelist->filelist_cache, 0, sizeof(flrj->tmp_filelist->filelist_cache)); flrj->tmp_filelist->selection_state = NULL; + flrj->tmp_filelist->asset_library = NULL; BLI_mutex_unlock(&flrj->lock); - flrj->tmp_filelist->read_jobf( - flrj->tmp_filelist, flrj->main_name, stop, do_update, progress, &flrj->lock); + flrj->tmp_filelist->read_jobf(flrj->current_main, + flrj->tmp_filelist, + flrj->main_name, + stop, + do_update, + progress, + &flrj->lock); } static void filelist_readjob_update(void *flrjv) @@ -3015,7 +3357,7 @@ static void filelist_readjob_update(void *flrjv) BLI_mutex_lock(&flrj->lock); - if (flrj->tmp_filelist->filelist.nbr_entries) { + if (flrj->tmp_filelist->filelist.nbr_entries > 0) { /* We just move everything out of 'thread context' into final list. */ new_nbr_entries = flrj->tmp_filelist->filelist.nbr_entries; BLI_movelisttolist(&new_entries, &flrj->tmp_filelist->filelist.entries); @@ -3033,7 +3375,7 @@ static void filelist_readjob_update(void *flrjv) /* if no new_nbr_entries, this is NOP */ BLI_movelisttolist(&fl_intern->entries, &new_entries); - flrj->filelist->filelist.nbr_entries = nbr_entries + new_nbr_entries; + flrj->filelist->filelist.nbr_entries = MAX2(nbr_entries, 0) + new_nbr_entries; } static void filelist_readjob_endjob(void *flrjv) @@ -3074,30 +3416,51 @@ void filelist_readjob_start(FileList *filelist, const bContext *C) wmJob *wm_job; FileListReadJob *flrj; + if (!filelist_is_dir(filelist, filelist->filelist.root)) { + return; + } + /* prepare job data */ flrj = MEM_callocN(sizeof(*flrj), __func__); flrj->filelist = filelist; + flrj->current_main = bmain; BLI_strncpy(flrj->main_name, BKE_main_blendfile_path(bmain), sizeof(flrj->main_name)); filelist->flags &= ~(FL_FORCE_RESET | FL_IS_READY); filelist->flags |= FL_IS_PENDING; + /* Init even for single threaded execution. Called functions use it. */ BLI_mutex_init(&flrj->lock); - /* setup job */ - wm_job = WM_jobs_get(CTX_wm_manager(C), - CTX_wm_window(C), - CTX_data_scene(C), - "Listing Dirs...", - WM_JOB_PROGRESS, - WM_JOB_TYPE_FILESEL_READDIR); - WM_jobs_customdata_set(wm_job, flrj, filelist_readjob_free); - WM_jobs_timer(wm_job, 0.01, NC_SPACE | ND_SPACE_FILE_LIST, NC_SPACE | ND_SPACE_FILE_LIST); - WM_jobs_callbacks( - wm_job, filelist_readjob_startjob, NULL, filelist_readjob_update, filelist_readjob_endjob); - - /* start the job */ - WM_jobs_start(CTX_wm_manager(C), wm_job); + if (filelist->tags & FILELIST_TAGS_NO_THREADS) { + short dummy_stop = false; + short dummy_do_update = false; + float dummy_progress = 0.0f; + + /* Single threaded execution. Just directly call the callbacks. */ + filelist_readjob_startjob(flrj, &dummy_stop, &dummy_do_update, &dummy_progress); + filelist_readjob_endjob(flrj); + filelist_readjob_free(flrj); + + WM_event_add_notifier(C, NC_SPACE | ND_SPACE_FILE_LIST, NULL); + return; + } + else { + /* setup job */ + wm_job = WM_jobs_get(CTX_wm_manager(C), + CTX_wm_window(C), + CTX_data_scene(C), + "Listing Dirs...", + WM_JOB_PROGRESS, + WM_JOB_TYPE_FILESEL_READDIR); + WM_jobs_customdata_set(wm_job, flrj, filelist_readjob_free); + WM_jobs_timer(wm_job, 0.01, NC_SPACE | ND_SPACE_FILE_LIST, NC_SPACE | ND_SPACE_FILE_LIST); + WM_jobs_callbacks( + wm_job, filelist_readjob_startjob, NULL, filelist_readjob_update, filelist_readjob_endjob); + + /* start the job */ + WM_jobs_start(CTX_wm_manager(C), wm_job); + } } void filelist_readjob_stop(wmWindowManager *wm, Scene *owner_scene) diff --git a/source/blender/editors/space_file/filelist.h b/source/blender/editors/space_file/filelist.h index 4b8cc052382..59bd5bb50d7 100644 --- a/source/blender/editors/space_file/filelist.h +++ b/source/blender/editors/space_file/filelist.h @@ -30,6 +30,7 @@ extern "C" { struct BlendHandle; struct FileList; struct FileSelection; +struct FileSelectAssetLibraryUID; struct wmWindowManager; struct FileDirEntry; @@ -46,14 +47,16 @@ typedef enum FileCheckType { CHECK_ALL = 3, } FileCheckType; -struct ListBase *folderlist_new(void); void folderlist_free(struct ListBase *folderlist); -struct ListBase *folderlist_duplicate(ListBase *folderlist); void folderlist_popdir(struct ListBase *folderlist, char *dir); void folderlist_pushdir(struct ListBase *folderlist, const char *dir); const char *folderlist_peeklastdir(struct ListBase *folderlist); int folderlist_clear_next(struct SpaceFile *sfile); +void folder_history_list_ensure_for_active_browse_mode(struct SpaceFile *sfile); +void folder_history_list_free(struct SpaceFile *sfile); +struct ListBase folder_history_list_duplicate(struct ListBase *listbase); + void filelist_setsorting(struct FileList *filelist, const short sort, bool invert_sort); void filelist_sort(struct FileList *filelist); @@ -63,17 +66,22 @@ void filelist_setfilter_options(struct FileList *filelist, const bool hide_parent, const uint64_t filter, const uint64_t filter_id, + const bool filter_assets_only, const char *filter_glob, const char *filter_search); void filelist_filter(struct FileList *filelist); +void filelist_setlibrary(struct FileList *filelist, + const struct FileSelectAssetLibraryUID *asset_library); void filelist_init_icons(void); void filelist_free_icons(void); struct ImBuf *filelist_getimage(struct FileList *filelist, const int index); +struct ImBuf *filelist_file_getimage(const FileDirEntry *file); struct ImBuf *filelist_geticon_image(struct FileList *filelist, const int index); int filelist_geticon(struct FileList *filelist, const int index, const bool is_main); struct FileList *filelist_new(short type); +void filelist_settype(struct FileList *filelist, short type); void filelist_clear(struct FileList *filelist); void filelist_clear_ex(struct FileList *filelist, const bool do_cache, const bool do_selection); void filelist_free(struct FileList *filelist); @@ -83,15 +91,18 @@ bool filelist_is_dir(struct FileList *filelist, const char *path); void filelist_setdir(struct FileList *filelist, char *r_dir); int filelist_files_ensure(struct FileList *filelist); -int filelist_empty(struct FileList *filelist); +int filelist_needs_reading(struct FileList *filelist); FileDirEntry *filelist_file(struct FileList *filelist, int index); int filelist_file_findpath(struct FileList *filelist, const char *file); +struct ID *filelist_file_get_id(const struct FileDirEntry *file); FileDirEntry *filelist_entry_find_uuid(struct FileList *filelist, const int uuid[4]); void filelist_file_cache_slidingwindow_set(struct FileList *filelist, size_t window_size); bool filelist_file_cache_block(struct FileList *filelist, const int index); -bool filelist_force_reset(struct FileList *filelist); +bool filelist_needs_force_reset(struct FileList *filelist); +void filelist_tag_force_reset(struct FileList *filelist); bool filelist_pending(struct FileList *filelist); +bool filelist_needs_reset_on_main_changes(const struct FileList *filelist); bool filelist_is_ready(struct FileList *filelist); unsigned int filelist_entry_select_set(const struct FileList *filelist, diff --git a/source/blender/editors/space_file/filesel.c b/source/blender/editors/space_file/filesel.c index 6e933e53a8f..2c66bd39e0a 100644 --- a/source/blender/editors/space_file/filesel.c +++ b/source/blender/editors/space_file/filesel.c @@ -56,7 +56,9 @@ #include "BKE_appdir.h" #include "BKE_context.h" +#include "BKE_idtype.h" #include "BKE_main.h" +#include "BKE_preferences.h" #include "BLF_api.h" @@ -77,14 +79,66 @@ #define VERTLIST_MAJORCOLUMN_WIDTH (25 * UI_UNIT_X) -FileSelectParams *ED_fileselect_get_active_params(const SpaceFile *sfile) +static void fileselect_initialize_params_common(SpaceFile *sfile, FileSelectParams *params) { - if (!sfile) { - /* Sometimes called in poll before space type was checked. */ - return NULL; + const char *blendfile_path = BKE_main_blendfile_path_from_global(); + + /* operator has no setting for this */ + params->active_file = -1; + + if (!params->dir[0]) { + if (blendfile_path[0] != '\0') { + BLI_split_dir_part(blendfile_path, params->dir, sizeof(params->dir)); + } + else { + const char *doc_path = BKE_appdir_folder_default(); + if (doc_path) { + BLI_strncpy(params->dir, doc_path, sizeof(params->dir)); + } + } } - return sfile->params; + folder_history_list_ensure_for_active_browse_mode(sfile); + folderlist_pushdir(sfile->folders_prev, params->dir); + + /* Switching thumbnails needs to recalc layout T28809. */ + if (sfile->layout) { + sfile->layout->dirty = true; + } +} + +static void fileselect_ensure_updated_asset_params(SpaceFile *sfile) +{ + BLI_assert(sfile->browse_mode == FILE_BROWSE_MODE_ASSETS); + BLI_assert(sfile->op == NULL); + + FileAssetSelectParams *asset_params = sfile->asset_params; + + if (!asset_params) { + asset_params = sfile->asset_params = MEM_callocN(sizeof(*asset_params), + "FileAssetSelectParams"); + asset_params->base_params.details_flags = U_default.file_space_data.details_flags; + asset_params->asset_library.type = FILE_ASSET_LIBRARY_LOCAL; + } + + FileSelectParams *base_params = &asset_params->base_params; + base_params->file[0] = '\0'; + base_params->filter_glob[0] = '\0'; + /* TODO this way of using filters to form categories is notably slower than specifying a + * "group" to read. That's because all types are read and filtering is applied afterwards. Would + * be nice if we could lazy-read individual groups. */ + base_params->flag |= U_default.file_space_data.flag | FILE_ASSETS_ONLY | FILE_FILTER; + base_params->flag &= ~FILE_DIRSEL_ONLY; + base_params->filter |= FILE_TYPE_BLENDERLIB; + base_params->filter_id = FILTER_ID_OB | FILTER_ID_GR; + base_params->display = FILE_IMGDISPLAY; + base_params->sort = FILE_SORT_ALPHA; + base_params->recursion_level = 1; + /* 'SMALL' size by default. More reasonable since this is typically used as regular editor, + * space is more of an issue here. */ + base_params->thumbnail_size = 96; + + fileselect_initialize_params_common(sfile, base_params); } /** @@ -92,6 +146,8 @@ FileSelectParams *ED_fileselect_get_active_params(const SpaceFile *sfile) * the previously used settings to be used here rather than overriding them */ static FileSelectParams *fileselect_ensure_updated_file_params(SpaceFile *sfile) { + BLI_assert(sfile->browse_mode == FILE_BROWSE_MODE_FILES); + FileSelectParams *params; wmOperator *op = sfile->op; @@ -297,42 +353,102 @@ static FileSelectParams *fileselect_ensure_updated_file_params(SpaceFile *sfile) params->filter_glob[0] = '\0'; } - /* operator has no setting for this */ - params->active_file = -1; + fileselect_initialize_params_common(sfile, params); - /* initialize the list with previous folders */ - if (!sfile->folders_prev) { - sfile->folders_prev = folderlist_new(); - } + return params; +} - if (!params->dir[0]) { - if (blendfile_path[0] != '\0') { - BLI_split_dir_part(blendfile_path, params->dir, sizeof(params->dir)); - } - else { - const char *doc_path = BKE_appdir_folder_default(); - if (doc_path) { - BLI_strncpy(params->dir, doc_path, sizeof(params->dir)); +/** + * If needed, create and return the file select parameters for the active browse mode. + */ +FileSelectParams *ED_fileselect_ensure_active_params(SpaceFile *sfile) +{ + switch ((eFileBrowse_Mode)sfile->browse_mode) { + case FILE_BROWSE_MODE_FILES: + if (!sfile->params) { + fileselect_ensure_updated_file_params(sfile); } - } + return sfile->params; + case FILE_BROWSE_MODE_ASSETS: + if (!sfile->asset_params) { + fileselect_ensure_updated_asset_params(sfile); + } + return &sfile->asset_params->base_params; } - folderlist_pushdir(sfile->folders_prev, params->dir); + BLI_assert(!"Invalid browse mode set in file space."); + return NULL; +} - /* Switching thumbnails needs to recalc layout T28809. */ - if (sfile->layout) { - sfile->layout->dirty = true; +/** + * Get the file select parameters for the active browse mode. + */ +FileSelectParams *ED_fileselect_get_active_params(const SpaceFile *sfile) +{ + if (!sfile) { + /* Sometimes called in poll before space type was checked. */ + return NULL; } - return params; + switch ((eFileBrowse_Mode)sfile->browse_mode) { + case FILE_BROWSE_MODE_FILES: + return sfile->params; + case FILE_BROWSE_MODE_ASSETS: + return (FileSelectParams *)sfile->asset_params; + } + + BLI_assert(!"Invalid browse mode set in file space."); + return NULL; } -FileSelectParams *ED_fileselect_ensure_active_params(SpaceFile *sfile) +FileSelectParams *ED_fileselect_get_file_params(const SpaceFile *sfile) { - if (!sfile->params) { - fileselect_ensure_updated_file_params(sfile); + return (sfile->browse_mode == FILE_BROWSE_MODE_FILES) ? sfile->params : NULL; +} + +FileAssetSelectParams *ED_fileselect_get_asset_params(const SpaceFile *sfile) +{ + return (sfile->browse_mode == FILE_BROWSE_MODE_ASSETS) ? sfile->asset_params : NULL; +} + +static void fileselect_refresh_asset_params(FileAssetSelectParams *asset_params) +{ + FileSelectAssetLibraryUID *library = &asset_params->asset_library; + FileSelectParams *base_params = &asset_params->base_params; + bUserAssetLibrary *user_library = NULL; + + /* Ensure valid repo, or fall-back to local one. */ + if (library->type == FILE_ASSET_LIBRARY_CUSTOM) { + user_library = BKE_preferences_asset_library_find_from_name( + &U, library->custom_library_identifier); + if (!user_library) { + library->type = FILE_ASSET_LIBRARY_LOCAL; + } + } + + switch (library->type) { + case FILE_ASSET_LIBRARY_LOCAL: + base_params->dir[0] = '\0'; + break; + case FILE_ASSET_LIBRARY_CUSTOM: + BLI_assert(user_library); + BLI_strncpy(base_params->dir, user_library->path, sizeof(base_params->dir)); + break; } - return sfile->params; + base_params->type = (library->type == FILE_ASSET_LIBRARY_LOCAL) ? FILE_MAIN_ASSET : FILE_LOADLIB; +} + +void fileselect_refresh_params(SpaceFile *sfile) +{ + FileAssetSelectParams *asset_params = ED_fileselect_get_asset_params(sfile); + if (asset_params) { + fileselect_refresh_asset_params(asset_params); + } +} + +bool ED_fileselect_is_asset_browser(const SpaceFile *sfile) +{ + return (sfile->browse_mode == FILE_BROWSE_MODE_ASSETS); } /* The subset of FileSelectParams.flag items we store into preferences. Note that FILE_SORT_ALPHA @@ -371,6 +487,8 @@ void ED_fileselect_set_params_from_userdef(SpaceFile *sfile) wmOperator *op = sfile->op; UserDef_FileSpaceData *sfile_udata = &U.file_space_data; + BLI_assert(sfile->browse_mode == FILE_BROWSE_MODE_FILES); + FileSelectParams *params = fileselect_ensure_updated_file_params(sfile); if (!op) { return; @@ -438,15 +556,6 @@ void ED_fileselect_params_to_userdef(SpaceFile *sfile, } } -void ED_fileselect_reset_params(SpaceFile *sfile) -{ - FileSelectParams *params = ED_fileselect_get_active_params(sfile); - params->type = FILE_UNIX; - params->flag = 0; - params->title[0] = '\0'; - params->active_file = -1; -} - /** * Sets FileSelectParams->file (name of selected file) */ @@ -1046,8 +1155,7 @@ void ED_fileselect_exit(wmWindowManager *wm, Scene *owner_scene, SpaceFile *sfil sfile->op = NULL; } - folderlist_free(sfile->folders_prev); - folderlist_free(sfile->folders_next); + folder_history_list_free(sfile); if (sfile->files) { ED_fileselect_clear(wm, owner_scene, sfile); diff --git a/source/blender/editors/space_file/space_file.c b/source/blender/editors/space_file/space_file.c index c72ca58abba..f1d72387791 100644 --- a/source/blender/editors/space_file/space_file.c +++ b/source/blender/editors/space_file/space_file.c @@ -35,6 +35,8 @@ #include "BKE_screen.h" #include "RNA_access.h" +#include "RNA_define.h" +#include "RNA_enum_types.h" #include "WM_api.h" #include "WM_message.h" @@ -149,22 +151,10 @@ static void file_free(SpaceLink *sl) sfile->files = NULL; } - if (sfile->folders_prev) { - folderlist_free(sfile->folders_prev); - MEM_freeN(sfile->folders_prev); - sfile->folders_prev = NULL; - } - - if (sfile->folders_next) { - folderlist_free(sfile->folders_next); - MEM_freeN(sfile->folders_next); - sfile->folders_next = NULL; - } + folder_history_list_free(sfile); - if (sfile->params) { - MEM_freeN(sfile->params); - sfile->params = NULL; - } + MEM_SAFE_FREE(sfile->params); + MEM_SAFE_FREE(sfile->asset_params); if (sfile->layout) { MEM_freeN(sfile->layout); @@ -205,19 +195,20 @@ static SpaceLink *file_duplicate(SpaceLink *sl) sfilen->previews_timer = NULL; sfilen->smoothscroll_timer = NULL; + FileSelectParams *active_params_old = ED_fileselect_get_active_params(sfileo); + if (active_params_old) { + sfilen->files = filelist_new(active_params_old->type); + filelist_setdir(sfilen->files, active_params_old->dir); + } + if (sfileo->params) { - sfilen->files = filelist_new(sfileo->params->type); sfilen->params = MEM_dupallocN(sfileo->params); - filelist_setdir(sfilen->files, sfilen->params->dir); } - - if (sfileo->folders_prev) { - sfilen->folders_prev = folderlist_duplicate(sfileo->folders_prev); + if (sfileo->asset_params) { + sfilen->asset_params = MEM_dupallocN(sfileo->asset_params); } - if (sfileo->folders_next) { - sfilen->folders_next = folderlist_duplicate(sfileo->folders_next); - } + sfilen->folder_histories = folder_history_list_duplicate(&sfileo->folder_histories); if (sfileo->layout) { sfilen->layout = MEM_dupallocN(sfileo->layout); @@ -265,24 +256,42 @@ static void file_ensure_valid_region_state(bContext *C, } } +/** + * Tag the space to recreate the file-list. + */ +static void file_tag_reset_list(ScrArea *area, SpaceFile *sfile) +{ + filelist_tag_force_reset(sfile->files); + ED_area_tag_refresh(area); +} + static void file_refresh(const bContext *C, ScrArea *area) { wmWindowManager *wm = CTX_wm_manager(C); wmWindow *win = CTX_wm_window(C); SpaceFile *sfile = CTX_wm_space_file(C); FileSelectParams *params = ED_fileselect_ensure_active_params(sfile); + FileAssetSelectParams *asset_params = ED_fileselect_get_asset_params(sfile); struct FSMenu *fsmenu = ED_fsmenu_get(); - if (!sfile->folders_prev) { - sfile->folders_prev = folderlist_new(); + fileselect_refresh_params(sfile); + folder_history_list_ensure_for_active_browse_mode(sfile); + + if (sfile->files && (sfile->tags & FILE_TAG_REBUILD_MAIN_FILES) && + filelist_needs_reset_on_main_changes(sfile->files)) { + filelist_tag_force_reset(sfile->files); } + sfile->tags &= ~FILE_TAG_REBUILD_MAIN_FILES; + if (!sfile->files) { sfile->files = filelist_new(params->type); params->highlight_file = -1; /* added this so it opens nicer (ton) */ } + filelist_settype(sfile->files, params->type); filelist_setdir(sfile->files, params->dir); filelist_setrecursion(sfile->files, params->recursion_level); filelist_setsorting(sfile->files, params->sort, params->flag & FILE_SORT_INVERT); + filelist_setlibrary(sfile->files, asset_params ? &asset_params->asset_library : NULL); filelist_setfilter_options( sfile->files, (params->flag & FILE_FILTER) != 0, @@ -290,6 +299,7 @@ static void file_refresh(const bContext *C, ScrArea *area) true, /* Just always hide parent, prefer to not add an extra user option for this. */ params->filter, params->filter_id, + (params->flag & FILE_ASSETS_ONLY) != 0, params->filter_glob, params->filter_search); @@ -300,12 +310,12 @@ static void file_refresh(const bContext *C, ScrArea *area) sfile->bookmarknr = fsmenu_get_active_indices(fsmenu, FS_CATEGORY_BOOKMARKS, params->dir); sfile->recentnr = fsmenu_get_active_indices(fsmenu, FS_CATEGORY_RECENT, params->dir); - if (filelist_force_reset(sfile->files)) { + if (filelist_needs_force_reset(sfile->files)) { filelist_readjob_stop(wm, CTX_data_scene(C)); filelist_clear(sfile->files); } - if (filelist_empty(sfile->files)) { + if (filelist_needs_reading(sfile->files)) { if (!filelist_pending(sfile->files)) { filelist_readjob_start(sfile->files, C); } @@ -365,6 +375,14 @@ static void file_listener(wmWindow *UNUSED(win), break; } break; + case NC_ASSET: { + if (sfile->files && filelist_needs_reset_on_main_changes(sfile->files)) { + /* Full refresh of the file list if local asset data was changed. Refreshing this view is + * cheap and users expect this to be updated immediately. */ + file_tag_reset_list(area, sfile); + } + break; + } } } @@ -442,6 +460,22 @@ static void file_main_region_message_subscribe(const struct bContext *UNUSED(C), } } +static bool file_main_region_needs_refresh_before_draw(SpaceFile *sfile) +{ + /* Needed, because filelist is not initialized on loading */ + if (!sfile->files || filelist_needs_reading(sfile->files)) { + return true; + } + + /* File reading tagged the space because main data changed that may require a filelist reset. */ + if (filelist_needs_reset_on_main_changes(sfile->files) && + (sfile->tags & FILE_TAG_REBUILD_MAIN_FILES)) { + return true; + } + + return false; +} + static void file_main_region_draw(const bContext *C, ARegion *region) { /* draw entirely, view changes should be handled here */ @@ -450,8 +484,7 @@ static void file_main_region_draw(const bContext *C, ARegion *region) View2D *v2d = ®ion->v2d; - /* Needed, because filelist is not initialized on loading */ - if (!sfile->files || filelist_empty(sfile->files)) { + if (file_main_region_needs_refresh_before_draw(sfile)) { file_refresh(C, NULL); } @@ -681,6 +714,52 @@ static void file_dropboxes(void) WM_dropbox_add(lb, "FILE_OT_filepath_drop", filepath_drop_poll, filepath_drop_copy); } +const char *file_context_dir[] = {"active_file", "active_id", NULL}; + +static int /*eContextResult*/ file_context(const bContext *C, + const char *member, + bContextDataResult *result) +{ + bScreen *screen = CTX_wm_screen(C); + SpaceFile *sfile = CTX_wm_space_file(C); + FileSelectParams *params = ED_fileselect_get_active_params(sfile); + + BLI_assert(!ED_area_is_global(CTX_wm_area(C))); + + if (CTX_data_dir(member)) { + CTX_data_dir_set(result, file_context_dir); + return CTX_RESULT_OK; + } + else if (CTX_data_equals(member, "active_file")) { + FileDirEntry *file = filelist_file(sfile->files, params->active_file); + CTX_data_pointer_set(result, &screen->id, &RNA_FileSelectEntry, file); + return CTX_RESULT_OK; + } + else if (CTX_data_equals(member, "active_id")) { + const FileDirEntry *file = filelist_file(sfile->files, params->active_file); + + ID *id = filelist_file_get_id(file); + if (id) { + CTX_data_id_pointer_set(result, id); + } + return CTX_RESULT_OK; + } + return CTX_RESULT_MEMBER_NOT_FOUND; +} + +static void file_id_remap(ScrArea *area, SpaceLink *sl, ID *UNUSED(old_id), ID *UNUSED(new_id)) +{ + SpaceFile *sfile = (SpaceFile *)sl; + + /* If the file shows main data (IDs), tag it for reset. */ + if (sfile->files && filelist_needs_reset_on_main_changes(sfile->files)) { + /* Full refresh of the file list if main data was changed, don't even attempt remap pointers. + * We could give file list types a id-remap callback, but it's probably not worth it. + * Refreshing local file lists is relatively cheap. */ + file_tag_reset_list(area, sfile); + } +} + /* only called once, from space/spacetypes.c */ void ED_spacetype_file(void) { @@ -700,6 +779,8 @@ void ED_spacetype_file(void) st->operatortypes = file_operatortypes; st->keymap = file_keymap; st->dropboxes = file_dropboxes; + st->context = file_context; + st->id_remap = file_id_remap; /* regions: main window */ art = MEM_callocN(sizeof(ARegionType), "spacetype file region"); -- cgit v1.2.3 From 2d6a69ae4e9905a19ac7228b97ed08fb4ea72e75 Mon Sep 17 00:00:00 2001 From: Julian Eisel Date: Mon, 14 Dec 2020 14:07:42 +0100 Subject: Asset System: New Asset Browser editor This introduces the User Interface part of the Asset Browser, based on the design in T54642. Additions: * New Asset Browser (internally a sub-editor of the File Browser). * Navigation region showing asset categories. * Main region showing the assets of the selected asset library with previews. The assets may be stored over multiple .blends in the directory that's "mounted" as asset library in the Preferences. They will all be shown in this list. * Header with an asset library dropdown, allowing to choose the active asset library to show. Options are the "Current File" as asset library and all custom libraries. * Display popover, filter popover and search box (partially dummies, see T82680). * Sidebar showing the metadata of the currently active file (name, preview, description and tags), which can be edited for assets in the "Current File" asset library. (For others it will reset on reload.) * The sidebar includes a button to load a custom preview image from a file. * Make asset files draggable (with preview image). * If a library with invalid path is selected, a message is drawn in the main region to help the user understand what's wrong. * Operators to add and remove asset tags. Exposed in the sidebar. * "Only Assets" option for Link/Append. * Internal utilities for asset UI scripts. For screenshots or demo videos, please see D9725. Or the 2.92 release notes. Note that there are many things to be tweaked and polished in the Asset Browser UI still. For example, the filter and display popovers are mostly dummies. See T82680. Part of the first Asset Browser milestone. Check the #asset_browser_milestone_1 project milestone on developer.blender.org. Differential Revision: https://developer.blender.org/D9725 Reviewed by: Brecht Van Lommel, Hans Goudey --- source/blender/editors/interface/interface_style.c | 8 +- source/blender/editors/space_file/file_draw.c | 186 +++++++++++++++++++-- source/blender/editors/space_file/file_intern.h | 3 + source/blender/editors/space_file/file_ops.c | 28 +++- source/blender/editors/space_file/file_utils.c | 17 +- source/blender/editors/space_file/space_file.c | 87 ++++++++-- 6 files changed, 297 insertions(+), 32 deletions(-) (limited to 'source/blender/editors') diff --git a/source/blender/editors/interface/interface_style.c b/source/blender/editors/interface/interface_style.c index c3d528ad5c5..a37fb0dfde1 100644 --- a/source/blender/editors/interface/interface_style.c +++ b/source/blender/editors/interface/interface_style.c @@ -206,8 +206,12 @@ void UI_fontstyle_draw_ex(const uiFontStyle *fs, BLF_disable(fs->uifont_id, font_flag); - *r_xofs = xofs; - *r_yofs = yofs; + if (r_xofs) { + *r_xofs = xofs; + } + if (r_yofs) { + *r_yofs = yofs; + } } void UI_fontstyle_draw(const uiFontStyle *fs, diff --git a/source/blender/editors/space_file/file_draw.c b/source/blender/editors/space_file/file_draw.c index e3bdda7c480..f2f7f9d82f9 100644 --- a/source/blender/editors/space_file/file_draw.c +++ b/source/blender/editors/space_file/file_draw.c @@ -25,6 +25,7 @@ #include #include +#include "BLI_alloca.h" #include "BLI_blenlib.h" #include "BLI_fileops_types.h" #include "BLI_math.h" @@ -134,6 +135,7 @@ static void draw_tile(int sx, int sy, int width, int height, int colorid, int sh } static void file_draw_icon(uiBlock *block, + const FileDirEntry *file, const char *path, int sx, int sy, @@ -157,8 +159,29 @@ static void file_draw_icon(uiBlock *block, UI_but_func_tooltip_set(but, file_draw_tooltip_func, BLI_strdup(path)); if (drag) { - /* path is no more static, cannot give it directly to but... */ - UI_but_drag_set_path(but, BLI_strdup(path), true); + /* TODO duplicated from file_draw_preview(). */ + ID *id; + + if ((id = filelist_file_get_id(file))) { + UI_but_drag_set_id(but, id); + } + else if (file->typeflag & FILE_TYPE_ASSET) { + ImBuf *preview_image = filelist_file_getimage(file); + char blend_path[FILE_MAX_LIBEXTRA]; + if (BLO_library_path_explode(path, blend_path, NULL, NULL)) { + UI_but_drag_set_asset(but, + file->name, + BLI_strdup(blend_path), + file->blentype, + icon, + preview_image, + UI_DPI_FAC); + } + } + else { + /* path is no more static, cannot give it directly to but... */ + UI_but_drag_set_path(but, BLI_strdup(path), true); + } } } @@ -200,6 +223,65 @@ static void file_draw_string(int sx, }); } +/** + * \param r_sx, r_sy: The lower right corner of the last line drawn. AKA the cursor position on + * completion. + */ +static void file_draw_string_multiline(int sx, + int sy, + const char *string, + int wrap_width, + int line_height, + const uchar text_col[4], + int *r_sx, + int *r_sy) +{ + rcti rect; + + if (string[0] == '\0' || wrap_width < 1) { + return; + } + + const uiStyle *style = UI_style_get(); + int font_id = style->widgetlabel.uifont_id; + int len = strlen(string); + + rctf textbox; + BLF_wordwrap(font_id, wrap_width); + BLF_enable(font_id, BLF_WORD_WRAP); + BLF_boundbox(font_id, string, len, &textbox); + BLF_disable(font_id, BLF_WORD_WRAP); + + /* no text clipping needed, UI_fontstyle_draw does it but is a bit too strict + * (for buttons it works) */ + rect.xmin = sx; + rect.xmax = sx + wrap_width; + /* Need to increase the clipping rect by one more line, since the #UI_fontstyle_draw_ex() will + * actually start drawing at (ymax - line-height). */ + rect.ymin = sy - round_fl_to_int(BLI_rctf_size_y(&textbox)) - line_height; + rect.ymax = sy; + + struct ResultBLF result; + UI_fontstyle_draw_ex(&style->widget, + &rect, + string, + text_col, + &(struct uiFontStyleDraw_Params){ + .align = UI_STYLE_TEXT_LEFT, + .word_wrap = true, + }, + len, + NULL, + NULL, + &result); + if (r_sx) { + *r_sx = result.width; + } + if (r_sy) { + *r_sy = rect.ymin + line_height; + } +} + void file_calc_previews(const bContext *C, ARegion *region) { SpaceFile *sfile = CTX_wm_space_file(C); @@ -210,6 +292,7 @@ void file_calc_previews(const bContext *C, ARegion *region) } static void file_draw_preview(uiBlock *block, + const FileDirEntry *file, const char *path, int sx, int sy, @@ -218,7 +301,6 @@ static void file_draw_preview(uiBlock *block, const int icon, FileLayout *layout, const bool is_icon, - const int typeflags, const bool drag, const bool dimmed, const bool is_link) @@ -232,7 +314,7 @@ static void file_draw_preview(uiBlock *block, float scale; int ex, ey; bool show_outline = !is_icon && - (typeflags & (FILE_TYPE_IMAGE | FILE_TYPE_MOVIE | FILE_TYPE_BLENDER)); + (file->typeflag & (FILE_TYPE_IMAGE | FILE_TYPE_MOVIE | FILE_TYPE_BLENDER)); BLI_assert(imb != NULL); @@ -273,14 +355,14 @@ static void file_draw_preview(uiBlock *block, float col[4] = {1.0f, 1.0f, 1.0f, 1.0f}; if (is_icon) { - if (typeflags & FILE_TYPE_DIR) { + if (file->typeflag & FILE_TYPE_DIR) { UI_GetThemeColor4fv(TH_ICON_FOLDER, col); } else { UI_GetThemeColor4fv(TH_TEXT, col); } } - else if (typeflags & FILE_TYPE_FTFONT) { + else if (file->typeflag & FILE_TYPE_FTFONT) { UI_GetThemeColor4fv(TH_TEXT, col); } @@ -288,7 +370,7 @@ static void file_draw_preview(uiBlock *block, col[3] *= 0.3f; } - if (!is_icon && typeflags & FILE_TYPE_BLENDERLIB) { + if (!is_icon && file->typeflag & FILE_TYPE_BLENDERLIB) { /* Datablock preview images use premultiplied alpha. */ GPU_blend(GPU_BLEND_ALPHA_PREMULT); } @@ -324,7 +406,7 @@ static void file_draw_preview(uiBlock *block, icon_color[2] = 255; } icon_x = xco + (ex / 2.0f) - (icon_size / 2.0f); - icon_y = yco + (ey / 2.0f) - (icon_size * ((typeflags & FILE_TYPE_DIR) ? 0.78f : 0.75f)); + icon_y = yco + (ey / 2.0f) - (icon_size * ((file->typeflag & FILE_TYPE_DIR) ? 0.78f : 0.75f)); UI_icon_draw_ex( icon_x, icon_y, icon, icon_aspect / U.dpi_fac, icon_opacity, 0.0f, icon_color, false); } @@ -346,13 +428,13 @@ static void file_draw_preview(uiBlock *block, /* Link to folder or non-previewed file. */ uchar icon_color[4]; UI_GetThemeColor4ubv(TH_BACK, icon_color); - icon_x = xco + ((typeflags & FILE_TYPE_DIR) ? 0.14f : 0.23f) * scaledx; - icon_y = yco + ((typeflags & FILE_TYPE_DIR) ? 0.24f : 0.14f) * scaledy; + icon_x = xco + ((file->typeflag & FILE_TYPE_DIR) ? 0.14f : 0.23f) * scaledx; + icon_y = yco + ((file->typeflag & FILE_TYPE_DIR) ? 0.24f : 0.14f) * scaledy; UI_icon_draw_ex( icon_x, icon_y, arrow, icon_aspect / U.dpi_fac * 1.8, 0.3f, 0.0f, icon_color, false); } } - else if (icon && !is_icon && !(typeflags & FILE_TYPE_FTFONT)) { + else if (icon && !is_icon && !(file->typeflag & FILE_TYPE_FTFONT)) { /* Smaller, fainter icon at bottom-left for preview image thumbnail, but not for fonts. */ float icon_x, icon_y; const uchar dark[4] = {0, 0, 0, 255}; @@ -385,8 +467,22 @@ static void file_draw_preview(uiBlock *block, /* dragregion */ if (drag) { + ID *id; + + if ((id = filelist_file_get_id(file))) { + UI_but_drag_set_id(but, id); + } /* path is no more static, cannot give it directly to but... */ - UI_but_drag_set_image(but, BLI_strdup(path), icon, imb, scale, true); + else if (file->typeflag & FILE_TYPE_ASSET) { + char blend_path[FILE_MAX_LIBEXTRA]; + if (BLO_library_path_explode(path, blend_path, NULL, NULL)) { + UI_but_drag_set_asset( + but, file->name, BLI_strdup(blend_path), file->blentype, icon, imb, scale); + } + } + else { + UI_but_drag_set_image(but, BLI_strdup(path), icon, imb, scale, true); + } } GPU_blend(GPU_BLEND_NONE); @@ -821,6 +917,7 @@ void file_draw_list(const bContext *C, ARegion *region) } file_draw_preview(block, + file, path, sx, sy, @@ -829,13 +926,13 @@ void file_draw_list(const bContext *C, ARegion *region) icon, layout, is_icon, - file->typeflag, do_drag, is_hidden, is_link); } else { file_draw_icon(block, + file, path, sx, sy - layout->tile_border_y, @@ -906,3 +1003,66 @@ void file_draw_list(const bContext *C, ARegion *region) layout->curr_size = params->thumbnail_size; } + +static void file_draw_invalid_library_hint(const SpaceFile *sfile, const ARegion *region) +{ + const FileAssetSelectParams *asset_params = ED_fileselect_get_asset_params(sfile); + + char library_ui_path[PATH_MAX]; + file_path_to_ui_path(asset_params->base_params.dir, library_ui_path, sizeof(library_ui_path)); + + uchar text_col[4]; + uchar text_alert_col[4]; + UI_GetThemeColor4ubv(TH_TEXT, text_col); + UI_GetThemeColor4ubv(TH_REDALERT, text_alert_col); + + const View2D *v2d = ®ion->v2d; + const int pad = sfile->layout->tile_border_x; + const int width = BLI_rctf_size_x(&v2d->tot) - (2 * pad); + const int line_height = sfile->layout->textheight; + int sx = v2d->tot.xmin + pad; + /* For some reason no padding needed. */ + int sy = v2d->tot.ymax; + + { + const char *message = TIP_("Library not found"); + const int draw_string_str_len = strlen(message) + 2 + sizeof(library_ui_path); + char *draw_string = alloca(draw_string_str_len); + BLI_snprintf(draw_string, draw_string_str_len, "%s: %s", message, library_ui_path); + file_draw_string_multiline(sx, sy, draw_string, width, line_height, text_alert_col, NULL, &sy); + } + + /* Next line, but separate it a bit further. */ + sy -= line_height; + + { + UI_icon_draw(sx, sy - UI_UNIT_Y, ICON_INFO); + + const char *suggestion = TIP_( + "Set up the library or edit libraries in the Preferences, File Paths section."); + file_draw_string_multiline( + sx + UI_UNIT_X, sy, suggestion, width - UI_UNIT_X, line_height, text_col, NULL, NULL); + } +} + +/** + * Draw a string hint if the file list is invalid. + * \return true if the list is invalid and a hint was drawn. + */ +bool file_draw_hint_if_invalid(const SpaceFile *sfile, const ARegion *region) +{ + FileAssetSelectParams *asset_params = ED_fileselect_get_asset_params(sfile); + /* Only for asset browser. */ + if (!ED_fileselect_is_asset_browser(sfile)) { + return false; + } + /* Check if the library exists. */ + if ((asset_params->asset_library.type == FILE_ASSET_LIBRARY_LOCAL) || + filelist_is_dir(sfile->files, asset_params->base_params.dir)) { + return false; + } + + file_draw_invalid_library_hint(sfile, region); + + return true; +} diff --git a/source/blender/editors/space_file/file_intern.h b/source/blender/editors/space_file/file_intern.h index a0e02681e0e..56fb588776e 100644 --- a/source/blender/editors/space_file/file_intern.h +++ b/source/blender/editors/space_file/file_intern.h @@ -38,6 +38,7 @@ struct View2D; void file_calc_previews(const bContext *C, ARegion *region); void file_draw_list(const bContext *C, ARegion *region); +bool file_draw_hint_if_invalid(const SpaceFile *sfile, const ARegion *region); void file_draw_check_ex(bContext *C, struct ScrArea *area); void file_draw_check(bContext *C); @@ -117,3 +118,5 @@ void file_execute_region_panels_register(struct ARegionType *art); /* file_utils.c */ void file_tile_boundbox(const ARegion *region, FileLayout *layout, const int file, rcti *r_bounds); + +void file_path_to_ui_path(const char *path, char *r_pathi, int max_size); diff --git a/source/blender/editors/space_file/file_ops.c b/source/blender/editors/space_file/file_ops.c index 8af84f65ced..be4577bcba7 100644 --- a/source/blender/editors/space_file/file_ops.c +++ b/source/blender/editors/space_file/file_ops.c @@ -40,6 +40,7 @@ # include "BLI_winstuff.h" #endif +#include "ED_asset.h" #include "ED_fileselect.h" #include "ED_screen.h" #include "ED_select_utils.h" @@ -2695,6 +2696,29 @@ static bool file_delete_poll(bContext *C) return poll; } +static bool file_delete_single(const FileSelectParams *params, + FileDirEntry *file, + const char **r_error_message) +{ + if (file->typeflag & FILE_TYPE_ASSET) { + ID *id = filelist_file_get_id(file); + if (!id) { + *r_error_message = "File is not a local data-block asset."; + return false; + } + ED_asset_clear_id(id); + } + else { + char str[FILE_MAX]; + BLI_join_dirfile(str, sizeof(str), params->dir, file->relpath); + if (BLI_delete_soft(str, r_error_message) != 0 || BLI_exists(str)) { + return false; + } + } + + return true; +} + static int file_delete_exec(bContext *C, wmOperator *op) { wmWindowManager *wm = CTX_wm_manager(C); @@ -2708,9 +2732,7 @@ static int file_delete_exec(bContext *C, wmOperator *op) for (int i = 0; i < numfiles; i++) { if (filelist_entry_select_index_get(sfile->files, i, CHECK_ALL)) { FileDirEntry *file = filelist_file(sfile->files, i); - char str[FILE_MAX]; - BLI_join_dirfile(str, sizeof(str), params->dir, file->relpath); - if (BLI_delete_soft(str, &error_message) != 0 || BLI_exists(str)) { + if (!file_delete_single(params, file, &error_message)) { report_error = true; } } diff --git a/source/blender/editors/space_file/file_utils.c b/source/blender/editors/space_file/file_utils.c index 452f2f704cf..9d85996c559 100644 --- a/source/blender/editors/space_file/file_utils.c +++ b/source/blender/editors/space_file/file_utils.c @@ -18,12 +18,14 @@ * \ingroup spfile */ +#include "BLI_fileops.h" #include "BLI_listbase.h" +#include "BLI_path_util.h" #include "BLI_rect.h" - -#include "BLO_readfile.h" +#include "BLI_string.h" #include "BKE_context.h" +#include "BLO_readfile.h" #include "ED_fileselect.h" #include "ED_screen.h" @@ -44,3 +46,14 @@ void file_tile_boundbox(const ARegion *region, FileLayout *layout, const int fil ymax - layout->tile_h - layout->tile_border_y, ymax); } + +/** + * If \a path leads to a .blend, remove the trailing slash (if needed). + */ +void file_path_to_ui_path(const char *path, char *r_path, int max_size) +{ + char tmp_path[PATH_MAX]; + BLI_strncpy(tmp_path, path, sizeof(tmp_path)); + BLI_path_slash_rstrip(tmp_path); + BLI_strncpy(r_path, BLO_has_bfile_extension(tmp_path) ? tmp_path : path, max_size); +} diff --git a/source/blender/editors/space_file/space_file.c b/source/blender/editors/space_file/space_file.c index f1d72387791..46ae52fd4cf 100644 --- a/source/blender/editors/space_file/space_file.c +++ b/source/blender/editors/space_file/space_file.c @@ -57,6 +57,23 @@ #include "filelist.h" #include "fsmenu.h" +static ARegion *file_ui_region_ensure(ScrArea *area, ARegion *region_prev) +{ + ARegion *region; + + if ((region = BKE_area_find_region_type(area, RGN_TYPE_UI)) != NULL) { + return region; + } + + region = MEM_callocN(sizeof(ARegion), "execute region for file"); + BLI_insertlinkafter(&area->regionbase, region_prev, region); + region->regiontype = RGN_TYPE_UI; + region->alignment = RGN_ALIGN_TOP; + region->flag = RGN_FLAG_DYNAMIC_SIZE; + + return region; +} + static ARegion *file_execute_region_ensure(ScrArea *area, ARegion *region_prev) { ARegion *region; @@ -223,15 +240,30 @@ static void file_ensure_valid_region_state(bContext *C, SpaceFile *sfile, FileSelectParams *params) { - ARegion *region_ui = BKE_area_find_region_type(area, RGN_TYPE_UI); - ARegion *region_props = BKE_area_find_region_type(area, RGN_TYPE_TOOL_PROPS); - ARegion *region_execute = BKE_area_find_region_type(area, RGN_TYPE_EXECUTE); + ARegion *region_tools = BKE_area_find_region_type(area, RGN_TYPE_TOOLS); bool needs_init = false; /* To avoid multiple ED_area_init() calls. */ + BLI_assert(region_tools); + + if (sfile->browse_mode == FILE_BROWSE_MODE_ASSETS) { + ARegion *region_execute = file_execute_region_ensure(area, region_tools); + ARegion *region_props = file_tool_props_region_ensure(area, region_execute); + + /* Hide specific regions by default. */ + region_props->flag |= RGN_FLAG_HIDDEN; + region_execute->flag |= RGN_FLAG_HIDDEN; + + ARegion *region_ui = BKE_area_find_region_type(area, RGN_TYPE_UI); + if (region_ui) { + ED_region_remove(C, area, region_ui); + needs_init = true; + } + } /* If there's an file-operation, ensure we have the option and execute region */ - if (sfile->op && (region_props == NULL)) { - region_execute = file_execute_region_ensure(area, region_ui); - region_props = file_tool_props_region_ensure(area, region_execute); + else if (sfile->op) { + ARegion *region_ui = file_ui_region_ensure(area, region_tools); + ARegion *region_execute = file_execute_region_ensure(area, region_ui); + ARegion *region_props = file_tool_props_region_ensure(area, region_execute); if (params->flag & FILE_HIDE_TOOL_PROPS) { region_props->flag |= RGN_FLAG_HIDDEN; @@ -243,12 +275,19 @@ static void file_ensure_valid_region_state(bContext *C, needs_init = true; } /* If there's _no_ file-operation, ensure we _don't_ have the option and execute region */ - else if ((sfile->op == NULL) && (region_props != NULL)) { - BLI_assert(region_execute != NULL); + else { + ARegion *region_props = BKE_area_find_region_type(area, RGN_TYPE_TOOL_PROPS); + ARegion *region_execute = BKE_area_find_region_type(area, RGN_TYPE_EXECUTE); + ARegion *region_ui = file_ui_region_ensure(area, region_tools); + UNUSED_VARS(region_ui); - ED_region_remove(C, area, region_props); - ED_region_remove(C, area, region_execute); - needs_init = true; + if (region_props) { + BLI_assert(region_execute); + + ED_region_remove(C, area, region_props); + ED_region_remove(C, area, region_execute); + needs_init = true; + } } if (needs_init) { @@ -530,7 +569,9 @@ static void file_main_region_draw(const bContext *C, ARegion *region) file_highlight_set(sfile, region, event->x, event->y); } - file_draw_list(C, region); + if (!file_draw_hint_if_invalid(sfile, region)) { + file_draw_list(C, region); + } /* reset view matrix */ UI_view2d_view_restore(C); @@ -714,6 +755,25 @@ static void file_dropboxes(void) WM_dropbox_add(lb, "FILE_OT_filepath_drop", filepath_drop_poll, filepath_drop_copy); } +static int file_space_subtype_get(ScrArea *area) +{ + SpaceFile *sfile = area->spacedata.first; + return sfile->browse_mode; +} + +static void file_space_subtype_set(ScrArea *area, int value) +{ + SpaceFile *sfile = area->spacedata.first; + sfile->browse_mode = value; +} + +static void file_space_subtype_item_extend(bContext *UNUSED(C), + EnumPropertyItem **item, + int *totitem) +{ + RNA_enum_items_add(item, totitem, rna_enum_space_file_browse_mode_items); +} + const char *file_context_dir[] = {"active_file", "active_id", NULL}; static int /*eContextResult*/ file_context(const bContext *C, @@ -779,6 +839,9 @@ void ED_spacetype_file(void) st->operatortypes = file_operatortypes; st->keymap = file_keymap; st->dropboxes = file_dropboxes; + st->space_subtype_item_extend = file_space_subtype_item_extend; + st->space_subtype_get = file_space_subtype_get; + st->space_subtype_set = file_space_subtype_set; st->context = file_context; st->id_remap = file_id_remap; -- cgit v1.2.3 From 9caeb9dfc7dfe8dcd6507a6b8dce5b98651b40ca Mon Sep 17 00:00:00 2001 From: Julian Eisel Date: Mon, 14 Dec 2020 23:01:24 +0100 Subject: Fix Asset Browser crash with undo in "Current File" library with sidebar When the Asset Browser was showing the "Current File" repository and the sidebar was open, undoing could crash, because the context API returned freed data. Don't let context return anything if a refresh is pending due to data changes like undo/redo. --- source/blender/editors/space_file/space_file.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) (limited to 'source/blender/editors') diff --git a/source/blender/editors/space_file/space_file.c b/source/blender/editors/space_file/space_file.c index 46ae52fd4cf..8be02b952a8 100644 --- a/source/blender/editors/space_file/space_file.c +++ b/source/blender/editors/space_file/space_file.c @@ -790,12 +790,18 @@ static int /*eContextResult*/ file_context(const bContext *C, CTX_data_dir_set(result, file_context_dir); return CTX_RESULT_OK; } - else if (CTX_data_equals(member, "active_file")) { + + /* The following member checks return file-list data, check if that needs refreshing first. */ + if (file_main_region_needs_refresh_before_draw(sfile)) { + return CTX_RESULT_NO_DATA; + } + + if (CTX_data_equals(member, "active_file")) { FileDirEntry *file = filelist_file(sfile->files, params->active_file); CTX_data_pointer_set(result, &screen->id, &RNA_FileSelectEntry, file); return CTX_RESULT_OK; } - else if (CTX_data_equals(member, "active_id")) { + if (CTX_data_equals(member, "active_id")) { const FileDirEntry *file = filelist_file(sfile->files, params->active_file); ID *id = filelist_file_get_id(file); @@ -804,6 +810,7 @@ static int /*eContextResult*/ file_context(const bContext *C, } return CTX_RESULT_OK; } + return CTX_RESULT_MEMBER_NOT_FOUND; } -- cgit v1.2.3 From 990406e1ff9371a8c896b71171caa876cfdff2f6 Mon Sep 17 00:00:00 2001 From: Julian Eisel Date: Tue, 15 Dec 2020 16:58:30 +0100 Subject: Fix crash when deleting/renaming asset library while it's visible Storing the asset library reference by name wasn't a good idea, I thought it would work with a careful fallback, but it's easier to just use the index instead. So change to using indices, make sure fallback methods work reliable and make sure the file list is updated when asset libraries are removed. I added a new notifier type for the latter, I prefer not using file notifiers in asset-library/preferences code. We have more than enough values for notifiers left. --- source/blender/editors/space_file/filelist.c | 7 ++++++- source/blender/editors/space_file/filesel.c | 7 +++++-- source/blender/editors/space_file/space_file.c | 5 +++++ source/blender/editors/space_userpref/userpref_ops.c | 2 ++ 4 files changed, 18 insertions(+), 3 deletions(-) (limited to 'source/blender/editors') diff --git a/source/blender/editors/space_file/filelist.c b/source/blender/editors/space_file/filelist.c index 5dc5f741ac3..afa1fa0edee 100644 --- a/source/blender/editors/space_file/filelist.c +++ b/source/blender/editors/space_file/filelist.c @@ -61,6 +61,7 @@ #include "BKE_lib_id.h" #include "BKE_main.h" #include "BKE_main_idmap.h" +#include "BKE_preferences.h" #include "BLO_readfile.h" #include "DNA_asset_types.h" @@ -1050,7 +1051,11 @@ static bool filelist_compare_asset_libraries(const FileSelectAssetLibraryUID *li return false; } if (library_a->type == FILE_ASSET_LIBRARY_CUSTOM) { - return STREQ(library_a->custom_library_identifier, library_b->custom_library_identifier); + /* Don't only check the index, also check that it's valid. */ + bUserAssetLibrary *library_ptr_a = BKE_preferences_asset_library_find_from_index( + &U, library_a->custom_library_index); + return (library_ptr_a != NULL) && + (library_a->custom_library_index == library_b->custom_library_index); } return true; diff --git a/source/blender/editors/space_file/filesel.c b/source/blender/editors/space_file/filesel.c index 2c66bd39e0a..cd27b7b5773 100644 --- a/source/blender/editors/space_file/filesel.c +++ b/source/blender/editors/space_file/filesel.c @@ -119,6 +119,7 @@ static void fileselect_ensure_updated_asset_params(SpaceFile *sfile) "FileAssetSelectParams"); asset_params->base_params.details_flags = U_default.file_space_data.details_flags; asset_params->asset_library.type = FILE_ASSET_LIBRARY_LOCAL; + asset_params->asset_library.custom_library_index = -1; } FileSelectParams *base_params = &asset_params->base_params; @@ -419,8 +420,10 @@ static void fileselect_refresh_asset_params(FileAssetSelectParams *asset_params) /* Ensure valid repo, or fall-back to local one. */ if (library->type == FILE_ASSET_LIBRARY_CUSTOM) { - user_library = BKE_preferences_asset_library_find_from_name( - &U, library->custom_library_identifier); + BLI_assert(library->custom_library_index >= 0); + + user_library = BKE_preferences_asset_library_find_from_index(&U, + library->custom_library_index); if (!user_library) { library->type = FILE_ASSET_LIBRARY_LOCAL; } diff --git a/source/blender/editors/space_file/space_file.c b/source/blender/editors/space_file/space_file.c index 8be02b952a8..09b7e5b348c 100644 --- a/source/blender/editors/space_file/space_file.c +++ b/source/blender/editors/space_file/space_file.c @@ -412,6 +412,11 @@ static void file_listener(wmWindow *UNUSED(win), ED_area_tag_refresh(area); } break; + case ND_SPACE_ASSET_PARAMS: + if (sfile->browse_mode == FILE_BROWSE_MODE_ASSETS) { + ED_area_tag_refresh(area); + } + break; } break; case NC_ASSET: { diff --git a/source/blender/editors/space_userpref/userpref_ops.c b/source/blender/editors/space_userpref/userpref_ops.c index 9cc8cc6ddaa..ee23cde78c2 100644 --- a/source/blender/editors/space_userpref/userpref_ops.c +++ b/source/blender/editors/space_userpref/userpref_ops.c @@ -170,6 +170,8 @@ static int preferences_asset_library_remove_exec(bContext *UNUSED(C), wmOperator if (library) { BKE_preferences_asset_library_remove(&U, library); U.runtime.is_dirty = true; + /* Trigger refresh for the Asset Browser. */ + WM_main_add_notifier(NC_SPACE | ND_SPACE_ASSET_PARAMS, NULL); } return OPERATOR_FINISHED; } -- cgit v1.2.3 From ffe63b0440cb55dee7a0ec3c383cce99167b47a1 Mon Sep 17 00:00:00 2001 From: Julian Eisel Date: Tue, 15 Dec 2020 18:49:56 +0100 Subject: Fix crash opening maximized File Browser from Asset Browser If Preferences > Interface > Temporary Editors > File Browser is set to "Maximized Area", opening a File Browser from an Asset Browser would cause the new maximized editor to be an Asset Browser. Exiting it again would crash. This fixes the wrong behavior and the crash. There's still an issue with exiting the editor again, it stays a File Browser then and doesn't go back to being an Asset Browser. That's to be fixed separately. --- source/blender/editors/screen/screen_edit.c | 1 + source/blender/editors/space_file/filesel.c | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) (limited to 'source/blender/editors') diff --git a/source/blender/editors/screen/screen_edit.c b/source/blender/editors/screen/screen_edit.c index 6be2fb8004b..c3dcaefab79 100644 --- a/source/blender/editors/screen/screen_edit.c +++ b/source/blender/editors/screen/screen_edit.c @@ -1369,6 +1369,7 @@ ScrArea *ED_screen_state_toggle(bContext *C, wmWindow *win, ScrArea *area, const newa->full = oldscreen; ED_screen_change(C, screen); + ED_area_tag_refresh(newa); } /* XXX bad code: setscreen() ends with first area active. fullscreen render assumes this too */ diff --git a/source/blender/editors/space_file/filesel.c b/source/blender/editors/space_file/filesel.c index cd27b7b5773..b919a30e6cd 100644 --- a/source/blender/editors/space_file/filesel.c +++ b/source/blender/editors/space_file/filesel.c @@ -490,7 +490,7 @@ void ED_fileselect_set_params_from_userdef(SpaceFile *sfile) wmOperator *op = sfile->op; UserDef_FileSpaceData *sfile_udata = &U.file_space_data; - BLI_assert(sfile->browse_mode == FILE_BROWSE_MODE_FILES); + sfile->browse_mode = FILE_BROWSE_MODE_FILES; FileSelectParams *params = fileselect_ensure_updated_file_params(sfile); if (!op) { -- cgit v1.2.3 From 3834dc2f7b38a8a29b8cd6dbcd55ac5be7890553 Mon Sep 17 00:00:00 2001 From: Philipp Oeser Date: Fri, 11 Dec 2020 12:04:30 +0100 Subject: Fix Adjust Last Operation popup for operators relying on button context This was reported for duplicating particle systems, then using F9 to enable the 'Duplicate Settings' option (see T83317). In this case, the operator gets the particle_system from (buttons) context and if none can get found will duplicate all settings instead. The reason why none gets found here is that buttons_context() doesnt have a valid path when called from F9/SCREEN_OT_redo_last, path is cleared when global undo does a file-read which clears the path (see lib_link_workspace_layout_restore). It can be recomputed though to be valid even from redo_last (at least when in the Properties Editor). This was likely causing other operators (relying on buttons context) from the Properties Editor to fail as well. Fixes T83317 Maniphest Tasks: T83317 Differential Revision: https://developer.blender.org/D9825 --- source/blender/editors/space_buttons/buttons_context.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'source/blender/editors') diff --git a/source/blender/editors/space_buttons/buttons_context.c b/source/blender/editors/space_buttons/buttons_context.c index 3a2b8cf0115..c1f29231f96 100644 --- a/source/blender/editors/space_buttons/buttons_context.c +++ b/source/blender/editors/space_buttons/buttons_context.c @@ -826,6 +826,11 @@ int /*eContextResult*/ buttons_context(const bContext *C, bContextDataResult *result) { SpaceProperties *sbuts = CTX_wm_space_properties(C); + if (sbuts && sbuts->path == NULL) { + /* path is cleared for SCREEN_OT_redo_last, when global undo does a file-read which clears the + * path (see lib_link_workspace_layout_restore). */ + buttons_context_compute(C, sbuts); + } ButsContextPath *path = sbuts ? sbuts->path : NULL; if (!path) { -- cgit v1.2.3 From 8df167873a3b36f7b179266802699d4f935cd2f9 Mon Sep 17 00:00:00 2001 From: Hans Goudey Date: Tue, 15 Dec 2020 12:39:27 -0600 Subject: Cleanup: Clang tidy else after return --- source/blender/editors/space_file/filelist.c | 31 ++++++++++++++-------------- 1 file changed, 15 insertions(+), 16 deletions(-) (limited to 'source/blender/editors') diff --git a/source/blender/editors/space_file/filelist.c b/source/blender/editors/space_file/filelist.c index afa1fa0edee..3ed7b5499db 100644 --- a/source/blender/editors/space_file/filelist.c +++ b/source/blender/editors/space_file/filelist.c @@ -3450,22 +3450,21 @@ void filelist_readjob_start(FileList *filelist, const bContext *C) WM_event_add_notifier(C, NC_SPACE | ND_SPACE_FILE_LIST, NULL); return; } - else { - /* setup job */ - wm_job = WM_jobs_get(CTX_wm_manager(C), - CTX_wm_window(C), - CTX_data_scene(C), - "Listing Dirs...", - WM_JOB_PROGRESS, - WM_JOB_TYPE_FILESEL_READDIR); - WM_jobs_customdata_set(wm_job, flrj, filelist_readjob_free); - WM_jobs_timer(wm_job, 0.01, NC_SPACE | ND_SPACE_FILE_LIST, NC_SPACE | ND_SPACE_FILE_LIST); - WM_jobs_callbacks( - wm_job, filelist_readjob_startjob, NULL, filelist_readjob_update, filelist_readjob_endjob); - - /* start the job */ - WM_jobs_start(CTX_wm_manager(C), wm_job); - } + + /* setup job */ + wm_job = WM_jobs_get(CTX_wm_manager(C), + CTX_wm_window(C), + CTX_data_scene(C), + "Listing Dirs...", + WM_JOB_PROGRESS, + WM_JOB_TYPE_FILESEL_READDIR); + WM_jobs_customdata_set(wm_job, flrj, filelist_readjob_free); + WM_jobs_timer(wm_job, 0.01, NC_SPACE | ND_SPACE_FILE_LIST, NC_SPACE | ND_SPACE_FILE_LIST); + WM_jobs_callbacks( + wm_job, filelist_readjob_startjob, NULL, filelist_readjob_update, filelist_readjob_endjob); + + /* start the job */ + WM_jobs_start(CTX_wm_manager(C), wm_job); } void filelist_readjob_stop(wmWindowManager *wm, Scene *owner_scene) -- cgit v1.2.3 From c9de65679bb0905e7f689b83931c9be9a8abfa02 Mon Sep 17 00:00:00 2001 From: Pablo Dobarro Date: Sun, 6 Dec 2020 23:11:33 +0100 Subject: Fix T83201: Cloth brush performance regression The if statement of the dynamic area mode branch should be an else if. When using local mode, this was running both the local and global code. I moved this code to sculpt_cloth and refactored it to use a switch case to prevent this from happening again. Reviewed By: mont29 Maniphest Tasks: T83201 Differential Revision: https://developer.blender.org/D9762 --- source/blender/editors/sculpt_paint/sculpt.c | 27 +--------------- source/blender/editors/sculpt_paint/sculpt_cloth.c | 37 ++++++++++++++++++++++ .../blender/editors/sculpt_paint/sculpt_intern.h | 4 +++ 3 files changed, 42 insertions(+), 26 deletions(-) (limited to 'source/blender/editors') diff --git a/source/blender/editors/sculpt_paint/sculpt.c b/source/blender/editors/sculpt_paint/sculpt.c index 94f05560f79..80a32682325 100644 --- a/source/blender/editors/sculpt_paint/sculpt.c +++ b/source/blender/editors/sculpt_paint/sculpt.c @@ -5742,32 +5742,7 @@ static void do_brush_action(Sculpt *sd, Object *ob, Brush *brush, UnifiedPaintSe BKE_pbvh_search_gather(ss->pbvh, NULL, NULL, &nodes, &totnode); } else if (brush->sculpt_tool == SCULPT_TOOL_CLOTH) { - if (brush->cloth_simulation_area_type == BRUSH_CLOTH_SIMULATION_AREA_LOCAL) { - SculptSearchSphereData data = { - .ss = ss, - .sd = sd, - .radius_squared = square_f(ss->cache->initial_radius * (1.0 + brush->cloth_sim_limit)), - .original = false, - .ignore_fully_ineffective = false, - .center = ss->cache->initial_location, - }; - BKE_pbvh_search_gather(ss->pbvh, SCULPT_search_sphere_cb, &data, &nodes, &totnode); - } - if (brush->cloth_simulation_area_type == BRUSH_CLOTH_SIMULATION_AREA_DYNAMIC) { - SculptSearchSphereData data = { - .ss = ss, - .sd = sd, - .radius_squared = square_f(ss->cache->radius * (1.0 + brush->cloth_sim_limit)), - .original = false, - .ignore_fully_ineffective = false, - .center = ss->cache->location, - }; - BKE_pbvh_search_gather(ss->pbvh, SCULPT_search_sphere_cb, &data, &nodes, &totnode); - } - else { - /* Gobal simulation, get all nodes. */ - BKE_pbvh_search_gather(ss->pbvh, NULL, NULL, &nodes, &totnode); - } + nodes = SCULPT_cloth_brush_affected_nodes_gather(ss, brush, &totnode); } else { const bool use_original = sculpt_tool_needs_original(brush->sculpt_tool) ? true : diff --git a/source/blender/editors/sculpt_paint/sculpt_cloth.c b/source/blender/editors/sculpt_paint/sculpt_cloth.c index f8165890cc4..0ac0d796ca4 100644 --- a/source/blender/editors/sculpt_paint/sculpt_cloth.c +++ b/source/blender/editors/sculpt_paint/sculpt_cloth.c @@ -119,6 +119,43 @@ static void cloth_brush_simulation_location_get(SculptSession *ss, copy_v3_v3(r_location, ss->cache->location); } +PBVHNode **SCULPT_cloth_brush_affected_nodes_gather(SculptSession *ss, + Brush *brush, + int *r_totnode) +{ + BLI_assert(ss->cache); + BLI_assert(brush->sculpt_tool == SCULPT_TOOL_CLOTH); + PBVHNode **nodes = NULL; + + switch (brush->cloth_simulation_area_type) { + case BRUSH_CLOTH_SIMULATION_AREA_LOCAL: { + SculptSearchSphereData data = { + .ss = ss, + .radius_squared = square_f(ss->cache->initial_radius * (1.0 + brush->cloth_sim_limit)), + .original = false, + .ignore_fully_ineffective = false, + .center = ss->cache->initial_location, + }; + BKE_pbvh_search_gather(ss->pbvh, SCULPT_search_sphere_cb, &data, &nodes, r_totnode); + } break; + case BRUSH_CLOTH_SIMULATION_AREA_GLOBAL: + BKE_pbvh_search_gather(ss->pbvh, NULL, NULL, &nodes, r_totnode); + break; + case BRUSH_CLOTH_SIMULATION_AREA_DYNAMIC: { + SculptSearchSphereData data = { + .ss = ss, + .radius_squared = square_f(ss->cache->radius * (1.0 + brush->cloth_sim_limit)), + .original = false, + .ignore_fully_ineffective = false, + .center = ss->cache->location, + }; + BKE_pbvh_search_gather(ss->pbvh, SCULPT_search_sphere_cb, &data, &nodes, r_totnode); + } break; + } + + return nodes; +} + static float cloth_brush_simulation_falloff_get(const Brush *brush, const float radius, const float location[3], diff --git a/source/blender/editors/sculpt_paint/sculpt_intern.h b/source/blender/editors/sculpt_paint/sculpt_intern.h index e0d413bc75f..bd5ba15b493 100644 --- a/source/blender/editors/sculpt_paint/sculpt_intern.h +++ b/source/blender/editors/sculpt_paint/sculpt_intern.h @@ -423,6 +423,10 @@ void SCULPT_cloth_plane_falloff_preview_draw(const uint gpuattr, const float outline_col[3], float outline_alpha); +PBVHNode **SCULPT_cloth_brush_affected_nodes_gather(SculptSession *ss, + Brush *brush, + int *r_totnode); + BLI_INLINE bool SCULPT_is_cloth_deform_brush(const Brush *brush) { return (brush->sculpt_tool == SCULPT_TOOL_CLOTH && ELEM(brush->cloth_deform_type, -- cgit v1.2.3 From 288f2efbd41f325c4127a0f42bf5d2c6682fd00e Mon Sep 17 00:00:00 2001 From: Pablo Dobarro Date: Mon, 7 Dec 2020 17:32:52 +0100 Subject: Fix T83504: Cancel trim operators when there is no geometry The boolean solver crashes when there is no geometry in the mesh. Also, using the trimming tools without a valid intersection in the PBVH will make the orientation and position functionality of the trimming shape not work, so this is the safer solution. Reviewed By: mont29 Maniphest Tasks: T83504 Differential Revision: https://developer.blender.org/D9777 --- source/blender/editors/sculpt_paint/paint_mask.c | 10 ++++++++++ 1 file changed, 10 insertions(+) (limited to 'source/blender/editors') diff --git a/source/blender/editors/sculpt_paint/paint_mask.c b/source/blender/editors/sculpt_paint/paint_mask.c index 17690757fa5..92c78a674f0 100644 --- a/source/blender/editors/sculpt_paint/paint_mask.c +++ b/source/blender/editors/sculpt_paint/paint_mask.c @@ -1552,6 +1552,11 @@ static int sculpt_trim_gesture_box_exec(bContext *C, wmOperator *op) return OPERATOR_CANCELLED; } + if (ss->totvert == 0) { + /* No geometry to trim or to detect a valid position for the trimming shape. */ + return OPERATOR_CANCELLED; + } + SculptGestureContext *sgcontext = sculpt_gesture_init_from_box(C, op); if (!sgcontext) { return OPERATOR_CANCELLED; @@ -1589,6 +1594,11 @@ static int sculpt_trim_gesture_lasso_exec(bContext *C, wmOperator *op) return OPERATOR_CANCELLED; } + if (ss->totvert == 0) { + /* No geometry to trim or to detect a valid position for the trimming shape. */ + return OPERATOR_CANCELLED; + } + SculptGestureContext *sgcontext = sculpt_gesture_init_from_lasso(C, op); if (!sgcontext) { return OPERATOR_CANCELLED; -- cgit v1.2.3 From c9b4d75336271fd0427f47a43f3bf4cb525c5252 Mon Sep 17 00:00:00 2001 From: Pablo Dobarro Date: Mon, 14 Dec 2020 17:22:20 +0100 Subject: Sculpt: Fair Face Sets operation for Face Set Edit This implements a mesh fairing algorithm and implements the fair operations for Face Set edit. This edit operations create a smooth as possible geometry patch in the area of the selected Face Set. The mesh fairing algorithm is designed by Brett Fedack for the addon "Mesh Fairing": https://github.com/fedackb/mesh-fairing, with some modifications: - The main fairing function in BKE_mesh_fair.h does not triangulate the mesh. For the test I did in sculpt mode results are good enough without triangulating the topology. Depending on the use and the result quality needed for a particular tool, the mesh can be triangulate in the affected area before starting fairing. - Cotangents loop weights are not implemented yet. The idea is to also expose the vertex and loop weights in a different function in case a tool needs to set up custom weights. This algorithm will also be used to solve the limitations of line project and implement the Lasso Project and Polyline Project tools. It can also be used in tools in other areas of Blender, like Edit Mode or future retopology tools. Reviewed By: brecht Differential Revision: https://developer.blender.org/D9603 --- source/blender/editors/sculpt_paint/CMakeLists.txt | 1 + .../blender/editors/sculpt_paint/sculpt_face_set.c | 91 +++++++++++++++++++++- 2 files changed, 91 insertions(+), 1 deletion(-) (limited to 'source/blender/editors') diff --git a/source/blender/editors/sculpt_paint/CMakeLists.txt b/source/blender/editors/sculpt_paint/CMakeLists.txt index 9bf3d2610d8..fff8d27ef5b 100644 --- a/source/blender/editors/sculpt_paint/CMakeLists.txt +++ b/source/blender/editors/sculpt_paint/CMakeLists.txt @@ -32,6 +32,7 @@ set(INC ../../windowmanager ../../../../intern/atomic ../../../../intern/clog + ../../../../intern/eigen ../../../../intern/glew-mx ../../../../intern/guardedalloc ) diff --git a/source/blender/editors/sculpt_paint/sculpt_face_set.c b/source/blender/editors/sculpt_paint/sculpt_face_set.c index ad42750bb92..1fba958d695 100644 --- a/source/blender/editors/sculpt_paint/sculpt_face_set.c +++ b/source/blender/editors/sculpt_paint/sculpt_face_set.c @@ -41,6 +41,7 @@ #include "BKE_context.h" #include "BKE_customdata.h" #include "BKE_mesh.h" +#include "BKE_mesh_fair.h" #include "BKE_mesh_mapping.h" #include "BKE_multires.h" #include "BKE_node.h" @@ -1024,6 +1025,8 @@ typedef enum eSculptFaceSetEditMode { SCULPT_FACE_SET_EDIT_GROW = 0, SCULPT_FACE_SET_EDIT_SHRINK = 1, SCULPT_FACE_SET_EDIT_DELETE_GEOMETRY = 2, + SCULPT_FACE_SET_EDIT_FAIR_POSITIONS = 3, + SCULPT_FACE_SET_EDIT_FAIR_TANGENCY = 4, } eSculptFaceSetEditMode; static EnumPropertyItem prop_sculpt_face_sets_edit_types[] = { @@ -1048,6 +1051,22 @@ static EnumPropertyItem prop_sculpt_face_sets_edit_types[] = { "Delete Geometry", "Deletes the faces that are assigned to the Face Set", }, + { + SCULPT_FACE_SET_EDIT_FAIR_POSITIONS, + "FAIR_POSITIONS", + 0, + "Fair Positions", + "Creates a smooth as possible geometry patch from the Face Set minimizing changes in " + "vertex positions", + }, + { + SCULPT_FACE_SET_EDIT_FAIR_TANGENCY, + "FAIR_TANGENCY", + 0, + "Fair Tangency", + "Creates a smooth as possible geometry patch from the Face Set minimizing changes in " + "vertex tangents", + }, {0, NULL, 0, NULL, NULL}, }; @@ -1181,6 +1200,29 @@ static void sculpt_face_set_delete_geometry(Object *ob, BM_mesh_free(bm); } +static void sculpt_face_set_edit_fair_face_set(Object *ob, + const int active_face_set_id, + const int fair_order) +{ + SculptSession *ss = ob->sculpt; + const int totvert = SCULPT_vertex_count_get(ss); + + Mesh *mesh = ob->data; + bool *fair_vertices = MEM_malloc_arrayN(sizeof(bool), totvert, "fair vertices"); + + SCULPT_boundary_info_ensure(ob); + + for (int i = 0; i < totvert; i++) { + fair_vertices[i] = !SCULPT_vertex_is_boundary(ss, i) && + SCULPT_vertex_has_face_set(ss, i, active_face_set_id) && + SCULPT_vertex_has_unique_face_set(ss, i); + } + + MVert *mvert = SCULPT_mesh_deformed_mverts_get(ss); + BKE_mesh_prefair_and_fair_vertices(mesh, mvert, fair_vertices, fair_order); + MEM_freeN(fair_vertices); +} + static void sculpt_face_set_apply_edit(Object *ob, const int active_face_set_id, const int mode, @@ -1204,6 +1246,12 @@ static void sculpt_face_set_apply_edit(Object *ob, case SCULPT_FACE_SET_EDIT_DELETE_GEOMETRY: sculpt_face_set_delete_geometry(ob, ss, active_face_set_id, modify_hidden); break; + case SCULPT_FACE_SET_EDIT_FAIR_POSITIONS: + sculpt_face_set_edit_fair_face_set(ob, active_face_set_id, MESH_FAIRING_DEPTH_POSITION); + break; + case SCULPT_FACE_SET_EDIT_FAIR_TANGENCY: + sculpt_face_set_edit_fair_face_set(ob, active_face_set_id, MESH_FAIRING_DEPTH_TANGENCY); + break; } } @@ -1230,6 +1278,16 @@ static bool sculpt_face_set_edit_is_operation_valid(SculptSession *ss, return false; } } + + if (ELEM(mode, SCULPT_FACE_SET_EDIT_FAIR_POSITIONS, SCULPT_FACE_SET_EDIT_FAIR_TANGENCY)) { + if (BKE_pbvh_type(ss->pbvh) == PBVH_GRIDS) { + /* TODO: Multires topology representation using grids and duplicates can't be used directly + * by the fair algorithm. Multires topology needs to be exposed in a different way or + * converted to a mesh for this operation. */ + return false; + } + } + return true; } @@ -1287,11 +1345,38 @@ static void sculpt_face_set_edit_modify_face_sets(Object *ob, MEM_freeN(nodes); } +static void sculpt_face_set_edit_modify_coordinates(bContext *C, + Object *ob, + const int active_face_set, + const eSculptFaceSetEditMode mode) +{ + Sculpt *sd = CTX_data_tool_settings(C)->sculpt; + SculptSession *ss = ob->sculpt; + PBVH *pbvh = ss->pbvh; + PBVHNode **nodes; + int totnode; + BKE_pbvh_search_gather(pbvh, NULL, NULL, &nodes, &totnode); + SCULPT_undo_push_begin(ob, "face set edit"); + for (int i = 0; i < totnode; i++) { + BKE_pbvh_node_mark_update(nodes[i]); + SCULPT_undo_push_node(ob, nodes[i], SCULPT_UNDO_COORDS); + } + sculpt_face_set_apply_edit(ob, abs(active_face_set), mode, false); + + if (ss->deform_modifiers_active || ss->shapekey_active) { + SCULPT_flush_stroke_deform(sd, ob, true); + } + SCULPT_flush_update_step(C, SCULPT_UPDATE_COORDS); + SCULPT_flush_update_done(C, ob, SCULPT_UPDATE_COORDS); + SCULPT_undo_push_end(); + MEM_freeN(nodes); +} + static int sculpt_face_set_edit_invoke(bContext *C, wmOperator *op, const wmEvent *event) { Object *ob = CTX_data_active_object(C); SculptSession *ss = ob->sculpt; - Depsgraph *depsgraph = CTX_data_depsgraph_pointer(C); + Depsgraph *depsgraph = CTX_data_ensure_evaluated_depsgraph(C); const int mode = RNA_enum_get(op->ptr, "mode"); const bool modify_hidden = RNA_boolean_get(op->ptr, "modify_hidden"); @@ -1320,6 +1405,10 @@ static int sculpt_face_set_edit_invoke(bContext *C, wmOperator *op, const wmEven case SCULPT_FACE_SET_EDIT_SHRINK: sculpt_face_set_edit_modify_face_sets(ob, active_face_set, mode, modify_hidden); break; + case SCULPT_FACE_SET_EDIT_FAIR_POSITIONS: + case SCULPT_FACE_SET_EDIT_FAIR_TANGENCY: + sculpt_face_set_edit_modify_coordinates(C, ob, active_face_set, mode); + break; } SCULPT_tag_update_overlays(C); -- cgit v1.2.3 From 1e799dd26ec1e8487d61f7cdfb592dc86881df18 Mon Sep 17 00:00:00 2001 From: Julian Eisel Date: Tue, 15 Dec 2020 21:20:57 +0100 Subject: Fix various issues with temporary, maximized File Browsers If Preferences > Interface > Temporary Editors > File Browser is set to "Maximized Area", opening a File Browser from a File or Asset Browser as regular editor would cause some issues. For example after closing the temporary File Browser, the regular browser would take over the file path and display settings from the temporary one. This is because they used to share the same area data. Some similar issues may have happend with temporary image editors. Now, this commit finally separates the space data of temporary maximized editors from the regular ones. So the editor data is entirely independent now, as it should be. --- source/blender/editors/include/ED_screen.h | 1 + source/blender/editors/screen/screen_edit.c | 187 ++++++++++++++++------------ 2 files changed, 111 insertions(+), 77 deletions(-) (limited to 'source/blender/editors') diff --git a/source/blender/editors/include/ED_screen.h b/source/blender/editors/include/ED_screen.h index dc1c43c0337..20417634020 100644 --- a/source/blender/editors/include/ED_screen.h +++ b/source/blender/editors/include/ED_screen.h @@ -239,6 +239,7 @@ void ED_screen_restore_temp_type(struct bContext *C, ScrArea *area); ScrArea *ED_screen_full_newspace(struct bContext *C, ScrArea *area, int type); void ED_screen_full_prevspace(struct bContext *C, ScrArea *area); void ED_screen_full_restore(struct bContext *C, ScrArea *area); +ScrArea *ED_screen_state_maximized_create(struct bContext *C); struct ScrArea *ED_screen_state_toggle(struct bContext *C, struct wmWindow *win, struct ScrArea *area, diff --git a/source/blender/editors/screen/screen_edit.c b/source/blender/editors/screen/screen_edit.c index c3dcaefab79..be52874ed0b 100644 --- a/source/blender/editors/screen/screen_edit.c +++ b/source/blender/editors/screen/screen_edit.c @@ -1133,12 +1133,11 @@ void ED_screen_scene_change(bContext *C, wmWindow *win, Scene *scene) ScrArea *ED_screen_full_newspace(bContext *C, ScrArea *area, int type) { - wmWindow *win = CTX_wm_window(C); ScrArea *newsa = NULL; SpaceLink *newsl; if (!area || area->full == NULL) { - newsa = ED_screen_state_toggle(C, win, area, SCREENMAXIMIZED); + newsa = ED_screen_state_maximized_create(C); } if (!newsa) { @@ -1149,11 +1148,11 @@ ScrArea *ED_screen_full_newspace(bContext *C, ScrArea *area, int type) newsl = newsa->spacedata.first; /* Tag the active space before changing, so we can identify it when user wants to go back. */ - if ((newsl->link_flag & SPACE_FLAG_TYPE_TEMPORARY) == 0) { + if (newsl && (newsl->link_flag & SPACE_FLAG_TYPE_TEMPORARY) == 0) { newsl->link_flag |= SPACE_FLAG_TYPE_WAS_ACTIVE; } - ED_area_newspace(C, newsa, type, newsl->link_flag & SPACE_FLAG_TYPE_TEMPORARY); + ED_area_newspace(C, newsa, type, (newsl && newsl->link_flag & SPACE_FLAG_TYPE_TEMPORARY)); return newsa; } @@ -1217,13 +1216,108 @@ void ED_screen_full_restore(bContext *C, ScrArea *area) } /** - * this function toggles: if area is maximized/full then the parent will be restored + * \param toggle_area: If this is set, its space data will be swapped with the one of the new emtpy + * area, when toggling back it can be swapped back again. + * \return The newly created screen with the non-normal area. + */ +static bScreen *screen_state_to_nonnormal(bContext *C, + wmWindow *win, + ScrArea *toggle_area, + int state) +{ + Main *bmain = CTX_data_main(C); + WorkSpace *workspace = WM_window_get_active_workspace(win); + + /* change from SCREENNORMAL to new state */ + WorkSpaceLayout *layout_new; + ScrArea *newa; + char newname[MAX_ID_NAME - 2]; + + BLI_assert(ELEM(state, SCREENMAXIMIZED, SCREENFULL)); + + bScreen *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); + + bScreen *screen = BKE_workspace_layout_screen_get(layout_new); + screen->state = state; + screen->redraws_flag = oldscreen->redraws_flag; + screen->temp = oldscreen->temp; + screen->flag = oldscreen->flag; + + /* timer */ + screen->animtimer = oldscreen->animtimer; + oldscreen->animtimer = NULL; + + newa = (ScrArea *)screen->areabase.first; + + /* swap area */ + if (toggle_area) { + ED_area_data_swap(newa, toggle_area); + newa->flag = toggle_area->flag; /* mostly for AREA_FLAG_WASFULLSCREEN */ + } + + if (state == SCREENFULL) { + /* temporarily hide global areas */ + LISTBASE_FOREACH (ScrArea *, glob_area, &win->global_areas.areabase) { + glob_area->global->flag |= GLOBAL_AREA_IS_HIDDEN; + } + /* temporarily hide the side panels/header */ + LISTBASE_FOREACH (ARegion *, region, &newa->regionbase) { + region->flagfullscreen = region->flag; + + if (ELEM(region->regiontype, + RGN_TYPE_UI, + RGN_TYPE_HEADER, + RGN_TYPE_TOOL_HEADER, + RGN_TYPE_FOOTER, + RGN_TYPE_TOOLS, + RGN_TYPE_NAV_BAR, + RGN_TYPE_EXECUTE)) { + region->flag |= RGN_FLAG_HIDDEN; + } + } + } + + if (toggle_area) { + toggle_area->full = oldscreen; + } + newa->full = oldscreen; + + ED_screen_change(C, screen); + ED_area_tag_refresh(newa); + + return screen; +} + +/** + * Create a new temporary screen with a maximized, empty area. + * This can be closed with #ED_screen_state_toggle(). + * + * Use this to just create a new maximized screen/area, rather than maximizing an existing one. + * Otherwise, maximize with #ED_screen_state_toggle(). + */ +ScrArea *ED_screen_state_maximized_create(bContext *C) +{ + bScreen *screen = screen_state_to_nonnormal(C, CTX_wm_window(C), NULL, SCREENMAXIMIZED); + return screen->areabase.first; +} + +/** + * This function toggles: if area is maximized/full then the parent will be restored. + * + * Use #ED_screen_state_maximized_create() if you do not want the toggle behavior when changing to + * a maximized area. I.e. if you just want to open a new maximized screen/area, not maximize a + * specific area. In the former case, space data of the maximized and non-maximized area should be + * independent, in the latter it should be the same. * * \warning \a area may be freed. */ ScrArea *ED_screen_state_toggle(bContext *C, wmWindow *win, ScrArea *area, const short state) { - Main *bmain = CTX_data_main(C); wmWindowManager *wm = CTX_wm_manager(C); WorkSpace *workspace = WM_window_get_active_workspace(win); @@ -1257,7 +1351,7 @@ ScrArea *ED_screen_state_toggle(bContext *C, wmWindow *win, ScrArea *area, const screen->state = SCREENNORMAL; screen->flag = oldscreen->flag; - /* find old area to restore from */ + /* Find old area we may have swapped dummy space data to. It's swapped back here. */ ScrArea *fullsa = NULL; LISTBASE_FOREACH (ScrArea *, old, &screen->areabase) { /* area to restore from is always first */ @@ -1271,13 +1365,6 @@ ScrArea *ED_screen_state_toggle(bContext *C, wmWindow *win, ScrArea *area, const area->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 */ LISTBASE_FOREACH (ScrArea *, glob_area, &win->global_areas.areabase) { @@ -1289,14 +1376,16 @@ ScrArea *ED_screen_state_toggle(bContext *C, wmWindow *win, ScrArea *area, const } } - ED_area_data_swap(fullsa, area); + if (fullsa) { + ED_area_data_swap(fullsa, area); + ED_area_tag_refresh(fullsa); + } /* animtimer back */ screen->animtimer = oldscreen->animtimer; oldscreen->animtimer = NULL; ED_screen_change(C, screen); - ED_area_tag_refresh(fullsa); BKE_workspace_layout_remove(CTX_data_main(C), workspace, layout_old); @@ -1307,69 +1396,16 @@ ScrArea *ED_screen_state_toggle(bContext *C, wmWindow *win, ScrArea *area, const screen->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)); - - bScreen *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); - - screen = BKE_workspace_layout_screen_get(layout_new); - screen->state = state; - screen->redraws_flag = oldscreen->redraws_flag; - screen->temp = oldscreen->temp; - screen->flag = oldscreen->flag; - - /* timer */ - screen->animtimer = oldscreen->animtimer; - oldscreen->animtimer = NULL; + ScrArea *toggle_area = area; /* 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 (!area || area->global) { - area = oldscreen->areabase.first; + if (!toggle_area || toggle_area->global) { + bScreen *oldscreen = WM_window_get_active_screen(win); + toggle_area = oldscreen->areabase.first; } - newa = (ScrArea *)screen->areabase.first; - - /* copy area */ - ED_area_data_swap(newa, area); - newa->flag = area->flag; /* mostly for AREA_FLAG_WASFULLSCREEN */ - - if (state == SCREENFULL) { - /* temporarily hide global areas */ - LISTBASE_FOREACH (ScrArea *, glob_area, &win->global_areas.areabase) { - glob_area->global->flag |= GLOBAL_AREA_IS_HIDDEN; - } - /* temporarily hide the side panels/header */ - LISTBASE_FOREACH (ARegion *, region, &newa->regionbase) { - region->flagfullscreen = region->flag; - - if (ELEM(region->regiontype, - RGN_TYPE_UI, - RGN_TYPE_HEADER, - RGN_TYPE_TOOL_HEADER, - RGN_TYPE_FOOTER, - RGN_TYPE_TOOLS, - RGN_TYPE_NAV_BAR, - RGN_TYPE_EXECUTE)) { - region->flag |= RGN_FLAG_HIDDEN; - } - } - } - - area->full = oldscreen; - newa->full = oldscreen; - - ED_screen_change(C, screen); - ED_area_tag_refresh(newa); + screen = screen_state_to_nonnormal(C, win, toggle_area, state); } /* XXX bad code: setscreen() ends with first area active. fullscreen render assumes this too */ @@ -1413,9 +1449,6 @@ ScrArea *ED_screen_temp_space_open(bContext *C, area->flag |= AREA_FLAG_STACKED_FULLSCREEN; ((SpaceLink *)area->spacedata.first)->link_flag |= SPACE_FLAG_TYPE_TEMPORARY; } - else if (ctx_area != NULL && ctx_area->spacetype == space_type) { - area = ED_screen_state_toggle(C, CTX_wm_window(C), ctx_area, SCREENMAXIMIZED); - } else { area = ED_screen_full_newspace(C, ctx_area, (int)space_type); ((SpaceLink *)area->spacedata.first)->link_flag |= SPACE_FLAG_TYPE_TEMPORARY; -- cgit v1.2.3 From 9e4a4c2e996c3741c2beaf5ed5aadc8cb8801ac3 Mon Sep 17 00:00:00 2001 From: Richard Antalik Date: Tue, 15 Dec 2020 21:42:06 +0100 Subject: VSE: Move remove gaps operator logic to module code Logic was broken into finding gaps and ofsetting strips. Functions were modified so they work on explicitly defined seqbase, so they can be used as python API functions. Functional changes: - Improve performance by calculating gap length and offseting strips at once. Previously strips were offset by one frame. - Calculate gap from start frame. Previously gap was considered only inbetween strips. Reviewed By: sergey Differential Revision: https://developer.blender.org/D9730 --- .../editors/space_sequencer/sequencer_draw.c | 2 +- .../editors/space_sequencer/sequencer_edit.c | 116 ++------------------- .../editors/space_sequencer/sequencer_intern.h | 1 - .../editors/space_sequencer/sequencer_view.c | 8 +- 4 files changed, 14 insertions(+), 113 deletions(-) (limited to 'source/blender/editors') diff --git a/source/blender/editors/space_sequencer/sequencer_draw.c b/source/blender/editors/space_sequencer/sequencer_draw.c index 081714991ff..e31fa3205ba 100644 --- a/source/blender/editors/space_sequencer/sequencer_draw.c +++ b/source/blender/editors/space_sequencer/sequencer_draw.c @@ -2292,7 +2292,7 @@ void draw_timeline_seq(const bContext *C, ARegion *region) UI_view2d_view_ortho(v2d); /* Get timeline bound-box, needed for the scroll-bars. */ - boundbox_seq(scene, &v2d->tot); + SEQ_timeline_boundbox(scene, ed->seqbasep, &v2d->tot); draw_seq_backdrop(v2d); UI_view2d_constant_grid_draw(v2d, FPS); diff --git a/source/blender/editors/space_sequencer/sequencer_edit.c b/source/blender/editors/space_sequencer/sequencer_edit.c index 953a77d22a6..184f821d411 100644 --- a/source/blender/editors/space_sequencer/sequencer_edit.c +++ b/source/blender/editors/space_sequencer/sequencer_edit.c @@ -183,117 +183,13 @@ bool sequencer_view_strips_poll(bContext *C) /** \name Remove Gaps Operator * \{ */ -static bool sequence_offset_after_frame(Scene *scene, const int delta, const int timeline_frame) -{ - Sequence *seq; - Editing *ed = BKE_sequencer_editing_get(scene, false); - bool done = false; - TimeMarker *marker; - - /* All strips >= timeline_frame are shifted. */ - - if (ed == NULL) { - return 0; - } - - for (seq = ed->seqbasep->first; seq; seq = seq->next) { - if (seq->startdisp >= timeline_frame) { - BKE_sequence_translate(scene, seq, delta); - BKE_sequence_calc(scene, seq); - BKE_sequence_invalidate_cache_preprocessed(scene, seq); - done = true; - } - } - - if (!scene->toolsettings->lock_markers) { - for (marker = scene->markers.first; marker; marker = marker->next) { - if (marker->frame >= timeline_frame) { - marker->frame += delta; - } - } - } - - return done; -} - -void boundbox_seq(Scene *scene, rctf *rect) -{ - Sequence *seq; - Editing *ed = BKE_sequencer_editing_get(scene, false); - float min[2], max[2]; - - if (ed == NULL) { - return; - } - - min[0] = SFRA; - max[0] = EFRA + 1; - min[1] = 0.0; - max[1] = 8.0; - - seq = ed->seqbasep->first; - while (seq) { - - if (min[0] > seq->startdisp - 1) { - min[0] = seq->startdisp - 1; - } - if (max[0] < seq->enddisp + 1) { - max[0] = seq->enddisp + 1; - } - if (max[1] < seq->machine + 2) { - max[1] = seq->machine + 2; - } - - seq = seq->next; - } - - rect->xmin = min[0]; - rect->xmax = max[0]; - rect->ymin = min[1]; - rect->ymax = max[1]; -} - static int sequencer_gap_remove_exec(bContext *C, wmOperator *op) { Scene *scene = CTX_data_scene(C); - rctf rectf; - int timeline_frame, efra, sfra; - bool first = false, done; - bool do_all = RNA_boolean_get(op->ptr, "all"); - - /* Get first and last frame. */ - boundbox_seq(scene, &rectf); - sfra = (int)rectf.xmin; - efra = (int)rectf.xmax; - - /* Check if the current frame has a gap already. */ - for (timeline_frame = CFRA; timeline_frame >= sfra; timeline_frame--) { - if (SEQ_render_evaluate_frame(scene, timeline_frame)) { - first = true; - break; - } - } + const bool do_all = RNA_boolean_get(op->ptr, "all"); + const Editing *ed = BKE_sequencer_editing_get(scene, false); - for (; timeline_frame < efra; timeline_frame++) { - /* There's still no strip to remove a gap for. */ - if (first == false) { - if (SEQ_render_evaluate_frame(scene, timeline_frame)) { - first = true; - } - } - else if (SEQ_render_evaluate_frame(scene, timeline_frame) == 0) { - done = true; - while (SEQ_render_evaluate_frame(scene, timeline_frame) == 0) { - done = sequence_offset_after_frame(scene, -1, timeline_frame); - if (done == false) { - break; - } - } - if (done == false || do_all == false) { - break; - } - } - } + SEQ_edit_remove_gaps(scene, ed->seqbasep, CFRA, do_all); WM_event_add_notifier(C, NC_SCENE | ND_SEQUENCER, scene); DEG_id_tag_update(&scene->id, ID_RECALC_SEQUENCER_STRIPS); @@ -330,9 +226,9 @@ void SEQUENCER_OT_gap_remove(struct wmOperatorType *ot) static int sequencer_gap_insert_exec(bContext *C, wmOperator *op) { Scene *scene = CTX_data_scene(C); - int frames = RNA_int_get(op->ptr, "frames"); - - sequence_offset_after_frame(scene, frames, CFRA); + const int frames = RNA_int_get(op->ptr, "frames"); + const Editing *ed = BKE_sequencer_editing_get(scene, false); + SEQ_offset_after_frame(scene, ed->seqbasep, frames, CFRA); WM_event_add_notifier(C, NC_SCENE | ND_SEQUENCER, scene); diff --git a/source/blender/editors/space_sequencer/sequencer_intern.h b/source/blender/editors/space_sequencer/sequencer_intern.h index 1ea4fb05d53..6ccfd3a9045 100644 --- a/source/blender/editors/space_sequencer/sequencer_intern.h +++ b/source/blender/editors/space_sequencer/sequencer_intern.h @@ -71,7 +71,6 @@ struct ImBuf *sequencer_ibuf_get(struct Main *bmain, /* sequencer_edit.c */ struct View2D; void seq_rectf(struct Sequence *seq, struct rctf *rectf); -void boundbox_seq(struct Scene *scene, struct rctf *rect); struct Sequence *find_nearest_seq(struct Scene *scene, struct View2D *v2d, int *hand, diff --git a/source/blender/editors/space_sequencer/sequencer_view.c b/source/blender/editors/space_sequencer/sequencer_view.c index 75d92d5f00d..d2166705943 100644 --- a/source/blender/editors/space_sequencer/sequencer_view.c +++ b/source/blender/editors/space_sequencer/sequencer_view.c @@ -87,8 +87,14 @@ static int sequencer_view_all_exec(bContext *C, wmOperator *op) rctf box; const int smooth_viewtx = WM_operator_smooth_viewtx_get(op); + Scene *scene = CTX_data_scene(C); + const Editing *ed = BKE_sequencer_editing_get(scene, false); + + if (ed == NULL) { + return OPERATOR_FINISHED; + } - boundbox_seq(CTX_data_scene(C), &box); + SEQ_timeline_boundbox(scene, ed->seqbasep, &box); UI_view2d_smooth_view(C, region, &box, smooth_viewtx); return OPERATOR_FINISHED; } -- cgit v1.2.3 From 151e847b8709c44a731f3d07c9a50139d728e227 Mon Sep 17 00:00:00 2001 From: Falk David Date: Tue, 15 Dec 2020 22:28:28 +0100 Subject: GPencil: Improve interpolation of strokes with unequal lengths Use the BKE_gpencil_stroke_uniform_subdivide function to subdivide strokes before interpolation. When the target/source stroke is smaller than the other stroke, it is subdivided until the lengths match. This improves the overall quality of the interpolation of different sized strokes. Before/After video: {F9511779} Reviewed By: #grease_pencil, antoniov, pepeland, mendio Differential Revision: https://developer.blender.org/D9839 --- .../blender/editors/gpencil/gpencil_interpolate.c | 69 +++++++++++----------- 1 file changed, 34 insertions(+), 35 deletions(-) (limited to 'source/blender/editors') diff --git a/source/blender/editors/gpencil/gpencil_interpolate.c b/source/blender/editors/gpencil/gpencil_interpolate.c index 3617f20763e..9bca294cf30 100644 --- a/source/blender/editors/gpencil/gpencil_interpolate.c +++ b/source/blender/editors/gpencil/gpencil_interpolate.c @@ -283,8 +283,8 @@ static void gpencil_interpolate_set_points(bContext *C, tGPDinterpolate *tgpi) tgpil = MEM_callocN(sizeof(tGPDinterpolate_layer), "GPencil Interpolate Layer"); tgpil->gpl = gpl; - tgpil->prevFrame = gpl->actframe; - tgpil->nextFrame = gpl->actframe->next; + tgpil->prevFrame = BKE_gpencil_frame_duplicate(gpl->actframe); + tgpil->nextFrame = BKE_gpencil_frame_duplicate(gpl->actframe->next); BLI_addtail(&tgpi->ilayers, tgpil); @@ -326,24 +326,25 @@ static void gpencil_interpolate_set_points(bContext *C, tGPDinterpolate *tgpi) valid = false; } - /* create new stroke */ - new_stroke = BKE_gpencil_stroke_duplicate(gps_from, true, true); - if (valid) { /* if destination stroke is smaller, resize new_stroke to size of gps_to stroke */ if (gps_from->totpoints > gps_to->totpoints) { - new_stroke->points = MEM_recallocN(new_stroke->points, - sizeof(*new_stroke->points) * gps_to->totpoints); - if (new_stroke->dvert != NULL) { - new_stroke->dvert = MEM_recallocN(new_stroke->dvert, - sizeof(*new_stroke->dvert) * gps_to->totpoints); - } - new_stroke->totpoints = gps_to->totpoints; + BKE_gpencil_stroke_uniform_subdivide(gpd, gps_to, gps_from->totpoints, true); } - /* update points position */ + if (gps_to->totpoints > gps_from->totpoints) { + BKE_gpencil_stroke_uniform_subdivide(gpd, gps_from, gps_to->totpoints, true); + } + + /* Create new stroke. */ + new_stroke = BKE_gpencil_stroke_duplicate(gps_from, true, true); + + /* Update points position. */ gpencil_interpolate_update_points(gps_from, gps_to, new_stroke, tgpil->factor); } else { + /* Create new stroke. */ + new_stroke = BKE_gpencil_stroke_duplicate(gps_from, true, true); + /* need an empty stroke to keep index correct for lookup, but resize to smallest size */ new_stroke->totpoints = 0; new_stroke->points = MEM_recallocN(new_stroke->points, sizeof(*new_stroke->points)); @@ -443,12 +444,16 @@ static void gpencil_interpolate_exit(bContext *C, wmOperator *op) /* finally, free memory used by temp data */ LISTBASE_FOREACH (tGPDinterpolate_layer *, tgpil, &tgpi->ilayers) { + BKE_gpencil_free_strokes(tgpil->prevFrame); + BKE_gpencil_free_strokes(tgpil->nextFrame); BKE_gpencil_free_strokes(tgpil->interFrame); - MEM_freeN(tgpil->interFrame); + MEM_SAFE_FREE(tgpil->prevFrame); + MEM_SAFE_FREE(tgpil->nextFrame); + MEM_SAFE_FREE(tgpil->interFrame); } BLI_freelistN(&tgpi->ilayers); - MEM_freeN(tgpi); + MEM_SAFE_FREE(tgpi); } DEG_id_tag_update(&gpd->id, ID_RECALC_TRANSFORM | ID_RECALC_GEOMETRY); WM_event_add_notifier(C, NC_GPENCIL | NA_EDITED, NULL); @@ -992,8 +997,8 @@ static int gpencil_interpolate_seq_exec(bContext *C, wmOperator *op) } /* store extremes */ - prevFrame = gpl->actframe; - nextFrame = gpl->actframe->next; + prevFrame = BKE_gpencil_frame_duplicate(gpl->actframe); + nextFrame = BKE_gpencil_frame_duplicate(gpl->actframe->next); /* Loop over intermediary frames and create the interpolation */ for (cframe = prevFrame->framenum + step; cframe < nextFrame->framenum; cframe += step) { @@ -1049,28 +1054,17 @@ static int gpencil_interpolate_seq_exec(bContext *C, wmOperator *op) interFrame->key_type = BEZT_KEYTYPE_BREAKDOWN; } - /* create new stroke */ - bGPDstroke *new_stroke = BKE_gpencil_stroke_duplicate(gps_from, true, true); - /* if destination stroke is smaller, resize new_stroke to size of gps_to stroke */ if (gps_from->totpoints > gps_to->totpoints) { - /* free weights of removed points */ - if (new_stroke->dvert != NULL) { - BKE_defvert_array_free_elems(new_stroke->dvert + gps_to->totpoints, - gps_from->totpoints - gps_to->totpoints); - } - - new_stroke->points = MEM_recallocN(new_stroke->points, - sizeof(*new_stroke->points) * gps_to->totpoints); - - if (new_stroke->dvert != NULL) { - new_stroke->dvert = MEM_recallocN(new_stroke->dvert, - sizeof(*new_stroke->dvert) * gps_to->totpoints); - } - - new_stroke->totpoints = gps_to->totpoints; + BKE_gpencil_stroke_uniform_subdivide(gpd, gps_to, gps_from->totpoints, true); + } + if (gps_to->totpoints > gps_from->totpoints) { + BKE_gpencil_stroke_uniform_subdivide(gpd, gps_from, gps_to->totpoints, true); } + /* create new stroke */ + bGPDstroke *new_stroke = BKE_gpencil_stroke_duplicate(gps_from, true, true); + /* update points position */ gpencil_interpolate_update_points(gps_from, gps_to, new_stroke, factor); @@ -1081,6 +1075,11 @@ static int gpencil_interpolate_seq_exec(bContext *C, wmOperator *op) BLI_addtail(&interFrame->strokes, new_stroke); } } + + BKE_gpencil_free_strokes(prevFrame); + BKE_gpencil_free_strokes(nextFrame); + MEM_SAFE_FREE(prevFrame); + MEM_SAFE_FREE(nextFrame); } /* notifiers */ -- cgit v1.2.3 From dd9d12bf45edac33fb414b9d7e4a0a716b2fa4d0 Mon Sep 17 00:00:00 2001 From: Peter Fog Date: Tue, 15 Dec 2020 22:01:58 +0100 Subject: VSE: Paste strips after playhead by default Paste copied strips after playhead, because this is more intuitive. Previous functionality is still available by enabling "Keep Offset" property, or under shortcut Ctrl+Shift+V. Reviewed By: ISS Differential Revision: https://developer.blender.org/D9734 --- .../editors/space_sequencer/sequencer_edit.c | 26 ++++++++++++++++++++-- 1 file changed, 24 insertions(+), 2 deletions(-) (limited to 'source/blender/editors') diff --git a/source/blender/editors/space_sequencer/sequencer_edit.c b/source/blender/editors/space_sequencer/sequencer_edit.c index 184f821d411..1e3529a9607 100644 --- a/source/blender/editors/space_sequencer/sequencer_edit.c +++ b/source/blender/editors/space_sequencer/sequencer_edit.c @@ -2527,7 +2527,7 @@ void ED_sequencer_deselect_all(Scene *scene) SEQ_CURRENT_END; } -static int sequencer_paste_exec(bContext *C, wmOperator *UNUSED(op)) +static int sequencer_paste_exec(bContext *C, wmOperator *op) { Main *bmain = CTX_data_main(C); Scene *scene = CTX_data_scene(C); @@ -2536,8 +2536,25 @@ static int sequencer_paste_exec(bContext *C, wmOperator *UNUSED(op)) int ofs; Sequence *iseq, *iseq_first; + if (BLI_listbase_count(&seqbase_clipboard) == 0) { + BKE_report(op->reports, RPT_INFO, "No strips to paste"); + return OPERATOR_CANCELLED; + } + ED_sequencer_deselect_all(scene); - ofs = scene->r.cfra - seqbase_clipboard_frame; + if (RNA_boolean_get(op->ptr, "keep_offset")) { + ofs = scene->r.cfra - seqbase_clipboard_frame; + } + else { + int min_seq_startdisp = INT_MAX; + LISTBASE_FOREACH (Sequence *, seq, &seqbase_clipboard) { + if (seq->startdisp < min_seq_startdisp) { + min_seq_startdisp = seq->startdisp; + } + } + /* Paste strips after playhead. */ + ofs = scene->r.cfra - min_seq_startdisp; + } /* Copy strips, temporarily restoring pointers to actual data-blocks. This * must happen on the clipboard itself, so that copying does user counting @@ -2585,6 +2602,11 @@ void SEQUENCER_OT_paste(wmOperatorType *ot) /* Flags. */ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; + + /* Properties. */ + PropertyRNA *prop = RNA_def_boolean( + ot->srna, "keep_offset", false, "Keep Offset", "Keep strip offset to playhead when pasting"); + RNA_def_property_flag(prop, PROP_SKIP_SAVE); } /** \} */ -- cgit v1.2.3 From fad80a95fd08ec87a37f30f0b94a7061d4e382f2 Mon Sep 17 00:00:00 2001 From: Peter Fog Date: Tue, 15 Dec 2020 23:15:32 +0100 Subject: VSE: Add Overlay popover panels Add panels with overlay settings for strips and preview and overlay enable/disable button. Entries from the View menus moved to the overlay panels, which will simplify cluttered View menus. Additional options have been added: - Strip Name - Strip Source(ex. path) - Strip Duration So users can now select what info they need to see on the strips. When No text is displayed, waveforms are drawn in full height. Reviewed By: ISS, HooglyBoogly, pablovazquez Differential Revision: https://developer.blender.org/D9751 --- .../editors/space_sequencer/sequencer_draw.c | 288 +++++++++++---------- .../editors/space_sequencer/space_sequencer.c | 5 +- 2 files changed, 155 insertions(+), 138 deletions(-) (limited to 'source/blender/editors') diff --git a/source/blender/editors/space_sequencer/sequencer_draw.c b/source/blender/editors/space_sequencer/sequencer_draw.c index e31fa3205ba..ac1b9e6d0a0 100644 --- a/source/blender/editors/space_sequencer/sequencer_draw.c +++ b/source/blender/editors/space_sequencer/sequencer_draw.c @@ -227,16 +227,16 @@ void color3ubv_from_seq(Scene *curscene, Sequence *seq, uchar col[3]) * \param x1, x2, y1, y2: The starting and end X value to draw the wave, same for y1 and y2. * \param stepsize: The width of a pixel. */ -static void draw_seq_waveform(View2D *v2d, - const bContext *C, - SpaceSeq *sseq, - Scene *scene, - Sequence *seq, - float x1, - float y1, - float x2, - float y2, - float stepsize) +static void draw_seq_waveform_overlay(View2D *v2d, + const bContext *C, + SpaceSeq *sseq, + Scene *scene, + Sequence *seq, + float x1, + float y1, + float x2, + float y2, + float stepsize) { /* Offset x1 and x2 values, to match view min/max, if strip is out of bounds. */ int x1_offset = max_ff(v2d->cur.xmin, x1); @@ -603,121 +603,113 @@ static void draw_seq_outline(Sequence *seq, } } -/* Draw info text on a sequence strip. */ -static void draw_seq_text(View2D *v2d, - Sequence *seq, - SpaceSeq *sseq, - float x1, - float x2, - float y1, - float y2, - bool seq_active, - bool y_threshold) +const char *draw_seq_text_get_name(SpaceSeq *sseq, Sequence *seq) { - rctf rect; - char str[32 + FILE_MAX]; - size_t str_len; const char *name = seq->name + 2; - uchar col[4]; - - /* All strings should include name. */ if (name[0] == '\0') { name = BKE_sequence_give_name(seq); } + return name; +} - if (ELEM(seq->type, SEQ_TYPE_META, SEQ_TYPE_ADJUSTMENT)) { - str_len = BLI_snprintf(str, sizeof(str), "%s | %d", name, seq->len); +static void draw_seq_text_get_source(SpaceSeq *sseq, + Sequence *seq, + char *r_source, + size_t source_len) +{ + /* Set source for the most common types. */ + if (ELEM(seq->type, SEQ_TYPE_IMAGE, SEQ_TYPE_MOVIE)) { + BLI_snprintf(r_source, source_len, "%s%s", seq->strip->dir, seq->strip->stripdata->name); } - else if (seq->type == SEQ_TYPE_SCENE) { - if (seq->scene) { - if (seq->scene_camera) { - str_len = BLI_snprintf(str, - sizeof(str), - "%s: %s (%s) | %d", - name, - seq->scene->id.name + 2, - ((ID *)seq->scene_camera)->name + 2, - seq->len); - } - else { - str_len = BLI_snprintf( - str, sizeof(str), "%s: %s | %d", name, seq->scene->id.name + 2, seq->len); - } - } - else { - str_len = BLI_snprintf(str, sizeof(str), "%s | %d", name, seq->len); + else if (seq->type == SEQ_TYPE_SOUND_RAM) { + if (seq->sound) { + BLI_snprintf(r_source, source_len, "%s", seq->sound->filepath); } } - else if (seq->type == SEQ_TYPE_MOVIECLIP) { - if (seq->clip && !STREQ(name, seq->clip->id.name + 2)) { - str_len = BLI_snprintf( - str, sizeof(str), "%s: %s | %d", name, seq->clip->id.name + 2, seq->len); - } - else { - str_len = BLI_snprintf(str, sizeof(str), "%s | %d", name, seq->len); - } + else if (seq->type == SEQ_TYPE_MULTICAM) { + BLI_snprintf(r_source, source_len, "Channel: %d", seq->multicam_source); } - else if (seq->type == SEQ_TYPE_MASK) { - if (seq->mask && !STREQ(name, seq->mask->id.name + 2)) { - str_len = BLI_snprintf( - str, sizeof(str), "%s: %s | %d", name, seq->mask->id.name + 2, seq->len); + else if (seq->type == SEQ_TYPE_TEXT) { + TextVars *textdata = seq->effectdata; + BLI_snprintf(r_source, source_len, "%s", textdata->text); + } + else if (seq->type == SEQ_TYPE_SCENE) { + if (seq->scene_camera) { + BLI_snprintf(r_source, + source_len, + "%s (%s)", + seq->scene->id.name + 2, + ((ID *)seq->scene_camera)->name + 2); } else { - str_len = BLI_snprintf(str, sizeof(str), "%s | %d", name, seq->len); + BLI_snprintf(r_source, source_len, "%s", seq->scene->id.name + 2); } } - else if (seq->type == SEQ_TYPE_MULTICAM) { - str_len = BLI_snprintf(str, sizeof(str), "Cam %s: %d", name, seq->multicam_source); - } - else if (seq->type == SEQ_TYPE_IMAGE) { - str_len = BLI_snprintf(str, - sizeof(str), - "%s: %s%s | %d", - name, - seq->strip->dir, - seq->strip->stripdata->name, - seq->len); + else if (seq->type == SEQ_TYPE_MOVIECLIP) { + BLI_snprintf(r_source, source_len, "%s", seq->clip->id.name + 2); } - else if (seq->type == SEQ_TYPE_TEXT) { - TextVars *textdata = seq->effectdata; - str_len = BLI_snprintf(str, sizeof(str), "%s | %d", textdata->text, seq->startdisp); + else if (seq->type == SEQ_TYPE_MASK) { + BLI_snprintf(r_source, source_len, "%s", seq->mask->id.name + 2); } - else if (seq->type & SEQ_TYPE_EFFECT) { - str_len = BLI_snprintf(str, sizeof(str), "%s | %d", name, seq->len); + else { + *r_source = '\0'; } - else if (seq->type == SEQ_TYPE_SOUND_RAM) { - /* If a waveform is drawn, avoid to draw text when there is not enough vertical space. */ - if (!y_threshold && (sseq->flag & SEQ_NO_WAVEFORMS) == 0 && - ((sseq->flag & SEQ_ALL_WAVEFORMS) || (seq->flag & SEQ_AUDIO_DRAW_WAVEFORM))) { +} - str[0] = 0; - str_len = 0; - } - else if (seq->sound) { - str_len = BLI_snprintf( - str, sizeof(str), "%s: %s | %d", name, seq->sound->filepath, seq->len); +static size_t draw_seq_text_get_overlay_string(SpaceSeq *sseq, + Sequence *seq, + char *r_overlay_string, + size_t overlay_string_len) +{ + const char *name = draw_seq_text_get_name(sseq, seq); + char source[FILE_MAX]; + int strip_duration = seq->enddisp - seq->startdisp; + draw_seq_text_get_source(sseq, seq, source, sizeof(source)); + + bool show_name = sseq->flag & SEQ_SHOW_STRIP_NAME; + bool show_source = (sseq->flag & (SEQ_SHOW_STRIP_SOURCE)) && source[0] != '\0'; + bool show_duration = sseq->flag & SEQ_SHOW_STRIP_DURATION; + + size_t string_len = 0; + if (show_name) { + string_len = BLI_snprintf(r_overlay_string, overlay_string_len, "%s", name); + if (show_source || show_duration) { + string_len += BLI_snprintf(r_overlay_string + string_len, overlay_string_len, " | "); } - else { - str_len = BLI_snprintf(str, sizeof(str), "%s | %d", name, seq->len); + } + if (show_source) { + string_len += BLI_snprintf(r_overlay_string + string_len, overlay_string_len, "%s", source); + if (show_duration) { + string_len += BLI_snprintf(r_overlay_string + string_len, overlay_string_len, " | "); } } - else if (seq->type == SEQ_TYPE_MOVIE) { - str_len = BLI_snprintf(str, - sizeof(str), - "%s: %s%s | %d", - name, - seq->strip->dir, - seq->strip->stripdata->name, - seq->len); + if (show_duration) { + string_len += BLI_snprintf( + r_overlay_string + string_len, overlay_string_len, "%d", strip_duration); } - else { - /* Should never get here!, but might with files from future. */ - BLI_assert(0); + return string_len; +} + +/* Draw info text on a sequence strip. */ +static void draw_seq_text_overlay(View2D *v2d, + Sequence *seq, + SpaceSeq *sseq, + float x1, + float x2, + float y1, + float y2, + bool seq_active) +{ + char overlay_string[FILE_MAX]; + size_t overlay_string_len = draw_seq_text_get_overlay_string( + sseq, seq, overlay_string, sizeof(overlay_string)); - str_len = BLI_snprintf(str, sizeof(str), "%s | %d", name, seq->len); + if (overlay_string_len == 0) { + return; } /* White text for the active strip. */ + uchar col[4]; col[0] = col[1] = col[2] = seq_active ? 255 : 10; col[3] = 255; @@ -731,15 +723,16 @@ static void draw_seq_text(View2D *v2d, } } + rctf rect; rect.xmin = x1; rect.ymin = y1; rect.xmax = x2; rect.ymax = y2; - UI_view2d_text_cache_add_rectf(v2d, &rect, str, str_len, col); + UI_view2d_text_cache_add_rectf(v2d, &rect, overlay_string, overlay_string_len, col); } -static void draw_sequence_extensions(Scene *scene, Sequence *seq, uint pos, float pixely) +static void draw_sequence_extensions_overlay(Scene *scene, Sequence *seq, uint pos, float pixely) { float x1, x2, y1, y2; uchar col[4], blend_col[3]; @@ -988,7 +981,7 @@ static void fcurve_batch_add_verts(GPUVertBuf *vbo, * - Volume for sound strips. * - Opacity for the other types. */ -static void draw_seq_fcurve( +static void draw_seq_fcurve_overlay( Scene *scene, View2D *v2d, Sequence *seq, float x1, float y1, float x2, float y2, float pixelx) { FCurve *fcu; @@ -1085,11 +1078,21 @@ static void draw_seq_strip(const bContext *C, x2 = (seq->endstill) ? (seq->start + seq->len) : seq->enddisp; y2 = seq->machine + SEQ_STRIP_OFSTOP; - /* Calculate height needed for drawing text on strip. */ - float text_margin_y = y2 - min_ff(0.40f, 20 * U.dpi_fac * pixely); + float text_margin_y; + bool y_threshold; + if ((sseq->flag & SEQ_SHOW_STRIP_NAME) || (sseq->flag & SEQ_SHOW_STRIP_SOURCE) || + (sseq->flag & SEQ_SHOW_STRIP_DURATION)) { - /* Is there enough space for drawing something else than text? */ - bool y_threshold = ((y2 - y1) / pixely) > 20 * U.dpi_fac; + /* Calculate height needed for drawing text on strip. */ + text_margin_y = y2 - min_ff(0.40f, 20 * U.dpi_fac * pixely); + + /* Is there enough space for drawing something else than text? */ + y_threshold = ((y2 - y1) / pixely) > 20 * U.dpi_fac; + } + else { + text_margin_y = y2; + y_threshold = 1; + } uint pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR); @@ -1102,12 +1105,13 @@ static void draw_seq_strip(const bContext *C, } /* Draw strip offsets when flag is enabled or during "solo preview". */ - if (!is_single_image && (seq->startofs || seq->endofs) && pixely > 0) { - if ((sseq->draw_flag & SEQ_DRAW_OFFSET_EXT) || (seq == special_seq_update)) { - draw_sequence_extensions(scene, seq, pos, pixely); + if ((sseq->flag & SEQ_SHOW_STRIP_OVERLAY)) { + if (!is_single_image && (seq->startofs || seq->endofs) && pixely > 0) { + if ((sseq->draw_flag & SEQ_DRAW_OFFSET_EXT) || (seq == special_seq_update)) { + draw_sequence_extensions_overlay(scene, seq, pos, pixely); + } } } - immUnbindProgram(); x1 = seq->startdisp; @@ -1118,24 +1122,24 @@ static void draw_seq_strip(const bContext *C, drawmeta_contents(scene, seq, x1, y1, x2, y2); } - if (sseq->flag & SEQ_SHOW_FCURVES) { - draw_seq_fcurve(scene, v2d, seq, x1, y1, x2, y2, pixelx); + if ((sseq->flag & SEQ_SHOW_STRIP_OVERLAY) && (sseq->flag & SEQ_SHOW_FCURVES)) { + draw_seq_fcurve_overlay(scene, v2d, seq, x1, y1, x2, y2, pixelx); } /* Draw sound strip waveform. */ - if ((seq->type == SEQ_TYPE_SOUND_RAM) && (sseq->flag & SEQ_NO_WAVEFORMS) == 0) { - draw_seq_waveform(v2d, - C, - sseq, - scene, - seq, - x1, - y_threshold ? y1 + 0.05f : y1, - x2, - y_threshold ? text_margin_y : y2, - BLI_rctf_size_x(®ion->v2d.cur) / region->winx); + if ((seq->type == SEQ_TYPE_SOUND_RAM) && ((sseq->flag & SEQ_SHOW_STRIP_OVERLAY)) && + (sseq->flag & SEQ_NO_WAVEFORMS) == 0) { + draw_seq_waveform_overlay(v2d, + C, + sseq, + scene, + seq, + x1, + y_threshold ? y1 + 0.05f : y1, + x2, + y_threshold ? text_margin_y : y2, + BLI_rctf_size_x(®ion->v2d.cur) / region->winx); } - /* Draw locked state. */ if (seq->flag & SEQ_LOCK) { draw_seq_locked(x1, y1, x2, y2); @@ -1162,11 +1166,21 @@ static void draw_seq_strip(const bContext *C, calculate_seq_text_offsets(v2d, seq, &x1, &x2, pixelx); - /* Don't draw strip if there is not enough vertical or horizontal space. */ - if (((x2 - x1) > 32 * pixelx * U.dpi_fac) && ((y2 - y1) > 8 * pixely * U.dpi_fac)) { - /* Depending on the vertical space, draw text on top or in the center of strip. */ - draw_seq_text( - v2d, seq, sseq, x1, x2, y_threshold ? text_margin_y : y1, y2, seq_active, y_threshold); + /* If a waveform is drawn, avoid drawing text when there is not enough vertical space. */ + if (seq->type == SEQ_TYPE_SOUND_RAM) { + if (!y_threshold && (sseq->flag & SEQ_NO_WAVEFORMS) == 0 && + ((sseq->flag & SEQ_ALL_WAVEFORMS) || (seq->flag & SEQ_AUDIO_DRAW_WAVEFORM))) { + return; + } + } + + if (sseq->flag & SEQ_SHOW_STRIP_OVERLAY) { + /* Don't draw strip if there is not enough vertical or horizontal space. */ + if (((x2 - x1) > 32 * pixelx * U.dpi_fac) && ((y2 - y1) > 8 * pixely * U.dpi_fac)) { + /* Depending on the vertical space, draw text on top or in the center of strip. */ + draw_seq_text_overlay( + v2d, seq, sseq, x1, x2, y_threshold ? text_margin_y : y1, y2, seq_active); + } } } @@ -1360,7 +1374,7 @@ static void sequencer_display_size(Scene *scene, float r_viewrect[2]) r_viewrect[0] *= scene->r.xasp / scene->r.yasp; } -static void sequencer_draw_gpencil(const bContext *C) +static void sequencer_draw_gpencil_overlay(const bContext *C) { /* Draw grease-pencil (image aligned). */ ED_annotation_draw_2dimage(C); @@ -1373,7 +1387,9 @@ static void sequencer_draw_gpencil(const bContext *C) } /* Draw content and safety borders borders. */ -static void sequencer_draw_borders(const SpaceSeq *sseq, const View2D *v2d, const Scene *scene) +static void sequencer_draw_borders_overlay(const SpaceSeq *sseq, + const View2D *v2d, + const Scene *scene) { float x1 = v2d->tot.xmin; float y1 = v2d->tot.ymin; @@ -1825,17 +1841,17 @@ void sequencer_draw_preview(const bContext *C, C, scene, region, sseq, ibuf, scope, draw_overlay, draw_backdrop); /* Draw over image. */ - if (sseq->flag & SEQ_SHOW_METADATA) { + if (sseq->flag & SEQ_SHOW_METADATA && sseq->flag & SEQ_SHOW_STRIP_OVERLAY) { ED_region_image_metadata_draw(0.0, 0.0, ibuf, &v2d->tot, 1.0, 1.0); } } - if (show_imbuf) { - sequencer_draw_borders(sseq, v2d, scene); + if (show_imbuf && (sseq->flag & SEQ_SHOW_STRIP_OVERLAY)) { + sequencer_draw_borders_overlay(sseq, v2d, scene); } - if (draw_gpencil && show_imbuf) { - sequencer_draw_gpencil(C); + if (draw_gpencil && show_imbuf && (sseq->flag & SEQ_SHOW_STRIP_OVERLAY)) { + sequencer_draw_gpencil_overlay(C); } #if 0 sequencer_draw_maskedit(C, scene, region, sseq); diff --git a/source/blender/editors/space_sequencer/space_sequencer.c b/source/blender/editors/space_sequencer/space_sequencer.c index 45c7bac54f8..64b51b70a12 100644 --- a/source/blender/editors/space_sequencer/space_sequencer.c +++ b/source/blender/editors/space_sequencer/space_sequencer.c @@ -99,7 +99,8 @@ static SpaceLink *sequencer_create(const ScrArea *UNUSED(area), const Scene *sce sseq->view = SEQ_VIEW_SEQUENCE; sseq->mainb = SEQ_DRAW_IMG_IMBUF; sseq->flag = SEQ_SHOW_GPENCIL | SEQ_USE_ALPHA | SEQ_SHOW_MARKERS | SEQ_SHOW_FCURVES | - SEQ_ZOOM_TO_FIT; + SEQ_ZOOM_TO_FIT | SEQ_SHOW_STRIP_OVERLAY | SEQ_SHOW_STRIP_NAME | + SEQ_SHOW_STRIP_SOURCE | SEQ_SHOW_STRIP_DURATION; /* Tool header. */ region = MEM_callocN(sizeof(ARegion), "tool header for sequencer"); @@ -706,7 +707,7 @@ static void sequencer_preview_region_draw(const bContext *C, ARegion *region) SpaceSeq *sseq = area->spacedata.first; Scene *scene = CTX_data_scene(C); wmWindowManager *wm = CTX_wm_manager(C); - const bool draw_overlay = (scene->ed && (scene->ed->over_flag & SEQ_EDIT_OVERLAY_SHOW)); + const bool draw_overlay = (scene->ed && (scene->ed->over_flag & SEQ_EDIT_OVERLAY_SHOW) && (sseq->flag & SEQ_SHOW_STRIP_OVERLAY)); /* XXX temp fix for wrong setting in sseq->mainb */ if (sseq->mainb == SEQ_DRAW_SEQUENCE) { -- cgit v1.2.3 From 977bd7937a07a5cbb269c1cda6e95ef0931a0704 Mon Sep 17 00:00:00 2001 From: Richard Antalik Date: Wed, 16 Dec 2020 00:20:20 +0100 Subject: Fix warnings introduced in previous commit --- source/blender/editors/space_sequencer/sequencer_draw.c | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) (limited to 'source/blender/editors') diff --git a/source/blender/editors/space_sequencer/sequencer_draw.c b/source/blender/editors/space_sequencer/sequencer_draw.c index ac1b9e6d0a0..5ad1e2399f5 100644 --- a/source/blender/editors/space_sequencer/sequencer_draw.c +++ b/source/blender/editors/space_sequencer/sequencer_draw.c @@ -603,7 +603,7 @@ static void draw_seq_outline(Sequence *seq, } } -const char *draw_seq_text_get_name(SpaceSeq *sseq, Sequence *seq) +static const char *draw_seq_text_get_name(Sequence *seq) { const char *name = seq->name + 2; if (name[0] == '\0') { @@ -612,10 +612,7 @@ const char *draw_seq_text_get_name(SpaceSeq *sseq, Sequence *seq) return name; } -static void draw_seq_text_get_source(SpaceSeq *sseq, - Sequence *seq, - char *r_source, - size_t source_len) +static void draw_seq_text_get_source(Sequence *seq, char *r_source, size_t source_len) { /* Set source for the most common types. */ if (ELEM(seq->type, SEQ_TYPE_IMAGE, SEQ_TYPE_MOVIE)) { @@ -661,10 +658,10 @@ static size_t draw_seq_text_get_overlay_string(SpaceSeq *sseq, char *r_overlay_string, size_t overlay_string_len) { - const char *name = draw_seq_text_get_name(sseq, seq); + const char *name = draw_seq_text_get_name(seq); char source[FILE_MAX]; int strip_duration = seq->enddisp - seq->startdisp; - draw_seq_text_get_source(sseq, seq, source, sizeof(source)); + draw_seq_text_get_source(seq, source, sizeof(source)); bool show_name = sseq->flag & SEQ_SHOW_STRIP_NAME; bool show_source = (sseq->flag & (SEQ_SHOW_STRIP_SOURCE)) && source[0] != '\0'; -- cgit v1.2.3 From 87fdb714383326255fa656809d637403b9bb2adb Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Wed, 16 Dec 2020 16:12:50 +1100 Subject: Cleanup: use static declarations --- source/blender/editors/space_file/space_file.c | 2 +- source/blender/editors/space_outliner/outliner_context.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'source/blender/editors') diff --git a/source/blender/editors/space_file/space_file.c b/source/blender/editors/space_file/space_file.c index 09b7e5b348c..d4f6618e82a 100644 --- a/source/blender/editors/space_file/space_file.c +++ b/source/blender/editors/space_file/space_file.c @@ -779,7 +779,7 @@ static void file_space_subtype_item_extend(bContext *UNUSED(C), RNA_enum_items_add(item, totitem, rna_enum_space_file_browse_mode_items); } -const char *file_context_dir[] = {"active_file", "active_id", NULL}; +static const char *file_context_dir[] = {"active_file", "active_id", NULL}; static int /*eContextResult*/ file_context(const bContext *C, const char *member, diff --git a/source/blender/editors/space_outliner/outliner_context.c b/source/blender/editors/space_outliner/outliner_context.c index e7dc2780c37..a314a640e42 100644 --- a/source/blender/editors/space_outliner/outliner_context.c +++ b/source/blender/editors/space_outliner/outliner_context.c @@ -50,7 +50,7 @@ static void outliner_context_selected_ids(const SpaceOutliner *space_outliner, CTX_data_type_set(result, CTX_DATA_TYPE_COLLECTION); } -const char *outliner_context_dir[] = {"selected_ids", NULL}; +static const char *outliner_context_dir[] = {"selected_ids", NULL}; int /*eContextResult*/ outliner_context(const bContext *C, const char *member, -- cgit v1.2.3 From 588f107f1155817afe4316549c84ca649be16600 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Wed, 16 Dec 2020 16:13:05 +1100 Subject: Cleanup: clang-format --- source/blender/editors/space_sequencer/space_sequencer.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'source/blender/editors') diff --git a/source/blender/editors/space_sequencer/space_sequencer.c b/source/blender/editors/space_sequencer/space_sequencer.c index 64b51b70a12..2bf4741e4f5 100644 --- a/source/blender/editors/space_sequencer/space_sequencer.c +++ b/source/blender/editors/space_sequencer/space_sequencer.c @@ -707,7 +707,8 @@ static void sequencer_preview_region_draw(const bContext *C, ARegion *region) SpaceSeq *sseq = area->spacedata.first; Scene *scene = CTX_data_scene(C); wmWindowManager *wm = CTX_wm_manager(C); - const bool draw_overlay = (scene->ed && (scene->ed->over_flag & SEQ_EDIT_OVERLAY_SHOW) && (sseq->flag & SEQ_SHOW_STRIP_OVERLAY)); + const bool draw_overlay = (scene->ed && (scene->ed->over_flag & SEQ_EDIT_OVERLAY_SHOW) && + (sseq->flag & SEQ_SHOW_STRIP_OVERLAY)); /* XXX temp fix for wrong setting in sseq->mainb */ if (sseq->mainb == SEQ_DRAW_SEQUENCE) { -- cgit v1.2.3 From b347c4e9ca896c7f1149502962add1163db1e82c Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Wed, 16 Dec 2020 16:19:04 +1100 Subject: Cleanup: remove redundant struct declarations --- source/blender/editors/include/ED_armature.h | 1 - source/blender/editors/include/ED_gpencil.h | 1 - source/blender/editors/include/ED_image.h | 2 -- source/blender/editors/include/ED_object.h | 1 - source/blender/editors/include/ED_transform.h | 2 -- source/blender/editors/include/ED_transform_snap_object_context.h | 1 - source/blender/editors/include/ED_util_imbuf.h | 1 - source/blender/editors/include/ED_uvedit.h | 1 - source/blender/editors/include/ED_view3d.h | 5 ----- source/blender/editors/include/UI_interface.h | 1 - source/blender/editors/sculpt_paint/paint_intern.h | 1 - source/blender/editors/sculpt_paint/sculpt_intern.h | 1 - source/blender/editors/space_buttons/buttons_intern.h | 1 - source/blender/editors/space_outliner/tree/tree_element_nla.hh | 1 - source/blender/editors/transform/transform.h | 2 +- source/blender/editors/transform/transform_convert.h | 3 --- source/blender/editors/transform/transform_snap.h | 2 -- source/blender/editors/uvedit/uvedit_intern.h | 1 - 18 files changed, 1 insertion(+), 27 deletions(-) (limited to 'source/blender/editors') diff --git a/source/blender/editors/include/ED_armature.h b/source/blender/editors/include/ED_armature.h index 3501acd4fdf..0c4576096fb 100644 --- a/source/blender/editors/include/ED_armature.h +++ b/source/blender/editors/include/ED_armature.h @@ -31,7 +31,6 @@ struct Base; struct Bone; struct Depsgraph; struct EditBone; -struct IDProperty; struct ListBase; struct Main; struct Mesh; diff --git a/source/blender/editors/include/ED_gpencil.h b/source/blender/editors/include/ED_gpencil.h index be2f714dfe1..1b7caf27ecf 100644 --- a/source/blender/editors/include/ED_gpencil.h +++ b/source/blender/editors/include/ED_gpencil.h @@ -51,7 +51,6 @@ struct ScrArea; struct SnapObjectContext; struct ToolSettings; struct View3D; -struct ViewLayer; struct bContext; struct Material; diff --git a/source/blender/editors/include/ED_image.h b/source/blender/editors/include/ED_image.h index c1d3a17b9b6..b139b0765a3 100644 --- a/source/blender/editors/include/ED_image.h +++ b/source/blender/editors/include/ED_image.h @@ -34,12 +34,10 @@ struct ARegion; struct ImBuf; struct Image; struct ImageUser; -struct LinkNodePair; struct Main; struct ReportList; struct Scene; struct SpaceImage; -struct ViewLayer; struct bContext; struct wmOperator; struct wmWindowManager; diff --git a/source/blender/editors/include/ED_object.h b/source/blender/editors/include/ED_object.h index 2e9b711c99a..f9358f62274 100644 --- a/source/blender/editors/include/ED_object.h +++ b/source/blender/editors/include/ED_object.h @@ -53,7 +53,6 @@ struct uiLayout; struct wmKeyConfig; struct wmOperator; struct wmOperatorType; -struct wmWindowManager; /* object_edit.c */ /* context.object */ diff --git a/source/blender/editors/include/ED_transform.h b/source/blender/editors/include/ED_transform.h index 0ea86e006e0..ca3e351a052 100644 --- a/source/blender/editors/include/ED_transform.h +++ b/source/blender/editors/include/ED_transform.h @@ -32,7 +32,6 @@ extern "C" { struct Object; struct bContext; struct wmKeyConfig; -struct wmMsgBus; struct wmOperatorType; void ED_keymap_transform(struct wmKeyConfig *keyconf); @@ -108,7 +107,6 @@ bool calculateTransformCenter(struct bContext *C, struct Object; struct Scene; -struct wmGizmoGroup; struct wmGizmoGroupType; /* UNUSED */ diff --git a/source/blender/editors/include/ED_transform_snap_object_context.h b/source/blender/editors/include/ED_transform_snap_object_context.h index ebaa32941f2..b7174964ef6 100644 --- a/source/blender/editors/include/ED_transform_snap_object_context.h +++ b/source/blender/editors/include/ED_transform_snap_object_context.h @@ -31,7 +31,6 @@ struct BMVert; struct ARegion; struct Depsgraph; struct ListBase; -struct Main; struct Object; struct Scene; struct View3D; diff --git a/source/blender/editors/include/ED_util_imbuf.h b/source/blender/editors/include/ED_util_imbuf.h index d142d3d6425..4bbaa68e849 100644 --- a/source/blender/editors/include/ED_util_imbuf.h +++ b/source/blender/editors/include/ED_util_imbuf.h @@ -31,7 +31,6 @@ extern "C" { #endif struct ARegion; -struct Main; struct bContext; struct wmEvent; struct wmOperator; diff --git a/source/blender/editors/include/ED_uvedit.h b/source/blender/editors/include/ED_uvedit.h index d08bc0b0b3d..4de97411059 100644 --- a/source/blender/editors/include/ED_uvedit.h +++ b/source/blender/editors/include/ED_uvedit.h @@ -33,7 +33,6 @@ struct BMEditMesh; struct BMFace; struct BMLoop; struct BMesh; -struct Depsgraph; struct Image; struct ImageUser; struct Main; diff --git a/source/blender/editors/include/ED_view3d.h b/source/blender/editors/include/ED_view3d.h index 13687bf0450..a4856845a65 100644 --- a/source/blender/editors/include/ED_view3d.h +++ b/source/blender/editors/include/ED_view3d.h @@ -41,8 +41,6 @@ struct Camera; struct CustomData_MeshMasks; struct Depsgraph; struct EditBone; -struct GPUOffScreen; -struct GPUViewport; struct ID; struct MVert; struct Main; @@ -55,7 +53,6 @@ struct RenderEngineType; struct Scene; struct ScrArea; struct View3D; -struct View3DShading; struct ViewContext; struct ViewLayer; struct bContext; @@ -64,8 +61,6 @@ struct bScreen; struct rctf; struct rcti; struct wmGizmo; -struct wmOperator; -struct wmOperatorType; struct wmWindow; struct wmWindowManager; diff --git a/source/blender/editors/include/UI_interface.h b/source/blender/editors/include/UI_interface.h index 83e94664c0b..7c128cbf1e6 100644 --- a/source/blender/editors/include/UI_interface.h +++ b/source/blender/editors/include/UI_interface.h @@ -50,7 +50,6 @@ struct PointerRNA; struct PropertyRNA; struct ReportList; struct ResultBLF; -struct ScrArea; struct bContext; struct bContextStore; struct bNode; diff --git a/source/blender/editors/sculpt_paint/paint_intern.h b/source/blender/editors/sculpt_paint/paint_intern.h index 175d98ba9aa..3ca0d853d6a 100644 --- a/source/blender/editors/sculpt_paint/paint_intern.h +++ b/source/blender/editors/sculpt_paint/paint_intern.h @@ -43,7 +43,6 @@ struct wmEvent; struct wmKeyConfig; struct wmOperator; struct wmOperatorType; -struct wmWindowManager; enum ePaintMode; enum ePaintSymmetryFlags; diff --git a/source/blender/editors/sculpt_paint/sculpt_intern.h b/source/blender/editors/sculpt_paint/sculpt_intern.h index bd5ba15b493..853b221e92a 100644 --- a/source/blender/editors/sculpt_paint/sculpt_intern.h +++ b/source/blender/editors/sculpt_paint/sculpt_intern.h @@ -39,7 +39,6 @@ struct AutomaskingCache; struct KeyBlock; struct Object; -struct SculptPoseIKChainSegment; struct SculptUndoNode; struct bContext; diff --git a/source/blender/editors/space_buttons/buttons_intern.h b/source/blender/editors/space_buttons/buttons_intern.h index 0a0846cf216..74e7bc11c26 100644 --- a/source/blender/editors/space_buttons/buttons_intern.h +++ b/source/blender/editors/space_buttons/buttons_intern.h @@ -35,7 +35,6 @@ struct bContext; struct bContextDataResult; struct bNode; struct bNodeTree; -struct uiLayout; struct wmOperatorType; struct SpaceProperties_Runtime { diff --git a/source/blender/editors/space_outliner/tree/tree_element_nla.hh b/source/blender/editors/space_outliner/tree/tree_element_nla.hh index 3ca62b13bd8..c94287ce576 100644 --- a/source/blender/editors/space_outliner/tree/tree_element_nla.hh +++ b/source/blender/editors/space_outliner/tree/tree_element_nla.hh @@ -23,7 +23,6 @@ #include "tree_element.hh" struct NlaTrack; -struct NlaStrip; namespace blender::ed::outliner { diff --git a/source/blender/editors/transform/transform.h b/source/blender/editors/transform/transform.h index 227330e8524..91bf2bf8aac 100644 --- a/source/blender/editors/transform/transform.h +++ b/source/blender/editors/transform/transform.h @@ -52,12 +52,12 @@ struct SnapObjectContext; struct TransDataContainer; struct TransInfo; struct TransSnap; -struct TransformOrientation; struct ViewLayer; struct bContext; struct wmEvent; struct wmKeyConfig; struct wmKeyMap; +struct wmOperator; struct wmTimer; /** #TransInfo.redraw */ diff --git a/source/blender/editors/transform/transform_convert.h b/source/blender/editors/transform/transform_convert.h index b753572ea7b..59fcd016020 100644 --- a/source/blender/editors/transform/transform_convert.h +++ b/source/blender/editors/transform/transform_convert.h @@ -29,12 +29,9 @@ struct FCurve; struct ListBase; struct Object; struct TransData; -struct TransDataContainer; struct TransDataCurveHandleFlags; struct TransInfo; struct bContext; -struct bKinematicConstraint; -struct bPoseChannel; /* transform_convert.c */ void transform_autoik_update(TransInfo *t, short mode); diff --git a/source/blender/editors/transform/transform_snap.h b/source/blender/editors/transform/transform_snap.h index 5bee572c603..db8ec943bfd 100644 --- a/source/blender/editors/transform/transform_snap.h +++ b/source/blender/editors/transform/transform_snap.h @@ -25,8 +25,6 @@ /* For enum. */ #include "DNA_space_types.h" -struct SnapObjectParams; - bool peelObjectsTransform(struct TransInfo *t, const float mval[2], const bool use_peel_object, diff --git a/source/blender/editors/uvedit/uvedit_intern.h b/source/blender/editors/uvedit/uvedit_intern.h index 306f8a2c561..28567234fab 100644 --- a/source/blender/editors/uvedit/uvedit_intern.h +++ b/source/blender/editors/uvedit/uvedit_intern.h @@ -25,7 +25,6 @@ struct BMFace; struct BMLoop; -struct Image; struct Object; struct Scene; struct SpaceImage; -- cgit v1.2.3 From a869a61c88e37ce8a16676162ef7db3c62449b46 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Wed, 16 Dec 2020 16:26:23 +1100 Subject: Cleanup: sort struct blocks --- source/blender/editors/include/ED_fileselect.h | 2 +- source/blender/editors/space_file/filelist.h | 2 +- source/blender/editors/space_outliner/outliner_intern.h | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) (limited to 'source/blender/editors') diff --git a/source/blender/editors/include/ED_fileselect.h b/source/blender/editors/include/ED_fileselect.h index 3288cf11cb0..6c66a6162b8 100644 --- a/source/blender/editors/include/ED_fileselect.h +++ b/source/blender/editors/include/ED_fileselect.h @@ -28,8 +28,8 @@ extern "C" { #endif struct ARegion; -struct FileSelectParams; struct FileAssetSelectParams; +struct FileSelectParams; struct Scene; struct ScrArea; struct SpaceFile; diff --git a/source/blender/editors/space_file/filelist.h b/source/blender/editors/space_file/filelist.h index 59bd5bb50d7..16984bb6e43 100644 --- a/source/blender/editors/space_file/filelist.h +++ b/source/blender/editors/space_file/filelist.h @@ -29,8 +29,8 @@ extern "C" { struct BlendHandle; struct FileList; -struct FileSelection; struct FileSelectAssetLibraryUID; +struct FileSelection; struct wmWindowManager; struct FileDirEntry; diff --git a/source/blender/editors/space_outliner/outliner_intern.h b/source/blender/editors/space_outliner/outliner_intern.h index ccb481197e4..339cc3068d0 100644 --- a/source/blender/editors/space_outliner/outliner_intern.h +++ b/source/blender/editors/space_outliner/outliner_intern.h @@ -32,7 +32,6 @@ extern "C" { /* internal exports only */ struct ARegion; -struct bContextDataResult; struct EditBone; struct ID; struct ListBase; @@ -43,6 +42,7 @@ struct TreeElement; struct TreeStoreElem; struct ViewLayer; struct bContext; +struct bContextDataResult; struct bPoseChannel; struct wmKeyConfig; struct wmOperatorType; -- cgit v1.2.3 From 055ef5df615632f81e30e39ae47b42a87af350ca Mon Sep 17 00:00:00 2001 From: Julian Eisel Date: Wed, 16 Dec 2020 01:05:46 +0100 Subject: Cleanup: Rename Asset Browser context member from "active_id" to "id" This is the same name we use elsewhere for the focused/active ID context member, so this should follow it. --- source/blender/editors/space_file/space_file.c | 2 +- source/blender/editors/util/ed_util.c | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) (limited to 'source/blender/editors') diff --git a/source/blender/editors/space_file/space_file.c b/source/blender/editors/space_file/space_file.c index d4f6618e82a..5bd7f6c17f6 100644 --- a/source/blender/editors/space_file/space_file.c +++ b/source/blender/editors/space_file/space_file.c @@ -806,7 +806,7 @@ static int /*eContextResult*/ file_context(const bContext *C, CTX_data_pointer_set(result, &screen->id, &RNA_FileSelectEntry, file); return CTX_RESULT_OK; } - if (CTX_data_equals(member, "active_id")) { + if (CTX_data_equals(member, "id")) { const FileDirEntry *file = filelist_file(sfile->files, params->active_file); ID *id = filelist_file_get_id(file); diff --git a/source/blender/editors/util/ed_util.c b/source/blender/editors/util/ed_util.c index 6547e42f410..4740e4d8d33 100644 --- a/source/blender/editors/util/ed_util.c +++ b/source/blender/editors/util/ed_util.c @@ -507,7 +507,7 @@ void ED_OT_flush_edits(wmOperatorType *ot) static bool lib_id_load_custom_preview_poll(bContext *C) { - const PointerRNA idptr = CTX_data_pointer_get(C, "active_id"); + const PointerRNA idptr = CTX_data_pointer_get(C, "id"); BLI_assert(!idptr.data || RNA_struct_is_ID(idptr.type)); const ID *id = idptr.data; @@ -541,7 +541,7 @@ static int lib_id_load_custom_preview_exec(bContext *C, wmOperator *op) return OPERATOR_CANCELLED; } - PointerRNA idptr = CTX_data_pointer_get(C, "active_id"); + PointerRNA idptr = CTX_data_pointer_get(C, "id"); ID *id = idptr.data; BKE_previewimg_id_custom_set(id, path); -- cgit v1.2.3 From 58d818f8bebf8c08b528d1637c93f15d2559cca1 Mon Sep 17 00:00:00 2001 From: Julian Eisel Date: Wed, 16 Dec 2020 11:44:22 +0100 Subject: Assets: Add operator & button to regenerate the automatic preview This makes it possible to trigger a refresh of the data-block preview, available next to the preview in the Asset Browser sidebar. The previews get easily outdated and automatically refreshing it all the time is not an option because it would be a consistently running, quite expensive process. So a button to cause a refresh should be reasonable. This button can also be used to switch back from a custom preview to a generated one. Although that may not be clear, and we should probably think of a way to explain that better. Addresses T82719. --- source/blender/editors/include/ED_util.h | 1 + source/blender/editors/screen/screen_ops.c | 1 + source/blender/editors/util/ed_util.c | 37 ++++++++++++++++++++++++++++-- 3 files changed, 37 insertions(+), 2 deletions(-) (limited to 'source/blender/editors') diff --git a/source/blender/editors/include/ED_util.h b/source/blender/editors/include/ED_util.h index d74a80045f1..ca6b4bdc618 100644 --- a/source/blender/editors/include/ED_util.h +++ b/source/blender/editors/include/ED_util.h @@ -54,6 +54,7 @@ void ED_spacedata_id_remap(struct ScrArea *area, void ED_OT_flush_edits(struct wmOperatorType *ot); void ED_OT_lib_id_load_custom_preview(struct wmOperatorType *ot); +void ED_OT_lib_id_generate_preview(struct wmOperatorType *ot); /* ************** XXX OLD CRUFT WARNING ************* */ diff --git a/source/blender/editors/screen/screen_ops.c b/source/blender/editors/screen/screen_ops.c index a0c5762c73c..51687d5de1d 100644 --- a/source/blender/editors/screen/screen_ops.c +++ b/source/blender/editors/screen/screen_ops.c @@ -5511,6 +5511,7 @@ void ED_operatortypes_screen(void) WM_operatortype_append(ED_OT_flush_edits); WM_operatortype_append(ED_OT_lib_id_load_custom_preview); + WM_operatortype_append(ED_OT_lib_id_generate_preview); } /** \} */ diff --git a/source/blender/editors/util/ed_util.c b/source/blender/editors/util/ed_util.c index 4740e4d8d33..d78758dcc1c 100644 --- a/source/blender/editors/util/ed_util.c +++ b/source/blender/editors/util/ed_util.c @@ -67,6 +67,7 @@ #include "ED_object.h" #include "ED_outliner.h" #include "ED_paint.h" +#include "ED_render.h" #include "ED_space_api.h" #include "ED_util.h" @@ -505,7 +506,7 @@ void ED_OT_flush_edits(wmOperatorType *ot) ot->flag = OPTYPE_INTERNAL; } -static bool lib_id_load_custom_preview_poll(bContext *C) +static bool lib_id_preview_editing_poll(bContext *C) { const PointerRNA idptr = CTX_data_pointer_get(C, "id"); BLI_assert(!idptr.data || RNA_struct_is_ID(idptr.type)); @@ -558,7 +559,7 @@ void ED_OT_lib_id_load_custom_preview(wmOperatorType *ot) ot->idname = "ED_OT_lib_id_load_custom_preview"; /* api callbacks */ - ot->poll = lib_id_load_custom_preview_poll; + ot->poll = lib_id_preview_editing_poll; ot->exec = lib_id_load_custom_preview_exec; ot->invoke = WM_operator_filesel; @@ -573,3 +574,35 @@ void ED_OT_lib_id_load_custom_preview(wmOperatorType *ot) FILE_DEFAULTDISPLAY, FILE_SORT_DEFAULT); } + +static int lib_id_generate_preview_exec(bContext *C, wmOperator *UNUSED(op)) +{ + PointerRNA idptr = CTX_data_pointer_get(C, "id"); + ID *id = idptr.data; + + ED_preview_kill_jobs(CTX_wm_manager(C), CTX_data_main(C)); + + PreviewImage *preview = BKE_previewimg_id_get(id); + if (preview) { + BKE_previewimg_clear(preview); + } + UI_icon_render_id(C, NULL, id, true, true); + + WM_event_add_notifier(C, NC_ASSET, NULL); + + return OPERATOR_FINISHED; +} + +void ED_OT_lib_id_generate_preview(wmOperatorType *ot) +{ + ot->name = "Generate Preview"; + ot->description = "Create an automatic preview for the selected data-block"; + ot->idname = "ED_OT_lib_id_generate_preview"; + + /* api callbacks */ + ot->poll = lib_id_preview_editing_poll; + ot->exec = lib_id_generate_preview_exec; + + /* flags */ + ot->flag = OPTYPE_INTERNAL; +} -- cgit v1.2.3 From 3fc9fc1cb46a49bbfa2da4443fb4edefcdc3b89d Mon Sep 17 00:00:00 2001 From: Julian Eisel Date: Wed, 16 Dec 2020 11:58:30 +0100 Subject: UI: Indicate asset data-blocks with an icon in Outliners & search menus It's useful to easily see which data-blocks are assets and which not. So just like we usually show the library linking/override icons, we show the asset icon there (these are mutually exclusive data-block states). Uses the `'MAT_SPHERE_SKY` icon, which wasn't used before (except by an add-on!) and is sorta fitting, but not quite. We should either change this one or add an own asset icon. Meanwhile this isn't too bad :) Also adds an internal macro to check if a data-block is an asset, consistent to how we do it for libraries and library overrides. --- source/blender/editors/interface/interface_icons.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'source/blender/editors') diff --git a/source/blender/editors/interface/interface_icons.c b/source/blender/editors/interface/interface_icons.c index 1c09dc6f4df..08e9ea31b53 100644 --- a/source/blender/editors/interface/interface_icons.c +++ b/source/blender/editors/interface/interface_icons.c @@ -2199,6 +2199,9 @@ int UI_icon_from_library(const ID *id) if (ID_IS_OVERRIDE_LIBRARY(id)) { return ICON_LIBRARY_DATA_OVERRIDE; } + if (ID_IS_ASSET(id)) { + return ICON_MAT_SPHERE_SKY; + } return ICON_NONE; } -- cgit v1.2.3 From 4f128269b2dcf453647e7293f68f35173d45486a Mon Sep 17 00:00:00 2001 From: Eric Cosky Date: Wed, 16 Dec 2020 12:12:06 +0100 Subject: Fix possible crash with custom (add-on defined) icons This change is a simple null check on the ID provided to icon_set_image() which appears to be a legitimate value for the ID when used by some addins (discovered with PowerSave shortly after syncing to main). Differential Revision: https://developer.blender.org/D9866 Reviewed by: Julian Eisel --- source/blender/editors/interface/interface_icons.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source/blender/editors') diff --git a/source/blender/editors/interface/interface_icons.c b/source/blender/editors/interface/interface_icons.c index 08e9ea31b53..899f4a6ddb1 100644 --- a/source/blender/editors/interface/interface_icons.c +++ b/source/blender/editors/interface/interface_icons.c @@ -1416,7 +1416,7 @@ static void icon_set_image(const bContext *C, const bool delay = prv_img->rect[size] != NULL; icon_create_rect(prv_img, size); - if (use_job && BKE_previewimg_id_supports_jobs(id)) { + if (use_job && (!id || BKE_previewimg_id_supports_jobs(id))) { /* Job (background) version */ ED_preview_icon_job( C, prv_img, id, prv_img->rect[size], prv_img->w[size], prv_img->h[size], delay); -- cgit v1.2.3 From 4c26dd430d5ec0867cd7b834e601fbaaf7e10e67 Mon Sep 17 00:00:00 2001 From: Jacques Lucke Date: Wed, 16 Dec 2020 13:31:56 +0100 Subject: Geometry Nodes: rename node to Attribute Randomize Previously, the node was called Random Attribute. For consistency reasons, we move the "Attribute" part of the name to the front. --- source/blender/editors/space_node/drawnode.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source/blender/editors') diff --git a/source/blender/editors/space_node/drawnode.c b/source/blender/editors/space_node/drawnode.c index f8c71791054..421d645d7bd 100644 --- a/source/blender/editors/space_node/drawnode.c +++ b/source/blender/editors/space_node/drawnode.c @@ -3220,7 +3220,7 @@ static void node_geometry_set_butfunc(bNodeType *ntype) case GEO_NODE_TRIANGULATE: ntype->draw_buttons = node_geometry_buts_triangulate; break; - case GEO_NODE_RANDOM_ATTRIBUTE: + case GEO_NODE_ATTRIBUTE_RANDOMIZE: ntype->draw_buttons = node_geometry_buts_random_attribute; break; case GEO_NODE_ATTRIBUTE_MATH: -- cgit v1.2.3 From 8d590e4b86287be22567d1adf8c6a7946bc7f63d Mon Sep 17 00:00:00 2001 From: Philipp Oeser Date: Wed, 16 Dec 2020 10:14:58 +0100 Subject: Fix T83801: UVEditor translation ignores "Pixel Coordinates" and aspect ratio Caused by rB4eda60c2d82d. T83801 reported not moving in pixel space, but even without that toggle above commit caused the translation to not take apsect ratio into account properly [a translation of 1 on the x axis for example on an image with non 1:1 aspect ration caused the UVs to not end up in the same place on the next 'tile'] Above commit removed 'removeAspectRatio()' [the counterpart of applyAspectRatio -- which does the pixel coord correction internally] from 'applyTranslation()'. This was also reported in T83352 [which was closed by rBf3b08af24c9f -- but that only solved the displax in header, not the actual transformation] Now bring back 'removeAspectRatio()'. Maniphest Tasks: T83801 Differential Revision: https://developer.blender.org/D9869 --- source/blender/editors/transform/transform_mode_translate.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'source/blender/editors') diff --git a/source/blender/editors/transform/transform_mode_translate.c b/source/blender/editors/transform/transform_mode_translate.c index 90c1f241338..8597c372537 100644 --- a/source/blender/editors/transform/transform_mode_translate.c +++ b/source/blender/editors/transform/transform_mode_translate.c @@ -377,6 +377,9 @@ static void applyTranslation(TransInfo *t, const int UNUSED(mval[2])) else { mul_v3_m3v3(global_dir, t->spacemtx, global_dir); } + if (t->flag & T_2D_EDIT) { + removeAspectRatio(t, global_dir); + } } else { copy_v3_v3(global_dir, t->values); -- cgit v1.2.3 From 7ed69bd672555f6bbedc598aacda56efb6eeafbb Mon Sep 17 00:00:00 2001 From: Julian Eisel Date: Wed, 16 Dec 2020 16:07:23 +0100 Subject: Fix T83843: Crash in Asset Browser sidebar with geometry asset selected No icon should be created if the preview doesn't exist. --- source/blender/editors/space_file/filelist.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'source/blender/editors') diff --git a/source/blender/editors/space_file/filelist.c b/source/blender/editors/space_file/filelist.c index 3ed7b5499db..8202a87864d 100644 --- a/source/blender/editors/space_file/filelist.c +++ b/source/blender/editors/space_file/filelist.c @@ -1511,7 +1511,9 @@ static void filelist_cache_preview_runf(TaskPool *__restrict pool, void *taskdat * in case user switch to a bigger preview size. */ ImBuf *imbuf = IMB_thumb_manage(preview->path, THB_LARGE, source); IMB_thumb_path_unlock(preview->path); - preview->icon_id = BKE_icon_imbuf_create(imbuf); + if (imbuf) { + preview->icon_id = BKE_icon_imbuf_create(imbuf); + } done = true; } -- cgit v1.2.3 From 5c5550f7b821cb6c67009682fec85ce0929474a3 Mon Sep 17 00:00:00 2001 From: Julian Eisel Date: Wed, 16 Dec 2020 16:10:53 +0100 Subject: Asset Browser: For assets without preview, show type icon in sidebar Otherwise it would just show empty space where the icon is supposed to be. Unfortunately this icon is upscaled quite a bit and doesn't look too great. Would be good to improve but not a high priority. --- source/blender/editors/include/ED_fileselect.h | 2 ++ source/blender/editors/space_file/filelist.c | 10 ++++++++-- 2 files changed, 10 insertions(+), 2 deletions(-) (limited to 'source/blender/editors') diff --git a/source/blender/editors/include/ED_fileselect.h b/source/blender/editors/include/ED_fileselect.h index 6c66a6162b8..7b240e0569f 100644 --- a/source/blender/editors/include/ED_fileselect.h +++ b/source/blender/editors/include/ED_fileselect.h @@ -30,6 +30,7 @@ extern "C" { struct ARegion; struct FileAssetSelectParams; struct FileSelectParams; +struct FileDirEntry; struct Scene; struct ScrArea; struct SpaceFile; @@ -154,6 +155,7 @@ struct ScrArea *ED_fileselect_handler_area_find(const struct wmWindow *win, int ED_path_extension_type(const char *path); int ED_file_extension_icon(const char *path); +int ED_file_icon(const struct FileDirEntry *file); void ED_file_read_bookmarks(void); diff --git a/source/blender/editors/space_file/filelist.c b/source/blender/editors/space_file/filelist.c index 8202a87864d..d66219c7549 100644 --- a/source/blender/editors/space_file/filelist.c +++ b/source/blender/editors/space_file/filelist.c @@ -1178,7 +1178,7 @@ ImBuf *filelist_geticon_image(struct FileList *filelist, const int index) return filelist_geticon_image_ex(file); } -static int filelist_geticon_ex(FileDirEntry *file, +static int filelist_geticon_ex(const FileDirEntry *file, const char *root, const bool is_main, const bool ignore_libdir) @@ -1217,7 +1217,7 @@ static int filelist_geticon_ex(FileDirEntry *file, if (file->redirection_path) { target = file->redirection_path; } - else { + else if (root) { BLI_join_dirfile(fullpath, sizeof(fullpath), root, file->relpath); BLI_path_slash_ensure(fullpath); } @@ -1301,6 +1301,12 @@ int filelist_geticon(struct FileList *filelist, const int index, const bool is_m return filelist_geticon_ex(file, filelist->filelist.root, is_main, false); } +int ED_file_icon(const FileDirEntry *file) +{ + return file->preview_icon_id ? file->preview_icon_id : + filelist_geticon_ex(file, NULL, false, false); +} + /* ********** Main ********** */ static void parent_dir_until_exists_or_default_root(char *dir) -- cgit v1.2.3 From f3ab123e33b87cfcf4d310323572c798f9953201 Mon Sep 17 00:00:00 2001 From: Jeroen Bakker Date: Wed, 16 Dec 2020 16:16:50 +0100 Subject: Cleanup: Remove unused crop field from RenderResult. The `crop` field was used by Blender Internal to do an overscan per tile and merge it back to the render result. --- source/blender/editors/render/render_internal.c | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) (limited to 'source/blender/editors') diff --git a/source/blender/editors/render/render_internal.c b/source/blender/editors/render/render_internal.c index 3dbf70aa4bc..a035ee3e342 100644 --- a/source/blender/editors/render/render_internal.c +++ b/source/blender/editors/render/render_internal.c @@ -150,31 +150,31 @@ static void image_buffer_rect_update(RenderJob *rj, } /* xmin here is first subrect x coord, xmax defines subrect width */ - xmin = renrect->xmin + rr->crop; - xmax = renrect->xmax - xmin + rr->crop; + xmin = renrect->xmin; + xmax = renrect->xmax - xmin; if (xmax < 2) { return; } - ymin = renrect->ymin + rr->crop; - ymax = renrect->ymax - ymin + rr->crop; + ymin = renrect->ymin; + ymax = renrect->ymax - ymin; if (ymax < 2) { return; } renrect->ymin = renrect->ymax; } else { - xmin = ymin = rr->crop; - xmax = rr->rectx - 2 * rr->crop; - ymax = rr->recty - 2 * rr->crop; + xmin = ymin = 0; + xmax = rr->rectx; + ymax = rr->recty; } /* xmin ymin is in tile coords. transform to ibuf */ - rxmin = rr->tilerect.xmin + xmin; + rxmin = rr->tilerect.xmin; if (rxmin >= ibuf->x) { return; } - rymin = rr->tilerect.ymin + ymin; + rymin = rr->tilerect.ymin; if (rymin >= ibuf->y) { return; } -- cgit v1.2.3 From d23894d3ef3f019eeb88ef3da77e8416c6f70f29 Mon Sep 17 00:00:00 2001 From: Pablo Dobarro Date: Fri, 11 Dec 2020 22:49:49 +0100 Subject: Sculpt: Multires Displacement Smear This tool implements smearing for multires displacement over the limit surface, similar to how smearing for colors and topology slide works. When used the displacement values of the vertices "slide" over the topology, creating the effect of smearing the surface detail. As the brush just modifies displacement values instead of coordinates, the total displacement of the affected area doesn't change. This means that this smearing effect can be used multiple times over the same area without generating any artifacts in the topology. When the brush is used with the pinch or expand smear modes, displacement differences are pushed into the same area, creating hard surface effects without pinching the topology. As any other brush that relies on the limit surface (like displacement erasers), this will work better after using apply base. Reviewed By: sergey, JulienKaspar, dbystedt Differential Revision: https://developer.blender.org/D9659 --- source/blender/editors/sculpt_paint/sculpt.c | 151 +++++++++++++++++++++ .../blender/editors/sculpt_paint/sculpt_intern.h | 4 + 2 files changed, 155 insertions(+) (limited to 'source/blender/editors') diff --git a/source/blender/editors/sculpt_paint/sculpt.c b/source/blender/editors/sculpt_paint/sculpt.c index 80a32682325..26db2673335 100644 --- a/source/blender/editors/sculpt_paint/sculpt.c +++ b/source/blender/editors/sculpt_paint/sculpt.c @@ -1227,6 +1227,7 @@ static bool sculpt_tool_is_proxy_used(const char sculpt_tool) SCULPT_TOOL_SMOOTH, SCULPT_TOOL_LAYER, SCULPT_TOOL_POSE, + SCULPT_TOOL_DISPLACEMENT_SMEAR, SCULPT_TOOL_BOUNDARY, SCULPT_TOOL_CLOTH, SCULPT_TOOL_PAINT, @@ -2362,6 +2363,7 @@ static float brush_strength(const Sculpt *sd, final_pressure = pressure * pressure; return final_pressure * overlap * feather; case SCULPT_TOOL_SMEAR: + case SCULPT_TOOL_DISPLACEMENT_SMEAR: return alpha * pressure * overlap * feather; case SCULPT_TOOL_CLAY_STRIPS: /* Clay Strips needs less strength to compensate the curve. */ @@ -3103,6 +3105,147 @@ static void do_displacement_eraser_brush(Sculpt *sd, Object *ob, PBVHNode **node /** \} */ +/** \name Sculpt Multires Displacement Smear Brush + * \{ */ + +static void do_displacement_smear_brush_task_cb_ex(void *__restrict userdata, + const int n, + const TaskParallelTLS *__restrict tls) +{ + SculptThreadedTaskData *data = userdata; + SculptSession *ss = data->ob->sculpt; + const Brush *brush = data->brush; + const float bstrength = clamp_f(ss->cache->bstrength, 0.0f, 1.0f); + + SculptBrushTest test; + SculptBrushTestFn sculpt_brush_test_sq_fn = SCULPT_brush_test_init_with_falloff_shape( + ss, &test, data->brush->falloff_shape); + const int thread_id = BLI_task_parallel_thread_id(tls); + + PBVHVertexIter vd; + BKE_pbvh_vertex_iter_begin(ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE) + { + if (!sculpt_brush_test_sq_fn(&test, vd.co)) { + continue; + } + const float fade = bstrength * SCULPT_brush_strength_factor(ss, + brush, + vd.co, + sqrtf(test.dist), + vd.no, + vd.fno, + vd.mask ? *vd.mask : 0.0f, + vd.index, + thread_id); + + float current_disp[3]; + float current_disp_norm[3]; + float interp_limit_surface_disp[3]; + + copy_v3_v3(interp_limit_surface_disp, ss->cache->prev_displacement[vd.index]); + + switch (brush->smear_deform_type) { + case BRUSH_SMEAR_DEFORM_DRAG: + sub_v3_v3v3(current_disp, ss->cache->location, ss->cache->last_location); + break; + case BRUSH_SMEAR_DEFORM_PINCH: + sub_v3_v3v3(current_disp, ss->cache->location, vd.co); + break; + case BRUSH_SMEAR_DEFORM_EXPAND: + sub_v3_v3v3(current_disp, vd.co, ss->cache->location); + break; + } + + normalize_v3_v3(current_disp_norm, current_disp); + mul_v3_v3fl(current_disp, current_disp_norm, ss->cache->bstrength); + + float weights_accum = 1.0f; + + SculptVertexNeighborIter ni; + SCULPT_VERTEX_NEIGHBORS_ITER_BEGIN (ss, vd.index, ni) { + float vertex_disp[3]; + float vertex_disp_norm[3]; + float neighbor_limit_co[3]; + SCULPT_vertex_limit_surface_get(ss, ni.index, neighbor_limit_co); + sub_v3_v3v3(vertex_disp, + ss->cache->limit_surface_co[ni.index], + ss->cache->limit_surface_co[vd.index]); + const float *neighbor_limit_surface_disp = ss->cache->prev_displacement[ni.index]; + normalize_v3_v3(vertex_disp_norm, vertex_disp); + if (dot_v3v3(current_disp_norm, vertex_disp_norm) < 0.0f) { + const float disp_interp = clamp_f( + -dot_v3v3(current_disp_norm, vertex_disp_norm), 0.0f, 1.0f); + madd_v3_v3fl(interp_limit_surface_disp, neighbor_limit_surface_disp, disp_interp); + weights_accum += disp_interp; + } + } + SCULPT_VERTEX_NEIGHBORS_ITER_END(ni); + + mul_v3_fl(interp_limit_surface_disp, 1.0f / weights_accum); + + float new_co[3]; + add_v3_v3v3(new_co, ss->cache->limit_surface_co[vd.index], interp_limit_surface_disp); + interp_v3_v3v3(vd.co, vd.co, new_co, fade); + + if (vd.mvert) { + vd.mvert->flag |= ME_VERT_PBVH_UPDATE; + } + } + BKE_pbvh_vertex_iter_end; +} + +static void do_displacement_smear_store_prev_disp_task_cb_ex( + void *__restrict userdata, const int n, const TaskParallelTLS *__restrict UNUSED(tls)) +{ + SculptThreadedTaskData *data = userdata; + SculptSession *ss = data->ob->sculpt; + + PBVHVertexIter vd; + BKE_pbvh_vertex_iter_begin(ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE) + { + sub_v3_v3v3(ss->cache->prev_displacement[vd.index], + SCULPT_vertex_co_get(ss, vd.index), + ss->cache->limit_surface_co[vd.index]); + } + BKE_pbvh_vertex_iter_end; +} + +static void do_displacement_smear_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode) +{ + Brush *brush = BKE_paint_brush(&sd->paint); + SculptSession *ss = ob->sculpt; + + BKE_curvemapping_init(brush->curve); + + const int totvert = SCULPT_vertex_count_get(ss); + if (!ss->cache->prev_displacement) { + ss->cache->prev_displacement = MEM_malloc_arrayN( + totvert, sizeof(float[3]), "prev displacement"); + ss->cache->limit_surface_co = MEM_malloc_arrayN(totvert, sizeof(float[3]), "limit surface co"); + for (int i = 0; i < totvert; i++) { + SCULPT_vertex_limit_surface_get(ss, i, ss->cache->limit_surface_co[i]); + sub_v3_v3v3(ss->cache->prev_displacement[i], + SCULPT_vertex_co_get(ss, i), + ss->cache->limit_surface_co[i]); + } + } + /* Threaded loop over nodes. */ + SculptThreadedTaskData data = { + .sd = sd, + .ob = ob, + .brush = brush, + .nodes = nodes, + }; + + TaskParallelSettings settings; + BKE_pbvh_parallel_range_settings(&settings, true, totnode); + BLI_task_parallel_range( + 0, totnode, &data, do_displacement_smear_store_prev_disp_task_cb_ex, &settings); + BLI_task_parallel_range(0, totnode, &data, do_displacement_smear_brush_task_cb_ex, &settings); +} + +/** \} */ + static void do_draw_brush_task_cb_ex(void *__restrict userdata, const int n, const TaskParallelTLS *__restrict tls) @@ -5927,6 +6070,9 @@ static void do_brush_action(Sculpt *sd, Object *ob, Brush *brush, UnifiedPaintSe case SCULPT_TOOL_DISPLACEMENT_ERASER: do_displacement_eraser_brush(sd, ob, nodes, totnode); break; + case SCULPT_TOOL_DISPLACEMENT_SMEAR: + do_displacement_smear_brush(sd, ob, nodes, totnode); + break; case SCULPT_TOOL_PAINT: SCULPT_do_paint_brush(sd, ob, nodes, totnode); break; @@ -6490,6 +6636,8 @@ static const char *sculpt_tool_name(Sculpt *sd) return "Draw Face Sets"; case SCULPT_TOOL_DISPLACEMENT_ERASER: return "Multires Displacement Eraser"; + case SCULPT_TOOL_DISPLACEMENT_SMEAR: + return "Multires Displacement Smear"; case SCULPT_TOOL_PAINT: return "Paint Brush"; case SCULPT_TOOL_SMEAR: @@ -6510,6 +6658,8 @@ void SCULPT_cache_free(StrokeCache *cache) MEM_SAFE_FREE(cache->layer_displacement_factor); MEM_SAFE_FREE(cache->prev_colors); MEM_SAFE_FREE(cache->detail_directions); + MEM_SAFE_FREE(cache->prev_displacement); + MEM_SAFE_FREE(cache->limit_surface_co); if (cache->pose_ik_chain) { SCULPT_pose_ik_chain_free(cache->pose_ik_chain); @@ -6681,6 +6831,7 @@ static void sculpt_update_cache_invariants( SCULPT_TOOL_MASK, SCULPT_TOOL_SMOOTH, SCULPT_TOOL_SIMPLIFY, + SCULPT_TOOL_DISPLACEMENT_SMEAR, SCULPT_TOOL_DISPLACEMENT_ERASER) && (sd->gravity_factor > 0.0f)); /* Get gravity vector in world space. */ diff --git a/source/blender/editors/sculpt_paint/sculpt_intern.h b/source/blender/editors/sculpt_paint/sculpt_intern.h index 853b221e92a..d1e17c7e59b 100644 --- a/source/blender/editors/sculpt_paint/sculpt_intern.h +++ b/source/blender/editors/sculpt_paint/sculpt_intern.h @@ -926,6 +926,10 @@ typedef struct StrokeCache { float (*prev_colors)[4]; + /* Multires Displacement Smear. */ + float (*prev_displacement)[3]; + float (*limit_surface_co)[3]; + /* The rest is temporary storage that isn't saved as a property */ bool first_time; /* Beginning of stroke may do some things special */ -- cgit v1.2.3 From a7628ec22abca8d1aaada75a8227638947168a3a Mon Sep 17 00:00:00 2001 From: Dalai Felinto Date: Wed, 16 Dec 2020 16:59:30 +0100 Subject: Geometry Nodes: Poisson disk point distribution node/method This patch does two things: * Introduce a Seed to the random distribution method * Bring in a new distribution method for the point scattering node Patch Review: https://developer.blender.org/D9787 Note: This commit doesn't not handle doversion. Which means that users need to manually update their files that were using the Point Distribute node and reconnect inputs to the "Maximum Density" socket. Original patch by Sebastian Parborg, with changes to not rely on the cy libraries and overall cleanup. Patch review by Jacques Lucke, besides help with the new "heap" system that was required for this algorithm. Based on Cem Yuksel. 2015. Sample Elimination for Generating Poisson Disk Sample. Sets. Computer Graphics Forum 34, 2 (May 2015), 25-32 http://www.cemyuksel.com/research/sampleelimination/ --- source/blender/editors/space_node/drawnode.c | 10 ++++++++++ 1 file changed, 10 insertions(+) (limited to 'source/blender/editors') diff --git a/source/blender/editors/space_node/drawnode.c b/source/blender/editors/space_node/drawnode.c index 421d645d7bd..2857c08cad6 100644 --- a/source/blender/editors/space_node/drawnode.c +++ b/source/blender/editors/space_node/drawnode.c @@ -3208,6 +3208,13 @@ static void node_geometry_buts_attribute_mix(uiLayout *layout, uiItemR(col, ptr, "input_type_b", DEFAULT_FLAGS, IFACE_("B"), ICON_NONE); } +static void node_geometry_buts_attribute_point_distribute(uiLayout *layout, + bContext *UNUSED(C), + PointerRNA *ptr) +{ + uiItemR(layout, ptr, "distribute_method", DEFAULT_FLAGS, "", ICON_NONE); +} + static void node_geometry_set_butfunc(bNodeType *ntype) { switch (ntype->type) { @@ -3235,6 +3242,9 @@ static void node_geometry_set_butfunc(bNodeType *ntype) case GEO_NODE_ATTRIBUTE_MIX: ntype->draw_buttons = node_geometry_buts_attribute_mix; break; + case GEO_NODE_POINT_DISTRIBUTE: + ntype->draw_buttons = node_geometry_buts_attribute_point_distribute; + break; } } -- cgit v1.2.3 From 571362642201a743168cdf4c827a59c09c40414b Mon Sep 17 00:00:00 2001 From: Richard Antalik Date: Wed, 16 Dec 2020 20:34:26 +0100 Subject: VSE: Improve motion-picture workflow This commit resolves problem introduced in e1665c3d3190 - it was difficult to import media at their original resolution. This is done by using original resolution as reference for scale. All crop and strip transform values and their animation is converted form old files. To make both workflows easy to use, sequencer tool settings have been created with preset for preffered scaling method. This setting is in sequencer timeline header and add image or movie strip operator properties. Two new operators have been added: `sequencer.strip_transform_fit` operator with 3 options: Scale To Fit, Scale to Fill and Stretch To Fill. Operator can fail if strip image or video is not loaded currently, this case should be either sanitized or data loaded on demand. `sequencer.strip_transform_clear` operator with 4 options: Clear position, scale, rotation and all (previous 3 options combined). Reviewed By: sergey, fsiddi Differential Revision: https://developer.blender.org/D9582 --- .../editors/space_sequencer/sequencer_add.c | 29 ++++- .../editors/space_sequencer/sequencer_edit.c | 145 +++++++++++++++++++++ .../editors/space_sequencer/sequencer_intern.h | 2 + .../editors/space_sequencer/sequencer_ops.c | 2 + 4 files changed, 176 insertions(+), 2 deletions(-) (limited to 'source/blender/editors') diff --git a/source/blender/editors/space_sequencer/sequencer_add.c b/source/blender/editors/space_sequencer/sequencer_add.c index 37dfcdbc765..71433a6978a 100644 --- a/source/blender/editors/space_sequencer/sequencer_add.c +++ b/source/blender/editors/space_sequencer/sequencer_add.c @@ -81,9 +81,18 @@ typedef struct SequencerAddData { #define SEQPROP_ENDFRAME (1 << 1) #define SEQPROP_NOPATHS (1 << 2) #define SEQPROP_NOCHAN (1 << 3) +#define SEQPROP_FIT_METHOD (1 << 4) #define SELECT 1 +static const EnumPropertyItem scale_fit_methods[] = { + {SEQ_SCALE_TO_FIT, "FIT", 0, "Scale to Fit", "Scale image to fit within the canvas"}, + {SEQ_SCALE_TO_FILL, "FILL", 0, "Scale to Fill", "Scale image to completely fill the canvas"}, + {SEQ_STRETCH_TO_FILL, "STRETCH", 0, "Stretch to Fill", "Stretch image to fill the canvas"}, + {SEQ_USE_ORIGINAL_SIZE, "ORIGINAL", 0, "Use Original Size", "Keep image at its original size"}, + {0, NULL, 0, NULL, NULL}, +}; + static void sequencer_generic_props__internal(wmOperatorType *ot, int flag) { PropertyRNA *prop; @@ -123,6 +132,15 @@ static void sequencer_generic_props__internal(wmOperatorType *ot, int flag) prop = RNA_def_boolean( ot->srna, "overlap", 0, "Allow Overlap", "Don't correct overlap on new sequence strips"); RNA_def_property_flag(prop, PROP_HIDDEN); + + if (flag & SEQPROP_FIT_METHOD) { + ot->prop = RNA_def_enum(ot->srna, + "fit_method", + scale_fit_methods, + SEQ_SCALE_TO_FIT, + "Fit Method", + "Scale fit method"); + } } static void sequencer_generic_invoke_path__internal(bContext *C, @@ -206,6 +224,8 @@ static void seq_load_operator_info(SeqLoadInfo *seq_load, bContext *C, wmOperato seq_load->end_frame = seq_load->start_frame; seq_load->channel = RNA_int_get(op->ptr, "channel"); seq_load->len = 1; + seq_load->fit_method = RNA_enum_get(op->ptr, "fit_method"); + SEQ_tool_settings_fit_method_set(CTX_data_scene(C), seq_load->fit_method); if ((prop = RNA_struct_find_property(op->ptr, "filepath"))) { /* Full path, file is set by the caller. */ @@ -659,6 +679,7 @@ static int sequencer_add_movie_strip_invoke(bContext *C, if (ed && ed->seqbasep && ed->seqbasep->first) { RNA_boolean_set(op->ptr, "use_framerate", false); } + RNA_enum_set(op->ptr, "fit_method", SEQ_tool_settings_fit_method_get(scene)); /* This is for drag and drop. */ if ((RNA_struct_property_is_set(op->ptr, "files") && RNA_collection_length(op->ptr, "files")) || @@ -725,7 +746,7 @@ void SEQUENCER_OT_movie_strip_add(struct wmOperatorType *ot) WM_FILESEL_SHOW_PROPS | WM_FILESEL_DIRECTORY, FILE_DEFAULTDISPLAY, FILE_SORT_DEFAULT); - sequencer_generic_props__internal(ot, SEQPROP_STARTFRAME); + sequencer_generic_props__internal(ot, SEQPROP_STARTFRAME | SEQPROP_FIT_METHOD); RNA_def_boolean(ot->srna, "sound", true, "Sound", "Load sound with the movie"); RNA_def_boolean(ot->srna, "use_framerate", @@ -928,6 +949,9 @@ static int sequencer_add_image_strip_invoke(bContext *C, PropertyRNA *prop; Scene *scene = CTX_data_scene(C); + const SequencerToolSettings *tool_settings = scene->toolsettings->sequencer_tool_settings; + RNA_enum_set(op->ptr, "fit_method", tool_settings->fit_method); + /* Name set already by drag and drop. */ if (RNA_struct_property_is_set(op->ptr, "files") && RNA_collection_length(op->ptr, "files")) { sequencer_generic_invoke_xy__internal( @@ -972,7 +996,8 @@ void SEQUENCER_OT_image_strip_add(struct wmOperatorType *ot) WM_FILESEL_SHOW_PROPS | WM_FILESEL_DIRECTORY, FILE_DEFAULTDISPLAY, FILE_SORT_DEFAULT); - sequencer_generic_props__internal(ot, SEQPROP_STARTFRAME | SEQPROP_ENDFRAME); + sequencer_generic_props__internal(ot, + SEQPROP_STARTFRAME | SEQPROP_ENDFRAME | SEQPROP_FIT_METHOD); RNA_def_boolean(ot->srna, "use_placeholders", diff --git a/source/blender/editors/space_sequencer/sequencer_edit.c b/source/blender/editors/space_sequencer/sequencer_edit.c index 1e3529a9607..ddc9ba2e0f6 100644 --- a/source/blender/editors/space_sequencer/sequencer_edit.c +++ b/source/blender/editors/space_sequencer/sequencer_edit.c @@ -3414,3 +3414,148 @@ Sequence *find_nearest_seq(Scene *scene, View2D *v2d, int *hand, const int mval[ } /** \} */ + +/* -------------------------------------------------------------------- */ +/** \name Clear Strip Transform Operator + * \{ */ + +enum { + STRIP_TRANSFORM_POSITION, + STRIP_TRANSFORM_SCALE, + STRIP_TRANSFORM_ROTATION, + STRIP_TRANSFORM_ALL, +}; + +static const EnumPropertyItem transform_reset_properties[] = { + {STRIP_TRANSFORM_POSITION, "POSITION", 0, "Position", "Reset strip transform location"}, + {STRIP_TRANSFORM_SCALE, "SCALE", 0, "Scale", "Reset strip transform scale"}, + {STRIP_TRANSFORM_ROTATION, "ROTATION", 0, "Rotation", "Reset strip transform rotation"}, + {STRIP_TRANSFORM_ALL, "ALL", 0, "All", "Reset strip transform location, scale and rotation"}, + {0, NULL, 0, NULL, NULL}, +}; + +static int sequencer_strip_transform_clear_exec(bContext *C, wmOperator *op) +{ + Scene *scene = CTX_data_scene(C); + const Editing *ed = BKE_sequencer_editing_get(scene, false); + Sequence *seq; + const int property = RNA_enum_get(op->ptr, "property"); + + for (seq = ed->seqbasep->first; seq; seq = seq->next) { + if (seq->flag & SELECT && seq->type != SEQ_TYPE_SOUND_RAM) { + StripTransform *transform = seq->strip->transform; + switch (property) { + case STRIP_TRANSFORM_POSITION: + transform->xofs = 0; + transform->yofs = 0; + break; + case STRIP_TRANSFORM_SCALE: + transform->scale_x = 1.0f; + transform->scale_y = 1.0f; + break; + case STRIP_TRANSFORM_ROTATION: + transform->rotation = 0.0f; + break; + case STRIP_TRANSFORM_ALL: + transform->xofs = 0; + transform->yofs = 0; + transform->scale_x = 1.0f; + transform->scale_y = 1.0f; + transform->rotation = 0.0f; + break; + } + BKE_sequence_invalidate_cache_preprocessed(scene, seq); + } + } + + WM_event_add_notifier(C, NC_SCENE | ND_SEQUENCER, scene); + return OPERATOR_FINISHED; +} + +void SEQUENCER_OT_strip_transform_clear(struct wmOperatorType *ot) +{ + /* Identifiers. */ + ot->name = "Clear Strip Transform"; + ot->idname = "SEQUENCER_OT_strip_transform_clear"; + ot->description = "Reset image transformation to default value"; + + /* Api callbacks. */ + ot->exec = sequencer_strip_transform_clear_exec; + ot->poll = sequencer_edit_poll; + + /* Flags. */ + ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; + + ot->prop = RNA_def_enum(ot->srna, + "property", + transform_reset_properties, + STRIP_TRANSFORM_ALL, + "Property", + "Strip transform property to be reset"); +} + +/** \} */ + +/* -------------------------------------------------------------------- */ +/** \name Transform Set Fit Operator + * \{ */ + +static const EnumPropertyItem scale_fit_methods[] = { + {SEQ_SCALE_TO_FIT, "FIT", 0, "Scale to Fit", "Scale image so fits in preview"}, + {SEQ_SCALE_TO_FILL, "FILL", 0, "Scale to Fill", "Scale image so it fills preview completely"}, + {SEQ_STRETCH_TO_FILL, "STRETCH", 0, "Stretch to Fill", "Stretch image so it fills preview"}, + {0, NULL, 0, NULL, NULL}, +}; + +static int sequencer_strip_transform_fit_exec(bContext *C, wmOperator *op) +{ + Scene *scene = CTX_data_scene(C); + const Editing *ed = BKE_sequencer_editing_get(scene, false); + Sequence *seq; + const eSeqImageFitMethod fit_method = RNA_enum_get(op->ptr, "fit_method"); + + for (seq = ed->seqbasep->first; seq; seq = seq->next) { + if (seq->flag & SELECT && seq->type != SEQ_TYPE_SOUND_RAM) { + const int timeline_frame = CFRA; + StripElem *strip_elem = SEQ_render_give_stripelem(seq, timeline_frame); + + if (strip_elem == NULL) { + continue; + } + + SEQ_set_scale_to_fit(seq, + strip_elem->orig_width, + strip_elem->orig_height, + scene->r.xsch, + scene->r.ysch, + fit_method); + BKE_sequence_invalidate_cache_preprocessed(scene, seq); + } + } + + WM_event_add_notifier(C, NC_SCENE | ND_SEQUENCER, scene); + return OPERATOR_FINISHED; +} + +void SEQUENCER_OT_strip_transform_fit(struct wmOperatorType *ot) +{ + /* Identifiers. */ + ot->name = "Strip Transform Set Fit"; + ot->idname = "SEQUENCER_OT_strip_transform_fit"; + + /* Api callbacks. */ + ot->exec = sequencer_strip_transform_fit_exec; + ot->poll = sequencer_edit_poll; + + /* Flags. */ + ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; + + ot->prop = RNA_def_enum(ot->srna, + "fit_method", + scale_fit_methods, + SEQ_SCALE_TO_FIT, + "Fit Method", + "Scale fit fit_method"); +} + +/** \} */ diff --git a/source/blender/editors/space_sequencer/sequencer_intern.h b/source/blender/editors/space_sequencer/sequencer_intern.h index 6ccfd3a9045..4c942a83f2b 100644 --- a/source/blender/editors/space_sequencer/sequencer_intern.h +++ b/source/blender/editors/space_sequencer/sequencer_intern.h @@ -144,6 +144,8 @@ void SEQUENCER_OT_enable_proxies(struct wmOperatorType *ot); void SEQUENCER_OT_export_subtitles(struct wmOperatorType *ot); void SEQUENCER_OT_set_range_to_strips(struct wmOperatorType *ot); +void SEQUENCER_OT_strip_transform_clear(struct wmOperatorType *ot); +void SEQUENCER_OT_strip_transform_fit(struct wmOperatorType *ot); /* sequencer_select.c */ void SEQUENCER_OT_select_all(struct wmOperatorType *ot); diff --git a/source/blender/editors/space_sequencer/sequencer_ops.c b/source/blender/editors/space_sequencer/sequencer_ops.c index bdf6e4ece7f..7bfc8600544 100644 --- a/source/blender/editors/space_sequencer/sequencer_ops.c +++ b/source/blender/editors/space_sequencer/sequencer_ops.c @@ -81,6 +81,8 @@ void sequencer_operatortypes(void) WM_operatortype_append(SEQUENCER_OT_change_path); WM_operatortype_append(SEQUENCER_OT_set_range_to_strips); + WM_operatortype_append(SEQUENCER_OT_strip_transform_clear); + WM_operatortype_append(SEQUENCER_OT_strip_transform_fit); /* sequencer_select.c */ WM_operatortype_append(SEQUENCER_OT_select_all); -- cgit v1.2.3 From ad7682ffdb3db5d368fd5d16f1649da780cc069f Mon Sep 17 00:00:00 2001 From: Gaia Clary Date: Wed, 16 Dec 2020 20:37:29 +0100 Subject: Allow vertex tools to operate on weight groups when armature is in object mode Since a few versions (even before 2.79) we have an option that allows to restrict the vertex tools to operate only on deform groups. This was originally implemented for working with vertex groups for skeletal animation. In that case it is fortunate to have weight tools operate only on deforming vertext groups (vgroups assigned to bones) In previous versions of Blender (up to 2.79) we have been able to use this option in Mesh Edit mode regardless of the armature mode. The current implementation (since 2.80 as far as i know) enables this option only when the associated armature is in pose mode. this has a bad consequence: It is not at all intuitive that you have to put the armature into Pose mode before you can make use of the option in mesh edit mode. Besides this it is not even necessary in the case when the user wants to restrict the tool only to all pose bones. In that case the armature can safely be kept in Object mode. However, when the tool shall apply only to selected pose bones, then it actually makes sense to have the armature in pose mode (as it is implemented right now) I do not know why this feature has been restricted as described above. It must have got lost somewhere on the way to Blender 2.90 This patch fixes the issue as it allows to select the "restrict to pose bones" option when the armature is in any mode. I see no downsides of this change, actually this is a fix for a feature that once worked and apparently got forgotten in newer releases. Reviewed By: sybren, campbellbarton Differential Revision: https://developer.blender.org/D9658 --- source/blender/editors/object/object_vgroup.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'source/blender/editors') diff --git a/source/blender/editors/object/object_vgroup.c b/source/blender/editors/object/object_vgroup.c index 3d6a6abfe0d..23f1718cb2e 100644 --- a/source/blender/editors/object/object_vgroup.c +++ b/source/blender/editors/object/object_vgroup.c @@ -741,6 +741,9 @@ const EnumPropertyItem *ED_object_vgroup_selection_itemf_helper(const bContext * RNA_enum_items_add_value( &item, &totitem, WT_vertex_group_select_item, WT_VGROUP_BONE_SELECT); } + } + + if (BKE_modifiers_is_deformed_by_armature(ob)) { if (selection_mask & (1 << WT_VGROUP_BONE_DEFORM)) { RNA_enum_items_add_value( &item, &totitem, WT_vertex_group_select_item, WT_VGROUP_BONE_DEFORM); -- cgit v1.2.3 From 07c46154318e321fe76c818c357439b79ea982cc Mon Sep 17 00:00:00 2001 From: Philipp Oeser Date: Wed, 16 Dec 2020 19:00:12 +0100 Subject: Fix T83856: Sculpt: anchored brushes with spherical falloff ignore topology automasking Anchored brushes with spherical falloff start off with zero radius, thus we have no pbvh nodes on the first brush step. This would prevent initializing the automasking cache [which only happens on the first brush step]. Maniphest Tasks: T83856 Differential Revision: https://developer.blender.org/D9873 --- source/blender/editors/sculpt_paint/sculpt.c | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) (limited to 'source/blender/editors') diff --git a/source/blender/editors/sculpt_paint/sculpt.c b/source/blender/editors/sculpt_paint/sculpt.c index 26db2673335..38d2bed7d97 100644 --- a/source/blender/editors/sculpt_paint/sculpt.c +++ b/source/blender/editors/sculpt_paint/sculpt.c @@ -5923,6 +5923,17 @@ static void do_brush_action(Sculpt *sd, Object *ob, Brush *brush, UnifiedPaintSe } } + /* Initialize automasking cache. For anchored brushes with spherical falloff, we start off with + * zero radius, thus we have no pbvh nodes on the first brush step. */ + if (totnode || + ((brush->falloff_shape == PAINT_FALLOFF_SHAPE_SPHERE) && (brush->flag & BRUSH_ANCHORED))) { + if (SCULPT_stroke_is_first_brush_step(ss->cache)) { + if (SCULPT_is_automasking_enabled(sd, ss, brush)) { + ss->cache->automasking = SCULPT_automasking_cache_init(sd, brush, ob); + } + } + } + /* Only act if some verts are inside the brush area. */ if (totnode) { float location[3]; @@ -5946,12 +5957,6 @@ static void do_brush_action(Sculpt *sd, Object *ob, Brush *brush, UnifiedPaintSe update_brush_local_mat(sd, ob); } - if (SCULPT_stroke_is_first_brush_step(ss->cache)) { - if (SCULPT_is_automasking_enabled(sd, ss, brush)) { - ss->cache->automasking = SCULPT_automasking_cache_init(sd, brush, ob); - } - } - if (brush->sculpt_tool == SCULPT_TOOL_POSE && SCULPT_stroke_is_first_brush_step(ss->cache)) { SCULPT_pose_brush_init(sd, ob, ss, brush); } -- cgit v1.2.3 From d11b219d40d7c72156fd11c335fde27212997957 Mon Sep 17 00:00:00 2001 From: Richard Antalik Date: Thu, 17 Dec 2020 02:11:22 +0100 Subject: Fix T83869: Crash when creating Sequencer in new scene Crash on null dereference in `SEQ_timeline_boundbox()`. This function was generalized in rB9e4a4c2e996c to work on arbitrary `seqbase`. Fixed by refactoring `SEQ_timeline_boundbox()` functions to return default sane values if `seqbase` is `NULL` Reviewed By: HooglyBoogly Differential Revision: https://developer.blender.org/D9878 --- source/blender/editors/space_sequencer/sequencer_draw.c | 2 +- source/blender/editors/space_sequencer/sequencer_view.c | 6 +----- 2 files changed, 2 insertions(+), 6 deletions(-) (limited to 'source/blender/editors') diff --git a/source/blender/editors/space_sequencer/sequencer_draw.c b/source/blender/editors/space_sequencer/sequencer_draw.c index 5ad1e2399f5..d7d601a3c76 100644 --- a/source/blender/editors/space_sequencer/sequencer_draw.c +++ b/source/blender/editors/space_sequencer/sequencer_draw.c @@ -2305,7 +2305,7 @@ void draw_timeline_seq(const bContext *C, ARegion *region) UI_view2d_view_ortho(v2d); /* Get timeline bound-box, needed for the scroll-bars. */ - SEQ_timeline_boundbox(scene, ed->seqbasep, &v2d->tot); + SEQ_timeline_boundbox(scene, SEQ_active_seqbase_get(ed), &v2d->tot); draw_seq_backdrop(v2d); UI_view2d_constant_grid_draw(v2d, FPS); diff --git a/source/blender/editors/space_sequencer/sequencer_view.c b/source/blender/editors/space_sequencer/sequencer_view.c index d2166705943..e12c43b7804 100644 --- a/source/blender/editors/space_sequencer/sequencer_view.c +++ b/source/blender/editors/space_sequencer/sequencer_view.c @@ -90,11 +90,7 @@ static int sequencer_view_all_exec(bContext *C, wmOperator *op) Scene *scene = CTX_data_scene(C); const Editing *ed = BKE_sequencer_editing_get(scene, false); - if (ed == NULL) { - return OPERATOR_FINISHED; - } - - SEQ_timeline_boundbox(scene, ed->seqbasep, &box); + SEQ_timeline_boundbox(scene, SEQ_active_seqbase_get(ed), &box); UI_view2d_smooth_view(C, region, &box, smooth_viewtx); return OPERATOR_FINISHED; } -- cgit v1.2.3 From 6203a3ee684d704f2270edde4df80e2549d1a38d Mon Sep 17 00:00:00 2001 From: Julian Eisel Date: Thu, 17 Dec 2020 11:20:12 +0100 Subject: Fix T83878: Crash right-clicking in Asset Browser with no asset active Data of the File Browser context callback needs to be validated and return `CTX_RESULT_NO_DATA` if the context member is valid but not set in the current context. --- source/blender/editors/space_file/space_file.c | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) (limited to 'source/blender/editors') diff --git a/source/blender/editors/space_file/space_file.c b/source/blender/editors/space_file/space_file.c index 5bd7f6c17f6..774dc54700c 100644 --- a/source/blender/editors/space_file/space_file.c +++ b/source/blender/editors/space_file/space_file.c @@ -803,16 +803,25 @@ static int /*eContextResult*/ file_context(const bContext *C, if (CTX_data_equals(member, "active_file")) { FileDirEntry *file = filelist_file(sfile->files, params->active_file); + if (file == NULL) { + return CTX_RESULT_NO_DATA; + } + CTX_data_pointer_set(result, &screen->id, &RNA_FileSelectEntry, file); return CTX_RESULT_OK; } if (CTX_data_equals(member, "id")) { const FileDirEntry *file = filelist_file(sfile->files, params->active_file); + if (file == NULL) { + return CTX_RESULT_NO_DATA; + } ID *id = filelist_file_get_id(file); - if (id) { - CTX_data_id_pointer_set(result, id); + if (id == NULL) { + return CTX_RESULT_NO_DATA; } + + CTX_data_id_pointer_set(result, id); return CTX_RESULT_OK; } -- cgit v1.2.3 From 0eedba328df3cbc326900c34cdfc39b8554ad5ec Mon Sep 17 00:00:00 2001 From: Jacques Lucke Date: Thu, 17 Dec 2020 11:55:45 +0100 Subject: Geometry Nodes: add Attribute Color Ramp node Differential Revision: https://developer.blender.org/D9861 Ref T82585. --- source/blender/editors/space_node/drawnode.c | 10 ++++++++++ 1 file changed, 10 insertions(+) (limited to 'source/blender/editors') diff --git a/source/blender/editors/space_node/drawnode.c b/source/blender/editors/space_node/drawnode.c index 2857c08cad6..45f3b6cf9c9 100644 --- a/source/blender/editors/space_node/drawnode.c +++ b/source/blender/editors/space_node/drawnode.c @@ -3215,6 +3215,13 @@ static void node_geometry_buts_attribute_point_distribute(uiLayout *layout, uiItemR(layout, ptr, "distribute_method", DEFAULT_FLAGS, "", ICON_NONE); } +static void node_geometry_buts_attribute_color_ramp(uiLayout *layout, + bContext *UNUSED(C), + PointerRNA *ptr) +{ + uiTemplateColorRamp(layout, ptr, "color_ramp", 0); +} + static void node_geometry_set_butfunc(bNodeType *ntype) { switch (ntype->type) { @@ -3245,6 +3252,9 @@ static void node_geometry_set_butfunc(bNodeType *ntype) case GEO_NODE_POINT_DISTRIBUTE: ntype->draw_buttons = node_geometry_buts_attribute_point_distribute; break; + case GEO_NODE_ATTRIBUTE_COLOR_RAMP: + ntype->draw_buttons = node_geometry_buts_attribute_color_ramp; + break; } } -- cgit v1.2.3 From cf2ebaf27c78b3f8f79d9d014ca2261228f87e70 Mon Sep 17 00:00:00 2001 From: Bastien Montagne Date: Thu, 17 Dec 2020 12:03:34 +0100 Subject: Fix T83875: Converting Proxy to override crashes blender. Some weird proxies apparently can have a local collection instancing... Not sure this is even really valid for proxies, but in any case we cannot override that, just detect and properly cancel the operation then. Should be backported to 2.91.1 should we do it. --- source/blender/editors/object/object_relations.c | 11 ++++++++++- source/blender/editors/space_outliner/outliner_tools.c | 13 ++++++++++--- 2 files changed, 20 insertions(+), 4 deletions(-) (limited to 'source/blender/editors') diff --git a/source/blender/editors/object/object_relations.c b/source/blender/editors/object/object_relations.c index 8ec9f7af184..5caa7c71e83 100644 --- a/source/blender/editors/object/object_relations.c +++ b/source/blender/editors/object/object_relations.c @@ -2527,7 +2527,7 @@ static bool convert_proxy_to_override_poll(bContext *C) return obact != NULL && obact->proxy != NULL; } -static int convert_proxy_to_override_exec(bContext *C, wmOperator *UNUSED(op)) +static int convert_proxy_to_override_exec(bContext *C, wmOperator *op) { Main *bmain = CTX_data_main(C); Scene *scene = CTX_data_scene(C); @@ -2541,6 +2541,15 @@ static int convert_proxy_to_override_exec(bContext *C, wmOperator *UNUSED(op)) const bool success = BKE_lib_override_library_proxy_convert(bmain, scene, view_layer, ob_proxy); + if (!success) { + BKE_reportf( + op->reports, + RPT_ERROR_INVALID_INPUT, + "Could not create a library override from proxy '%s' (might use already local data?)", + ob_proxy->id.name + 2); + return OPERATOR_CANCELLED; + } + /* Remove the instance empty from this scene, the items now have an overridden collection * instead. */ if (success && is_override_instancing_object) { diff --git a/source/blender/editors/space_outliner/outliner_tools.c b/source/blender/editors/space_outliner/outliner_tools.c index e4c3ebfdff5..492fc5c23bc 100644 --- a/source/blender/editors/space_outliner/outliner_tools.c +++ b/source/blender/editors/space_outliner/outliner_tools.c @@ -737,7 +737,7 @@ static void id_local_fn(bContext *C, } static void object_proxy_to_override_convert_fn(bContext *C, - ReportList *UNUSED(reports), + ReportList *reports, Scene *UNUSED(scene), TreeElement *UNUSED(te), TreeStoreElem *UNUSED(tsep), @@ -754,8 +754,15 @@ static void object_proxy_to_override_convert_fn(bContext *C, return; } - BKE_lib_override_library_proxy_convert( - CTX_data_main(C), scene, CTX_data_view_layer(C), ob_proxy); + if (!BKE_lib_override_library_proxy_convert( + CTX_data_main(C), scene, CTX_data_view_layer(C), ob_proxy)) { + BKE_reportf( + reports, + RPT_ERROR_INVALID_INPUT, + "Could not create a library override from proxy '%s' (might use already local data?)", + ob_proxy->id.name + 2); + return; + } DEG_id_tag_update(&scene->id, ID_RECALC_BASE_FLAGS | ID_RECALC_COPY_ON_WRITE); WM_event_add_notifier(C, NC_WINDOW, NULL); -- cgit v1.2.3 From fed995ced5b0b963bb42de5aa3e93a3c5dc91aac Mon Sep 17 00:00:00 2001 From: Philipp Oeser Date: Thu, 17 Dec 2020 13:41:10 +0100 Subject: Fix T83888: Ctrl F in Asset Browser crashes blender In case of being in Asset browsing mode, the search field is located in the header (RGN_TYPE_HEADER not RGN_TYPE_UI as for file browsing mode). To be future proof, now iterate all regions and act if the "filter_search" can be activated. Maniphest Tasks: T83888 Differential Revision: https://developer.blender.org/D9882 --- source/blender/editors/space_file/file_ops.c | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) (limited to 'source/blender/editors') diff --git a/source/blender/editors/space_file/file_ops.c b/source/blender/editors/space_file/file_ops.c index be4577bcba7..3730174a6c7 100644 --- a/source/blender/editors/space_file/file_ops.c +++ b/source/blender/editors/space_file/file_ops.c @@ -2778,13 +2778,20 @@ void FILE_OT_delete(struct wmOperatorType *ot) static int file_start_filter_exec(bContext *C, wmOperator *UNUSED(op)) { ScrArea *area = CTX_wm_area(C); - ARegion *region = BKE_area_find_region_type(area, RGN_TYPE_UI); SpaceFile *sfile = CTX_wm_space_file(C); FileSelectParams *params = ED_fileselect_get_active_params(sfile); ARegion *region_ctx = CTX_wm_region(C); - CTX_wm_region_set(C, region); - UI_textbutton_activate_rna(C, region, params, "filter_search"); + + if (area) { + LISTBASE_FOREACH (ARegion *, region, &area->regionbase) { + CTX_wm_region_set(C, region); + if (UI_textbutton_activate_rna(C, region, params, "filter_search")) { + break; + } + } + } + CTX_wm_region_set(C, region_ctx); return OPERATOR_FINISHED; -- cgit v1.2.3 From 48ddb94a26611a27d24ec02c2275b4f1fe27f87f Mon Sep 17 00:00:00 2001 From: Hans Goudey Date: Thu, 17 Dec 2020 12:22:47 -0600 Subject: Geometry Nodes: Point separate and attribute compare nodes This patch adds two related nodes, a node for separating points and mesh vertices based on a boolean attribute input, and a node for creating boolean attributes with comparisons. See the differential for an example file and video. Point Separate (T83059) The output in both geometries is just point data, contained in the mesh and point cloud components, depending which components had data in the input geometry. Any points with the mask attribute set to true will be moved from the first geometry output to the second. This means that for meshes, all edge and face data will be removed. Any point domain attributes are moved to the correct output geometry as well. Attribute Compare (T83057) The attribute compare does the "Equal" and "Not Equal" operations by comparing vectors and colors based on their distance from each other. For other operations, the comparison is between the lengths of the vector inputs. In general, the highest complexity data type is used for the operation, and a new function to determine that is added. Differential Revision: https://developer.blender.org/D9876 --- source/blender/editors/space_node/drawnode.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) (limited to 'source/blender/editors') diff --git a/source/blender/editors/space_node/drawnode.c b/source/blender/editors/space_node/drawnode.c index 45f3b6cf9c9..c2951a9d7a8 100644 --- a/source/blender/editors/space_node/drawnode.c +++ b/source/blender/editors/space_node/drawnode.c @@ -3149,6 +3149,15 @@ static void node_geometry_buts_boolean_math(uiLayout *layout, bContext *UNUSED(C uiItemR(layout, ptr, "operation", DEFAULT_FLAGS, "", ICON_NONE); } +static void node_geometry_buts_attribute_compare(uiLayout *layout, + bContext *UNUSED(C), + PointerRNA *ptr) +{ + uiItemR(layout, ptr, "operation", DEFAULT_FLAGS, "", ICON_NONE); + uiItemR(layout, ptr, "input_type_a", DEFAULT_FLAGS, IFACE_("Type A"), ICON_NONE); + uiItemR(layout, ptr, "input_type_b", DEFAULT_FLAGS, IFACE_("Type B"), ICON_NONE); +} + static void node_geometry_buts_subdivision_surface(uiLayout *layout, bContext *UNUSED(C), PointerRNA *UNUSED(ptr)) @@ -3240,6 +3249,9 @@ static void node_geometry_set_butfunc(bNodeType *ntype) case GEO_NODE_ATTRIBUTE_MATH: ntype->draw_buttons = node_geometry_buts_attribute_math; break; + case GEO_NODE_ATTRIBUTE_COMPARE: + ntype->draw_buttons = node_geometry_buts_attribute_compare; + break; case GEO_NODE_POINT_INSTANCE: ntype->draw_buttons = node_geometry_buts_point_instance; break; -- cgit v1.2.3 From f193b1afb313bcb937a396f09da2b9903a0d2fc3 Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Thu, 17 Dec 2020 19:29:39 +0100 Subject: Color Management: use scene linear HSV for number buttons in color pickers Previously these HSV values were in the color picking space, which meant the relation to the scene linear RGB values was confusing. The new situation: * RGB number buttons: scene linear color space * HSV number buttons: scene linear color space * Picker widgets: color picking color space * Hex: sRGB color space Fixes T69562, T83853, Ref T68926 --- .../blender/editors/interface/interface_intern.h | 13 ++++- .../interface/interface_region_color_picker.c | 66 ++++++++++------------ 2 files changed, 42 insertions(+), 37 deletions(-) (limited to 'source/blender/editors') diff --git a/source/blender/editors/interface/interface_intern.h b/source/blender/editors/interface/interface_intern.h index 5c7cad4c8d5..8f894d0c4bb 100644 --- a/source/blender/editors/interface/interface_intern.h +++ b/source/blender/editors/interface/interface_intern.h @@ -378,11 +378,20 @@ typedef struct uiButExtraOpIcon { typedef struct ColorPicker { struct ColorPicker *next, *prev; - /** Color data, may be HSV or HSL. */ + + /** Color in HSV or HSL, in color picking color space. Used for HSV cube, + * circle and slider widgets. The color picking space is perceptually + * linear for intuitive editing. */ float color_data[3]; - /** Initial color data (detect changes). */ + /** Initial color data (to detect changes). */ float color_data_init[3]; bool is_init; + + /** HSV or HSL color in scene linear color space value used for number + * buttons. This is scene linear so that there is a clear correspondence + * to the scene linear RGB values. */ + float hsv[3]; + /** Cubic saturation for the color wheel. */ bool use_color_cubic; bool use_color_lock; diff --git a/source/blender/editors/interface/interface_region_color_picker.c b/source/blender/editors/interface/interface_region_color_picker.c index f9a9e7182d2..cbf3dbf393d 100644 --- a/source/blender/editors/interface/interface_region_color_picker.c +++ b/source/blender/editors/interface/interface_region_color_picker.c @@ -182,15 +182,16 @@ static void ui_update_color_picker_buts_rgb(uiBut *from_but, ColorPicker *cpicker, const float rgb[3]) { - float *hsv = cpicker->color_data; + /* Convert from RGB to HSV in scene linear space color for numeric editing. */ + ui_rgb_to_color_picker_compat_v(rgb, cpicker->hsv); - /* Convert from RGB to HSV in perceptually linear space. */ + /* Convert from RGB to HSV in perceptually linear space for picker widgets. */ float tmp[3]; copy_v3_v3(tmp, rgb); if (from_but) { ui_scene_linear_to_color_picker_space(from_but, tmp); } - ui_rgb_to_color_picker_compat_v(tmp, hsv); + ui_rgb_to_color_picker_compat_v(tmp, cpicker->color_data); /* this updates button strings, * is hackish... but button pointers are on stack of caller function */ @@ -235,16 +236,16 @@ static void ui_update_color_picker_buts_rgb(uiBut *from_but, ui_but_value_set(bt, rgb[2]); } else if (bt->str[0] == 'H') { - ui_but_value_set(bt, hsv[0]); + ui_but_value_set(bt, cpicker->hsv[0]); } else if (bt->str[0] == 'S') { - ui_but_value_set(bt, hsv[1]); + ui_but_value_set(bt, cpicker->hsv[1]); } else if (bt->str[0] == 'V') { - ui_but_value_set(bt, hsv[2]); + ui_but_value_set(bt, cpicker->hsv[2]); } else if (bt->str[0] == 'L') { - ui_but_value_set(bt, hsv[2]); + ui_but_value_set(bt, cpicker->hsv[2]); } } @@ -252,7 +253,7 @@ static void ui_update_color_picker_buts_rgb(uiBut *from_but, } } -static void ui_colorpicker_rna_cb(bContext *UNUSED(C), void *bt1, void *UNUSED(arg)) +static void ui_colorpicker_rgba_update_cb(bContext *UNUSED(C), void *bt1, void *UNUSED(arg)) { uiBut *but = (uiBut *)bt1; uiPopupBlockHandle *popup = but->block->handle; @@ -270,19 +271,14 @@ static void ui_colorpicker_rna_cb(bContext *UNUSED(C), void *bt1, void *UNUSED(a } } -static void ui_color_wheel_rna_cb(bContext *UNUSED(C), void *bt1, void *UNUSED(arg)) +static void ui_colorpicker_hsv_update_cb(bContext *UNUSED(C), void *bt1, void *UNUSED(arg)) { uiBut *but = (uiBut *)bt1; uiPopupBlockHandle *popup = but->block->handle; float rgb[3]; ColorPicker *cpicker = but->custom_data; - float *hsv = cpicker->color_data; - - ui_color_picker_to_rgb_v(hsv, rgb); - - /* hsv is saved in perceptually linear space so convert back */ - ui_color_picker_to_scene_linear_space(but, rgb); + ui_color_picker_to_rgb_v(cpicker->hsv, rgb); ui_update_color_picker_buts_rgb(but, but->block, cpicker, rgb); if (popup) { @@ -331,12 +327,12 @@ static void ui_colorpicker_hide_reveal(uiBlock *block, enum ePickerType colormod { /* tag buttons */ LISTBASE_FOREACH (uiBut *, bt, &block->buttons) { - if ((bt->func == ui_colorpicker_rna_cb) && (bt->type == UI_BTYPE_NUM_SLIDER) && + if ((bt->func == ui_colorpicker_rgba_update_cb) && (bt->type == UI_BTYPE_NUM_SLIDER) && (bt->rnaindex != 3)) { /* RGB sliders (color circle and alpha are always shown) */ SET_FLAG_FROM_TEST(bt->flag, (colormode != PICKER_TYPE_RGB), UI_HIDDEN); } - else if (bt->func == ui_color_wheel_rna_cb) { + else if (bt->func == ui_colorpicker_hsv_update_cb) { /* HSV sliders */ SET_FLAG_FROM_TEST(bt->flag, (colormode != PICKER_TYPE_HSV), UI_HIDDEN); } @@ -386,7 +382,7 @@ static void ui_colorpicker_circle(uiBlock *block, 0.0, 0, TIP_("Color")); - UI_but_func_set(bt, ui_colorpicker_rna_cb, bt, NULL); + UI_but_func_set(bt, ui_colorpicker_rgba_update_cb, bt, NULL); bt->custom_data = cpicker; /* value */ @@ -408,7 +404,7 @@ static void ui_colorpicker_circle(uiBlock *block, 0, "Lightness"); hsv_but->gradient_type = UI_GRAD_L_ALT; - UI_but_func_set(&hsv_but->but, ui_colorpicker_rna_cb, &hsv_but->but, NULL); + UI_but_func_set(&hsv_but->but, ui_colorpicker_rgba_update_cb, &hsv_but->but, NULL); } else { hsv_but = (uiButHSVCube *)uiDefButR_prop(block, @@ -428,7 +424,7 @@ static void ui_colorpicker_circle(uiBlock *block, 0, TIP_("Value")); hsv_but->gradient_type = UI_GRAD_V_ALT; - UI_but_func_set(&hsv_but->but, ui_colorpicker_rna_cb, &hsv_but->but, NULL); + UI_but_func_set(&hsv_but->but, ui_colorpicker_rgba_update_cb, &hsv_but->but, NULL); } hsv_but->but.custom_data = cpicker; } @@ -461,7 +457,7 @@ static void ui_colorpicker_square(uiBlock *block, 0, TIP_("Color")); hsv_but->gradient_type = type; - UI_but_func_set(&hsv_but->but, ui_colorpicker_rna_cb, &hsv_but->but, NULL); + UI_but_func_set(&hsv_but->but, ui_colorpicker_rgba_update_cb, &hsv_but->but, NULL); hsv_but->but.custom_data = cpicker; /* value */ @@ -482,7 +478,7 @@ static void ui_colorpicker_square(uiBlock *block, 0, TIP_("Value")); hsv_but->gradient_type = type + 3; - UI_but_func_set(&hsv_but->but, ui_colorpicker_rna_cb, &hsv_but->but, NULL); + UI_but_func_set(&hsv_but->but, ui_colorpicker_rgba_update_cb, &hsv_but->but, NULL); hsv_but->but.custom_data = cpicker; } @@ -497,7 +493,6 @@ static void ui_block_colorpicker(uiBlock *block, uiBut *from_but, float rgba[4], float softmin, softmax, hardmin, hardmax, step, precision; int yco; ColorPicker *cpicker = ui_block_colorpicker_create(block); - float *hsv = cpicker->color_data; PointerRNA *ptr = &from_but->rnapoin; PropertyRNA *prop = from_but->rnaprop; @@ -513,8 +508,9 @@ static void ui_block_colorpicker(uiBlock *block, uiBut *from_but, float rgba[4], float rgb_perceptual[3]; copy_v3_v3(rgb_perceptual, rgba); + ui_rgb_to_color_picker_v(rgba, cpicker->hsv); ui_scene_linear_to_color_picker_space(from_but, rgb_perceptual); - ui_rgb_to_color_picker_v(rgb_perceptual, hsv); + ui_rgb_to_color_picker_v(rgb_perceptual, cpicker->color_data); if (cpicker->is_init == false) { copy_v3_v3(cpicker->color_data_init, cpicker->color_data); cpicker->is_init = true; @@ -639,7 +635,7 @@ static void ui_block_colorpicker(uiBlock *block, uiBut *from_but, float rgba[4], 0, 3, TIP_("Red")); - UI_but_func_set(bt, ui_colorpicker_rna_cb, bt, NULL); + UI_but_func_set(bt, ui_colorpicker_rgba_update_cb, bt, NULL); bt->custom_data = cpicker; bt = uiDefButR_prop(block, UI_BTYPE_NUM_SLIDER, @@ -657,7 +653,7 @@ static void ui_block_colorpicker(uiBlock *block, uiBut *from_but, float rgba[4], 0, 3, TIP_("Green")); - UI_but_func_set(bt, ui_colorpicker_rna_cb, bt, NULL); + UI_but_func_set(bt, ui_colorpicker_rgba_update_cb, bt, NULL); bt->custom_data = cpicker; bt = uiDefButR_prop(block, UI_BTYPE_NUM_SLIDER, @@ -675,7 +671,7 @@ static void ui_block_colorpicker(uiBlock *block, uiBut *from_but, float rgba[4], 0, 3, TIP_("Blue")); - UI_but_func_set(bt, ui_colorpicker_rna_cb, bt, NULL); + UI_but_func_set(bt, ui_colorpicker_rgba_update_cb, bt, NULL); bt->custom_data = cpicker; /* Could use: @@ -693,14 +689,14 @@ static void ui_block_colorpicker(uiBlock *block, uiBut *from_but, float rgba[4], yco, butwidth, UI_UNIT_Y, - hsv, + cpicker->hsv, 0.0, 1.0, 10, 3, TIP_("Hue")); UI_but_flag_disable(bt, UI_BUT_UNDO); - UI_but_func_set(bt, ui_color_wheel_rna_cb, bt, hsv); + UI_but_func_set(bt, ui_colorpicker_hsv_update_cb, bt, NULL); bt->custom_data = cpicker; bt = uiDefButF(block, UI_BTYPE_NUM_SLIDER, @@ -710,14 +706,14 @@ static void ui_block_colorpicker(uiBlock *block, uiBut *from_but, float rgba[4], yco -= UI_UNIT_Y, butwidth, UI_UNIT_Y, - hsv + 1, + cpicker->hsv + 1, 0.0, 1.0, 10, 3, TIP_("Saturation")); UI_but_flag_disable(bt, UI_BUT_UNDO); - UI_but_func_set(bt, ui_color_wheel_rna_cb, bt, hsv); + UI_but_func_set(bt, ui_colorpicker_hsv_update_cb, bt, NULL); bt->custom_data = cpicker; if (U.color_picker_type == USER_CP_CIRCLE_HSL) { bt = uiDefButF(block, @@ -728,7 +724,7 @@ static void ui_block_colorpicker(uiBlock *block, uiBut *from_but, float rgba[4], yco -= UI_UNIT_Y, butwidth, UI_UNIT_Y, - hsv + 2, + cpicker->hsv + 2, 0.0, 1.0, 10, @@ -744,7 +740,7 @@ static void ui_block_colorpicker(uiBlock *block, uiBut *from_but, float rgba[4], yco -= UI_UNIT_Y, butwidth, UI_UNIT_Y, - hsv + 2, + cpicker->hsv + 2, 0.0, softmax, 10, @@ -754,7 +750,7 @@ static void ui_block_colorpicker(uiBlock *block, uiBut *from_but, float rgba[4], UI_but_flag_disable(bt, UI_BUT_UNDO); bt->hardmax = hardmax; /* not common but rgb may be over 1.0 */ - UI_but_func_set(bt, ui_color_wheel_rna_cb, bt, hsv); + UI_but_func_set(bt, ui_colorpicker_hsv_update_cb, bt, NULL); bt->custom_data = cpicker; UI_block_align_end(block); @@ -776,7 +772,7 @@ static void ui_block_colorpicker(uiBlock *block, uiBut *from_but, float rgba[4], 0, 3, TIP_("Alpha")); - UI_but_func_set(bt, ui_colorpicker_rna_cb, bt, NULL); + UI_but_func_set(bt, ui_colorpicker_rgba_update_cb, bt, NULL); bt->custom_data = cpicker; } else { -- cgit v1.2.3 From b10d8e330e529abb1cb017312b46a33ede24a8d0 Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Thu, 17 Dec 2020 19:39:39 +0100 Subject: Cleanup: renaming and code deduplication for color space clarity in picker Ref T68926 --- .../blender/editors/interface/interface_handlers.c | 48 +++--- .../blender/editors/interface/interface_intern.h | 17 +-- .../interface/interface_region_color_picker.c | 161 +++++++++++---------- .../blender/editors/interface/interface_widgets.c | 26 ++-- 4 files changed, 129 insertions(+), 123 deletions(-) (limited to 'source/blender/editors') diff --git a/source/blender/editors/interface/interface_handlers.c b/source/blender/editors/interface/interface_handlers.c index 72ed2cc0933..08e71e0cfd0 100644 --- a/source/blender/editors/interface/interface_handlers.c +++ b/source/blender/editors/interface/interface_handlers.c @@ -5861,7 +5861,7 @@ static int ui_do_but_COLOR(bContext *C, uiBut *but, uiHandleButtonData *data, co if (ELEM(event->type, MOUSEPAN, WHEELDOWNMOUSE, WHEELUPMOUSE) && event->ctrl) { ColorPicker *cpicker = but->custom_data; float hsv_static[3] = {0.0f}; - float *hsv = cpicker ? cpicker->color_data : hsv_static; + float *hsv = cpicker ? cpicker->hsv_perceptual : hsv_static; float col[3]; ui_but_v3_get(but, col); @@ -6089,7 +6089,7 @@ static bool ui_numedit_but_HSVCUBE(uiBut *but, { const uiButHSVCube *hsv_but = (uiButHSVCube *)but; ColorPicker *cpicker = but->custom_data; - float *hsv = cpicker->color_data; + float *hsv = cpicker->hsv_perceptual; float rgb[3]; float x, y; float mx_fl, my_fl; @@ -6107,7 +6107,7 @@ static bool ui_numedit_but_HSVCUBE(uiBut *but, #endif ui_but_v3_get(but, rgb); - ui_scene_linear_to_color_picker_space(but, rgb); + ui_scene_linear_to_perceptual_space(but, rgb); ui_rgb_to_color_picker_HSVCUBE_compat_v(hsv_but, rgb, hsv); @@ -6120,7 +6120,7 @@ static bool ui_numedit_but_HSVCUBE(uiBut *but, /* calculate original hsv again */ copy_v3_v3(rgb, data->origvec); - ui_scene_linear_to_color_picker_space(but, rgb); + ui_scene_linear_to_perceptual_space(but, rgb); copy_v3_v3(hsvo, hsv); @@ -6183,7 +6183,7 @@ static bool ui_numedit_but_HSVCUBE(uiBut *but, } ui_color_picker_to_rgb_HSVCUBE_v(hsv_but, hsv, rgb); - ui_color_picker_to_scene_linear_space(but, rgb); + ui_perceptual_to_scene_linear_space(but, rgb); /* clamp because with color conversion we can exceed range T34295. */ if (hsv_but->gradient_type == UI_GRAD_V_ALT) { @@ -6206,13 +6206,13 @@ static void ui_ndofedit_but_HSVCUBE(uiButHSVCube *hsv_but, const bool shift) { ColorPicker *cpicker = hsv_but->but.custom_data; - float *hsv = cpicker->color_data; + float *hsv = cpicker->hsv_perceptual; const float hsv_v_max = max_ff(hsv[2], hsv_but->but.softmax); float rgb[3]; const float sensitivity = (shift ? 0.15f : 0.3f) * ndof->dt; ui_but_v3_get(&hsv_but->but, rgb); - ui_scene_linear_to_color_picker_space(&hsv_but->but, rgb); + ui_scene_linear_to_perceptual_space(&hsv_but->but, rgb); ui_rgb_to_color_picker_HSVCUBE_compat_v(hsv_but, rgb, hsv); switch (hsv_but->gradient_type) { @@ -6261,7 +6261,7 @@ static void ui_ndofedit_but_HSVCUBE(uiButHSVCube *hsv_but, hsv_clamp_v(hsv, hsv_v_max); ui_color_picker_to_rgb_HSVCUBE_v(hsv_but, hsv, rgb); - ui_color_picker_to_scene_linear_space(&hsv_but->but, rgb); + ui_perceptual_to_scene_linear_space(&hsv_but->but, rgb); copy_v3_v3(data->vec, rgb); ui_but_v3_set(&hsv_but->but, data->vec); @@ -6318,7 +6318,7 @@ static int ui_do_but_HSVCUBE( float rgb[3], def_hsv[3]; float def[4]; ColorPicker *cpicker = but->custom_data; - float *hsv = cpicker->color_data; + float *hsv = cpicker->hsv_perceptual; RNA_property_float_get_default_array(&but->rnapoin, but->rnaprop, def); ui_rgb_to_color_picker_HSVCUBE_v(hsv_but, def, def_hsv); @@ -6374,7 +6374,7 @@ static bool ui_numedit_but_HSVCIRCLE(uiBut *but, { const bool changed = true; ColorPicker *cpicker = but->custom_data; - float *hsv = cpicker->color_data; + float *hsv = cpicker->hsv_perceptual; float mx_fl, my_fl; ui_mouse_scale_warp(data, mx, my, &mx_fl, &my_fl, shift); @@ -6400,8 +6400,8 @@ static bool ui_numedit_but_HSVCIRCLE(uiBut *but, float rgb[3]; ui_but_v3_get(but, rgb); - ui_scene_linear_to_color_picker_space(but, rgb); - ui_rgb_to_color_picker_compat_v(rgb, hsv); + ui_scene_linear_to_perceptual_space(but, rgb); + ui_color_picker_rgb_to_hsv_compat(rgb, hsv); /* exception, when using color wheel in 'locked' value state: * allow choosing a hue for black values, by giving a tiny increment */ @@ -6428,8 +6428,8 @@ static bool ui_numedit_but_HSVCIRCLE(uiBut *but, /* calculate original hsv again */ copy_v3_v3(hsvo, hsv); copy_v3_v3(rgbo, data->origvec); - ui_scene_linear_to_color_picker_space(but, rgbo); - ui_rgb_to_color_picker_compat_v(rgbo, hsvo); + ui_scene_linear_to_perceptual_space(but, rgbo); + ui_color_picker_rgb_to_hsv_compat(rgbo, hsvo); /* and original position */ ui_hsvcircle_pos_from_vals(cpicker, &rect, hsvo, &xpos, &ypos); @@ -6448,7 +6448,7 @@ static bool ui_numedit_but_HSVCIRCLE(uiBut *but, ui_color_snap_hue(snap, &hsv[0]); } - ui_color_picker_to_rgb_v(hsv, rgb); + ui_color_picker_hsv_to_rgb(hsv, rgb); if ((cpicker->use_luminosity_lock)) { if (!is_zero_v3(rgb)) { @@ -6456,7 +6456,7 @@ static bool ui_numedit_but_HSVCIRCLE(uiBut *but, } } - ui_color_picker_to_scene_linear_space(but, rgb); + ui_perceptual_to_scene_linear_space(but, rgb); ui_but_v3_set(but, rgb); data->draglastx = mx; @@ -6473,14 +6473,14 @@ static void ui_ndofedit_but_HSVCIRCLE(uiBut *but, const bool shift) { ColorPicker *cpicker = but->custom_data; - float *hsv = cpicker->color_data; + float *hsv = cpicker->hsv_perceptual; float rgb[3]; float phi, r /*, sqr */ /* UNUSED */, v[2]; const float sensitivity = (shift ? 0.06f : 0.3f) * ndof->dt; ui_but_v3_get(but, rgb); - ui_scene_linear_to_color_picker_space(but, rgb); - ui_rgb_to_color_picker_compat_v(rgb, hsv); + ui_scene_linear_to_perceptual_space(but, rgb); + ui_color_picker_rgb_to_hsv_compat(rgb, hsv); /* Convert current color on hue/sat disc to circular coordinates phi, r */ phi = fmodf(hsv[0] + 0.25f, 1.0f) * -2.0f * (float)M_PI; @@ -6530,7 +6530,7 @@ static void ui_ndofedit_but_HSVCIRCLE(uiBut *but, hsv_clamp_v(hsv, FLT_MAX); - ui_color_picker_to_rgb_v(hsv, data->vec); + ui_color_picker_hsv_to_rgb(hsv, data->vec); if (cpicker->use_luminosity_lock) { if (!is_zero_v3(data->vec)) { @@ -6538,7 +6538,7 @@ static void ui_ndofedit_but_HSVCIRCLE(uiBut *but, } } - ui_color_picker_to_scene_linear_space(but, data->vec); + ui_perceptual_to_scene_linear_space(but, data->vec); ui_but_v3_set(but, data->vec); } #endif /* WITH_INPUT_NDOF */ @@ -6547,7 +6547,7 @@ static int ui_do_but_HSVCIRCLE( bContext *C, uiBlock *block, uiBut *but, uiHandleButtonData *data, const wmEvent *event) { ColorPicker *cpicker = but->custom_data; - float *hsv = cpicker->color_data; + float *hsv = cpicker->hsv_perceptual; int mx = event->x; int my = event->y; ui_window_to_block(data->region, block, &mx, &my); @@ -6594,10 +6594,10 @@ static int ui_do_but_HSVCIRCLE( def = MEM_callocN(sizeof(float) * len, "reset_defaults - float"); RNA_property_float_get_default_array(&but->rnapoin, but->rnaprop, def); - ui_color_picker_to_rgb_v(def, def_hsv); + ui_color_picker_hsv_to_rgb(def, def_hsv); ui_but_v3_get(but, rgb); - ui_rgb_to_color_picker_compat_v(rgb, hsv); + ui_color_picker_rgb_to_hsv_compat(rgb, hsv); def_hsv[0] = hsv[0]; def_hsv[2] = hsv[2]; diff --git a/source/blender/editors/interface/interface_intern.h b/source/blender/editors/interface/interface_intern.h index 8f894d0c4bb..a35d9d5d336 100644 --- a/source/blender/editors/interface/interface_intern.h +++ b/source/blender/editors/interface/interface_intern.h @@ -382,15 +382,15 @@ typedef struct ColorPicker { /** Color in HSV or HSL, in color picking color space. Used for HSV cube, * circle and slider widgets. The color picking space is perceptually * linear for intuitive editing. */ - float color_data[3]; + float hsv_perceptual[3]; /** Initial color data (to detect changes). */ - float color_data_init[3]; + float hsv_perceptual_init[3]; bool is_init; /** HSV or HSL color in scene linear color space value used for number * buttons. This is scene linear so that there is a clear correspondence * to the scene linear RGB values. */ - float hsv[3]; + float hsv_scene_linear[3]; /** Cubic saturation for the color wheel. */ bool use_color_cubic; @@ -743,15 +743,14 @@ struct uiPopupBlockHandle { /* exposed as public API in UI_interface.h */ /* interface_region_color_picker.c */ -void ui_rgb_to_color_picker_compat_v(const float rgb[3], float r_cp[3]); -void ui_rgb_to_color_picker_v(const float rgb[3], float r_cp[3]); -void ui_color_picker_to_rgb_v(const float r_cp[3], float rgb[3]); -void ui_color_picker_to_rgb(float r_cp0, float r_cp1, float r_cp2, float *r, float *g, float *b); +void ui_color_picker_rgb_to_hsv_compat(const float rgb[3], float r_cp[3]); +void ui_color_picker_rgb_to_hsv(const float rgb[3], float r_cp[3]); +void ui_color_picker_hsv_to_rgb(const float r_cp[3], float rgb[3]); bool ui_but_is_color_gamma(uiBut *but); -void ui_scene_linear_to_color_picker_space(uiBut *but, float rgb[3]); -void ui_color_picker_to_scene_linear_space(uiBut *but, float rgb[3]); +void ui_scene_linear_to_perceptual_space(uiBut *but, float rgb[3]); +void ui_perceptual_to_scene_linear_space(uiBut *but, float rgb[3]); uiBlock *ui_block_func_COLOR(struct bContext *C, uiPopupBlockHandle *handle, void *arg_but); ColorPicker *ui_block_colorpicker_create(struct uiBlock *block); diff --git a/source/blender/editors/interface/interface_region_color_picker.c b/source/blender/editors/interface/interface_region_color_picker.c index cbf3dbf393d..82028d4e595 100644 --- a/source/blender/editors/interface/interface_region_color_picker.c +++ b/source/blender/editors/interface/interface_region_color_picker.c @@ -77,8 +77,10 @@ static void ui_color_picker_rgb_round(float rgb[3]) } } -void ui_rgb_to_color_picker_compat_v(const float rgb[3], float r_cp[3]) +void ui_color_picker_rgb_to_hsv_compat(const float rgb[3], float r_cp[3]) { + /* Convert RGB to HSV, remaining as compatible as possible with the existing + * r_hsv value (for example when value goes to zero, preserve the hue). */ switch (U.color_picker_type) { case USER_CP_CIRCLE_HSL: rgb_to_hsl_compat_v(rgb, r_cp); @@ -89,7 +91,7 @@ void ui_rgb_to_color_picker_compat_v(const float rgb[3], float r_cp[3]) } } -void ui_rgb_to_color_picker_v(const float rgb[3], float r_cp[3]) +void ui_color_picker_rgb_to_hsv(const float rgb[3], float r_cp[3]) { switch (U.color_picker_type) { case USER_CP_CIRCLE_HSL: @@ -101,7 +103,7 @@ void ui_rgb_to_color_picker_v(const float rgb[3], float r_cp[3]) } } -void ui_color_picker_to_rgb_v(const float r_cp[3], float rgb[3]) +void ui_color_picker_hsv_to_rgb(const float r_cp[3], float rgb[3]) { switch (U.color_picker_type) { case USER_CP_CIRCLE_HSL: @@ -113,18 +115,6 @@ void ui_color_picker_to_rgb_v(const float r_cp[3], float rgb[3]) } } -void ui_color_picker_to_rgb(float r_cp0, float r_cp1, float r_cp2, float *r, float *g, float *b) -{ - switch (U.color_picker_type) { - case USER_CP_CIRCLE_HSL: - hsl_to_rgb(r_cp0, r_cp1, r_cp2, r, g, b); - break; - default: - hsv_to_rgb(r_cp0, r_cp1, r_cp2, r, g, b); - break; - } -} - /* Returns true if the button is for a color with gamma baked in, * or if it's a color picker for such a button. */ bool ui_but_is_color_gamma(uiBut *but) @@ -138,7 +128,7 @@ bool ui_but_is_color_gamma(uiBut *but) return but->block->is_color_gamma_picker; } -void ui_scene_linear_to_color_picker_space(uiBut *but, float rgb[3]) +void ui_scene_linear_to_perceptual_space(uiBut *but, float rgb[3]) { /* Map to color picking space for HSV values and HSV cube/circle, * assuming it is more perceptually linear than the scene linear @@ -149,7 +139,7 @@ void ui_scene_linear_to_color_picker_space(uiBut *but, float rgb[3]) } } -void ui_color_picker_to_scene_linear_space(uiBut *but, float rgb[3]) +void ui_perceptual_to_scene_linear_space(uiBut *but, float rgb[3]) { if (!ui_but_is_color_gamma(but)) { IMB_colormanagement_color_picking_to_scene_linear_v3(rgb); @@ -163,16 +153,46 @@ void ui_color_picker_to_scene_linear_space(uiBut *but, float rgb[3]) /** \name Color Picker * \{ */ +static void ui_color_picker_update_hsv(ColorPicker *cpicker, + uiBut *from_but, + const float rgb_scene_linear[3]) +{ + /* Convert from RGB to HSV in scene linear space color for number editing. */ + if (cpicker->is_init == false) { + ui_color_picker_rgb_to_hsv(rgb_scene_linear, cpicker->hsv_scene_linear); + } + else { + ui_color_picker_rgb_to_hsv_compat(rgb_scene_linear, cpicker->hsv_scene_linear); + } + + /* Convert from RGB to HSV in perceptually linear space for picker widgets. */ + float rgb_perceptual[3]; + copy_v3_v3(rgb_perceptual, rgb_scene_linear); + if (from_but) { + ui_scene_linear_to_perceptual_space(from_but, rgb_perceptual); + } + + if (cpicker->is_init == false) { + ui_color_picker_rgb_to_hsv(rgb_perceptual, cpicker->hsv_perceptual); + copy_v3_v3(cpicker->hsv_perceptual_init, cpicker->hsv_perceptual); + } + else { + ui_color_picker_rgb_to_hsv_compat(rgb_perceptual, cpicker->hsv_perceptual); + } + + cpicker->is_init = true; +} + /* for picker, while editing hsv */ void ui_but_hsv_set(uiBut *but) { - float col[3]; + float rgb_perceptual[3]; ColorPicker *cpicker = but->custom_data; - float *hsv = cpicker->color_data; + float *hsv_perceptual = cpicker->hsv_perceptual; - ui_color_picker_to_rgb_v(hsv, col); + ui_color_picker_hsv_to_rgb(hsv_perceptual, rgb_perceptual); - ui_but_v3_set(but, col); + ui_but_v3_set(but, rgb_perceptual); } /* Updates all buttons who share the same color picker as the one passed @@ -180,18 +200,9 @@ void ui_but_hsv_set(uiBut *but) static void ui_update_color_picker_buts_rgb(uiBut *from_but, uiBlock *block, ColorPicker *cpicker, - const float rgb[3]) + const float rgb_scene_linear[3]) { - /* Convert from RGB to HSV in scene linear space color for numeric editing. */ - ui_rgb_to_color_picker_compat_v(rgb, cpicker->hsv); - - /* Convert from RGB to HSV in perceptually linear space for picker widgets. */ - float tmp[3]; - copy_v3_v3(tmp, rgb); - if (from_but) { - ui_scene_linear_to_color_picker_space(from_but, tmp); - } - ui_rgb_to_color_picker_compat_v(tmp, cpicker->color_data); + ui_color_picker_update_hsv(cpicker, from_but, rgb_scene_linear); /* this updates button strings, * is hackish... but button pointers are on stack of caller function */ @@ -201,7 +212,7 @@ static void ui_update_color_picker_buts_rgb(uiBut *from_but, } if (bt->rnaprop) { - ui_but_v3_set(bt, rgb); + ui_but_v3_set(bt, rgb_scene_linear); /* original button that created the color picker already does undo * push, so disable it on RNA buttons in the color picker block */ @@ -214,7 +225,7 @@ static void ui_update_color_picker_buts_rgb(uiBut *from_but, /* Hex code is assumed to be in sRGB space * (coming from other applications, web, etc) */ - copy_v3_v3(rgb_hex, rgb); + copy_v3_v3(rgb_hex, rgb_scene_linear); if (from_but && !ui_but_is_color_gamma(from_but)) { IMB_colormanagement_scene_linear_to_srgb_v3(rgb_hex); ui_color_picker_rgb_round(rgb_hex); @@ -227,25 +238,25 @@ static void ui_update_color_picker_buts_rgb(uiBut *from_but, } else if (bt->str[1] == ' ') { if (bt->str[0] == 'R') { - ui_but_value_set(bt, rgb[0]); + ui_but_value_set(bt, rgb_scene_linear[0]); } else if (bt->str[0] == 'G') { - ui_but_value_set(bt, rgb[1]); + ui_but_value_set(bt, rgb_scene_linear[1]); } else if (bt->str[0] == 'B') { - ui_but_value_set(bt, rgb[2]); + ui_but_value_set(bt, rgb_scene_linear[2]); } else if (bt->str[0] == 'H') { - ui_but_value_set(bt, cpicker->hsv[0]); + ui_but_value_set(bt, cpicker->hsv_scene_linear[0]); } else if (bt->str[0] == 'S') { - ui_but_value_set(bt, cpicker->hsv[1]); + ui_but_value_set(bt, cpicker->hsv_scene_linear[1]); } else if (bt->str[0] == 'V') { - ui_but_value_set(bt, cpicker->hsv[2]); + ui_but_value_set(bt, cpicker->hsv_scene_linear[2]); } else if (bt->str[0] == 'L') { - ui_but_value_set(bt, cpicker->hsv[2]); + ui_but_value_set(bt, cpicker->hsv_scene_linear[2]); } } @@ -259,11 +270,11 @@ static void ui_colorpicker_rgba_update_cb(bContext *UNUSED(C), void *bt1, void * uiPopupBlockHandle *popup = but->block->handle; PropertyRNA *prop = but->rnaprop; PointerRNA ptr = but->rnapoin; - float rgb[4]; + float rgb_scene_linear[4]; if (prop) { - RNA_property_float_get_array(&ptr, prop, rgb); - ui_update_color_picker_buts_rgb(but, but->block, but->custom_data, rgb); + RNA_property_float_get_array(&ptr, prop, rgb_scene_linear); + ui_update_color_picker_buts_rgb(but, but->block, but->custom_data, rgb_scene_linear); } if (popup) { @@ -275,11 +286,11 @@ static void ui_colorpicker_hsv_update_cb(bContext *UNUSED(C), void *bt1, void *U { uiBut *but = (uiBut *)bt1; uiPopupBlockHandle *popup = but->block->handle; - float rgb[3]; + float rgb_scene_linear[3]; ColorPicker *cpicker = but->custom_data; - ui_color_picker_to_rgb_v(cpicker->hsv, rgb); - ui_update_color_picker_buts_rgb(but, but->block, cpicker, rgb); + ui_color_picker_hsv_to_rgb(cpicker->hsv_scene_linear, rgb_scene_linear); + ui_update_color_picker_buts_rgb(but, but->block, cpicker, rgb_scene_linear); if (popup) { popup->menuretval = UI_RETURN_UPDATE; @@ -317,7 +328,7 @@ static void ui_popup_close_cb(bContext *UNUSED(C), void *bt1, void *UNUSED(arg)) if (popup) { ColorPicker *cpicker = but->custom_data; BLI_assert(cpicker->is_init); - popup->menuretval = (equals_v3v3(cpicker->color_data, cpicker->color_data_init) ? + popup->menuretval = (equals_v3v3(cpicker->hsv_perceptual, cpicker->hsv_perceptual_init) ? UI_RETURN_CANCEL : UI_RETURN_OK); } @@ -483,7 +494,10 @@ static void ui_colorpicker_square(uiBlock *block, } /* a HS circle, V slider, rgb/hsv/hex sliders */ -static void ui_block_colorpicker(uiBlock *block, uiBut *from_but, float rgba[4], bool show_picker) +static void ui_block_colorpicker(uiBlock *block, + uiBut *from_but, + float rgba_scene_linear[4], + bool show_picker) { /* ePickerType */ static char colormode = 1; @@ -500,21 +514,13 @@ static void ui_block_colorpicker(uiBlock *block, uiBut *from_but, float rgba[4], butwidth = width - 1.5f * UI_UNIT_X; /* sneaky way to check for alpha */ - rgba[3] = FLT_MAX; + rgba_scene_linear[3] = FLT_MAX; RNA_property_float_ui_range(ptr, prop, &softmin, &softmax, &step, &precision); RNA_property_float_range(ptr, prop, &hardmin, &hardmax); - RNA_property_float_get_array(ptr, prop, rgba); + RNA_property_float_get_array(ptr, prop, rgba_scene_linear); - float rgb_perceptual[3]; - copy_v3_v3(rgb_perceptual, rgba); - ui_rgb_to_color_picker_v(rgba, cpicker->hsv); - ui_scene_linear_to_color_picker_space(from_but, rgb_perceptual); - ui_rgb_to_color_picker_v(rgb_perceptual, cpicker->color_data); - if (cpicker->is_init == false) { - copy_v3_v3(cpicker->color_data_init, cpicker->color_data); - cpicker->is_init = true; - } + ui_color_picker_update_hsv(cpicker, from_but, rgba_scene_linear); /* when the softmax isn't defined in the RNA, * using very large numbers causes sRGB/linear round trip to fail. */ @@ -689,7 +695,7 @@ static void ui_block_colorpicker(uiBlock *block, uiBut *from_but, float rgba[4], yco, butwidth, UI_UNIT_Y, - cpicker->hsv, + cpicker->hsv_scene_linear, 0.0, 1.0, 10, @@ -706,7 +712,7 @@ static void ui_block_colorpicker(uiBlock *block, uiBut *from_but, float rgba[4], yco -= UI_UNIT_Y, butwidth, UI_UNIT_Y, - cpicker->hsv + 1, + cpicker->hsv_scene_linear + 1, 0.0, 1.0, 10, @@ -724,7 +730,7 @@ static void ui_block_colorpicker(uiBlock *block, uiBut *from_but, float rgba[4], yco -= UI_UNIT_Y, butwidth, UI_UNIT_Y, - cpicker->hsv + 2, + cpicker->hsv_scene_linear + 2, 0.0, 1.0, 10, @@ -740,7 +746,7 @@ static void ui_block_colorpicker(uiBlock *block, uiBut *from_but, float rgba[4], yco -= UI_UNIT_Y, butwidth, UI_UNIT_Y, - cpicker->hsv + 2, + cpicker->hsv_scene_linear + 2, 0.0, softmax, 10, @@ -755,7 +761,7 @@ static void ui_block_colorpicker(uiBlock *block, uiBut *from_but, float rgba[4], UI_block_align_end(block); - if (rgba[3] != FLT_MAX) { + if (rgba_scene_linear[3] != FLT_MAX) { bt = uiDefButR_prop(block, UI_BTYPE_NUM_SLIDER, 0, @@ -776,14 +782,14 @@ static void ui_block_colorpicker(uiBlock *block, uiBut *from_but, float rgba[4], bt->custom_data = cpicker; } else { - rgba[3] = 1.0f; + rgba_scene_linear[3] = 1.0f; } /* Hex color is in sRGB space. */ float rgb_hex[3]; uchar rgb_hex_uchar[3]; - copy_v3_v3(rgb_hex, rgba); + copy_v3_v3(rgb_hex, rgba_scene_linear); if (!ui_but_is_color_gamma(from_but)) { IMB_colormanagement_scene_linear_to_srgb_v3(rgb_hex); @@ -846,21 +852,22 @@ static int ui_colorpicker_small_wheel_cb(const bContext *UNUSED(C), LISTBASE_FOREACH (uiBut *, but, &block->buttons) { if (but->type == UI_BTYPE_HSVCUBE && but->active == NULL) { uiPopupBlockHandle *popup = block->handle; - float rgb[3]; ColorPicker *cpicker = but->custom_data; - float *hsv = cpicker->color_data; + float *hsv_perceptual = cpicker->hsv_perceptual; - ui_but_v3_get(but, rgb); - ui_scene_linear_to_color_picker_space(but, rgb); - ui_rgb_to_color_picker_compat_v(rgb, hsv); + float rgb_perceptual[3]; + ui_but_v3_get(but, rgb_perceptual); + ui_scene_linear_to_perceptual_space(but, rgb_perceptual); + ui_color_picker_rgb_to_hsv_compat(rgb_perceptual, hsv_perceptual); - hsv[2] = clamp_f(hsv[2] + add, 0.0f, 1.0f); + hsv_perceptual[2] = clamp_f(hsv_perceptual[2] + add, 0.0f, 1.0f); - ui_color_picker_to_rgb_v(hsv, rgb); - ui_color_picker_to_scene_linear_space(but, rgb); - ui_but_v3_set(but, rgb); + float rgb_scene_linear[3]; + ui_color_picker_hsv_to_rgb(hsv_perceptual, rgb_scene_linear); + ui_perceptual_to_scene_linear_space(but, rgb_scene_linear); + ui_but_v3_set(but, rgb_scene_linear); - ui_update_color_picker_buts_rgb(but, block, cpicker, rgb); + ui_update_color_picker_buts_rgb(but, block, cpicker, rgb_scene_linear); if (popup) { popup->menuretval = UI_RETURN_UPDATE; } diff --git a/source/blender/editors/interface/interface_widgets.c b/source/blender/editors/interface/interface_widgets.c index 9c7b112855f..e92c32bb1bd 100644 --- a/source/blender/editors/interface/interface_widgets.c +++ b/source/blender/editors/interface/interface_widgets.c @@ -2906,12 +2906,12 @@ static void ui_draw_but_HSVCIRCLE(uiBut *but, const uiWidgetColors *wcol, const const bool is_color_gamma = ui_but_is_color_gamma(but); /* Initialize for compatibility. */ - copy_v3_v3(hsv, cpicker->color_data); + copy_v3_v3(hsv, cpicker->hsv_perceptual); /* Compute current hue. */ ui_but_v3_get(but, rgb); - ui_scene_linear_to_color_picker_space(but, rgb); - ui_rgb_to_color_picker_compat_v(rgb, hsv); + ui_scene_linear_to_perceptual_space(but, rgb); + ui_color_picker_rgb_to_hsv_compat(rgb, hsv); CLAMP(hsv[2], 0.0f, 1.0f); /* for display only */ @@ -2928,8 +2928,8 @@ static void ui_draw_but_HSVCIRCLE(uiBut *but, const uiWidgetColors *wcol, const } const float hsv_center[3] = {0.0f, 0.0f, hsv[2]}; - ui_color_picker_to_rgb_v(hsv_center, rgb_center); - ui_color_picker_to_scene_linear_space(but, rgb_center); + ui_color_picker_hsv_to_rgb(hsv_center, rgb_center); + ui_perceptual_to_scene_linear_space(but, rgb_center); if (!is_color_gamma) { ui_block_cm_to_display_space_v3(but->block, rgb_center); @@ -2956,8 +2956,8 @@ static void ui_draw_but_HSVCIRCLE(uiBut *but, const uiWidgetColors *wcol, const rect, centx + co * radius, centy + si * radius, hsv_ang, hsv_ang + 1); hsv_ang[2] = hsv[2]; - ui_color_picker_to_rgb_v(hsv_ang, rgb_ang); - ui_color_picker_to_scene_linear_space(but, rgb_ang); + ui_color_picker_hsv_to_rgb(hsv_ang, rgb_ang); + ui_perceptual_to_scene_linear_space(but, rgb_ang); if (!is_color_gamma) { ui_block_cm_to_display_space_v3(but->block, rgb_ang); @@ -2987,10 +2987,10 @@ static void ui_draw_but_HSVCIRCLE(uiBut *but, const uiWidgetColors *wcol, const GPU_line_smooth(false); /* cursor */ - copy_v3_v3(hsv, cpicker->color_data); + copy_v3_v3(hsv, cpicker->hsv_perceptual); ui_but_v3_get(but, rgb); - ui_scene_linear_to_color_picker_space(but, rgb); - ui_rgb_to_color_picker_compat_v(rgb, hsv); + ui_scene_linear_to_perceptual_space(but, rgb); + ui_color_picker_rgb_to_hsv_compat(rgb, hsv); float xpos, ypos; ui_hsvcircle_pos_from_vals(cpicker, rect, hsv, &xpos, &ypos); @@ -3212,14 +3212,14 @@ static void ui_draw_but_HSVCUBE(uiBut *but, const rcti *rect) float rgb[3]; float x = 0.0f, y = 0.0f; ColorPicker *cpicker = but->custom_data; - float *hsv = cpicker->color_data; + float *hsv = cpicker->hsv_perceptual; float hsv_n[3]; /* Initialize for compatibility. */ copy_v3_v3(hsv_n, hsv); ui_but_v3_get(but, rgb); - ui_scene_linear_to_color_picker_space(but, rgb); + ui_scene_linear_to_perceptual_space(but, rgb); rgb_to_hsv_compat_v(rgb, hsv_n); ui_draw_gradient(rect, hsv_n, hsv_but->gradient_type, 1.0f); @@ -3251,7 +3251,7 @@ static void ui_draw_but_HSV_v(uiBut *but, const rcti *rect) float rgb[3], hsv[3], v; ui_but_v3_get(but, rgb); - ui_scene_linear_to_color_picker_space(but, rgb); + ui_scene_linear_to_perceptual_space(but, rgb); if (hsv_but->gradient_type == UI_GRAD_L_ALT) { rgb_to_hsl_v(rgb, hsv); -- cgit v1.2.3 From ef17fb2715a3f24cd5cddd6725bfef4858f87617 Mon Sep 17 00:00:00 2001 From: Yevgeny Makarov Date: Thu, 17 Dec 2020 19:06:21 -0600 Subject: UI: Don't use abbreviations in label text Expand abbreviations for words like "Bright" (instead of "Brightness"), "Premul", "Lib", "Dir", etc. Differential Revision: https://developer.blender.org/D9862 --- source/blender/editors/gpencil/gpencil_vertex_ops.c | 2 +- source/blender/editors/object/object_relations.c | 2 +- source/blender/editors/sculpt_paint/paint_vertex_color_ops.c | 2 +- source/blender/editors/space_file/file_ops.c | 2 +- source/blender/editors/space_userpref/userpref_ops.c | 4 ++-- source/blender/editors/space_view3d/view3d_edit.c | 2 +- 6 files changed, 7 insertions(+), 7 deletions(-) (limited to 'source/blender/editors') diff --git a/source/blender/editors/gpencil/gpencil_vertex_ops.c b/source/blender/editors/gpencil/gpencil_vertex_ops.c index 90b2c1c3895..b212872b607 100644 --- a/source/blender/editors/gpencil/gpencil_vertex_ops.c +++ b/source/blender/editors/gpencil/gpencil_vertex_ops.c @@ -237,7 +237,7 @@ void GPENCIL_OT_vertex_color_brightness_contrast(wmOperatorType *ot) PropertyRNA *prop; /* identifiers */ - ot->name = "Vertex Paint Bright/Contrast"; + ot->name = "Vertex Paint Brightness/Contrast"; ot->idname = "GPENCIL_OT_vertex_color_brightness_contrast"; ot->description = "Adjust vertex color brightness/contrast"; diff --git a/source/blender/editors/object/object_relations.c b/source/blender/editors/object/object_relations.c index 5caa7c71e83..ee9ef192d18 100644 --- a/source/blender/editors/object/object_relations.c +++ b/source/blender/editors/object/object_relations.c @@ -484,7 +484,7 @@ void OBJECT_OT_proxy_make(wmOperatorType *ot) DummyRNA_DEFAULT_items, 0, "Proxy Object", - "Name of lib-linked/collection object to make a proxy for"); + "Name of library-linked/collection object to make a proxy for"); RNA_def_enum_funcs(prop, proxy_collection_object_itemf); RNA_def_property_flag(prop, PROP_ENUM_NO_TRANSLATE); ot->prop = prop; diff --git a/source/blender/editors/sculpt_paint/paint_vertex_color_ops.c b/source/blender/editors/sculpt_paint/paint_vertex_color_ops.c index b831687ca67..96d22fe4a21 100644 --- a/source/blender/editors/sculpt_paint/paint_vertex_color_ops.c +++ b/source/blender/editors/sculpt_paint/paint_vertex_color_ops.c @@ -401,7 +401,7 @@ void PAINT_OT_vertex_color_brightness_contrast(wmOperatorType *ot) PropertyRNA *prop; /* identifiers */ - ot->name = "Vertex Paint Bright/Contrast"; + ot->name = "Vertex Paint Brightness/Contrast"; ot->idname = "PAINT_OT_vertex_color_brightness_contrast"; ot->description = "Adjust vertex color brightness/contrast"; diff --git a/source/blender/editors/space_file/file_ops.c b/source/blender/editors/space_file/file_ops.c index 3730174a6c7..88dd82bb9ea 100644 --- a/source/blender/editors/space_file/file_ops.c +++ b/source/blender/editors/space_file/file_ops.c @@ -967,7 +967,7 @@ void FILE_OT_select_bookmark(wmOperatorType *ot) ot->poll = ED_operator_file_active; /* properties */ - prop = RNA_def_string(ot->srna, "dir", NULL, FILE_MAXDIR, "Dir", ""); + prop = RNA_def_string(ot->srna, "dir", NULL, FILE_MAXDIR, "Directory", ""); RNA_def_property_flag(prop, PROP_SKIP_SAVE); } diff --git a/source/blender/editors/space_userpref/userpref_ops.c b/source/blender/editors/space_userpref/userpref_ops.c index ee23cde78c2..f05d6df9944 100644 --- a/source/blender/editors/space_userpref/userpref_ops.c +++ b/source/blender/editors/space_userpref/userpref_ops.c @@ -93,7 +93,7 @@ static int preferences_autoexec_add_exec(bContext *UNUSED(C), wmOperator *UNUSED static void PREFERENCES_OT_autoexec_path_add(wmOperatorType *ot) { - ot->name = "Add Autoexec Path"; + ot->name = "Add Auto-Execution Path"; ot->idname = "PREFERENCES_OT_autoexec_path_add"; ot->description = "Add path to exclude from auto-execution"; @@ -121,7 +121,7 @@ static int preferences_autoexec_remove_exec(bContext *UNUSED(C), wmOperator *op) static void PREFERENCES_OT_autoexec_path_remove(wmOperatorType *ot) { - ot->name = "Remove Autoexec Path"; + ot->name = "Remove Auto-Execution Path"; ot->idname = "PREFERENCES_OT_autoexec_path_remove"; ot->description = "Remove path to exclude from auto-execution"; diff --git a/source/blender/editors/space_view3d/view3d_edit.c b/source/blender/editors/space_view3d/view3d_edit.c index 9429da342a6..ebfa4f6d9af 100644 --- a/source/blender/editors/space_view3d/view3d_edit.c +++ b/source/blender/editors/space_view3d/view3d_edit.c @@ -4708,7 +4708,7 @@ static int viewpersportho_exec(bContext *C, wmOperator *UNUSED(op)) void VIEW3D_OT_view_persportho(wmOperatorType *ot) { /* identifiers */ - ot->name = "View Persp/Ortho"; + ot->name = "View Perspective/Orthographic"; ot->description = "Switch the current view from perspective/orthographic projection"; ot->idname = "VIEW3D_OT_view_persportho"; -- cgit v1.2.3 From 7cbcfb7f492d027d415326d3b100803e949ce84a Mon Sep 17 00:00:00 2001 From: Nathan Craddock Date: Thu, 17 Dec 2020 19:59:49 -0700 Subject: Cleanup: Use LISTBASE_FOREACH macro in outliner code No functional changes. --- source/blender/editors/space_outliner/outliner_draw.c | 4 +--- source/blender/editors/space_outliner/outliner_edit.c | 7 +++---- 2 files changed, 4 insertions(+), 7 deletions(-) (limited to 'source/blender/editors') diff --git a/source/blender/editors/space_outliner/outliner_draw.c b/source/blender/editors/space_outliner/outliner_draw.c index 6364fbc0a87..657ada874ea 100644 --- a/source/blender/editors/space_outliner/outliner_draw.c +++ b/source/blender/editors/space_outliner/outliner_draw.c @@ -2928,8 +2928,6 @@ static void outliner_draw_iconrow(bContext *C, /* closed tree element */ static void outliner_set_coord_tree_element(TreeElement *te, int startx, int starty) { - TreeElement *ten; - /* closed items may be displayed in row of parent, don't change their coordinate! */ if ((te->flag & TE_ICONROW) == 0 && (te->flag & TE_ICONROW_MERGED) == 0) { te->xs = 0; @@ -2937,7 +2935,7 @@ static void outliner_set_coord_tree_element(TreeElement *te, int startx, int sta te->xend = 0; } - for (ten = te->subtree.first; ten; ten = ten->next) { + LISTBASE_FOREACH (TreeElement *, ten, &te->subtree) { outliner_set_coord_tree_element(ten, startx + UI_UNIT_X, starty); } } diff --git a/source/blender/editors/space_outliner/outliner_edit.c b/source/blender/editors/space_outliner/outliner_edit.c index a1ff6193cd0..1cb98e704f2 100644 --- a/source/blender/editors/space_outliner/outliner_edit.c +++ b/source/blender/editors/space_outliner/outliner_edit.c @@ -1253,8 +1253,7 @@ static void outliner_set_coordinates_element_recursive(SpaceOutliner *space_outl *starty -= UI_UNIT_Y; if (TSELEM_OPEN(tselem, space_outliner)) { - TreeElement *ten; - for (ten = te->subtree.first; ten; ten = ten->next) { + LISTBASE_FOREACH (TreeElement *, ten, &te->subtree) { outliner_set_coordinates_element_recursive(space_outliner, ten, startx + UI_UNIT_X, starty); } } @@ -1753,7 +1752,7 @@ static void tree_element_to_path(TreeElement *te, { ListBase hierarchy = {NULL, NULL}; LinkData *ld; - TreeElement *tem, *temnext, *temsub; + TreeElement *tem, *temnext; TreeStoreElem *tse /* , *tsenext */ /* UNUSED */; PointerRNA *ptr, *nextptr; PropertyRNA *prop; @@ -1823,7 +1822,7 @@ static void tree_element_to_path(TreeElement *te, /* otherwise use index */ int index = 0; - for (temsub = tem->subtree.first; temsub; temsub = temsub->next, index++) { + LISTBASE_FOREACH (TreeElement *, temsub, &tem->subtree) { if (temsub == temnext) { break; } -- cgit v1.2.3 From 7d25139eaf4ab11e69d6adb2f436489eca016b64 Mon Sep 17 00:00:00 2001 From: Nathan Craddock Date: Thu, 17 Dec 2020 16:28:24 -0700 Subject: Fix T82960: Inaccurate selection on collapsed outliner rows After rB15083d9e1 the outliner tree is not rebuilt after expanding or collapsing rows. Because the tree is no longer rebuilt the positions and flags of the elements are not cleared when collapsing a row. This caused hover highlights and selections on the collapsed child icons to be incorrect in many cases. For example, only the direct children of a collapsed element are drawn inline. If any grandchild elements had been previously icon row flagged they would continue to be evaluated as icon row elements despite being hidden. In this case the x coordinates of the child and grandchild would overlap causing selection to appear erratic. Now the flags for inline row icons are explicitly cleared, which was previously only done because the tree was rebuilt on collapsing rows. --- source/blender/editors/space_outliner/outliner_draw.c | 1 + 1 file changed, 1 insertion(+) (limited to 'source/blender/editors') diff --git a/source/blender/editors/space_outliner/outliner_draw.c b/source/blender/editors/space_outliner/outliner_draw.c index 657ada874ea..d2381cf30db 100644 --- a/source/blender/editors/space_outliner/outliner_draw.c +++ b/source/blender/editors/space_outliner/outliner_draw.c @@ -2845,6 +2845,7 @@ static void outliner_draw_iconrow(bContext *C, LISTBASE_FOREACH (TreeElement *, te, lb) { TreeStoreElem *tselem = TREESTORE(te); + te->flag &= ~(TE_ICONROW | TE_ICONROW_MERGED); /* object hierarchy always, further constrained on level */ if (level < 1 || (tselem->type == 0 && te->idcode == ID_OB)) { -- cgit v1.2.3 From 095b69361403bacd322172d6293b0faeee40b44e Mon Sep 17 00:00:00 2001 From: Hans Goudey Date: Thu, 17 Dec 2020 23:35:05 -0600 Subject: Outliner: Set active modifier on click The outliner already expands the panel for the modifier you click on, this just extends that idea to also set it active, which is consistent with behavior of active and selected items elsewhere in Blender. --- source/blender/editors/space_outliner/outliner_select.c | 1 + 1 file changed, 1 insertion(+) (limited to 'source/blender/editors') diff --git a/source/blender/editors/space_outliner/outliner_select.c b/source/blender/editors/space_outliner/outliner_select.c index fa8bce9df6a..658e6adbe33 100644 --- a/source/blender/editors/space_outliner/outliner_select.c +++ b/source/blender/editors/space_outliner/outliner_select.c @@ -1185,6 +1185,7 @@ static void outliner_set_properties_tab(bContext *C, TreeElement *te, TreeStoreE } else { ModifierData *md = (ModifierData *)te->directdata; + BKE_object_modifier_set_active(ob, md); switch ((ModifierType)md->type) { case eModifierType_ParticleSystem: -- cgit v1.2.3 From 4f9e21bdc9772603acc0ba6727da9dd67287ac0f Mon Sep 17 00:00:00 2001 From: Jeroen Bakker Date: Fri, 18 Dec 2020 09:15:55 +0100 Subject: Fix T82591: Performance regression when rendering at very high resolution This patch introduces a partial update of GPUTexture. When rendering a large image the GPUTexture could have been scaled. The old implementation would rescale the image on CPU and create a new GPUTexture. This resulted in flooding the PCI bus. The new solution would only scale and upload the parts of the GPUTexture that has been changed. It does this by keeping track of areas of 256x256 pixels. When something changes the tiles that cover that changes will be rescaled and uploaded the next time the GPUTexture is requested. Test situation: Default Cube, 4 samples, 19200x10800 tile size 512. Blender 2.83.9: 4m27s. Blender 2.91: 20+m (regression) This patch: 1m01s. There is still room for more optimizations: * Reduce the time that an image is locked. ** Use task scheduling to update the tiles of an image. ** Generic optimization of the ImBuf scale method. Maniphest Tasks: T82591 Differential Revision: https://developer.blender.org/D9591 --- source/blender/editors/render/render_internal.c | 134 ++++++++++++++---------- source/blender/editors/space_image/image_edit.c | 3 + 2 files changed, 84 insertions(+), 53 deletions(-) (limited to 'source/blender/editors') diff --git a/source/blender/editors/render/render_internal.c b/source/blender/editors/render/render_internal.c index a035ee3e342..69c1e887392 100644 --- a/source/blender/editors/render/render_internal.c +++ b/source/blender/editors/render/render_internal.c @@ -29,6 +29,7 @@ #include "BLI_listbase.h" #include "BLI_math.h" +#include "BLI_rect.h" #include "BLI_threads.h" #include "BLI_timecode.h" #include "BLI_utildefines.h" @@ -121,72 +122,90 @@ typedef struct RenderJob { } RenderJob; /* called inside thread! */ -static void image_buffer_rect_update(RenderJob *rj, - RenderResult *rr, - ImBuf *ibuf, - ImageUser *iuser, - volatile rcti *renrect, - const char *viewname) +static bool image_buffer_calc_tile_rect(const RenderResult *rr, + const ImBuf *ibuf, + volatile rcti *renrect, + rcti *r_ibuf_rect, + int *r_offset_x, + int *r_offset_y) { - Scene *scene = rj->scene; - const float *rectf = NULL; - int ymin, ymax, xmin, xmax; - int rymin, rxmin; - int linear_stride, linear_offset_x, linear_offset_y; - ColorManagedViewSettings *view_settings; - ColorManagedDisplaySettings *display_settings; - - if (ibuf->userflags & IB_DISPLAY_BUFFER_INVALID) { - /* The whole image buffer it so be color managed again anyway. */ - return; - } + int tile_y, tile_height, tile_x, tile_width; /* if renrect argument, we only refresh scanlines */ if (renrect) { - /* if (ymax == recty), rendering of layer is ready, + /* if (tile_height == recty), rendering of layer is ready, * we should not draw, other things happen... */ if (rr->renlay == NULL || renrect->ymax >= rr->recty) { - return; + return false; } - /* xmin here is first subrect x coord, xmax defines subrect width */ - xmin = renrect->xmin; - xmax = renrect->xmax - xmin; - if (xmax < 2) { - return; + /* tile_x here is first subrect x coord, tile_width defines subrect width */ + tile_x = renrect->xmin; + tile_width = renrect->xmax - tile_x; + if (tile_width < 2) { + return false; } - ymin = renrect->ymin; - ymax = renrect->ymax - ymin; - if (ymax < 2) { - return; + tile_y = renrect->ymin; + tile_height = renrect->ymax - tile_y; + if (tile_height < 2) { + return false; } renrect->ymin = renrect->ymax; } else { - xmin = ymin = 0; - xmax = rr->rectx; - ymax = rr->recty; + tile_x = tile_y = 0; + tile_width = rr->rectx; + tile_height = rr->recty; } - /* xmin ymin is in tile coords. transform to ibuf */ - rxmin = rr->tilerect.xmin; - if (rxmin >= ibuf->x) { - return; + /* tile_x tile_y is in tile coords. transform to ibuf */ + int offset_x = rr->tilerect.xmin; + if (offset_x >= ibuf->x) { + return false; } - rymin = rr->tilerect.ymin; - if (rymin >= ibuf->y) { - return; + int offset_y = rr->tilerect.ymin; + if (offset_y >= ibuf->y) { + return false; } - if (rxmin + xmax > ibuf->x) { - xmax = ibuf->x - rxmin; + if (offset_x + tile_width > ibuf->x) { + tile_width = ibuf->x - offset_x; } - if (rymin + ymax > ibuf->y) { - ymax = ibuf->y - rymin; + if (offset_y + tile_height > ibuf->y) { + tile_height = ibuf->y - offset_y; } - if (xmax < 1 || ymax < 1) { + if (tile_width < 1 || tile_height < 1) { + return false; + } + + r_ibuf_rect->xmax = tile_x + tile_width; + r_ibuf_rect->ymax = tile_y + tile_height; + r_ibuf_rect->xmin = tile_x; + r_ibuf_rect->ymin = tile_y; + *r_offset_x = offset_x; + *r_offset_y = offset_y; + return true; +} + +static void image_buffer_rect_update(RenderJob *rj, + RenderResult *rr, + ImBuf *ibuf, + ImageUser *iuser, + const rcti *tile_rect, + int offset_x, + int offset_y, + const char *viewname) +{ + Scene *scene = rj->scene; + const float *rectf = NULL; + int linear_stride, linear_offset_x, linear_offset_y; + ColorManagedViewSettings *view_settings; + ColorManagedDisplaySettings *display_settings; + + if (ibuf->userflags & IB_DISPLAY_BUFFER_INVALID) { + /* The whole image buffer is to be color managed again anyway. */ return; } @@ -230,10 +249,10 @@ static void image_buffer_rect_update(RenderJob *rj, return; } - rectf += 4 * (rr->rectx * ymin + xmin); + rectf += 4 * (rr->rectx * tile_rect->ymin + tile_rect->xmin); linear_stride = rr->rectx; - linear_offset_x = rxmin; - linear_offset_y = rymin; + linear_offset_x = offset_x; + linear_offset_y = offset_y; } else { rectf = ibuf->rect_float; @@ -253,10 +272,10 @@ static void image_buffer_rect_update(RenderJob *rj, linear_offset_y, view_settings, display_settings, - rxmin, - rymin, - rxmin + xmax, - rymin + ymax); + offset_x, + offset_y, + offset_x + BLI_rcti_size_x(tile_rect), + offset_y + BLI_rcti_size_y(tile_rect)); } /* ****************************** render invoking ***************** */ @@ -578,8 +597,16 @@ static void image_rect_update(void *rjv, RenderResult *rr, volatile rcti *renrec /* update part of render */ render_image_update_pass_and_layer(rj, rr, &rj->iuser); + rcti tile_rect; + int offset_x; + int offset_y; ibuf = BKE_image_acquire_ibuf(ima, &rj->iuser, &lock); if (ibuf) { + if (!image_buffer_calc_tile_rect(rr, ibuf, renrect, &tile_rect, &offset_x, &offset_y)) { + BKE_image_release_ibuf(ima, ibuf, lock); + return; + } + /* Don't waste time on CPU side color management if * image will be displayed using GLSL. * @@ -589,9 +616,10 @@ static void image_rect_update(void *rjv, RenderResult *rr, volatile rcti *renrec */ if (!rj->supports_glsl_draw || ibuf->channels == 1 || ED_draw_imbuf_method(ibuf) != IMAGE_DRAW_METHOD_GLSL) { - image_buffer_rect_update(rj, rr, ibuf, &rj->iuser, renrect, viewname); + image_buffer_rect_update(rj, rr, ibuf, &rj->iuser, &tile_rect, offset_x, offset_y, viewname); } - ima->gpuflag |= IMA_GPU_REFRESH; + BKE_image_update_gputexture_delayed( + ima, ibuf, offset_x, offset_y, BLI_rcti_size_x(&tile_rect), BLI_rcti_size_y(&tile_rect)); /* make jobs timer to send notifier */ *(rj->do_update) = true; diff --git a/source/blender/editors/space_image/image_edit.c b/source/blender/editors/space_image/image_edit.c index 180f1fb183c..c26f92c5463 100644 --- a/source/blender/editors/space_image/image_edit.c +++ b/source/blender/editors/space_image/image_edit.c @@ -407,6 +407,9 @@ bool ED_image_slot_cycle(struct Image *image, int direction) image->render_slot = ((cur == 1) ? 0 : 1); } + if ((cur != image->render_slot)) { + image->gpuflag |= IMA_GPU_REFRESH; + } return (cur != image->render_slot); } -- cgit v1.2.3 From f43561eae6826eead2e5e78bc8792b3c15dda6ae Mon Sep 17 00:00:00 2001 From: Dalai Felinto Date: Thu, 17 Dec 2020 18:37:04 +0100 Subject: Function Nodes: Input Vector Ref: T82651 Normally people use "Combine XYZ" to input a vector, but it is more interesting to have an explicit vector input. So this is basically "Combine XYZ" without any input sockets, the values are stored in the node itself. Differential Revision: https://developer.blender.org/D9885 --- source/blender/editors/space_node/drawnode.c | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'source/blender/editors') diff --git a/source/blender/editors/space_node/drawnode.c b/source/blender/editors/space_node/drawnode.c index c2951a9d7a8..b6744719cad 100644 --- a/source/blender/editors/space_node/drawnode.c +++ b/source/blender/editors/space_node/drawnode.c @@ -3289,6 +3289,12 @@ static void node_function_buts_switch(uiLayout *layout, bContext *UNUSED(C), Poi uiItemR(layout, ptr, "data_type", DEFAULT_FLAGS, "", ICON_NONE); } +static void node_function_buts_input_vector(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr) +{ + uiLayout *col = uiLayoutColumn(layout, true); + uiItemR(col, ptr, "vector", UI_ITEM_R_EXPAND, "", ICON_NONE); +} + static void node_function_set_butfunc(bNodeType *ntype) { switch (ntype->type) { @@ -3301,6 +3307,9 @@ static void node_function_set_butfunc(bNodeType *ntype) case FN_NODE_SWITCH: ntype->draw_buttons = node_function_buts_switch; break; + case FN_NODE_INPUT_VECTOR: + ntype->draw_buttons = node_function_buts_input_vector; + break; } } -- cgit v1.2.3 From 95afc53604de148c0ed7cfbee88906ae09f6b807 Mon Sep 17 00:00:00 2001 From: Vincent Blankfield Date: Fri, 18 Dec 2020 14:04:58 +0100 Subject: Fix T83716: Dope Sheet, incorrect scaling of channel UI elements Change the top coordinate of the animation channel list UI elements to `rect->ymin` so they correctly span from `rect->ymin` to `channel_height`. Some buttons in the dope sheet channels didn't scale properly with the `Keyframe Scale Factor` preferences setting. This was caused by using the `ymid` value (`ymid = BLI_rctf_cent_y(rect) - 0.5f * ICON_WIDTH`) to position the buttons that supposed to fill all vertical space in the channel (with `channel_height` height). The `ymid` value is only appropriate for the UI elements that with `ICON_WIDTH` height. Maniphest Tasks: T83716 Reviewed by: sybren Differential Revision: https://developer.blender.org/D9841 --- source/blender/editors/animation/anim_channels_defines.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'source/blender/editors') diff --git a/source/blender/editors/animation/anim_channels_defines.c b/source/blender/editors/animation/anim_channels_defines.c index c70a86eab1d..6cb829d3a23 100644 --- a/source/blender/editors/animation/anim_channels_defines.c +++ b/source/blender/editors/animation/anim_channels_defines.c @@ -5353,7 +5353,7 @@ void ANIM_channel_draw_widgets(const bContext *C, "", ICON_NONE, offset, - ymid, + rect->ymin, SLIDER_WIDTH, channel_height); UI_but_func_set(but, achannel_setting_slider_nla_curve_cb, ale->id, ale->data); @@ -5411,7 +5411,7 @@ void ANIM_channel_draw_widgets(const bContext *C, "", icon, offset, - ymid, + rect->ymin, ICON_WIDTH, channel_height); } @@ -5437,7 +5437,7 @@ void ANIM_channel_draw_widgets(const bContext *C, "", icon, offset, - ymid, + rect->ymin, ICON_WIDTH, channel_height); } @@ -5457,7 +5457,7 @@ void ANIM_channel_draw_widgets(const bContext *C, "", ICON_NONE, offset, - ymid, + rect->ymin, width, channel_height); } @@ -5483,7 +5483,7 @@ void ANIM_channel_draw_widgets(const bContext *C, "", ICON_NONE, offset, - ymid, + rect->ymin, SLIDER_WIDTH, channel_height); -- cgit v1.2.3 From f3b50380f042b33db0d7973c5c3daa7a460f75aa Mon Sep 17 00:00:00 2001 From: Philipp Oeser Date: Fri, 18 Dec 2020 10:35:08 +0100 Subject: Fix T83916: Cannot drag link from socket if node is inside frame Caused by rB7470c10601d0 where iterating nodetree nodes was changed from backwards to forwards by mistake. Maniphest Tasks: T83916 Differential Revision: https://developer.blender.org/D9890 --- source/blender/editors/space_node/node_edit.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source/blender/editors') diff --git a/source/blender/editors/space_node/node_edit.c b/source/blender/editors/space_node/node_edit.c index fdce5e3f30b..e6f11f3eb83 100644 --- a/source/blender/editors/space_node/node_edit.c +++ b/source/blender/editors/space_node/node_edit.c @@ -854,7 +854,7 @@ static void edit_node_properties_get( /* is rct in visible part of node? */ static bNode *visible_node(SpaceNode *snode, const rctf *rct) { - LISTBASE_FOREACH (bNode *, node, &snode->edittree->nodes) { + LISTBASE_FOREACH_BACKWARD (bNode *, node, &snode->edittree->nodes) { if (BLI_rctf_isect(&node->totr, rct, NULL)) { return node; } -- cgit v1.2.3 From 1be465cccbf96c64e5a90962bd2c76cbc7675fb0 Mon Sep 17 00:00:00 2001 From: Antonio Vazquez Date: Fri, 18 Dec 2020 15:57:10 +0100 Subject: GPencil: Fix potential error in interpolate frame As now it is using a duplicated frame, the untag must be done before copying the frames. --- source/blender/editors/gpencil/gpencil_interpolate.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'source/blender/editors') diff --git a/source/blender/editors/gpencil/gpencil_interpolate.c b/source/blender/editors/gpencil/gpencil_interpolate.c index 9bca294cf30..1c967110198 100644 --- a/source/blender/editors/gpencil/gpencil_interpolate.c +++ b/source/blender/editors/gpencil/gpencil_interpolate.c @@ -483,14 +483,15 @@ static bool gpencil_interpolate_set_init_values(bContext *C, wmOperator *op, tGP /* set interpolation weight */ tgpi->shift = RNA_float_get(op->ptr, "shift"); - /* set layers */ - gpencil_interpolate_set_points(C, tgpi); /* Untag strokes to be sure nothing is pending due any canceled process. */ LISTBASE_FOREACH (bGPDlayer *, gpl, &tgpi->gpd->layers) { gpencil_interpolate_untag_strokes(gpl); } + /* Set layers */ + gpencil_interpolate_set_points(C, tgpi); + return 1; } -- cgit v1.2.3 From 3deb21055ad16618b80297b7a82bca46b7b9c1f9 Mon Sep 17 00:00:00 2001 From: Jacques Lucke Date: Fri, 18 Dec 2020 16:00:45 +0100 Subject: Geometry Nodes: support randomly picking instances from collection This uses the "id" attribute to randomly pick instances from a collection for each point. There is one issue. When the collection is updated (e.g. when an object is added to it), the nodes modifier is not automatically updated. It seems like we don't have the infrastructure to support this dependency yet. The same issue exists in the Boolean modifier and with collision collections. This should be solved separately soonish. When "Whole Collection" is disabled, one direct child of the input collection is instanced at each point. A direct child can be an object or a collection. Currently, all objects are picked approximately equally often. In the future, we will provide more control over which point gets which instance. Differential Revision: https://developer.blender.org/D9884 Ref T82372. --- source/blender/editors/space_node/drawnode.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'source/blender/editors') diff --git a/source/blender/editors/space_node/drawnode.c b/source/blender/editors/space_node/drawnode.c index b6744719cad..652c70155ab 100644 --- a/source/blender/editors/space_node/drawnode.c +++ b/source/blender/editors/space_node/drawnode.c @@ -3196,6 +3196,9 @@ static void node_geometry_buts_point_instance(uiLayout *layout, PointerRNA *ptr) { uiItemR(layout, ptr, "instance_type", DEFAULT_FLAGS | UI_ITEM_R_EXPAND, NULL, ICON_NONE); + if (RNA_enum_get(ptr, "instance_type") == GEO_NODE_POINT_INSTANCE_TYPE_COLLECTION) { + uiItemR(layout, ptr, "use_whole_collection", DEFAULT_FLAGS, NULL, ICON_NONE); + } } static void node_geometry_buts_attribute_fill(uiLayout *layout, -- cgit v1.2.3 From 2250b5cefee7f7cce31e388cb83515543ffe60f0 Mon Sep 17 00:00:00 2001 From: Julian Eisel Date: Fri, 18 Dec 2020 18:12:11 +0100 Subject: UI: Redesigned data-block selectors The previous design is rather old and has a couple of problems: * Scalability: The current solution of adding little icon buttons next to the data-block name field doesn't scale well. It only works if there's a small number of operations. We need to be able to place more items there for better data-block management. Especially with the introduction of library overrides. * Discoverability: It's not obvious what some of the icons do. They appear and disappear, but it's not obvious why some are available at times and others not. * Unclear Status: Currently their library status (linked, indirectly linked, broken link, library override) isn't really clear. * Unusual behavior: Some of the icon buttons allow Shift or Ctrl clicking to invoke alternative behaviors. This is not a usual pattern in Blender. This patch does the following changes: * Adds a menu to the right of the name button to access all kinds of operations (create, delete, unlink, user management, library overrides, etc). * Make good use of the "disabled hint" for tooltips, to explain why buttons are disabled. The UI team wants to establish this as a good practise. * Use superimposed icons for duplicate and unlink, rather than extra buttons (uses less space, looks less distracting and is a nice + consistent design language). * Remove fake user and user count button, they are available from the menu now. * Support tooltips for superimposed icons (committed mouse hover feedback to master already). * Slightly increase size of the name button - it was already a bit small before, and the move from real buttons to superimposed icons reduces usable space for the name itself. * More clearly differentiate between duplicate and creating a new data-block. The latter is only available in the menu. * Display library status icon on the left (linked, missing library, overridden, asset) * Disables "Make Single User" button - in review we weren't sure if there are good use-cases for it, so better to see if we can remove it. Note that I do expect some aspects of this design to change still. I think some changes are problematic, but others disagreed. I will open a feedback thread on devtalk to see what others think. Differential Revision: https://developer.blender.org/D8554 Reviewed by: Bastien Montagne Design discussed and agreed on with the UI team, also see T79959. --- source/blender/editors/include/ED_util.h | 3 +- source/blender/editors/include/UI_interface.h | 34 +- source/blender/editors/interface/interface.c | 143 ++- .../editors/interface/interface_context_menu.c | 2 +- .../blender/editors/interface/interface_handlers.c | 51 +- source/blender/editors/interface/interface_ops.c | 1 + .../editors/interface/interface_region_tooltip.c | 68 +- .../editors/interface/interface_templates.c | 1086 ++++++++++++-------- source/blender/editors/render/render_intern.h | 3 + source/blender/editors/render/render_ops.c | 3 + source/blender/editors/render/render_shading.c | 236 +++-- source/blender/editors/screen/screen_ops.c | 1 - source/blender/editors/space_action/action_data.c | 178 ++-- .../blender/editors/space_action/action_intern.h | 1 + source/blender/editors/space_action/action_ops.c | 2 + source/blender/editors/space_api/spacetypes.c | 2 + source/blender/editors/space_clip/clip_buttons.c | 1 + source/blender/editors/space_file/file_panels.c | 9 +- source/blender/editors/space_image/image_buttons.c | 3 +- source/blender/editors/space_nla/nla_buttons.c | 3 +- source/blender/editors/space_node/drawnode.c | 94 +- source/blender/editors/util/CMakeLists.txt | 1 + source/blender/editors/util/ed_util.c | 21 - source/blender/editors/util/ed_util_ops.c | 155 +++ 24 files changed, 1428 insertions(+), 673 deletions(-) create mode 100644 source/blender/editors/util/ed_util_ops.c (limited to 'source/blender/editors') diff --git a/source/blender/editors/include/ED_util.h b/source/blender/editors/include/ED_util.h index ca6b4bdc618..1e87a940a7d 100644 --- a/source/blender/editors/include/ED_util.h +++ b/source/blender/editors/include/ED_util.h @@ -52,10 +52,11 @@ void ED_spacedata_id_remap(struct ScrArea *area, struct ID *old_id, struct ID *new_id); -void ED_OT_flush_edits(struct wmOperatorType *ot); void ED_OT_lib_id_load_custom_preview(struct wmOperatorType *ot); void ED_OT_lib_id_generate_preview(struct wmOperatorType *ot); +void ED_operatortypes_edutils(void); + /* ************** XXX OLD CRUFT WARNING ************* */ void apply_keyb_grid( diff --git a/source/blender/editors/include/UI_interface.h b/source/blender/editors/include/UI_interface.h index 7c128cbf1e6..ced411ef75f 100644 --- a/source/blender/editors/include/UI_interface.h +++ b/source/blender/editors/include/UI_interface.h @@ -76,6 +76,7 @@ struct wmWindow; typedef struct uiBlock uiBlock; typedef struct uiBut uiBut; +typedef struct uiButExtraOpIcon uiButExtraOpIcon; typedef struct uiLayout uiLayout; typedef struct uiPopupBlockHandle uiPopupBlockHandle; @@ -1381,13 +1382,16 @@ typedef struct uiStringInfo { /* Note: Expects pointers to uiStringInfo structs as parameters. * Will fill them with translated strings, when possible. * Strings in uiStringInfo must be MEM_freeN'ed by caller. */ -void UI_but_string_info_get(struct bContext *C, uiBut *but, ...) ATTR_SENTINEL(0); +void UI_but_string_info_get(struct bContext *C, uiBut *but, uiButExtraOpIcon *extra_icon, ...) + ATTR_SENTINEL(0); /* Edit i18n stuff. */ /* Name of the main py op from i18n addon. */ #define EDTSRC_I18N_OP_NAME "UI_OT_edittranslation" /** + * TODO This is old stuff, only used by templateID. Should be cleaned up. + * * Special Buttons * * Buttons with a more specific purpose: @@ -1405,14 +1409,16 @@ enum { UI_ID_ALONE = 1 << 4, UI_ID_OPEN = 1 << 3, UI_ID_DELETE = 1 << 5, - UI_ID_LOCAL = 1 << 6, - UI_ID_AUTO_NAME = 1 << 7, - UI_ID_FAKE_USER = 1 << 8, + UI_ID_MAKE_LOCAL = 1 << 6, + UI_ID_LIB_OVERRIDE_ADD = 1 << 7, + UI_ID_AUTO_NAME = 1 << 8, UI_ID_PIN = 1 << 9, UI_ID_PREVIEWS = 1 << 10, - UI_ID_OVERRIDE = 1 << 11, + UI_ID_LIB_OVERRIDE_REMOVE = 1 << 11, + UI_ID_LIB_OVERRIDE_RESET = 1 << 12, UI_ID_FULL = UI_ID_RENAME | UI_ID_BROWSE | UI_ID_ADD_NEW | UI_ID_OPEN | UI_ID_ALONE | - UI_ID_DELETE | UI_ID_LOCAL, + UI_ID_DELETE | UI_ID_MAKE_LOCAL | UI_ID_LIB_OVERRIDE_ADD | + UI_ID_LIB_OVERRIDE_REMOVE | UI_ID_LIB_OVERRIDE_RESET, }; /** @@ -1658,10 +1664,12 @@ void UI_but_func_hold_set(uiBut *but, uiButHandleHoldFunc func, void *argN); void UI_but_func_pushed_state_set(uiBut *but, uiButPushedStateFunc func, void *arg); -PointerRNA *UI_but_extra_operator_icon_add(uiBut *but, - const char *opname, - short opcontext, - int icon); +struct uiButExtraOpIcon *UI_but_extra_operator_icon_add(uiBut *but, + const char *opname, + short opcontext, + int icon); +struct wmOperatorType *UI_but_extra_operator_icon_optype_get(struct uiButExtraOpIcon *extra_icon); +PointerRNA *UI_but_extra_operator_icon_opptr_get(struct uiButExtraOpIcon *extra_icon); /* Autocomplete * @@ -1963,6 +1971,7 @@ void uiTemplateID(uiLayout *layout, struct PointerRNA *ptr, const char *propname, const char *newop, + const char *duplicateop, const char *openop, const char *unlinkop, int filter, @@ -2567,6 +2576,11 @@ struct ARegion *UI_tooltip_create_from_button(struct bContext *C, struct ARegion *butregion, uiBut *but, bool is_label); +struct ARegion *UI_tooltip_create_from_button_or_extra_icon(struct bContext *C, + struct ARegion *butregion, + uiBut *but, + uiButExtraOpIcon *extra_icon, + bool is_label); struct ARegion *UI_tooltip_create_from_gizmo(struct bContext *C, struct wmGizmo *gz); void UI_tooltip_free(struct bContext *C, struct bScreen *screen, struct ARegion *region); diff --git a/source/blender/editors/interface/interface.c b/source/blender/editors/interface/interface.c index c5c2f0e55c4..26fd75cc74c 100644 --- a/source/blender/editors/interface/interface.c +++ b/source/blender/editors/interface/interface.c @@ -1167,16 +1167,21 @@ void ui_but_add_shortcut(uiBut *but, const char *shortcut_str, const bool do_str * \{ */ static bool ui_but_event_operator_string_from_operator(const bContext *C, - uiBut *but, + wmOperatorCallParams *op_call_params, char *buf, const size_t buf_len) { - BLI_assert(but->optype != NULL); + BLI_assert(op_call_params->optype != NULL); bool found = false; - IDProperty *prop = (but->opptr) ? but->opptr->data : NULL; - - if (WM_key_event_operator_string( - C, but->optype->idname, but->opcontext, prop, true, buf, buf_len)) { + IDProperty *prop = (op_call_params->opptr) ? op_call_params->opptr->data : NULL; + + if (WM_key_event_operator_string(C, + op_call_params->optype->idname, + op_call_params->opcontext, + prop, + true, + buf, + buf_len)) { found = true; } return found; @@ -1253,15 +1258,22 @@ static bool ui_but_event_operator_string_from_panel(const bContext *C, return found; } -static bool ui_but_event_operator_string(const bContext *C, - uiBut *but, - char *buf, - const size_t buf_len) +static bool ui_but_event_operator_string( + const bContext *C, uiBut *but, uiButExtraOpIcon *extra_icon, char *buf, const size_t buf_len) { bool found = false; + wmOperatorType *extra_icon_optype = UI_but_extra_operator_icon_optype_get(extra_icon); - if (but->optype != NULL) { - found = ui_but_event_operator_string_from_operator(C, but, buf, buf_len); + if (extra_icon_optype) { + found = ui_but_event_operator_string_from_operator(C, extra_icon->optype_params, buf, buf_len); + } + else if (but->optype != NULL) { + found = ui_but_event_operator_string_from_operator( + C, + &(wmOperatorCallParams){ + .optype = but->optype, .opptr = but->opptr, .opcontext = but->opcontext}, + buf, + buf_len); } else if (UI_but_menutype_get(but) != NULL) { found = ui_but_event_operator_string_from_menu(C, but, buf, buf_len); @@ -1564,7 +1576,7 @@ static void ui_menu_block_set_keymaps(const bContext *C, uiBlock *block) continue; } - if (ui_but_event_operator_string(C, but, buf, sizeof(buf))) { + if (ui_but_event_operator_string(C, but, NULL, buf, sizeof(buf))) { ui_but_add_shortcut(but, buf, false); } else if (ui_but_event_property_operator_string(C, but, buf, sizeof(buf))) { @@ -1605,12 +1617,12 @@ typedef enum PredefinedExtraOpIconType { PREDEFINED_EXTRA_OP_ICON_EYEDROPPER, } PredefinedExtraOpIconType; -static PointerRNA *ui_but_extra_operator_icon_add_ptr(uiBut *but, - wmOperatorType *optype, - short opcontext, - int icon) +static uiButExtraOpIcon *ui_but_extra_operator_icon_add_ptr(uiBut *but, + wmOperatorType *optype, + short opcontext, + int icon) { - uiButExtraOpIcon *extra_op_icon = MEM_mallocN(sizeof(*extra_op_icon), __func__); + uiButExtraOpIcon *extra_op_icon = MEM_callocN(sizeof(*extra_op_icon), __func__); extra_op_icon->icon = (BIFIconID)icon; extra_op_icon->optype_params = MEM_callocN(sizeof(*extra_op_icon->optype_params), @@ -1625,13 +1637,15 @@ static PointerRNA *ui_but_extra_operator_icon_add_ptr(uiBut *but, BLI_addtail(&but->extra_op_icons, extra_op_icon); - return extra_op_icon->optype_params->opptr; + return extra_op_icon; } static void ui_but_extra_operator_icon_free(uiButExtraOpIcon *extra_icon) { - WM_operator_properties_free(extra_icon->optype_params->opptr); - MEM_freeN(extra_icon->optype_params->opptr); + if (extra_icon->optype_params->opptr) { + WM_operator_properties_free(extra_icon->optype_params->opptr); + MEM_freeN(extra_icon->optype_params->opptr); + } MEM_freeN(extra_icon->optype_params); MEM_freeN(extra_icon); } @@ -1644,18 +1658,25 @@ void ui_but_extra_operator_icons_free(uiBut *but) BLI_listbase_clear(&but->extra_op_icons); } -PointerRNA *UI_but_extra_operator_icon_add(uiBut *but, - const char *opname, - short opcontext, - int icon) +uiButExtraOpIcon *UI_but_extra_operator_icon_add(uiBut *but, + const char *opname, + short opcontext, + int icon) { wmOperatorType *optype = WM_operatortype_find(opname, false); - if (optype) { - return ui_but_extra_operator_icon_add_ptr(but, optype, opcontext, icon); - } + BLI_assert(optype); + return ui_but_extra_operator_icon_add_ptr(but, optype, opcontext, icon); +} - return NULL; +PointerRNA *UI_but_extra_operator_icon_opptr_get(uiButExtraOpIcon *extra_icon) +{ + return extra_icon->optype_params->opptr; +} + +wmOperatorType *UI_but_extra_operator_icon_optype_get(uiButExtraOpIcon *extra_icon) +{ + return extra_icon ? extra_icon->optype_params->optype : NULL; } static bool ui_but_icon_extra_is_visible_text_clear(const uiBut *but) @@ -6818,7 +6839,7 @@ void UI_but_func_hold_set(uiBut *but, uiButHandleHoldFunc func, void *argN) but->hold_argN = argN; } -void UI_but_string_info_get(bContext *C, uiBut *but, ...) +void UI_but_string_info_get(bContext *C, uiBut *but, uiButExtraOpIcon *extra_icon, ...) { va_list args; uiStringInfo *si; @@ -6827,13 +6848,19 @@ void UI_but_string_info_get(bContext *C, uiBut *but, ...) int totitems; bool free_items = false; - va_start(args, but); + wmOperatorType *extra_icon_optype = UI_but_extra_operator_icon_optype_get(extra_icon); + wmOperatorType *optype = extra_icon ? extra_icon_optype : but->optype; + + /* Don't query RNA data when the extra-icon overrides the button. */ + PropertyRNA *rnaprop = extra_icon ? NULL : but->rnaprop; + + va_start(args, extra_icon); while ((si = (uiStringInfo *)va_arg(args, void *))) { uiStringInfoType type = si->type; char *tmp = NULL; if (type == BUT_GET_LABEL) { - if (but->str && but->str[0]) { + if (but->str && but->str[0] && !extra_icon) { const char *str_sep; size_t str_len; @@ -6863,16 +6890,16 @@ void UI_but_string_info_get(bContext *C, uiBut *but, ...) } if (type == BUT_GET_RNAPROP_IDENTIFIER) { - if (but->rnaprop) { - tmp = BLI_strdup(RNA_property_identifier(but->rnaprop)); + if (rnaprop) { + tmp = BLI_strdup(RNA_property_identifier(rnaprop)); } } else if (type == BUT_GET_RNASTRUCT_IDENTIFIER) { - if (but->rnaprop && but->rnapoin.data) { + if (rnaprop && but->rnapoin.data) { tmp = BLI_strdup(RNA_struct_identifier(but->rnapoin.type)); } - else if (but->optype) { - tmp = BLI_strdup(but->optype->idname); + else if (optype) { + tmp = BLI_strdup(optype->idname); } else if (ELEM(but->type, UI_BTYPE_MENU, UI_BTYPE_PULLDOWN)) { MenuType *mt = UI_but_menutype_get(but); @@ -6888,23 +6915,25 @@ void UI_but_string_info_get(bContext *C, uiBut *but, ...) } } else if (ELEM(type, BUT_GET_RNA_LABEL, BUT_GET_RNA_TIP)) { - if (but->rnaprop) { + if (rnaprop) { if (type == BUT_GET_RNA_LABEL) { - tmp = BLI_strdup(RNA_property_ui_name(but->rnaprop)); + tmp = BLI_strdup(RNA_property_ui_name(rnaprop)); } else { - const char *t = RNA_property_ui_description(but->rnaprop); + const char *t = RNA_property_ui_description(rnaprop); if (t && t[0]) { tmp = BLI_strdup(t); } } } - else if (but->optype) { + else if (optype) { + PointerRNA *opptr = extra_icon_optype ? UI_but_extra_operator_icon_opptr_get(extra_icon) : + but->opptr; if (type == BUT_GET_RNA_LABEL) { - tmp = BLI_strdup(WM_operatortype_name(but->optype, but->opptr)); + tmp = BLI_strdup(WM_operatortype_name(optype, opptr)); } else { - tmp = WM_operatortype_description(C, but->optype, but->opptr); + tmp = WM_operatortype_description(C, optype, opptr); } } else if (ELEM(but->type, UI_BTYPE_MENU, UI_BTYPE_PULLDOWN, UI_BTYPE_POPOVER)) { @@ -6956,11 +6985,11 @@ void UI_but_string_info_get(bContext *C, uiBut *but, ...) } else if (type == BUT_GET_RNA_LABEL_CONTEXT) { const char *_tmp = BLT_I18NCONTEXT_DEFAULT; - if (but->rnaprop) { - _tmp = RNA_property_translation_context(but->rnaprop); + if (rnaprop) { + _tmp = RNA_property_translation_context(rnaprop); } - else if (but->optype) { - _tmp = RNA_struct_translation_context(but->optype->srna); + else if (optype) { + _tmp = RNA_struct_translation_context(optype->srna); } else if (ELEM(but->type, UI_BTYPE_MENU, UI_BTYPE_PULLDOWN)) { MenuType *mt = UI_but_menutype_get(but); @@ -6979,16 +7008,16 @@ void UI_but_string_info_get(bContext *C, uiBut *but, ...) int value = 0; /* get the enum property... */ - if (but->rnaprop && RNA_property_type(but->rnaprop) == PROP_ENUM) { + if (rnaprop && RNA_property_type(rnaprop) == PROP_ENUM) { /* enum property */ ptr = &but->rnapoin; - prop = but->rnaprop; + prop = rnaprop; value = (ELEM(but->type, UI_BTYPE_ROW, UI_BTYPE_TAB)) ? (int)but->hardmax : (int)ui_but_value_get(but); } - else if (but->optype) { - PointerRNA *opptr = UI_but_operator_ptr_get(but); - wmOperatorType *ot = but->optype; + else if (optype) { + PointerRNA *opptr = extra_icon_optype ? UI_but_extra_operator_icon_opptr_get(extra_icon) : + UI_but_operator_ptr_get(but); /* so the context is passed to itemf functions */ WM_operator_properties_sanitize(opptr, false); @@ -6998,11 +7027,11 @@ void UI_but_string_info_get(bContext *C, uiBut *but, ...) * operator menus in the Anim Editors will show tooltips for the different * operations instead of the meaningless generic operator tooltip */ - if (ot->prop && RNA_property_type(ot->prop) == PROP_ENUM) { - if (RNA_struct_contains_property(opptr, ot->prop)) { + if (optype->prop && RNA_property_type(optype->prop) == PROP_ENUM) { + if (RNA_struct_contains_property(opptr, optype->prop)) { ptr = opptr; - prop = ot->prop; - value = RNA_property_enum_get(opptr, ot->prop); + prop = optype->prop; + value = RNA_property_enum_get(opptr, optype->prop); } } } @@ -7035,7 +7064,7 @@ void UI_but_string_info_get(bContext *C, uiBut *but, ...) else if (type == BUT_GET_OP_KEYMAP) { if (!ui_block_is_menu(but->block)) { char buf[128]; - if (ui_but_event_operator_string(C, but, buf, sizeof(buf))) { + if (ui_but_event_operator_string(C, but, extra_icon, buf, sizeof(buf))) { tmp = BLI_strdup(buf); } } diff --git a/source/blender/editors/interface/interface_context_menu.c b/source/blender/editors/interface/interface_context_menu.c index 870c3a2a13f..fd3b00eec31 100644 --- a/source/blender/editors/interface/interface_context_menu.c +++ b/source/blender/editors/interface/interface_context_menu.c @@ -509,7 +509,7 @@ bool ui_popup_context_menu_for_button(bContext *C, uiBut *but) uiStringInfo label = {BUT_GET_LABEL, NULL}; /* highly unlikely getting the label ever fails */ - UI_but_string_info_get(C, but, &label, NULL); + UI_but_string_info_get(C, but, NULL, &label, NULL); pup = UI_popup_menu_begin(C, label.strinfo ? label.strinfo : "", ICON_NONE); layout = UI_popup_menu_layout(pup); diff --git a/source/blender/editors/interface/interface_handlers.c b/source/blender/editors/interface/interface_handlers.c index 08e71e0cfd0..790c2cd5313 100644 --- a/source/blender/editors/interface/interface_handlers.c +++ b/source/blender/editors/interface/interface_handlers.c @@ -334,6 +334,7 @@ typedef struct uiHandleButtonData { int retval; /* booleans (could be made into flags) */ bool cancel, escapecancel; + bool skip_undo_push; bool applied, applied_interactive; bool changed_cursor; wmTimer *flashtimer; @@ -820,7 +821,9 @@ static void ui_apply_but_func(bContext *C, uiBut *but) /* typically call ui_apply_but_undo(), ui_apply_but_autokey() */ static void ui_apply_but_undo(uiBut *but) { - if (but->flag & UI_BUT_UNDO) { + const bool force_skip_undo = (but->active && but->active->skip_undo_push); + + if (but->flag & UI_BUT_UNDO && !force_skip_undo) { const char *str = NULL; size_t str_len_clip = SIZE_MAX - 1; bool skip_undo = false; @@ -2866,7 +2869,8 @@ void ui_but_active_string_clear_and_exit(bContext *C, uiBut *but) but->active->str[0] = 0; ui_apply_but_TEX(C, but, but->active); - button_activate_state(C, but, BUTTON_STATE_EXIT); + /* use onfree event so undo is handled by caller and apply is already done above */ + button_activate_exit((bContext *)C, but, but->active, false, true); } static void ui_textedit_string_ensure_max_length(uiBut *but, uiHandleButtonData *data, int maxlen) @@ -4011,16 +4015,38 @@ static void ui_numedit_apply(bContext *C, uiBlock *block, uiBut *but, uiHandleBu ED_region_tag_redraw(data->region); } -static void ui_but_extra_operator_icon_apply(bContext *C, uiBut *but, uiButExtraOpIcon *op_icon) +static void ui_but_extra_operator_icon_apply_func(uiBut *but, uiButExtraOpIcon *op_icon) { - if (but->active->interactive) { - ui_apply_but(C, but->block, but, but->active, true); + if (ui_afterfunc_check(but->block, but)) { + uiAfterFunc *after = ui_afterfunc_new(); + + after->optype = op_icon->optype_params->optype; + after->opcontext = op_icon->optype_params->opcontext; + after->opptr = op_icon->optype_params->opptr; + + if (but->context) { + after->context = CTX_store_copy(but->context); + } + + /* Ownership moved, don't let the UI code free it. */ + op_icon->optype_params->opptr = NULL; } +} + +static void ui_but_extra_operator_icon_apply(bContext *C, + uiBut *but, + uiHandleButtonData *data, + uiButExtraOpIcon *op_icon) +{ button_activate_state(C, but, BUTTON_STATE_EXIT); - WM_operator_name_call_ptr(C, - op_icon->optype_params->optype, - op_icon->optype_params->opcontext, - op_icon->optype_params->opptr); + ui_apply_but(C, but->block, but, data, true); + + data->postbut = but; + data->posttype = BUTTON_ACTIVATE_OVER; + /* Leave undo up to the operator. */ + data->skip_undo_push = true; + + ui_but_extra_operator_icon_apply_func(but, op_icon); /* Force recreation of extra operator icons (pseudo update). */ ui_but_extra_operator_icons_free(but); @@ -4219,7 +4245,7 @@ static bool ui_do_but_extra_operator_icon(bContext *C, ED_region_tag_redraw(data->region); button_tooltip_timer_reset(C, but); - ui_but_extra_operator_icon_apply(C, but, op_icon); + ui_but_extra_operator_icon_apply(C, but, data, op_icon); /* Note: 'but', 'data' may now be freed, don't access. */ return true; @@ -7854,7 +7880,10 @@ static ARegion *ui_but_tooltip_init( uiBut *but = UI_region_active_but_get(region); *r_exit_on_event = false; if (but) { - return UI_tooltip_create_from_button(C, region, but, is_label); + uiButExtraOpIcon *extra_icon = ui_but_extra_operator_icon_mouse_over_get( + but, but->active, CTX_wm_window(C)->eventstate); + + return UI_tooltip_create_from_button_or_extra_icon(C, region, but, extra_icon, is_label); } return NULL; } diff --git a/source/blender/editors/interface/interface_ops.c b/source/blender/editors/interface/interface_ops.c index e5aa0665a16..2995cff8ed5 100644 --- a/source/blender/editors/interface/interface_ops.c +++ b/source/blender/editors/interface/interface_ops.c @@ -1521,6 +1521,7 @@ static int edittranslation_exec(bContext *C, wmOperator *op) UI_but_string_info_get(C, but, + NULL, &but_label, &rna_label, &enum_label, diff --git a/source/blender/editors/interface/interface_region_tooltip.c b/source/blender/editors/interface/interface_region_tooltip.c index 12f3ba609f0..89515608c5b 100644 --- a/source/blender/editors/interface/interface_region_tooltip.c +++ b/source/blender/editors/interface/interface_region_tooltip.c @@ -534,7 +534,7 @@ static uiTooltipData *ui_tooltip_data_from_tool(bContext *C, uiBut *but, bool is { uiStringInfo op_keymap = {BUT_GET_OP_KEYMAP, NULL}; - UI_but_string_info_get(C, but, &op_keymap, NULL); + UI_but_string_info_get(C, but, NULL, &op_keymap, NULL); shortcut = op_keymap.strinfo; } @@ -764,7 +764,9 @@ static uiTooltipData *ui_tooltip_data_from_tool(bContext *C, uiBut *but, bool is return data; } -static uiTooltipData *ui_tooltip_data_from_button(bContext *C, uiBut *but) +static uiTooltipData *ui_tooltip_data_from_button(bContext *C, + uiBut *but, + uiButExtraOpIcon *extra_icon) { uiStringInfo but_label = {BUT_GET_LABEL, NULL}; uiStringInfo but_tip = {BUT_GET_TIP, NULL}; @@ -777,20 +779,29 @@ static uiTooltipData *ui_tooltip_data_from_button(bContext *C, uiBut *but) char buf[512]; + wmOperatorType *extra_icon_optype = UI_but_extra_operator_icon_optype_get(extra_icon); + wmOperatorType *optype = extra_icon ? extra_icon_optype : but->optype; + /* create tooltip data */ uiTooltipData *data = MEM_callocN(sizeof(uiTooltipData), "uiTooltipData"); - UI_but_string_info_get(C, - but, - &but_label, - &but_tip, - &enum_label, - &enum_tip, - &op_keymap, - &prop_keymap, - &rna_struct, - &rna_prop, - NULL); + if (extra_icon) { + UI_but_string_info_get(C, but, extra_icon, &but_label, &but_tip, &op_keymap, NULL); + } + else { + UI_but_string_info_get(C, + but, + NULL, + &but_label, + &but_tip, + &enum_label, + &enum_tip, + &op_keymap, + &prop_keymap, + &rna_struct, + &rna_prop, + NULL); + } /* Tip Label (only for buttons not already showing the label). * Check prefix instead of comparing because the button may include the shortcut. */ @@ -923,15 +934,16 @@ static uiTooltipData *ui_tooltip_data_from_button(bContext *C, uiBut *but) } } } - else if (but->optype) { - PointerRNA *opptr; - char *str; - opptr = UI_but_operator_ptr_get(but); /* allocated when needed, the button owns it */ + else if (optype) { + PointerRNA *opptr = extra_icon_optype ? + UI_but_extra_operator_icon_opptr_get(extra_icon) : + UI_but_operator_ptr_get( + but); /* allocated when needed, the button owns it */ /* so the context is passed to fieldf functions (some py fieldf functions use it) */ WM_operator_properties_sanitize(opptr, false); - str = ui_tooltip_text_python_from_op(C, but->optype, opptr); + char *str = ui_tooltip_text_python_from_op(C, optype, opptr); /* operator info */ if (U.flag & USER_TOOLTIPS_PYTHON) { @@ -958,7 +970,7 @@ static uiTooltipData *ui_tooltip_data_from_button(bContext *C, uiBut *but) disabled_msg = CTX_wm_operator_poll_msg_get(C); } /* alternatively, buttons can store some reasoning too */ - else if (but->disabled_info) { + if (!disabled_msg && but->disabled_info) { disabled_msg = TIP_(but->disabled_info); } @@ -1398,11 +1410,8 @@ static ARegion *ui_tooltip_create_with_data(bContext *C, /** \name ToolTip Public API * \{ */ -/** - * \param is_label: When true, show a small tip that only shows the name, - * otherwise show the full tooltip. - */ -ARegion *UI_tooltip_create_from_button(bContext *C, ARegion *butregion, uiBut *but, bool is_label) +ARegion *UI_tooltip_create_from_button_or_extra_icon( + bContext *C, ARegion *butregion, uiBut *but, uiButExtraOpIcon *extra_icon, bool is_label) { wmWindow *win = CTX_wm_window(C); /* aspect values that shrink text are likely unreadable */ @@ -1419,7 +1428,7 @@ ARegion *UI_tooltip_create_from_button(bContext *C, ARegion *butregion, uiBut *b } if (data == NULL) { - data = ui_tooltip_data_from_button(C, but); + data = ui_tooltip_data_from_button(C, but, extra_icon); } if (data == NULL) { @@ -1457,6 +1466,15 @@ ARegion *UI_tooltip_create_from_button(bContext *C, ARegion *butregion, uiBut *b return region; } +/** + * \param is_label: When true, show a small tip that only shows the name, + * otherwise show the full tooltip. + */ +ARegion *UI_tooltip_create_from_button(bContext *C, ARegion *butregion, uiBut *but, bool is_label) +{ + return UI_tooltip_create_from_button_or_extra_icon(C, butregion, but, NULL, is_label); +} + ARegion *UI_tooltip_create_from_gizmo(bContext *C, wmGizmo *gz) { wmWindow *win = CTX_wm_window(C); diff --git a/source/blender/editors/interface/interface_templates.c b/source/blender/editors/interface/interface_templates.c index b895f1702f4..6e96704271f 100644 --- a/source/blender/editors/interface/interface_templates.c +++ b/source/blender/editors/interface/interface_templates.c @@ -102,9 +102,16 @@ // #define USE_OP_RESET_BUT /* defines for templateID/TemplateSearch */ -#define TEMPLATE_SEARCH_TEXTBUT_WIDTH (UI_UNIT_X * 6) +#define TEMPLATE_SEARCH_TEXTBUT_WIDTH (UI_UNIT_X * 8) #define TEMPLATE_SEARCH_TEXTBUT_HEIGHT UI_UNIT_Y +/* Add "Make Single User" button to templateID. Users can just manually duplicate an ID, it's + * unclear what the use-case of this specific button is. So for now disabling it, we can bring it + * back or remove it later. + * - Julian + */ +//#define USE_TEMPLATE_ID_MAKE_SINGLE_USER + void UI_template_fix_linking(void) { } @@ -308,6 +315,12 @@ typedef struct TemplateID { ListBase *idlb; short idcode; + + const char *new_op; + const char *duplicate_op; + const char *unlink_op; + const char *open_op; + short filter; int prv_rows, prv_cols; bool preview; @@ -564,80 +577,64 @@ static void template_id_cb(bContext *C, void *arg_litem, void *arg_event) memset(&idptr, 0, sizeof(idptr)); RNA_property_pointer_set(&template_ui->ptr, template_ui->prop, idptr, NULL); RNA_property_update(C, &template_ui->ptr, template_ui->prop); - - if (id && CTX_wm_window(C)->eventstate->shift) { - /* only way to force-remove data (on save) */ - id_us_clear_real(id); - id_fake_user_clear(id); - id->us = 0; - undo_push_label = "Delete Data-Block"; - } - break; - case UI_ID_FAKE_USER: + case UI_ID_MAKE_LOCAL: if (id) { - if (id->flag & LIB_FAKEUSER) { - id_us_plus(id); - } - else { - id_us_min(id); + Main *bmain = CTX_data_main(C); + if (BKE_lib_id_make_local(bmain, id, false, 0)) { + BKE_main_id_clear_newpoins(bmain); + + /* reassign to get get proper updates/notifiers */ + idptr = RNA_property_pointer_get(&template_ui->ptr, template_ui->prop); + RNA_property_pointer_set(&template_ui->ptr, template_ui->prop, idptr, NULL); + RNA_property_update(C, &template_ui->ptr, template_ui->prop); + undo_push_label = "Make Local"; } - undo_push_label = "Fake User"; - } - else { - return; } break; - case UI_ID_LOCAL: - if (id) { + case UI_ID_LIB_OVERRIDE_ADD: + if (id && ID_IS_OVERRIDABLE_LIBRARY(id)) { Main *bmain = CTX_data_main(C); - if (CTX_wm_window(C)->eventstate->shift) { - if (ID_IS_OVERRIDABLE_LIBRARY(id)) { - /* Only remap that specific ID usage to overriding local data-block. */ - ID *override_id = BKE_lib_override_library_create_from_id(bmain, id, false); - if (override_id != NULL) { - BKE_main_id_clear_newpoins(bmain); - - if (GS(override_id->name) == ID_OB) { - Scene *scene = CTX_data_scene(C); - if (!BKE_collection_has_object_recursive(scene->master_collection, - (Object *)override_id)) { - BKE_collection_object_add_from( - bmain, scene, (Object *)id, (Object *)override_id); - } - } - - /* Assign new pointer, takes care of updates/notifiers */ - RNA_id_pointer_create(override_id, &idptr); + /* Only remap that specific ID usage to overriding local data-block. */ + ID *override_id = BKE_lib_override_library_create_from_id(bmain, id, false); + if (override_id != NULL) { + BKE_main_id_clear_newpoins(bmain); + + if (GS(override_id->name) == ID_OB) { + Scene *scene = CTX_data_scene(C); + if (!BKE_collection_has_object_recursive(scene->master_collection, + (Object *)override_id)) { + BKE_collection_object_add_from(bmain, scene, (Object *)id, (Object *)override_id); } - undo_push_label = "Make Library Override"; } - } - else { - if (BKE_lib_id_make_local(bmain, id, false, 0)) { - BKE_main_id_clear_newpoins(bmain); - /* reassign to get get proper updates/notifiers */ - idptr = RNA_property_pointer_get(&template_ui->ptr, template_ui->prop); - undo_push_label = "Make Local"; - } - } - if (undo_push_label != NULL) { - RNA_property_pointer_set(&template_ui->ptr, template_ui->prop, idptr, NULL); - RNA_property_update(C, &template_ui->ptr, template_ui->prop); + /* Assign new pointer, takes care of updates/notifiers */ + RNA_id_pointer_create(override_id, &idptr); } + /* reassign to get get proper updates/notifiers */ + RNA_property_pointer_set(&template_ui->ptr, template_ui->prop, idptr, NULL); + RNA_property_update(C, &template_ui->ptr, template_ui->prop); + undo_push_label = "Make Library Override"; } break; - case UI_ID_OVERRIDE: + case UI_ID_LIB_OVERRIDE_RESET: + if (id && ID_IS_OVERRIDE_LIBRARY_REAL(id)) { + Main *bmain = CTX_data_main(C); + BKE_lib_override_library_id_reset(bmain, id); + undo_push_label = "Reset Library Override"; + } + break; + case UI_ID_LIB_OVERRIDE_REMOVE: if (id && ID_IS_OVERRIDE_LIBRARY(id)) { BKE_lib_override_library_free(&id->override_library, true); /* reassign to get get proper updates/notifiers */ idptr = RNA_property_pointer_get(&template_ui->ptr, template_ui->prop); RNA_property_pointer_set(&template_ui->ptr, template_ui->prop, idptr, NULL); RNA_property_update(C, &template_ui->ptr, template_ui->prop); - undo_push_label = "Override Data-Block"; + undo_push_label = "Remove Library Override"; } break; +#ifdef USE_TEMPLATE_ID_MAKE_SINGLE_USER case UI_ID_ALONE: if (id) { const bool do_scene_obj = ((GS(id->name) == ID_OB) && @@ -659,6 +656,7 @@ static void template_id_cb(bContext *C, void *arg_litem, void *arg_event) undo_push_label = "Make Single User"; } break; +#endif #if 0 case UI_ID_AUTO_NAME: break; @@ -772,17 +770,221 @@ static const char *template_id_context(StructRNA *type) # define template_id_context(type) 0 #endif -static uiBut *template_id_def_new_but(uiBlock *block, - const ID *id, - const TemplateID *template_ui, - StructRNA *type, - const char *const newop, - const bool editable, - const bool id_open, - const bool use_tab_but, - int but_height) -{ +static void template_id_linked_operation_button( + uiBlock *block, Main *bmain, ID *id, TemplateID *template_ui, int operation) +{ + BLI_assert(ELEM(operation, UI_ID_MAKE_LOCAL, UI_ID_LIB_OVERRIDE_ADD)); + + const char *label = (operation == UI_ID_MAKE_LOCAL) ? + CTX_N_(BLT_I18NCONTEXT_OPERATOR_DEFAULT, "Make Local") : + CTX_N_(BLT_I18NCONTEXT_OPERATOR_DEFAULT, "Add Library Override"); + const char *tip = (operation == UI_ID_MAKE_LOCAL) ? + N_("Make library linked data-block local to this file") : + N_("Create a local override of this library linked data-block"); + BIFIconID icon = (operation == UI_ID_MAKE_LOCAL) ? ICON_BLANK1 : ICON_LIBRARY_DATA_OVERRIDE; + + uiBut *but = uiDefIconTextBut(block, + UI_BTYPE_BUT, + 0, + icon, + CTX_IFACE_(BLT_I18NCONTEXT_OPERATOR_DEFAULT, label), + 0, + 0, + UI_UNIT_X, + UI_UNIT_Y, + NULL, + 0, + 0, + 0, + 0, + TIP_(tip)); + + bool disabled = false; + + if (!ID_IS_LINKED(id)) { + disabled = true; + but->disabled_info = TIP_("Data-block is not linked"); + } + else if (id->tag & LIB_TAG_INDIRECT) { + disabled = true; + but->disabled_info = TIP_("Indirect library data-block, cannot change"); + } + else if (!BKE_lib_id_make_local(bmain, id, true /* test */, 0)) { + disabled = true; + but->disabled_info = TIP_("Data-blocks of this type cannot be made local"); + } + else if (!RNA_property_editable_info( + &template_ui->ptr, template_ui->prop, &but->disabled_info)) { + disabled = true; + } + + if (disabled) { + UI_but_flag_enable(but, UI_BUT_DISABLED); + } + else { + UI_but_funcN_set(but, template_id_cb, MEM_dupallocN(template_ui), POINTER_FROM_INT(operation)); + } +} + +static void template_id_library_overridden_button(uiBlock *block, + ID *id, + TemplateID *template_ui, + int operation) +{ + BLI_assert(ELEM(operation, UI_ID_LIB_OVERRIDE_RESET, UI_ID_LIB_OVERRIDE_REMOVE) && + ID_IS_OVERRIDE_LIBRARY(id)); + + if (operation == UI_ID_LIB_OVERRIDE_RESET && ID_IS_OVERRIDE_LIBRARY_REAL(id)) { + uiBut *but = uiDefIconTextBut( + block, + UI_BTYPE_BUT, + 0, + ICON_BLANK1, + CTX_IFACE_(BLT_I18NCONTEXT_OPERATOR_DEFAULT, "Reset Library Override"), + 0, + 0, + UI_UNIT_X, + UI_UNIT_Y, + NULL, + 0, + 0, + 0, + 0, + TIP_("Reset the local override to the state of " + "the overridden data-block")); + if (!ID_IS_OVERRIDE_LIBRARY_REAL(id)) { + but->disabled_info = TIP_("Data-block is a virtual, not a real override"); + UI_but_flag_enable(but, UI_BUT_DISABLED); + } + else { + UI_but_funcN_set(but, + template_id_cb, + MEM_dupallocN(template_ui), + POINTER_FROM_INT(UI_ID_LIB_OVERRIDE_RESET)); + } + } + else if (operation == UI_ID_LIB_OVERRIDE_REMOVE) { + uiBut *but = uiDefIconTextBut( + block, + UI_BTYPE_BUT, + 0, + ICON_BLANK1, + CTX_IFACE_(BLT_I18NCONTEXT_OPERATOR_DEFAULT, "Make Local"), + 0, + 0, + UI_UNIT_X, + UI_UNIT_Y, + NULL, + 0, + 0, + 0, + 0, + TIP_("Remove library override and make the library linked data-block " + "fully local to this file")); + UI_but_funcN_set(but, + template_id_cb, + MEM_dupallocN(template_ui), + POINTER_FROM_INT(UI_ID_LIB_OVERRIDE_REMOVE)); + } +} + +#ifdef USE_TEMPLATE_ID_MAKE_SINGLE_USER +static uiBut *template_id_make_single_user_button(uiBlock *block, ID *id, TemplateID *template_ui) +{ + uiBut *but = uiDefIconTextBut( + block, + UI_BTYPE_BUT, + 0, + ICON_BLANK1, + CTX_IFACE_(BLT_I18NCONTEXT_OPERATOR_DEFAULT, "Make Single-User Copy"), + 0, + 0, + UI_UNIT_X, + UI_UNIT_Y, + NULL, + 0, + 0, + 0, + 0, + TIP_("Duplicate the data-block and assign the newly created copy")); + + if (ID_REAL_USERS(id) <= 1) { + UI_but_flag_enable(but, UI_BUT_DISABLED); + but->disabled_info = TIP_("Data-block already is a single-user"); + /* No need for further setup. */ + return but; + } + + UI_but_funcN_set(but, template_id_cb, MEM_dupallocN(template_ui), POINTER_FROM_INT(UI_ID_ALONE)); + ID *idfrom = template_ui->ptr.owner_id; + bool disabled = false; + + if (!RNA_property_editable_info(&template_ui->ptr, template_ui->prop, &but->disabled_info)) { + disabled = true; + } + if (!BKE_id_copy_is_allowed(id)) { + but->disabled_info = TIP_("Data-blocks of this type cannot be copied"); + disabled = true; + } + /* object in editmode - don't change data */ + if (idfrom && GS(idfrom->name) == ID_OB && (((Object *)idfrom)->mode & OB_MODE_EDIT)) { + but->disabled_info = TIP_("Cannot change object data in Edit Mode"); + disabled = true; + } + + if (disabled) { + UI_but_flag_enable(but, UI_BUT_DISABLED); + } + + return but; +} +#endif + +static void template_id_use_fake_user_button(uiBlock *block, PointerRNA *idptr) +{ + const bool use_fake_user = ID_FAKE_USERS(idptr->data) > 0; + uiBut *but = uiDefIconTextButR( + block, + UI_BTYPE_ICON_TOGGLE, + 0, + ICON_FAKE_USER_OFF, + use_fake_user ? CTX_IFACE_(BLT_I18NCONTEXT_OPERATOR_DEFAULT, "Remove Fake User") : + CTX_IFACE_(BLT_I18NCONTEXT_OPERATOR_DEFAULT, "Add Fake User"), + 0, + 0, + UI_UNIT_X, + UI_UNIT_Y, + idptr, + "use_fake_user", + -1, + 0, + 0, + -1, + -1, + TIP_("When set, ensures the data-block is kept when reloading the file, even if not used at " + "all")); + + if ((ELEM(GS(((ID *)idptr->data)->name), ID_GR, ID_SCE, ID_SCR, ID_TXT, ID_OB, ID_WS))) { + but->disabled_info = TIP_("Data-block type does not support fake user"); + UI_but_flag_enable(but, UI_BUT_DISABLED); + } +} + +enum TemplateIDCreateType { + TEMPLATE_ID_CREATE_NEW, + TEMPLATE_ID_CREATE_DUPLICATE, +}; + +static uiBut *template_id_new_button(uiBlock *block, + const ID *id, + TemplateID *template_ui, + enum TemplateIDCreateType create_type, + StructRNA *type, + const bool id_open, + const bool use_tab_but, + int but_height) +{ uiBut *but; const int w = id ? UI_UNIT_X : id_open ? UI_UNIT_X * 3 : UI_UNIT_X * 6; const int but_type = use_tab_but ? UI_BTYPE_TAB : UI_BTYPE_BUT; @@ -820,54 +1022,384 @@ static uiBut *template_id_def_new_but(uiBlock *block, BLT_I18NCONTEXT_ID_POINTCLOUD, BLT_I18NCONTEXT_ID_VOLUME, BLT_I18NCONTEXT_ID_SIMULATION, ); + BLT_I18N_MSGID_MULTI_CTXT("Duplicate", + BLT_I18NCONTEXT_DEFAULT, + BLT_I18NCONTEXT_ID_SCENE, + BLT_I18NCONTEXT_ID_OBJECT, + BLT_I18NCONTEXT_ID_MESH, + BLT_I18NCONTEXT_ID_CURVE, + BLT_I18NCONTEXT_ID_METABALL, + BLT_I18NCONTEXT_ID_MATERIAL, + BLT_I18NCONTEXT_ID_TEXTURE, + BLT_I18NCONTEXT_ID_IMAGE, + BLT_I18NCONTEXT_ID_LATTICE, + BLT_I18NCONTEXT_ID_LIGHT, + BLT_I18NCONTEXT_ID_CAMERA, + BLT_I18NCONTEXT_ID_WORLD, + BLT_I18NCONTEXT_ID_SCREEN, + BLT_I18NCONTEXT_ID_TEXT, ); + BLT_I18N_MSGID_MULTI_CTXT("Duplicate", + BLT_I18NCONTEXT_ID_SPEAKER, + BLT_I18NCONTEXT_ID_SOUND, + BLT_I18NCONTEXT_ID_ARMATURE, + BLT_I18NCONTEXT_ID_ACTION, + BLT_I18NCONTEXT_ID_NODETREE, + BLT_I18NCONTEXT_ID_BRUSH, + BLT_I18NCONTEXT_ID_PARTICLESETTINGS, + BLT_I18NCONTEXT_ID_GPENCIL, + BLT_I18NCONTEXT_ID_FREESTYLELINESTYLE, + BLT_I18NCONTEXT_ID_WORKSPACE, + BLT_I18NCONTEXT_ID_LIGHTPROBE, + BLT_I18NCONTEXT_ID_HAIR, + BLT_I18NCONTEXT_ID_POINTCLOUD, + BLT_I18NCONTEXT_ID_VOLUME, + BLT_I18NCONTEXT_ID_SIMULATION, ); /* Note: BLT_I18N_MSGID_MULTI_CTXT takes a maximum number of parameters, * check the definition to see if a new call must be added when the limit * is exceeded. */ - if (newop) { + const char *text; + const char *op; + BIFIconID icon; + + switch (create_type) { + case TEMPLATE_ID_CREATE_NEW: + icon = ICON_ADD; + text = CTX_IFACE_(template_id_context(type), "New"); + op = template_ui->new_op; + break; + case TEMPLATE_ID_CREATE_DUPLICATE: + icon = ICON_DUPLICATE; + text = CTX_IFACE_(template_id_context(type), "Duplicate"); + op = template_ui->duplicate_op; + break; + } + + const bool icon_only = use_tab_but; + if (icon_only) { + text = ""; + } + + if (op) { + but = uiDefIconTextButO( + block, but_type, op, WM_OP_INVOKE_DEFAULT, icon, text, 0, 0, w, but_height, NULL); + UI_but_funcN_set( + but, template_id_cb, MEM_dupallocN(template_ui), POINTER_FROM_INT(UI_ID_ADD_NEW)); + + if (!RNA_property_editable_info(&template_ui->ptr, template_ui->prop, &but->disabled_info)) { + UI_but_flag_enable(but, UI_BUT_DISABLED); + } + } + else { + but = uiDefIconTextBut(block, + but_type, + 0, + icon, + text, + 0, + 0, + w, + but_height, + NULL, + 0, + 0, + 0, + 0, + TIP_("Create a new data-block")); + but->disabled_info = TIP_("Creating a new data-block is not supported here"); + UI_but_flag_enable(but, UI_BUT_DISABLED); + } + if (icon_only) { + UI_but_drawflag_disable(but, UI_BUT_ICON_LEFT); + } + +#ifndef WITH_INTERNATIONAL + UNUSED_VARS(type); +#endif + + return but; +} + +static void template_id_unlink_button(uiBlock *block, + TemplateID *template_ui, + bool hide_if_disabled) +{ + const char *disable_info; + const bool is_menu = ui_block_is_menu(block); + const bool editable = RNA_property_editable_info( + &template_ui->ptr, template_ui->prop, &disable_info); + /* allow unlink if 'unlinkop' is passed, even when 'PROP_NEVER_UNLINK' is set */ + uiBut *but = NULL; + + if (hide_if_disabled && !editable) { + /* Add no button. */ + } + else if (template_ui->unlink_op) { + but = uiDefIconTextButO(block, + UI_BTYPE_BUT, + template_ui->unlink_op, + WM_OP_INVOKE_DEFAULT, + ICON_X, + is_menu ? NULL : "", + 0, + 0, + UI_UNIT_X, + UI_UNIT_Y, + NULL); + /* so we can access the template from operators, font unlinking needs this */ + UI_but_funcN_set(but, NULL, MEM_dupallocN(template_ui), NULL); + } + else { + const bool never_unlink = RNA_property_flag(template_ui->prop) & + (PROP_NEVER_UNLINK | PROP_NEVER_NULL); + + if (!never_unlink || !hide_if_disabled) { + but = uiDefIconTextBut(block, + UI_BTYPE_BUT, + 0, + ICON_X, + is_menu ? CTX_IFACE_(BLT_I18NCONTEXT_OPERATOR_DEFAULT, "Unlink") : "", + 0, + 0, + UI_UNIT_X, + UI_UNIT_Y, + NULL, + 0, + 0, + 0, + 0, + TIP_("Remove this usage of the data-block")); + if (!never_unlink) { + UI_but_funcN_set( + but, template_id_cb, MEM_dupallocN(template_ui), POINTER_FROM_INT(UI_ID_DELETE)); + } + if (!is_menu) { + UI_but_drawflag_disable(but, UI_BUT_ICON_LEFT); + } + } + + if (but && never_unlink) { + but->disabled_info = TIP_("Property must never be in an unlinked state"); + UI_but_flag_enable(but, UI_BUT_DISABLED); + } + } + + if (but) { + if (!editable) { + but->disabled_info = disable_info; + UI_but_flag_enable(but, UI_BUT_DISABLED); + } + } +} + +static void template_id_open_button(uiBlock *block, + ID *id, + TemplateID *template_ui, + const bool compact) +{ + const bool is_menu = ui_block_is_menu(block); + const int w = compact ? UI_UNIT_X * 3 : UI_UNIT_X * 6; + char text[UI_MAX_NAME_STR] = ""; + const bool icon_only = !is_menu && id; + uiBut *but; + + if (!icon_only) { + BLI_snprintf(text, + sizeof(text), + "%s%s", + CTX_IFACE_(BLT_I18NCONTEXT_OPERATOR_DEFAULT, "Open"), + is_menu ? "..." : ""); + } + + if (template_ui->open_op) { but = uiDefIconTextButO(block, - but_type, - newop, + UI_BTYPE_BUT, + template_ui->open_op, WM_OP_INVOKE_DEFAULT, - (id && !use_tab_but) ? ICON_DUPLICATE : ICON_ADD, - (id) ? "" : CTX_IFACE_(template_id_context(type), "New"), + ICON_FILEBROWSER, + text, 0, 0, w, - but_height, + UI_UNIT_Y, NULL); UI_but_funcN_set( - but, template_id_cb, MEM_dupallocN(template_ui), POINTER_FROM_INT(UI_ID_ADD_NEW)); + but, template_id_cb, MEM_dupallocN(template_ui), POINTER_FROM_INT(UI_ID_OPEN)); } else { but = uiDefIconTextBut(block, - but_type, + UI_BTYPE_BUT, 0, - (id && !use_tab_but) ? ICON_DUPLICATE : ICON_ADD, - (id) ? "" : CTX_IFACE_(template_id_context(type), "New"), + ICON_FILEBROWSER, + text, 0, 0, w, - but_height, + UI_UNIT_Y, NULL, 0, 0, 0, 0, NULL); - UI_but_funcN_set( - but, template_id_cb, MEM_dupallocN(template_ui), POINTER_FROM_INT(UI_ID_ADD_NEW)); + but->disabled_info = TIP_("Browsing for a new data-block is not supported here"); + UI_but_flag_enable(but, UI_BUT_DISABLED); } - if ((idfrom && idfrom->lib) || !editable) { + if (!RNA_property_editable_info(&template_ui->ptr, template_ui->prop, &but->disabled_info)) { UI_but_flag_enable(but, UI_BUT_DISABLED); } +} -#ifndef WITH_INTERNATIONAL - UNUSED_VARS(type); +static void template_id_unpack_button(uiBlock *block, ID *id) +{ + wmOperatorType *optype = WM_operatortype_find("FILE_OT_unpack_item", false); + uiBut *but; + + but = uiDefIconTextButO_ptr(block, + UI_BTYPE_BUT, + optype, + WM_OP_INVOKE_REGION_WIN, + ICON_PACKAGE, + NULL, + 0, + 0, + UI_UNIT_X, + UI_UNIT_Y, + NULL); + + if (!BKE_packedfile_id_check(id)) { + but->disabled_info = TIP_("File is not packed"); + UI_but_flag_enable(but, UI_BUT_DISABLED); + } + UI_but_operator_ptr_get(but); + + RNA_string_set(but->opptr, "id_name", id->name + 2); + RNA_int_set(but->opptr, "id_type", GS(id->name)); +} + +static void template_id_user_count_label(uiLayout *layout, const ID *id) +{ + char numstr[UI_MAX_NAME_STR]; + BLI_snprintf(numstr, + sizeof(numstr), + "%d %s", + ID_REAL_USERS(id), + ID_REAL_USERS(id) > 1 ? IFACE_("Users") : IFACE_("User")); + uiItemL(layout, numstr, ICON_NONE); +} + +static void template_id_menu(bContext *C, uiLayout *layout, void *arg) +{ + /* Button that spawned the menu. */ + const uiBut *menu_parent_but = arg; + TemplateID *template_ui = menu_parent_but->func_argN; + PointerRNA idptr = RNA_property_pointer_get(&template_ui->ptr, template_ui->prop); + ID *id = idptr.data; + uiBlock *block = uiLayoutGetBlock(layout); + + BLI_assert(id); + + template_id_new_button( + block, id, template_ui, TEMPLATE_ID_CREATE_NEW, idptr.type, false, false, UI_UNIT_X); + template_id_new_button( + block, id, template_ui, TEMPLATE_ID_CREATE_DUPLICATE, idptr.type, false, false, UI_UNIT_X); + template_id_unlink_button(block, template_ui, false); + +#ifdef USE_TEMPLATE_ID_MAKE_SINGLE_USER + template_id_make_single_user_button(block, id, template_ui); #endif + template_id_use_fake_user_button(block, &idptr); - return but; + if (template_ui->open_op || BKE_packedfile_id_check(id)) { + uiItemS(layout); + + template_id_open_button(block, id, template_ui, false); + template_id_unpack_button(block, id); + } + + /* Library operators. */ + if (ID_IS_OVERRIDE_LIBRARY(id)) { + uiItemS(layout); + + template_id_library_overridden_button(block, id, template_ui, UI_ID_LIB_OVERRIDE_RESET); + template_id_library_overridden_button(block, id, template_ui, UI_ID_LIB_OVERRIDE_REMOVE); + } + else if (ID_IS_LINKED(id)) { + uiItemS(layout); + + Main *bmain = CTX_data_main(C); + template_id_linked_operation_button(block, bmain, id, template_ui, UI_ID_MAKE_LOCAL); + template_id_linked_operation_button(block, bmain, id, template_ui, UI_ID_LIB_OVERRIDE_ADD); + } + + uiItemS(layout); + template_id_user_count_label(layout, id); +} + +static void template_id_name_button( + uiBlock *block, StructRNA *type, TemplateID *template_ui, int flag, const bool hide_extras) +{ + PointerRNA idptr = RNA_property_pointer_get(&template_ui->ptr, template_ui->prop); + ID *id = idptr.data; + BIFIconID lib_icon = UI_icon_from_library(id); + + char name[UI_MAX_NAME_STR] = ""; + uiBut *but = uiDefIconTextButR(block, + UI_BTYPE_TEXT, + 0, + lib_icon, + name, + 0, + 0, + TEMPLATE_SEARCH_TEXTBUT_WIDTH, + TEMPLATE_SEARCH_TEXTBUT_HEIGHT, + &idptr, + "name", + -1, + 0, + 0, + 0, + 0, + RNA_struct_ui_description(type)); + /* Note: Also needed for the extra icons below (their operators access the TemplateID). */ + UI_but_funcN_set( + but, template_id_cb, MEM_dupallocN(template_ui), POINTER_FROM_INT(UI_ID_RENAME)); + + const bool user_alert = (id->us <= 0); + if (user_alert) { + UI_but_flag_enable(but, UI_BUT_REDALERT); + } + + if (hide_extras) { + return; + } + + if (template_ui->duplicate_op && (flag & UI_ID_ADD_NEW)) { + UI_but_extra_operator_icon_add( + but, template_ui->duplicate_op, WM_OP_INVOKE_DEFAULT, ICON_DUPLICATE); + } + + if (id && (flag & UI_ID_DELETE)) { + const bool never_unlink = RNA_property_flag(template_ui->prop) & + (PROP_NEVER_UNLINK | PROP_NEVER_NULL); + if (template_ui->unlink_op) { + UI_but_extra_operator_icon_add(but, template_ui->unlink_op, WM_OP_INVOKE_DEFAULT, ICON_X); + } + else if (!never_unlink) { + UI_but_extra_operator_icon_add(but, "ED_OT_lib_unlink", WM_OP_INVOKE_DEFAULT, ICON_X); + } + } + + /* Disable fake user icon for now, only have it in the menu. */ + const bool add_extra_fake_user_icon = false; + if (add_extra_fake_user_icon && id->lib == NULL && + !(ELEM(GS(id->name), ID_GR, ID_SCE, ID_SCR, ID_TXT, ID_OB, ID_WS))) { + UI_but_extra_operator_icon_add(but, + "ED_OT_lib_fake_user_toggle", + WM_OP_INVOKE_DEFAULT, + ID_FAKE_USERS(id) ? ICON_FAKE_USER_ON : ICON_FAKE_USER_OFF); + } } static void template_ID(const bContext *C, @@ -875,9 +1407,6 @@ static void template_ID(const bContext *C, TemplateID *template_ui, StructRNA *type, int flag, - const char *newop, - const char *openop, - const char *unlinkop, const char *text, const bool live_icon, const bool hide_buttons) @@ -885,15 +1414,12 @@ static void template_ID(const bContext *C, uiBut *but; uiBlock *block; PointerRNA idptr; - // ListBase *lb; // UNUSED - ID *id, *idfrom; + ID *id; const bool editable = RNA_property_editable(&template_ui->ptr, template_ui->prop); const bool use_previews = template_ui->preview = (flag & UI_ID_PREVIEWS) != 0; idptr = RNA_property_pointer_get(&template_ui->ptr, template_ui->prop); id = idptr.data; - idfrom = template_ui->ptr.owner_id; - // lb = template_ui->idlb; /* Allow opertators to take the ID from context. */ uiLayoutSetContextPointer(layout, "id", &idptr); @@ -926,277 +1452,39 @@ static void template_ID(const bContext *C, /* text button with name */ if (id) { - char name[UI_MAX_NAME_STR]; - const bool user_alert = (id->us <= 0); - - // text_idbutton(id, name); - name[0] = '\0'; - but = uiDefButR(block, - UI_BTYPE_TEXT, - 0, - name, - 0, - 0, - TEMPLATE_SEARCH_TEXTBUT_WIDTH, - TEMPLATE_SEARCH_TEXTBUT_HEIGHT, - &idptr, - "name", - -1, - 0, - 0, - -1, - -1, - RNA_struct_ui_description(type)); - UI_but_funcN_set( - but, template_id_cb, MEM_dupallocN(template_ui), POINTER_FROM_INT(UI_ID_RENAME)); - if (user_alert) { - UI_but_flag_enable(but, UI_BUT_REDALERT); - } - - if (id->lib) { - if (id->tag & LIB_TAG_INDIRECT) { - but = uiDefIconBut(block, - UI_BTYPE_BUT, - 0, - ICON_LIBRARY_DATA_INDIRECT, - 0, - 0, - UI_UNIT_X, - UI_UNIT_Y, - NULL, - 0, - 0, - 0, - 0, - TIP_("Indirect library data-block, cannot change")); - UI_but_flag_enable(but, UI_BUT_DISABLED); - } - else { - const bool disabled = (!BKE_lib_id_make_local(CTX_data_main(C), id, true /* test */, 0) || - (idfrom && idfrom->lib)); - but = uiDefIconBut(block, - UI_BTYPE_BUT, - 0, - ICON_LIBRARY_DATA_DIRECT, - 0, - 0, - UI_UNIT_X, - UI_UNIT_Y, - NULL, - 0, - 0, - 0, - 0, - TIP_("Direct linked library data-block, click to make local, " - "Shift + Click to create a library override")); - if (disabled) { - UI_but_flag_enable(but, UI_BUT_DISABLED); - } - else { - UI_but_funcN_set( - but, template_id_cb, MEM_dupallocN(template_ui), POINTER_FROM_INT(UI_ID_LOCAL)); - } - } - } - else if (ID_IS_OVERRIDE_LIBRARY(id)) { - but = uiDefIconBut(block, - UI_BTYPE_BUT, - 0, - ICON_LIBRARY_DATA_OVERRIDE, - 0, - 0, - UI_UNIT_X, - UI_UNIT_Y, - NULL, - 0, - 0, - 0, - 0, - TIP_("Library override of linked data-block, click to make fully local")); - UI_but_funcN_set( - but, template_id_cb, MEM_dupallocN(template_ui), POINTER_FROM_INT(UI_ID_OVERRIDE)); - } - - if ((ID_REAL_USERS(id) > 1) && (hide_buttons == false)) { - char numstr[32]; - short numstr_len; - - numstr_len = BLI_snprintf(numstr, sizeof(numstr), "%d", ID_REAL_USERS(id)); - - but = uiDefBut( - block, - UI_BTYPE_BUT, - 0, - numstr, - 0, - 0, - numstr_len * 0.2f * UI_UNIT_X + UI_UNIT_X, - UI_UNIT_Y, - NULL, - 0, - 0, - 0, - 0, - TIP_("Display number of users of this data (click to make a single-user copy)")); - but->flag |= UI_BUT_UNDO; - - UI_but_funcN_set( - but, template_id_cb, MEM_dupallocN(template_ui), POINTER_FROM_INT(UI_ID_ALONE)); - if ((!BKE_id_copy_is_allowed(id)) || (idfrom && idfrom->lib) || (!editable) || - /* object in editmode - don't change data */ - (idfrom && GS(idfrom->name) == ID_OB && (((Object *)idfrom)->mode & OB_MODE_EDIT))) { - UI_but_flag_enable(but, UI_BUT_DISABLED); - } - } - - if (user_alert) { - UI_but_flag_enable(but, UI_BUT_REDALERT); - } - - if (id->lib == NULL && !(ELEM(GS(id->name), ID_GR, ID_SCE, ID_SCR, ID_TXT, ID_OB, ID_WS)) && - (hide_buttons == false)) { - uiDefIconButR(block, - UI_BTYPE_ICON_TOGGLE, - 0, - ICON_FAKE_USER_OFF, - 0, - 0, - UI_UNIT_X, - UI_UNIT_Y, - &idptr, - "use_fake_user", - -1, - 0, - 0, - -1, - -1, - NULL); - } + template_id_name_button(block, type, template_ui, flag, hide_buttons); } - - if ((flag & UI_ID_ADD_NEW) && (hide_buttons == false)) { - template_id_def_new_but( - block, id, template_ui, type, newop, editable, flag & UI_ID_OPEN, false, UI_UNIT_X); + /* If no ID is set, show a "new" button instead of a text button. */ + else if ((flag & UI_ID_ADD_NEW) && (hide_buttons == false)) { + template_id_new_button( + block, id, template_ui, TEMPLATE_ID_CREATE_NEW, type, flag & UI_ID_OPEN, false, UI_UNIT_X); } - /* Due to space limit in UI - skip the "open" icon for packed data, and allow to unpack. - * Only for images, sound and fonts */ - if (id && BKE_packedfile_id_check(id)) { - but = uiDefIconButO(block, - UI_BTYPE_BUT, - "FILE_OT_unpack_item", - WM_OP_INVOKE_REGION_WIN, - ICON_PACKAGE, - 0, - 0, - UI_UNIT_X, - UI_UNIT_Y, - TIP_("Packed File, click to unpack")); - UI_but_operator_ptr_get(but); - - RNA_string_set(but->opptr, "id_name", id->name + 2); - RNA_int_set(but->opptr, "id_type", GS(id->name)); + if ((flag & UI_ID_OPEN) && !id) { + template_id_open_button(block, id, template_ui, flag & UI_ID_ADD_NEW); } - else if (flag & UI_ID_OPEN) { - const int w = id ? UI_UNIT_X : (flag & UI_ID_ADD_NEW) ? UI_UNIT_X * 3 : UI_UNIT_X * 6; - - if (openop) { - but = uiDefIconTextButO(block, - UI_BTYPE_BUT, - openop, - WM_OP_INVOKE_DEFAULT, - ICON_FILEBROWSER, - (id) ? "" : IFACE_("Open"), - 0, - 0, - w, - UI_UNIT_Y, - NULL); - UI_but_funcN_set( - but, template_id_cb, MEM_dupallocN(template_ui), POINTER_FROM_INT(UI_ID_OPEN)); - } - else { - but = uiDefIconTextBut(block, - UI_BTYPE_BUT, - 0, - ICON_FILEBROWSER, - (id) ? "" : IFACE_("Open"), - 0, - 0, - w, - UI_UNIT_Y, - NULL, - 0, - 0, - 0, - 0, - NULL); - UI_but_funcN_set( - but, template_id_cb, MEM_dupallocN(template_ui), POINTER_FROM_INT(UI_ID_OPEN)); - } - if ((idfrom && idfrom->lib) || !editable) { - UI_but_flag_enable(but, UI_BUT_DISABLED); - } + if (template_ui->idcode == ID_TE) { + uiTemplateTextureShow(layout, C, &template_ui->ptr, template_ui->prop); } - /* delete button */ - /* don't use RNA_property_is_unlink here */ - if (id && (flag & UI_ID_DELETE) && (hide_buttons == false)) { - /* allow unlink if 'unlinkop' is passed, even when 'PROP_NEVER_UNLINK' is set */ - but = NULL; - - if (unlinkop) { - but = uiDefIconButO(block, - UI_BTYPE_BUT, - unlinkop, - WM_OP_INVOKE_DEFAULT, - ICON_X, - 0, - 0, - UI_UNIT_X, - UI_UNIT_Y, - NULL); - /* so we can access the template from operators, font unlinking needs this */ - UI_but_funcN_set(but, NULL, MEM_dupallocN(template_ui), NULL); - } - else { - if ((RNA_property_flag(template_ui->prop) & PROP_NEVER_UNLINK) == 0) { - but = uiDefIconBut( - block, - UI_BTYPE_BUT, - 0, - ICON_X, - 0, - 0, - UI_UNIT_X, - UI_UNIT_Y, - NULL, - 0, - 0, - 0, - 0, - TIP_("Unlink data-block " - "(Shift + Click to set users to zero, data will then not be saved)")); - UI_but_funcN_set( - but, template_id_cb, MEM_dupallocN(template_ui), POINTER_FROM_INT(UI_ID_DELETE)); - - if (RNA_property_flag(template_ui->prop) & PROP_NEVER_NULL) { - UI_but_flag_enable(but, UI_BUT_DISABLED); - } - } - } - - if (but) { - if ((idfrom && idfrom->lib) || !editable) { - UI_but_flag_enable(but, UI_BUT_DISABLED); - } - } + if (id && !hide_buttons) { + /* Additional operations menu ("Make Local", overrides, etc). */ + but = uiDefIconMenuBut(block, + template_id_menu, + NULL, + ICON_DOWNARROW_HLT, + 0, + 0, + UI_UNIT_X, + UI_UNIT_Y, + TIP_("Show more operations for the selected data-block")); + UI_but_type_set_menu_from_pulldown(but); + /* Same hack as ui_item_menu() to allow allocated arg. */ + but->poin = (char *)but; + but->func_argN = MEM_dupallocN(template_ui); } - if (template_ui->idcode == ID_TE) { - uiTemplateTextureShow(layout, C, &template_ui->ptr, template_ui->prop); - } UI_block_align_end(block); } @@ -1215,7 +1503,6 @@ static void template_ID_tabs(const bContext *C, TemplateID *template, StructRNA *type, int flag, - const char *newop, const char *menu) { const ARegion *region = CTX_wm_region(C); @@ -1263,22 +1550,20 @@ static void template_ID_tabs(const bContext *C, BLI_freelistN(&ordered); if (flag & UI_ID_ADD_NEW) { - const bool editable = RNA_property_editable(&template->ptr, template->prop); uiBut *but; if (active_ptr.type) { type = active_ptr.type; } - but = template_id_def_new_but(block, - active_ptr.data, - template, - type, - newop, - editable, - flag & UI_ID_OPEN, - true, - but_height); + but = template_id_new_button(block, + active_ptr.data, + template, + TEMPLATE_ID_CREATE_NEW, + type, + flag & UI_ID_OPEN, + true, + but_height); UI_but_drawflag_enable(but, but_align); } } @@ -1288,6 +1573,7 @@ static void ui_template_id(uiLayout *layout, PointerRNA *ptr, const char *propname, const char *newop, + const char *duplicateop, const char *openop, const char *unlinkop, /* Only respected by tabs (use_tabs). */ @@ -1317,6 +1603,10 @@ static void ui_template_id(uiLayout *layout, template_ui = MEM_callocN(sizeof(TemplateID), "TemplateID"); template_ui->ptr = *ptr; template_ui->prop = prop; + template_ui->new_op = newop; + template_ui->duplicate_op = duplicateop; + template_ui->unlink_op = unlinkop; + template_ui->open_op = openop; template_ui->prv_rows = prv_rows; template_ui->prv_cols = prv_cols; template_ui->scale = scale; @@ -1328,7 +1618,7 @@ static void ui_template_id(uiLayout *layout, template_ui->filter = 0; } - if (newop) { + if (newop || duplicateop) { flag |= UI_ID_ADD_NEW; } if (openop) { @@ -1346,21 +1636,11 @@ static void ui_template_id(uiLayout *layout, if (template_ui->idlb) { if (use_tabs) { layout = uiLayoutRow(layout, true); - template_ID_tabs(C, layout, template_ui, type, flag, newop, menu); + template_ID_tabs(C, layout, template_ui, type, flag, menu); } else { layout = uiLayoutRow(layout, true); - template_ID(C, - layout, - template_ui, - type, - flag, - newop, - openop, - unlinkop, - text, - live_icon, - hide_buttons); + template_ID(C, layout, template_ui, type, flag, text, live_icon, hide_buttons); } } @@ -1372,6 +1652,7 @@ void uiTemplateID(uiLayout *layout, PointerRNA *ptr, const char *propname, const char *newop, + const char *duplicateop, const char *openop, const char *unlinkop, int filter, @@ -1383,6 +1664,7 @@ void uiTemplateID(uiLayout *layout, ptr, propname, newop, + duplicateop, openop, unlinkop, NULL, @@ -1412,6 +1694,7 @@ void uiTemplateIDBrowse(uiLayout *layout, ptr, propname, newop, + NULL, openop, unlinkop, NULL, @@ -1443,6 +1726,7 @@ void uiTemplateIDPreview(uiLayout *layout, ptr, propname, newop, + NULL, openop, unlinkop, NULL, @@ -1475,6 +1759,7 @@ void uiTemplateGpencilColorPreview(uiLayout *layout, NULL, NULL, NULL, + NULL, UI_ID_BROWSE | UI_ID_PREVIEWS | UI_ID_DELETE, rows, cols, @@ -1503,6 +1788,7 @@ void uiTemplateIDTabs(uiLayout *layout, newop, NULL, NULL, + NULL, menu, NULL, UI_ID_BROWSE | UI_ID_RENAME, @@ -1662,35 +1948,25 @@ static void template_search_add_button_searchmenu(const bContext *C, static void template_search_add_button_name(uiBlock *block, PointerRNA *active_ptr, - const StructRNA *type) + const StructRNA *type, + const char *newop, + const char *unlinkop) { - uiDefAutoButR(block, - active_ptr, - RNA_struct_name_property(type), - 0, - "", - ICON_NONE, - 0, - 0, - TEMPLATE_SEARCH_TEXTBUT_WIDTH, - TEMPLATE_SEARCH_TEXTBUT_HEIGHT); -} - -static void template_search_add_button_operator(uiBlock *block, - const char *const operator_name, - const int opcontext, - const int icon, - const bool editable) -{ - if (!operator_name) { - return; + uiBut *but = uiDefAutoButR(block, + active_ptr, + RNA_struct_name_property(type), + 0, + "", + ICON_NONE, + 0, + 0, + TEMPLATE_SEARCH_TEXTBUT_WIDTH, + TEMPLATE_SEARCH_TEXTBUT_HEIGHT); + if (newop) { + UI_but_extra_operator_icon_add(but, newop, WM_OP_INVOKE_DEFAULT, ICON_DUPLICATE); } - - uiBut *but = uiDefIconButO( - block, UI_BTYPE_BUT, operator_name, opcontext, icon, 0, 0, UI_UNIT_X, UI_UNIT_Y, NULL); - - if (!editable) { - UI_but_drawflag_enable(but, UI_BUT_DISABLED); + if (unlinkop) { + UI_but_extra_operator_icon_add(but, unlinkop, WM_OP_INVOKE_REGION_WIN, ICON_X); } } @@ -1716,10 +1992,7 @@ static void template_search_buttons(const bContext *C, UI_block_align_begin(block); template_search_add_button_searchmenu(C, layout, block, template_search, editable, false); - template_search_add_button_name(block, &active_ptr, type); - template_search_add_button_operator( - block, newop, WM_OP_INVOKE_DEFAULT, ICON_DUPLICATE, editable); - template_search_add_button_operator(block, unlinkop, WM_OP_INVOKE_REGION_WIN, ICON_X, editable); + template_search_add_button_name(block, &active_ptr, type, newop, unlinkop); UI_block_align_end(block); } @@ -7191,6 +7464,7 @@ void uiTemplateCacheFile(uiLayout *layout, ptr, propname, NULL, + NULL, "CACHEFILE_OT_open", NULL, UI_TEMPLATE_ID_FILTER_ALL, diff --git a/source/blender/editors/render/render_intern.h b/source/blender/editors/render/render_intern.h index e1d03e6f3be..e60455667e9 100644 --- a/source/blender/editors/render/render_intern.h +++ b/source/blender/editors/render/render_intern.h @@ -38,8 +38,11 @@ void OBJECT_OT_material_slot_move(struct wmOperatorType *ot); void OBJECT_OT_material_slot_remove_unused(struct wmOperatorType *ot); void MATERIAL_OT_new(struct wmOperatorType *ot); +void MATERIAL_OT_duplicate(struct wmOperatorType *ot); void TEXTURE_OT_new(struct wmOperatorType *ot); +void TEXTURE_OT_duplicate(struct wmOperatorType *ot); void WORLD_OT_new(struct wmOperatorType *ot); +void WORLD_OT_duplicate(struct wmOperatorType *ot); void MATERIAL_OT_copy(struct wmOperatorType *ot); void MATERIAL_OT_paste(struct wmOperatorType *ot); diff --git a/source/blender/editors/render/render_ops.c b/source/blender/editors/render/render_ops.c index e0aa02b354d..48e894036d9 100644 --- a/source/blender/editors/render/render_ops.c +++ b/source/blender/editors/render/render_ops.c @@ -45,8 +45,11 @@ void ED_operatortypes_render(void) WM_operatortype_append(OBJECT_OT_material_slot_remove_unused); WM_operatortype_append(MATERIAL_OT_new); + WM_operatortype_append(MATERIAL_OT_duplicate); WM_operatortype_append(TEXTURE_OT_new); + WM_operatortype_append(TEXTURE_OT_duplicate); WM_operatortype_append(WORLD_OT_new); + WM_operatortype_append(WORLD_OT_duplicate); WM_operatortype_append(MATERIAL_OT_copy); WM_operatortype_append(MATERIAL_OT_paste); diff --git a/source/blender/editors/render/render_shading.c b/source/blender/editors/render/render_shading.c index b69337b1621..cac01bdc048 100644 --- a/source/blender/editors/render/render_shading.c +++ b/source/blender/editors/render/render_shading.c @@ -735,45 +735,40 @@ void OBJECT_OT_material_slot_remove_unused(wmOperatorType *ot) /** \} */ /* -------------------------------------------------------------------- */ -/** \name New Material Operator +/** \name Create Material Operators * \{ */ -static int new_material_exec(bContext *C, wmOperator *UNUSED(op)) +struct MaterialCreationData { + Object *ob; + PropertyPointerRNA pprop; +}; + +static void material_creation_data_init_from_UI_context(bContext *C, + struct MaterialCreationData *r_create_data) { - Material *ma = CTX_data_pointer_get_type(C, "material", &RNA_Material).data; - Main *bmain = CTX_data_main(C); - PointerRNA ptr, idptr; + PointerRNA ptr; PropertyRNA *prop; /* hook into UI */ UI_context_active_but_prop_get_templateID(C, &ptr, &prop); - Object *ob = (prop && RNA_struct_is_a(ptr.type, &RNA_Object)) ? ptr.data : NULL; + r_create_data->ob = (prop && RNA_struct_is_a(ptr.type, &RNA_Object)) ? ptr.data : NULL; + r_create_data->pprop.ptr = ptr; + r_create_data->pprop.prop = prop; +} - /* add or copy material */ - if (ma) { - Material *new_ma = (Material *)BKE_id_copy_ex( - bmain, &ma->id, NULL, LIB_ID_COPY_DEFAULT | LIB_ID_COPY_ACTIONS); - ma = new_ma; - } - else { - const char *name = DATA_("Material"); - if (!(ob != NULL && ob->type == OB_GPENCIL)) { - ma = BKE_material_add(bmain, name); - } - else { - ma = BKE_gpencil_material_add(bmain, name); - } - ED_node_shader_default(C, &ma->id); - ma->use_nodes = true; - } +static void material_creation_assign(bContext *C, + Material *ma, + struct MaterialCreationData *create_data) +{ + Main *bmain = CTX_data_main(C); - if (prop) { - if (ob != NULL) { + if (create_data->pprop.prop) { + if (create_data->ob != NULL) { /* Add slot follows user-preferences for creating new slots, * RNA pointer assignment doesn't, see: T60014. */ - if (BKE_object_material_get_p(ob, ob->actcol) == NULL) { - BKE_object_material_slot_add(bmain, ob); + if (BKE_object_material_get_p(create_data->ob, create_data->ob->actcol) == NULL) { + BKE_object_material_slot_add(bmain, create_data->ob); } } @@ -781,10 +776,32 @@ static int new_material_exec(bContext *C, wmOperator *UNUSED(op)) * pointer use also increases user, so this compensates it */ id_us_min(&ma->id); + PointerRNA idptr; RNA_id_pointer_create(&ma->id, &idptr); - RNA_property_pointer_set(&ptr, prop, idptr, NULL); - RNA_property_update(C, &ptr, prop); + RNA_property_pointer_set(&create_data->pprop.ptr, create_data->pprop.prop, idptr, NULL); + RNA_property_update(C, &create_data->pprop.ptr, create_data->pprop.prop); + } +} + +static int new_material_exec(bContext *C, wmOperator *UNUSED(op)) +{ + Main *bmain = CTX_data_main(C); + struct MaterialCreationData create_data; + + material_creation_data_init_from_UI_context(C, &create_data); + + const char *name = DATA_("Material"); + Material *ma; + if ((create_data.ob == NULL) || (create_data.ob->type != OB_GPENCIL)) { + ma = BKE_material_add(bmain, name); + } + else { + ma = BKE_gpencil_material_add(bmain, name); } + ED_node_shader_default(C, &ma->id); + ma->use_nodes = true; + + material_creation_assign(C, ma, &create_data); WM_event_add_notifier(C, NC_MATERIAL | NA_ADDED, ma); @@ -806,27 +823,57 @@ void MATERIAL_OT_new(wmOperatorType *ot) ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_INTERNAL; } -/** \} */ +static int duplicate_material_exec(bContext *C, wmOperator *op) +{ + Material *old_ma = CTX_data_pointer_get_type(C, "material", &RNA_Material).data; + + if (!old_ma) { + BKE_report( + op->reports, + RPT_ERROR, + "Incorrect context for duplicating a material (did not find material to duplicate)"); + return OPERATOR_CANCELLED; + } + + Main *bmain = CTX_data_main(C); + struct MaterialCreationData create_data; + + material_creation_data_init_from_UI_context(C, &create_data); + + Material *new_ma = (Material *)BKE_id_copy_ex( + bmain, &old_ma->id, NULL, LIB_ID_COPY_DEFAULT | LIB_ID_COPY_ACTIONS); + + material_creation_assign(C, new_ma, &create_data); + + WM_event_add_notifier(C, NC_MATERIAL | NA_ADDED, new_ma); + + return OPERATOR_FINISHED; +} + +void MATERIAL_OT_duplicate(wmOperatorType *ot) +{ + /* identifiers */ + ot->name = "Duplicate Material"; + ot->idname = "MATERIAL_OT_duplicate"; + ot->description = "Duplicate an existing material"; + + /* api callbacks */ + ot->exec = duplicate_material_exec; + ot->poll = object_materials_supported_poll; + + /* flags */ + ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_INTERNAL; +} /* -------------------------------------------------------------------- */ -/** \name New Texture Operator +/** \name Create Texture Operators * \{ */ -static int new_texture_exec(bContext *C, wmOperator *UNUSED(op)) +static void texture_creation_assign(bContext *C, Tex *tex) { - Tex *tex = CTX_data_pointer_get_type(C, "texture", &RNA_Texture).data; - Main *bmain = CTX_data_main(C); PointerRNA ptr, idptr; PropertyRNA *prop; - /* add or copy texture */ - if (tex) { - tex = (Tex *)BKE_id_copy(bmain, &tex->id); - } - else { - tex = BKE_texture_add(bmain, DATA_("Texture")); - } - /* hook into UI */ UI_context_active_but_prop_get_templateID(C, &ptr, &prop); @@ -839,6 +886,14 @@ static int new_texture_exec(bContext *C, wmOperator *UNUSED(op)) RNA_property_pointer_set(&ptr, prop, idptr, NULL); RNA_property_update(C, &ptr, prop); } +} + +static int new_texture_exec(bContext *C, wmOperator *UNUSED(op)) +{ + Main *bmain = CTX_data_main(C); + Tex *tex = BKE_texture_add(bmain, DATA_("Texture")); + + texture_creation_assign(C, tex); WM_event_add_notifier(C, NC_TEXTURE | NA_ADDED, tex); @@ -859,31 +914,53 @@ void TEXTURE_OT_new(wmOperatorType *ot) ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_INTERNAL; } +static int duplicate_texture_exec(bContext *C, wmOperator *op) +{ + Tex *tex = CTX_data_pointer_get_type(C, "texture", &RNA_Texture).data; + + if (!tex) { + BKE_report(op->reports, + RPT_ERROR, + "Incorrect context for duplicating a texture (did not find texture to duplicate)"); + return OPERATOR_CANCELLED; + } + + /* add or copy texture */ + Main *bmain = CTX_data_main(C); + tex = (Tex *)BKE_id_copy(bmain, &tex->id); + + texture_creation_assign(C, tex); + + WM_event_add_notifier(C, NC_TEXTURE | NA_ADDED, tex); + + return OPERATOR_FINISHED; +} + +void TEXTURE_OT_duplicate(wmOperatorType *ot) +{ + /* identifiers */ + ot->name = "Duplicate Texture"; + ot->idname = "TEXTURE_OT_duplicate"; + ot->description = "Duplicate an existing texture"; + + /* api callbacks */ + ot->exec = duplicate_texture_exec; + + /* flags */ + ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_INTERNAL; +} + /** \} */ /* -------------------------------------------------------------------- */ -/** \name new world operator +/** \name Create world operators * \{ */ -static int new_world_exec(bContext *C, wmOperator *UNUSED(op)) +static void world_creation_assign(bContext *C, World *wo) { - World *wo = CTX_data_pointer_get_type(C, "world", &RNA_World).data; - Main *bmain = CTX_data_main(C); PointerRNA ptr, idptr; PropertyRNA *prop; - /* add or copy world */ - if (wo) { - World *new_wo = (World *)BKE_id_copy_ex( - bmain, &wo->id, NULL, LIB_ID_COPY_DEFAULT | LIB_ID_COPY_ACTIONS); - wo = new_wo; - } - else { - wo = BKE_world_add(bmain, DATA_("World")); - ED_node_shader_default(C, &wo->id); - wo->use_nodes = true; - } - /* hook into UI */ UI_context_active_but_prop_get_templateID(C, &ptr, &prop); @@ -896,6 +973,17 @@ static int new_world_exec(bContext *C, wmOperator *UNUSED(op)) RNA_property_pointer_set(&ptr, prop, idptr, NULL); RNA_property_update(C, &ptr, prop); } +} + +static int new_world_exec(bContext *C, wmOperator *UNUSED(op)) +{ + Main *bmain = CTX_data_main(C); + + World *wo = BKE_world_add(bmain, DATA_("World")); + ED_node_shader_default(C, &wo->id); + wo->use_nodes = true; + + world_creation_assign(C, wo); WM_event_add_notifier(C, NC_WORLD | NA_ADDED, wo); @@ -907,7 +995,7 @@ void WORLD_OT_new(wmOperatorType *ot) /* identifiers */ ot->name = "New World"; ot->idname = "WORLD_OT_new"; - ot->description = "Create a new world Data-Block"; + ot->description = "Create a new world data-block"; /* api callbacks */ ot->exec = new_world_exec; @@ -916,6 +1004,36 @@ void WORLD_OT_new(wmOperatorType *ot) ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_INTERNAL; } +static int duplicate_world_exec(bContext *C, wmOperator *UNUSED(op)) +{ + World *wo = CTX_data_pointer_get_type(C, "world", &RNA_World).data; + + if (wo) { + Main *bmain = CTX_data_main(C); + wo = (World *)BKE_id_copy(bmain, &wo->id); + } + + world_creation_assign(C, wo); + + WM_event_add_notifier(C, NC_WORLD | NA_ADDED, wo); + + return OPERATOR_FINISHED; +} + +void WORLD_OT_duplicate(wmOperatorType *ot) +{ + /* identifiers */ + ot->name = "Duplicate World"; + ot->idname = "WORLD_OT_duplicate"; + ot->description = "Duplicate an existing world data-block"; + + /* api callbacks */ + ot->exec = duplicate_world_exec; + + /* flags */ + ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_INTERNAL; +} + /** \} */ /* -------------------------------------------------------------------- */ diff --git a/source/blender/editors/screen/screen_ops.c b/source/blender/editors/screen/screen_ops.c index 51687d5de1d..8768404d74f 100644 --- a/source/blender/editors/screen/screen_ops.c +++ b/source/blender/editors/screen/screen_ops.c @@ -5509,7 +5509,6 @@ void ED_operatortypes_screen(void) WM_operatortype_append(ED_OT_undo_redo); WM_operatortype_append(ED_OT_undo_history); - WM_operatortype_append(ED_OT_flush_edits); WM_operatortype_append(ED_OT_lib_id_load_custom_preview); WM_operatortype_append(ED_OT_lib_id_generate_preview); } diff --git a/source/blender/editors/space_action/action_data.c b/source/blender/editors/space_action/action_data.c index 3a584a7f0cb..4d5a93f75e0 100644 --- a/source/blender/editors/space_action/action_data.c +++ b/source/blender/editors/space_action/action_data.c @@ -158,7 +158,78 @@ static void actedit_change_action(bContext *C, bAction *act) RNA_property_update(C, &ptr, prop); } -/* ******************** New Action Operator *********************** */ +/* ******************** New Action Operators *********************** */ + +static void action_creation_assign(bContext *C, + bAction *action, + PointerRNA *ptr, + PropertyRNA *prop) +{ + PointerRNA idptr; + /* Set the new action. + * NOTE: we can't use actedit_change_action, as this function is also called from the NLA. */ + RNA_id_pointer_create(&action->id, &idptr); + RNA_property_pointer_set(ptr, prop, idptr, NULL); + RNA_property_update(C, ptr, prop); +} + +/** + * Stash the previously active action to prevent it from being lost. + * \return The old action if any. + */ +static bAction *action_creation_stash_old(bContext *C, PointerRNA *ptr, PropertyRNA *prop) +{ + bAction *oldact = NULL; + AnimData *adt = NULL; + + if (prop) { + /* The operator was called from a button. */ + PointerRNA oldptr; + + oldptr = RNA_property_pointer_get(ptr, prop); + oldact = (bAction *)oldptr.owner_id; + + /* stash the old action to prevent it from being lost */ + if (ptr->type == &RNA_AnimData) { + adt = ptr->data; + } + else if (ptr->type == &RNA_SpaceDopeSheetEditor) { + adt = ED_actedit_animdata_from_context(C); + } + } + else { + adt = ED_actedit_animdata_from_context(C); + oldact = adt->action; + } + + if (!adt || !oldact) { + /* Found nothing to stash in current context. */ + return NULL; + } + + /* Perform stashing operation. */ + if (BKE_nla_action_stash(adt, ID_IS_OVERRIDE_LIBRARY(ptr->owner_id))) { + /* The stash operation will remove the user already + * (and unlink the action from the AnimData action slot). + * Hence, we must unset the ref to the action in the + * action editor too (if this is where we're being called from) + * first before setting the new action once it is created, + * or else the user gets decremented twice! + */ + if (ptr->type == &RNA_SpaceDopeSheetEditor) { + SpaceAction *saction = ptr->data; + saction->action = NULL; + } + } + else { +#if 0 + printf("WARNING: Failed to stash %s. It may already exist in the NLA stack though\n", + oldact->id.name); +#endif + } + + return oldact; +} /* Criteria: * 1) There must be an dopesheet/action editor, and it must be in a mode which uses actions... @@ -207,71 +278,17 @@ static bool action_new_poll(bContext *C) static int action_new_exec(bContext *C, wmOperator *UNUSED(op)) { - PointerRNA ptr, idptr; + PointerRNA ptr; PropertyRNA *prop; - bAction *oldact = NULL; - AnimData *adt = NULL; /* hook into UI */ UI_context_active_but_prop_get_templateID(C, &ptr, &prop); - if (prop) { - /* The operator was called from a button. */ - PointerRNA oldptr; - - oldptr = RNA_property_pointer_get(&ptr, prop); - oldact = (bAction *)oldptr.owner_id; - - /* stash the old action to prevent it from being lost */ - if (ptr.type == &RNA_AnimData) { - adt = ptr.data; - } - else if (ptr.type == &RNA_SpaceDopeSheetEditor) { - adt = ED_actedit_animdata_from_context(C); - } - } - else { - adt = ED_actedit_animdata_from_context(C); - oldact = adt->action; - } - { - bAction *action = NULL; - - /* Perform stashing operation - But only if there is an action */ - if (adt && oldact) { - /* stash the action */ - if (BKE_nla_action_stash(adt, ID_IS_OVERRIDE_LIBRARY(ptr.owner_id))) { - /* The stash operation will remove the user already - * (and unlink the action from the AnimData action slot). - * Hence, we must unset the ref to the action in the - * action editor too (if this is where we're being called from) - * first before setting the new action once it is created, - * or else the user gets decremented twice! - */ - if (ptr.type == &RNA_SpaceDopeSheetEditor) { - SpaceAction *saction = ptr.data; - saction->action = NULL; - } - } - else { -#if 0 - printf("WARNING: Failed to stash %s. It may already exist in the NLA stack though\n", - oldact->id.name); -#endif - } - } - - /* create action */ - action = action_create_new(C, oldact); + action_creation_stash_old(C, &ptr, prop); - if (prop) { - /* set this new action - * NOTE: we can't use actedit_change_action, as this function is also called from the NLA - */ - RNA_id_pointer_create(&action->id, &idptr); - RNA_property_pointer_set(&ptr, prop, idptr, NULL); - RNA_property_update(C, &ptr, prop); - } + bAction *action = action_create_new(C, NULL); + if (prop) { + action_creation_assign(C, action, &ptr, prop); } /* set notifier that keyframes have changed */ @@ -285,7 +302,7 @@ void ACTION_OT_new(wmOperatorType *ot) /* identifiers */ ot->name = "New Action"; ot->idname = "ACTION_OT_new"; - ot->description = "Create new action"; + ot->description = "Create a new action"; /* api callbacks */ ot->exec = action_new_exec; @@ -295,6 +312,45 @@ void ACTION_OT_new(wmOperatorType *ot) ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; } +static int action_duplicate_assign_exec(bContext *C, wmOperator *UNUSED(op)) +{ + PointerRNA ptr; + PropertyRNA *prop; + + /* hook into UI */ + UI_context_active_but_prop_get_templateID(C, &ptr, &prop); + + bAction *old_action = action_creation_stash_old(C, &ptr, prop); + + bAction *new_action = action_create_new(C, old_action); + if (prop) { + action_creation_assign(C, new_action, &ptr, prop); + } + + /* set notifier that keyframes have changed */ + WM_event_add_notifier(C, NC_ANIMATION | ND_KEYFRAME | NA_ADDED, NULL); + + return OPERATOR_FINISHED; +} + +/** + * Duplicate an action assigned to a templateID and update it's assignment - based on UI context. + */ +void ACTION_OT_duplicate_assign(wmOperatorType *ot) +{ + /* identifiers */ + ot->name = "Duplicate & Assign Action"; + ot->idname = "ACTION_OT_duplicate_assign"; + ot->description = "Create a copy of an existing action and assign it"; + + /* api callbacks */ + ot->exec = action_duplicate_assign_exec; + ot->poll = action_new_poll; + + /* flags */ + ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_INTERNAL; +} + /* ******************* Action Push-Down Operator ******************** */ /* Criteria: diff --git a/source/blender/editors/space_action/action_intern.h b/source/blender/editors/space_action/action_intern.h index ffe0606c98f..4bce6c62a1a 100644 --- a/source/blender/editors/space_action/action_intern.h +++ b/source/blender/editors/space_action/action_intern.h @@ -106,6 +106,7 @@ void ACTION_OT_snap(struct wmOperatorType *ot); void ACTION_OT_mirror(struct wmOperatorType *ot); void ACTION_OT_new(struct wmOperatorType *ot); +void ACTION_OT_duplicate_assign(struct wmOperatorType *ot); void ACTION_OT_unlink(struct wmOperatorType *ot); void ACTION_OT_push_down(struct wmOperatorType *ot); diff --git a/source/blender/editors/space_action/action_ops.c b/source/blender/editors/space_action/action_ops.c index 7422c05511c..329c3a9f6f6 100644 --- a/source/blender/editors/space_action/action_ops.c +++ b/source/blender/editors/space_action/action_ops.c @@ -73,7 +73,9 @@ void action_operatortypes(void) WM_operatortype_append(ACTION_OT_copy); WM_operatortype_append(ACTION_OT_paste); + /* UI-context based operators. */ WM_operatortype_append(ACTION_OT_new); + WM_operatortype_append(ACTION_OT_duplicate_assign); WM_operatortype_append(ACTION_OT_unlink); WM_operatortype_append(ACTION_OT_push_down); diff --git a/source/blender/editors/space_api/spacetypes.c b/source/blender/editors/space_api/spacetypes.c index 0fe94ec382c..10fa2c19919 100644 --- a/source/blender/editors/space_api/spacetypes.c +++ b/source/blender/editors/space_api/spacetypes.c @@ -65,6 +65,7 @@ #include "ED_space_api.h" #include "ED_transform.h" #include "ED_userpref.h" +#include "ED_util.h" #include "ED_uvedit.h" #include "io_ops.h" @@ -124,6 +125,7 @@ void ED_spacetypes_init(void) ED_operatortypes_render(); ED_operatortypes_mask(); ED_operatortypes_io(); + ED_operatortypes_edutils(); ED_operatortypes_view2d(); ED_operatortypes_ui(); diff --git a/source/blender/editors/space_clip/clip_buttons.c b/source/blender/editors/space_clip/clip_buttons.c index a95d0e3ea88..e0f603eb3d1 100644 --- a/source/blender/editors/space_clip/clip_buttons.c +++ b/source/blender/editors/space_clip/clip_buttons.c @@ -140,6 +140,7 @@ void uiTemplateMovieClip( ptr, propname, NULL, + NULL, "CLIP_OT_open", NULL, UI_TEMPLATE_ID_FILTER_ALL, diff --git a/source/blender/editors/space_file/file_panels.c b/source/blender/editors/space_file/file_panels.c index afa85d183d8..411f99cc3b4 100644 --- a/source/blender/editors/space_file/file_panels.c +++ b/source/blender/editors/space_file/file_panels.c @@ -180,11 +180,16 @@ static void file_panel_execution_buttons_draw(const bContext *C, Panel *panel) UI_but_funcN_set(but, file_filename_enter_handle, NULL, but); if (params->flag & FILE_CHECK_EXISTING) { - but_extra_rna_ptr = UI_but_extra_operator_icon_add( + uiButExtraOpIcon *extra_icon; + + extra_icon = UI_but_extra_operator_icon_add( but, "FILE_OT_filenum", WM_OP_EXEC_REGION_WIN, ICON_REMOVE); + but_extra_rna_ptr = UI_but_extra_operator_icon_opptr_get(extra_icon); RNA_int_set(but_extra_rna_ptr, "increment", -1); - but_extra_rna_ptr = UI_but_extra_operator_icon_add( + + extra_icon = UI_but_extra_operator_icon_add( but, "FILE_OT_filenum", WM_OP_EXEC_REGION_WIN, ICON_ADD); + but_extra_rna_ptr = UI_but_extra_operator_icon_opptr_get(extra_icon); RNA_int_set(but_extra_rna_ptr, "increment", 1); } diff --git a/source/blender/editors/space_image/image_buttons.c b/source/blender/editors/space_image/image_buttons.c index c0c0280959c..f8f25e399eb 100644 --- a/source/blender/editors/space_image/image_buttons.c +++ b/source/blender/editors/space_image/image_buttons.c @@ -806,7 +806,8 @@ void uiTemplateImage(uiLayout *layout, C, ptr, propname, - ima ? NULL : "IMAGE_OT_new", + "IMAGE_OT_new", + NULL, "IMAGE_OT_open", NULL, UI_TEMPLATE_ID_FILTER_ALL, diff --git a/source/blender/editors/space_nla/nla_buttons.c b/source/blender/editors/space_nla/nla_buttons.c index 083fd641dc1..1d7e5448b92 100644 --- a/source/blender/editors/space_nla/nla_buttons.c +++ b/source/blender/editors/space_nla/nla_buttons.c @@ -292,8 +292,9 @@ static void nla_panel_animdata(const bContext *C, Panel *panel) (bContext *)C, &adt_ptr, "action", - "ACTION_OT_new", NULL, + "ACTION_OT_new", + "ACTION_OT_duplicate_assign", "NLA_OT_action_unlink", UI_TEMPLATE_ID_FILTER_ALL, false, diff --git a/source/blender/editors/space_node/drawnode.c b/source/blender/editors/space_node/drawnode.c index 652c70155ab..421e66604e4 100644 --- a/source/blender/editors/space_node/drawnode.c +++ b/source/blender/editors/space_node/drawnode.c @@ -771,6 +771,7 @@ static void node_shader_buts_tex_image(uiLayout *layout, bContext *C, PointerRNA ptr, "image", "IMAGE_OT_new", + NULL, "IMAGE_OT_open", NULL, UI_TEMPLATE_ID_FILTER_ALL, @@ -808,6 +809,7 @@ static void node_shader_buts_tex_environment(uiLayout *layout, bContext *C, Poin ptr, "image", "IMAGE_OT_new", + NULL, "IMAGE_OT_open", NULL, UI_TEMPLATE_ID_FILTER_ALL, @@ -1395,6 +1397,7 @@ static void node_composit_buts_image(uiLayout *layout, bContext *C, PointerRNA * ptr, "image", "IMAGE_OT_new", + NULL, "IMAGE_OT_open", NULL, UI_TEMPLATE_ID_FILTER_ALL, @@ -1426,7 +1429,8 @@ static void node_composit_buts_viewlayers(uiLayout *layout, bContext *C, Pointer bNode *node = ptr->data; uiLayout *col, *row; - uiTemplateID(layout, C, ptr, "scene", NULL, NULL, NULL, UI_TEMPLATE_ID_FILTER_ALL, false, NULL); + uiTemplateID( + layout, C, ptr, "scene", NULL, NULL, NULL, NULL, UI_TEMPLATE_ID_FILTER_ALL, false, NULL); if (!node->id) { return; @@ -1548,7 +1552,8 @@ static void node_composit_buts_defocus(uiLayout *layout, bContext *C, PointerRNA col = uiLayoutColumn(layout, false); uiItemR(col, ptr, "use_preview", DEFAULT_FLAGS, NULL, ICON_NONE); - uiTemplateID(layout, C, ptr, "scene", NULL, NULL, NULL, UI_TEMPLATE_ID_FILTER_ALL, false, NULL); + uiTemplateID( + layout, C, ptr, "scene", NULL, NULL, NULL, NULL, UI_TEMPLATE_ID_FILTER_ALL, false, NULL); col = uiLayoutColumn(layout, false); uiItemR(col, ptr, "use_zbuffer", DEFAULT_FLAGS, NULL, ICON_NONE); @@ -2163,8 +2168,17 @@ static void node_composit_buts_ycc(uiLayout *layout, bContext *UNUSED(C), Pointe static void node_composit_buts_movieclip(uiLayout *layout, bContext *C, PointerRNA *ptr) { - uiTemplateID( - layout, C, ptr, "clip", NULL, "CLIP_OT_open", NULL, UI_TEMPLATE_ID_FILTER_ALL, false, NULL); + uiTemplateID(layout, + C, + ptr, + "clip", + NULL, + NULL, + "CLIP_OT_open", + NULL, + UI_TEMPLATE_ID_FILTER_ALL, + false, + NULL); } static void node_composit_buts_movieclip_ex(uiLayout *layout, bContext *C, PointerRNA *ptr) @@ -2172,8 +2186,17 @@ static void node_composit_buts_movieclip_ex(uiLayout *layout, bContext *C, Point bNode *node = ptr->data; PointerRNA clipptr; - uiTemplateID( - layout, C, ptr, "clip", NULL, "CLIP_OT_open", NULL, UI_TEMPLATE_ID_FILTER_ALL, false, NULL); + uiTemplateID(layout, + C, + ptr, + "clip", + NULL, + NULL, + "CLIP_OT_open", + NULL, + UI_TEMPLATE_ID_FILTER_ALL, + false, + NULL); if (!node->id) { return; @@ -2188,8 +2211,17 @@ static void node_composit_buts_stabilize2d(uiLayout *layout, bContext *C, Pointe { bNode *node = ptr->data; - uiTemplateID( - layout, C, ptr, "clip", NULL, "CLIP_OT_open", NULL, UI_TEMPLATE_ID_FILTER_ALL, false, NULL); + uiTemplateID(layout, + C, + ptr, + "clip", + NULL, + NULL, + "CLIP_OT_open", + NULL, + UI_TEMPLATE_ID_FILTER_ALL, + false, + NULL); if (!node->id) { return; @@ -2214,8 +2246,17 @@ static void node_composit_buts_moviedistortion(uiLayout *layout, bContext *C, Po { bNode *node = ptr->data; - uiTemplateID( - layout, C, ptr, "clip", NULL, "CLIP_OT_open", NULL, UI_TEMPLATE_ID_FILTER_ALL, false, NULL); + uiTemplateID(layout, + C, + ptr, + "clip", + NULL, + NULL, + "CLIP_OT_open", + NULL, + UI_TEMPLATE_ID_FILTER_ALL, + false, + NULL); if (!node->id) { return; @@ -2538,7 +2579,8 @@ static void node_composit_buts_mask(uiLayout *layout, bContext *C, PointerRNA *p { bNode *node = ptr->data; - uiTemplateID(layout, C, ptr, "mask", NULL, NULL, NULL, UI_TEMPLATE_ID_FILTER_ALL, false, NULL); + uiTemplateID( + layout, C, ptr, "mask", NULL, NULL, NULL, NULL, UI_TEMPLATE_ID_FILTER_ALL, false, NULL); uiItemR(layout, ptr, "use_feather", DEFAULT_FLAGS, NULL, ICON_NONE); uiItemR(layout, ptr, "size_source", DEFAULT_FLAGS, "", ICON_NONE); @@ -2559,7 +2601,8 @@ static void node_composit_buts_keyingscreen(uiLayout *layout, bContext *C, Point { bNode *node = ptr->data; - uiTemplateID(layout, C, ptr, "clip", NULL, NULL, NULL, UI_TEMPLATE_ID_FILTER_ALL, false, NULL); + uiTemplateID( + layout, C, ptr, "clip", NULL, NULL, NULL, NULL, UI_TEMPLATE_ID_FILTER_ALL, false, NULL); if (node->id) { MovieClip *clip = (MovieClip *)node->id; @@ -2595,8 +2638,17 @@ static void node_composit_buts_trackpos(uiLayout *layout, bContext *C, PointerRN { bNode *node = ptr->data; - uiTemplateID( - layout, C, ptr, "clip", NULL, "CLIP_OT_open", NULL, UI_TEMPLATE_ID_FILTER_ALL, false, NULL); + uiTemplateID(layout, + C, + ptr, + "clip", + NULL, + NULL, + "CLIP_OT_open", + NULL, + UI_TEMPLATE_ID_FILTER_ALL, + false, + NULL); if (node->id) { MovieClip *clip = (MovieClip *)node->id; @@ -2636,8 +2688,17 @@ static void node_composit_buts_planetrackdeform(uiLayout *layout, bContext *C, P bNode *node = ptr->data; NodePlaneTrackDeformData *data = node->storage; - uiTemplateID( - layout, C, ptr, "clip", NULL, "CLIP_OT_open", NULL, UI_TEMPLATE_ID_FILTER_ALL, false, NULL); + uiTemplateID(layout, + C, + ptr, + "clip", + NULL, + NULL, + "CLIP_OT_open", + NULL, + UI_TEMPLATE_ID_FILTER_ALL, + false, + NULL); if (node->id) { MovieClip *clip = (MovieClip *)node->id; @@ -3072,6 +3133,7 @@ static void node_texture_buts_image(uiLayout *layout, bContext *C, PointerRNA *p ptr, "image", "IMAGE_OT_new", + NULL, "IMAGE_OT_open", NULL, UI_TEMPLATE_ID_FILTER_ALL, diff --git a/source/blender/editors/util/CMakeLists.txt b/source/blender/editors/util/CMakeLists.txt index bbaf5d5475a..0aab3810254 100644 --- a/source/blender/editors/util/CMakeLists.txt +++ b/source/blender/editors/util/CMakeLists.txt @@ -39,6 +39,7 @@ set(SRC ed_transverts.c ed_util.c ed_util_imbuf.c + ed_util_ops.c gizmo_utils.c numinput.c select_utils.c diff --git a/source/blender/editors/util/ed_util.c b/source/blender/editors/util/ed_util.c index d78758dcc1c..5d2584c566d 100644 --- a/source/blender/editors/util/ed_util.c +++ b/source/blender/editors/util/ed_util.c @@ -485,27 +485,6 @@ void ED_spacedata_id_remap(struct ScrArea *area, struct SpaceLink *sl, ID *old_i } } -static int ed_flush_edits_exec(bContext *C, wmOperator *UNUSED(op)) -{ - Main *bmain = CTX_data_main(C); - ED_editors_flush_edits(bmain); - return OPERATOR_FINISHED; -} - -void ED_OT_flush_edits(wmOperatorType *ot) -{ - /* identifiers */ - ot->name = "Flush Edits"; - ot->description = "Flush edit data from active editing modes"; - ot->idname = "ED_OT_flush_edits"; - - /* api callbacks */ - ot->exec = ed_flush_edits_exec; - - /* flags */ - ot->flag = OPTYPE_INTERNAL; -} - static bool lib_id_preview_editing_poll(bContext *C) { const PointerRNA idptr = CTX_data_pointer_get(C, "id"); diff --git a/source/blender/editors/util/ed_util_ops.c b/source/blender/editors/util/ed_util_ops.c new file mode 100644 index 00000000000..d8d1a64c1ee --- /dev/null +++ b/source/blender/editors/util/ed_util_ops.c @@ -0,0 +1,155 @@ +/* + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +/** \file + * \ingroup edutil + * + * Utility operators for UI data or for the UI to use. + */ + +#include + +#include "BLI_utildefines.h" + +#include "BKE_context.h" +#include "BKE_lib_id.h" +#include "BKE_main.h" +#include "BKE_report.h" + +#include "DNA_windowmanager_types.h" + +#include "ED_util.h" + +#include "RNA_access.h" + +#include "UI_interface.h" + +#include "WM_api.h" +#include "WM_types.h" + +static int lib_fake_user_toggle_exec(bContext *C, wmOperator *op) +{ + PropertyPointerRNA pprop; + PointerRNA idptr = PointerRNA_NULL; + + UI_context_active_but_prop_get_templateID(C, &pprop.ptr, &pprop.prop); + + if (pprop.prop) { + idptr = RNA_property_pointer_get(&pprop.ptr, pprop.prop); + } + + if ((pprop.prop == NULL) || RNA_pointer_is_null(&idptr) || !RNA_struct_is_ID(idptr.type)) { + BKE_report( + op->reports, RPT_ERROR, "Incorrect context for running data-block fake user toggling"); + return OPERATOR_CANCELLED; + } + + ID *id = idptr.data; + + if ((id->lib != NULL) || (ELEM(GS(id->name), ID_GR, ID_SCE, ID_SCR, ID_TXT, ID_OB, ID_WS))) { + BKE_report(op->reports, RPT_ERROR, "Data-block type does not support fake user"); + return OPERATOR_CANCELLED; + } + + if (ID_FAKE_USERS(id)) { + id_fake_user_clear(id); + } + else { + id_fake_user_set(id); + } + + return OPERATOR_FINISHED; +} + +static void ED_OT_lib_fake_user_toggle(wmOperatorType *ot) +{ + /* identifiers */ + ot->name = "Toggle Fake User"; + ot->description = "Save this data-block even if it has no users"; + ot->idname = "ED_OT_lib_fake_user_toggle"; + + /* api callbacks */ + ot->exec = lib_fake_user_toggle_exec; + + /* flags */ + ot->flag = OPTYPE_UNDO | OPTYPE_INTERNAL; +} + +static int lib_unlink_exec(bContext *C, wmOperator *op) +{ + PropertyPointerRNA pprop; + PointerRNA idptr; + + UI_context_active_but_prop_get_templateID(C, &pprop.ptr, &pprop.prop); + + if (pprop.prop) { + idptr = RNA_property_pointer_get(&pprop.ptr, pprop.prop); + } + + if ((pprop.prop == NULL) || RNA_pointer_is_null(&idptr) || !RNA_struct_is_ID(idptr.type)) { + BKE_report( + op->reports, RPT_ERROR, "Incorrect context for running data-block fake user toggling"); + return OPERATOR_CANCELLED; + } + + memset(&idptr, 0, sizeof(idptr)); + RNA_property_pointer_set(&pprop.ptr, pprop.prop, idptr, NULL); + RNA_property_update(C, &pprop.ptr, pprop.prop); + + return OPERATOR_FINISHED; +} + +static void ED_OT_lib_unlink(wmOperatorType *ot) +{ + /* identifiers */ + ot->name = "Unlink Data-Block"; + ot->description = "Remove a usage of a data-block, clearing the assignment"; + ot->idname = "ED_OT_lib_unlink"; + + /* api callbacks */ + ot->exec = lib_unlink_exec; + + /* flags */ + ot->flag = OPTYPE_UNDO | OPTYPE_INTERNAL; +} + +static int ed_flush_edits_exec(bContext *C, wmOperator *UNUSED(op)) +{ + Main *bmain = CTX_data_main(C); + ED_editors_flush_edits(bmain); + return OPERATOR_FINISHED; +} + +static void ED_OT_flush_edits(wmOperatorType *ot) +{ + /* identifiers */ + ot->name = "Flush Edits"; + ot->description = "Flush edit data from active editing modes"; + ot->idname = "ED_OT_flush_edits"; + + /* api callbacks */ + ot->exec = ed_flush_edits_exec; + + /* flags */ + ot->flag = OPTYPE_INTERNAL; +} + +void ED_operatortypes_edutils(void) +{ + WM_operatortype_append(ED_OT_lib_fake_user_toggle); + WM_operatortype_append(ED_OT_lib_unlink); + WM_operatortype_append(ED_OT_flush_edits); +} -- cgit v1.2.3 From 6be9747b9622e9ea0bacdc7f94b4f575feb659aa Mon Sep 17 00:00:00 2001 From: Hans Goudey Date: Fri, 18 Dec 2020 12:12:32 -0600 Subject: Cleanup: Use bool instead of int --- source/blender/editors/interface/interface_layout.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source/blender/editors') diff --git a/source/blender/editors/interface/interface_layout.c b/source/blender/editors/interface/interface_layout.c index 4b19b8f97f4..b3c34b3fb43 100644 --- a/source/blender/editors/interface/interface_layout.c +++ b/source/blender/editors/interface/interface_layout.c @@ -5485,8 +5485,8 @@ uiLayout *UI_block_layout(uiBlock *block, layout->y = y; layout->root = root; layout->space = style->templatespace; - layout->active = 1; - layout->enabled = 1; + layout->active = true; + layout->enabled = true; layout->context = NULL; layout->emboss = UI_EMBOSS_UNDEFINED; -- cgit v1.2.3 From e2983392894e380203966e49b2caa3807a661eb9 Mon Sep 17 00:00:00 2001 From: Hans Goudey Date: Fri, 18 Dec 2020 12:39:50 -0600 Subject: Cleanup: Declare variables where initialized Also decrease scope of some variable declarations. --- .../blender/editors/interface/interface_layout.c | 183 ++++++++------------- 1 file changed, 71 insertions(+), 112 deletions(-) (limited to 'source/blender/editors') diff --git a/source/blender/editors/interface/interface_layout.c b/source/blender/editors/interface/interface_layout.c index b3c34b3fb43..3b366688e59 100644 --- a/source/blender/editors/interface/interface_layout.c +++ b/source/blender/editors/interface/interface_layout.c @@ -3457,8 +3457,6 @@ static void menu_item_enum_rna_menu(bContext *UNUSED(C), uiLayout *layout, void void uiItemMenuEnumR_prop( uiLayout *layout, struct PointerRNA *ptr, PropertyRNA *prop, const char *name, int icon) { - MenuItemLevel *lvl; - if (!name) { name = RNA_property_ui_name(prop); } @@ -3466,7 +3464,7 @@ void uiItemMenuEnumR_prop( icon = ICON_BLANK1; } - lvl = MEM_callocN(sizeof(MenuItemLevel), "MenuItemLevel"); + MenuItemLevel *lvl = MEM_callocN(sizeof(MenuItemLevel), "MenuItemLevel"); lvl->rnapoin = *ptr; BLI_strncpy(lvl->propname, RNA_property_identifier(prop), sizeof(lvl->propname)); lvl->opcontext = layout->root->opcontext; @@ -3550,15 +3548,15 @@ static int ui_litem_min_width(int itemw) static void ui_litem_layout_row(uiLayout *litem) { uiItem *last_free_item = NULL; - int x, y, w, tot, totw, neww, newtotw, itemw, minw, itemh, offset; - int fixedw, freew, fixedx, freex, flag = 0, lastw = 0; + int x, neww, newtotw, itemw, minw, itemh, offset; + int freew, fixedx, freex, flag = 0, lastw = 0; float extra_pixel; /* x = litem->x; */ /* UNUSED */ - y = litem->y; - w = litem->w; - totw = 0; - tot = 0; + int y = litem->y; + int w = litem->w; + int totw = 0; + int tot = 0; LISTBASE_FOREACH (uiItem *, item, &litem->items) { ui_item_size(item, &itemw, &itemh); @@ -3573,7 +3571,7 @@ static void ui_litem_layout_row(uiLayout *litem) if (w != 0) { w -= (tot - 1) * litem->space; } - fixedw = 0; + int fixedw = 0; /* keep clamping items to fixed minimum size until all are done */ do { @@ -3724,12 +3722,11 @@ static void ui_litem_estimate_column(uiLayout *litem, bool is_box) static void ui_litem_layout_column(uiLayout *litem, bool is_box, bool is_menu) { - int itemw, itemh, x, y; - - x = litem->x; - y = litem->y; + int x = litem->x; + int y = litem->y; LISTBASE_FOREACH (uiItem *, item, &litem->items) { + int itemw, itemh; ui_item_size(item, &itemw, &itemh); y -= itemh; @@ -3753,15 +3750,13 @@ static void ui_litem_layout_column(uiLayout *litem, bool is_box, bool is_menu) * stores a float vector in unit circle */ static RadialDirection ui_get_radialbut_vec(float vec[2], short itemnum) { - RadialDirection dir; - if (itemnum >= PIE_MAX_ITEMS) { itemnum %= PIE_MAX_ITEMS; printf("Warning: Pie menus with more than %i items are currently unsupported\n", PIE_MAX_ITEMS); } - dir = ui_radial_dir_order[itemnum]; + RadialDirection dir = ui_radial_dir_order[itemnum]; ui_but_pie_dir(dir, vec); return dir; @@ -3789,7 +3784,7 @@ static bool ui_item_is_radial_drawable(uiButtonItem *bitem) static void ui_litem_layout_radial(uiLayout *litem) { - int itemh, itemw, x, y; + int itemh, itemw; int itemnum = 0; int totitems = 0; @@ -3800,8 +3795,8 @@ static void ui_litem_layout_radial(uiLayout *litem) const int pie_radius = U.pie_menu_radius * UI_DPI_FAC; - x = litem->x; - y = litem->y; + int x = litem->x; + int y = litem->y; int minx = x, miny = y, maxx = x, maxy = y; @@ -3921,16 +3916,14 @@ static void ui_litem_layout_box(uiLayout *litem) { uiLayoutItemBx *box = (uiLayoutItemBx *)litem; const uiStyle *style = litem->root->style; - uiBut *but; - int w, h; int boxspace = style->boxspace; if (litem->root->type == UI_LAYOUT_HEADER) { boxspace = 0; } - w = litem->w; - h = litem->h; + int w = litem->w; + int h = litem->h; litem->x += boxspace; litem->y -= boxspace; @@ -3955,7 +3948,7 @@ static void ui_litem_layout_box(uiLayout *litem) } /* roundbox around the sublayout */ - but = box->roundbox; + uiBut *but = box->roundbox; but->rect.xmin = litem->x; but->rect.ymin = litem->y; but->rect.xmax = litem->x + litem->w; @@ -3967,12 +3960,11 @@ static void ui_litem_estimate_column_flow(uiLayout *litem) { const uiStyle *style = litem->root->style; uiLayoutItemFlow *flow = (uiLayoutItemFlow *)litem; - int col, x, y, emh, emy, miny, itemw, itemh, maxw = 0; - int toth, totitem; + int itemw, itemh, maxw = 0; /* compute max needed width and total height */ - toth = 0; - totitem = 0; + int toth = 0; + int totitem = 0; LISTBASE_FOREACH (uiItem *, item, &litem->items) { ui_item_size(item, &itemw, &itemh); maxw = MAX2(maxw, itemw); @@ -3995,16 +3987,16 @@ static void ui_litem_estimate_column_flow(uiLayout *litem) } /* compute sizes */ - x = 0; - y = 0; - emy = 0; - miny = 0; + int x = 0; + int y = 0; + int emy = 0; + int miny = 0; maxw = 0; - emh = toth / flow->totcol; + int emh = toth / flow->totcol; /* create column per column */ - col = 0; + int col = 0; LISTBASE_FOREACH (uiItem *, item, &litem->items) { ui_item_size(item, &itemw, &itemh); @@ -4031,12 +4023,11 @@ static void ui_litem_layout_column_flow(uiLayout *litem) { const uiStyle *style = litem->root->style; uiLayoutItemFlow *flow = (uiLayoutItemFlow *)litem; - int col, x, y, w, emh, emy, miny, itemw, itemh; - int toth, totitem; + int col, emh, itemw, itemh; /* compute max needed width and total height */ - toth = 0; - totitem = 0; + int toth = 0; + int totitem = 0; LISTBASE_FOREACH (uiItem *, item, &litem->items) { ui_item_size(item, &itemw, &itemh); toth += itemh; @@ -4044,12 +4035,12 @@ static void ui_litem_layout_column_flow(uiLayout *litem) } /* compute sizes */ - x = litem->x; - y = litem->y; - emy = 0; - miny = 0; + int x = litem->x; + int y = litem->y; + int emy = 0; + int miny = 0; - w = litem->w - (flow->totcol - 1) * style->columnspace; + int w = litem->w - (flow->totcol - 1) * style->columnspace; emh = toth / flow->totcol; /* create column per column */ @@ -4457,14 +4448,13 @@ static void ui_litem_layout_grid_flow(uiLayout *litem) /* free layout */ static void ui_litem_estimate_absolute(uiLayout *litem) { - int itemx, itemy, itemw, itemh, minx, miny; - - minx = 1e6; - miny = 1e6; + int minx = 1e6; + int miny = 1e6; litem->w = 0; litem->h = 0; LISTBASE_FOREACH (uiItem *, item, &litem->items) { + int itemx, itemy, itemw, itemh; ui_item_offset(item, &itemx, &itemy); ui_item_size(item, &itemw, &itemh); @@ -4482,12 +4472,12 @@ static void ui_litem_estimate_absolute(uiLayout *litem) static void ui_litem_layout_absolute(uiLayout *litem) { float scalex = 1.0f, scaley = 1.0f; - int x, y, newx, newy, itemx, itemy, itemh, itemw, minx, miny, totw, toth; + int x, y, newx, newy, itemx, itemy, itemh, itemw; - minx = 1e6; - miny = 1e6; - totw = 0; - toth = 0; + int minx = 1e6; + int miny = 1e6; + int totw = 0; + int toth = 0; LISTBASE_FOREACH (uiItem *, item, &litem->items) { ui_item_offset(item, &itemx, &itemy); @@ -4548,24 +4538,24 @@ static void ui_litem_estimate_split(uiLayout *litem) static void ui_litem_layout_split(uiLayout *litem) { uiLayoutItemSplit *split = (uiLayoutItemSplit *)litem; - float percentage, extra_pixel = 0.0f; + float extra_pixel = 0.0f; const int tot = BLI_listbase_count(&litem->items); - int itemh, x, y, w, colw = 0; if (tot == 0) { return; } - x = litem->x; - y = litem->y; + int x = litem->x; + int y = litem->y; - percentage = (split->percentage == 0.0f) ? 1.0f / (float)tot : split->percentage; + float percentage = (split->percentage == 0.0f) ? 1.0f / (float)tot : split->percentage; - w = (litem->w - (tot - 1) * litem->space); - colw = w * percentage; + int w = (litem->w - (tot - 1) * litem->space); + int colw = w * percentage; colw = MAX2(colw, 0); LISTBASE_FOREACH (uiItem *, item, &litem->items) { + int itemh; ui_item_size(item, NULL, &itemh); ui_item_position(item, x, y - itemh, colw, itemh); @@ -4590,12 +4580,11 @@ static void ui_litem_layout_split(uiLayout *litem) /* overlap layout */ static void ui_litem_estimate_overlap(uiLayout *litem) { - int itemw, itemh; - litem->w = 0; litem->h = 0; LISTBASE_FOREACH (uiItem *, item, &litem->items) { + int itemw, itemh; ui_item_size(item, &itemw, &itemh); litem->w = MAX2(itemw, litem->w); @@ -4605,12 +4594,12 @@ static void ui_litem_estimate_overlap(uiLayout *litem) static void ui_litem_layout_overlap(uiLayout *litem) { - int itemw, itemh, x, y; - x = litem->x; - y = litem->y; + int x = litem->x; + int y = litem->y; LISTBASE_FOREACH (uiItem *, item, &litem->items) { + int itemw, itemh; ui_item_size(item, &itemw, &itemh); ui_item_position(item, x, y - itemh, litem->w, itemh); @@ -4657,9 +4646,7 @@ static void ui_layout_heading_set(uiLayout *layout, const char *heading) /* layout create functions */ uiLayout *uiLayoutRow(uiLayout *layout, bool align) { - uiLayout *litem; - - litem = MEM_callocN(sizeof(uiLayout), "uiLayoutRow"); + uiLayout *litem = MEM_callocN(sizeof(uiLayout), "uiLayoutRow"); ui_litem_init_from_parent(litem, layout, align); litem->item.type = ITEM_LAYOUT_ROW; @@ -4682,9 +4669,7 @@ uiLayout *uiLayoutRowWithHeading(uiLayout *layout, bool align, const char *headi uiLayout *uiLayoutColumn(uiLayout *layout, bool align) { - uiLayout *litem; - - litem = MEM_callocN(sizeof(uiLayout), "uiLayoutColumn"); + uiLayout *litem = MEM_callocN(sizeof(uiLayout), "uiLayoutColumn"); ui_litem_init_from_parent(litem, layout, align); litem->item.type = ITEM_LAYOUT_COLUMN; @@ -4710,9 +4695,7 @@ uiLayout *uiLayoutColumnWithHeading(uiLayout *layout, bool align, const char *he uiLayout *uiLayoutColumnFlow(uiLayout *layout, int number, bool align) { - uiLayoutItemFlow *flow; - - flow = MEM_callocN(sizeof(uiLayoutItemFlow), "uiLayoutItemFlow"); + uiLayoutItemFlow *flow = MEM_callocN(sizeof(uiLayoutItemFlow), "uiLayoutItemFlow"); ui_litem_init_from_parent(&flow->litem, layout, align); flow->litem.item.type = ITEM_LAYOUT_COLUMN_FLOW; @@ -4731,9 +4714,7 @@ uiLayout *uiLayoutGridFlow(uiLayout *layout, bool even_rows, bool align) { - uiLayoutItemGridFlow *flow; - - flow = MEM_callocN(sizeof(uiLayoutItemGridFlow), __func__); + uiLayoutItemGridFlow *flow = MEM_callocN(sizeof(uiLayoutItemGridFlow), __func__); flow->litem.item.type = ITEM_LAYOUT_GRID_FLOW; ui_litem_init_from_parent(&flow->litem, layout, align); @@ -4750,9 +4731,7 @@ uiLayout *uiLayoutGridFlow(uiLayout *layout, static uiLayoutItemBx *ui_layout_box(uiLayout *layout, int type) { - uiLayoutItemBx *box; - - box = MEM_callocN(sizeof(uiLayoutItemBx), "uiLayoutItemBx"); + uiLayoutItemBx *box = MEM_callocN(sizeof(uiLayoutItemBx), "uiLayoutItemBx"); ui_litem_init_from_parent(&box->litem, layout, false); box->litem.item.type = ITEM_LAYOUT_BOX; @@ -4767,8 +4746,6 @@ static uiLayoutItemBx *ui_layout_box(uiLayout *layout, int type) uiLayout *uiLayoutRadial(uiLayout *layout) { - uiLayout *litem; - /* radial layouts are only valid for radial menus */ if (layout->root->type != UI_LAYOUT_PIEMENU) { return ui_item_local_sublayout(layout, layout, 0); @@ -4776,14 +4753,14 @@ uiLayout *uiLayoutRadial(uiLayout *layout) /* only one radial wheel per root layout is allowed, so check and return that, if it exists */ LISTBASE_FOREACH (uiItem *, item, &layout->root->layout->items) { - litem = (uiLayout *)item; + uiLayout *litem = (uiLayout *)item; if (litem->item.type == ITEM_LAYOUT_RADIAL) { UI_block_layout_set_current(layout->root->block, litem); return litem; } } - litem = MEM_callocN(sizeof(uiLayout), "uiLayoutRadial"); + uiLayout *litem = MEM_callocN(sizeof(uiLayout), "uiLayoutRadial"); ui_litem_init_from_parent(litem, layout, false); litem->item.type = ITEM_LAYOUT_RADIAL; @@ -4838,9 +4815,7 @@ uiLayout *uiLayoutListBox(uiLayout *layout, uiLayout *uiLayoutAbsolute(uiLayout *layout, bool align) { - uiLayout *litem; - - litem = MEM_callocN(sizeof(uiLayout), "uiLayoutAbsolute"); + uiLayout *litem = MEM_callocN(sizeof(uiLayout), "uiLayoutAbsolute"); ui_litem_init_from_parent(litem, layout, align); litem->item.type = ITEM_LAYOUT_ABSOLUTE; @@ -4852,9 +4827,7 @@ uiLayout *uiLayoutAbsolute(uiLayout *layout, bool align) uiBlock *uiLayoutAbsoluteBlock(uiLayout *layout) { - uiBlock *block; - - block = uiLayoutGetBlock(layout); + uiBlock *block = uiLayoutGetBlock(layout); uiLayoutAbsolute(layout, false); return block; @@ -4862,9 +4835,7 @@ uiBlock *uiLayoutAbsoluteBlock(uiLayout *layout) uiLayout *uiLayoutOverlap(uiLayout *layout) { - uiLayout *litem; - - litem = MEM_callocN(sizeof(uiLayout), "uiLayoutOverlap"); + uiLayout *litem = MEM_callocN(sizeof(uiLayout), "uiLayoutOverlap"); ui_litem_init_from_parent(litem, layout, false); litem->item.type = ITEM_LAYOUT_OVERLAP; @@ -4876,9 +4847,7 @@ uiLayout *uiLayoutOverlap(uiLayout *layout) uiLayout *uiLayoutSplit(uiLayout *layout, float percentage, bool align) { - uiLayoutItemSplit *split; - - split = MEM_callocN(sizeof(uiLayoutItemSplit), "uiLayoutItemSplit"); + uiLayoutItemSplit *split = MEM_callocN(sizeof(uiLayoutItemSplit), "uiLayoutItemSplit"); ui_litem_init_from_parent(&split->litem, layout, align); split->litem.item.type = ITEM_LAYOUT_SPLIT; @@ -5290,12 +5259,9 @@ static void ui_item_estimate(uiItem *item) static void ui_item_align(uiLayout *litem, short nr) { - uiButtonItem *bitem; - uiLayoutItemBx *box; - LISTBASE_FOREACH_BACKWARD (uiItem *, item, &litem->items) { if (item->type == ITEM_BUTTON) { - bitem = (uiButtonItem *)item; + uiButtonItem *bitem = (uiButtonItem *)item; #ifndef USE_UIBUT_SPATIAL_ALIGN if (ui_but_can_align(bitem->but)) #endif @@ -5312,7 +5278,7 @@ static void ui_item_align(uiLayout *litem, short nr) /* pass */ } else if (item->type == ITEM_LAYOUT_BOX) { - box = (uiLayoutItemBx *)item; + uiLayoutItemBx *box = (uiLayoutItemBx *)item; if (!box->roundbox->alignnr) { box->roundbox->alignnr = nr; } @@ -5325,11 +5291,9 @@ static void ui_item_align(uiLayout *litem, short nr) static void ui_item_flag(uiLayout *litem, int flag) { - uiButtonItem *bitem; - LISTBASE_FOREACH_BACKWARD (uiItem *, item, &litem->items) { if (item->type == ITEM_BUTTON) { - bitem = (uiButtonItem *)item; + uiButtonItem *bitem = (uiButtonItem *)item; bitem->but->flag |= flag; } else { @@ -5465,17 +5429,14 @@ uiLayout *UI_block_layout(uiBlock *block, int padding, const uiStyle *style) { - uiLayout *layout; - uiLayoutRoot *root; - - root = MEM_callocN(sizeof(uiLayoutRoot), "uiLayoutRoot"); + uiLayoutRoot *root = MEM_callocN(sizeof(uiLayoutRoot), "uiLayoutRoot"); root->type = type; root->style = style; root->block = block; root->padding = padding; root->opcontext = WM_OP_INVOKE_REGION_WIN; - layout = MEM_callocN(sizeof(uiLayout), "uiLayout"); + uiLayout *layout = MEM_callocN(sizeof(uiLayout), "uiLayout"); layout->item.type = (type == UI_LAYOUT_VERT_BAR) ? ITEM_LAYOUT_COLUMN : ITEM_LAYOUT_ROOT; /* Only used when 'UI_ITEM_PROP_SEP' is set. */ @@ -5529,9 +5490,7 @@ void UI_block_layout_set_current(uiBlock *block, uiLayout *layout) void ui_layout_add_but(uiLayout *layout, uiBut *but) { - uiButtonItem *bitem; - - bitem = MEM_callocN(sizeof(uiButtonItem), "uiButtonItem"); + uiButtonItem *bitem = MEM_callocN(sizeof(uiButtonItem), "uiButtonItem"); bitem->item.type = ITEM_BUTTON; bitem->but = but; -- cgit v1.2.3 From c106b07e233889323e501cc033ac2010b2799bdc Mon Sep 17 00:00:00 2001 From: Hans Goudey Date: Fri, 18 Dec 2020 17:04:52 -0600 Subject: Cleanup: Remove unused variables from the bNode struct In some cases the variables were set but never used anywhere. Differential Revision: https://developer.blender.org/D9889 --- source/blender/editors/space_node/drawnode.c | 36 --------------------------- source/blender/editors/space_node/node_draw.c | 2 -- 2 files changed, 38 deletions(-) (limited to 'source/blender/editors') diff --git a/source/blender/editors/space_node/drawnode.c b/source/blender/editors/space_node/drawnode.c index 421e66604e4..0ce31707204 100644 --- a/source/blender/editors/space_node/drawnode.c +++ b/source/blender/editors/space_node/drawnode.c @@ -203,42 +203,6 @@ static void node_buts_normal(uiLayout *layout, bContext *UNUSED(C), PointerRNA * uiItemR(layout, &sockptr, "default_value", DEFAULT_FLAGS, "", ICON_NONE); } -#if 0 /* not used in 2.5x yet */ -static void node_browse_tex_cb(bContext *C, void *ntree_v, void *node_v) -{ - Main *bmain = CTX_data_main(C); - bNodeTree *ntree = ntree_v; - bNode *node = node_v; - Tex *tex; - - if (node->menunr < 1) { - return; - } - - if (node->id) { - id_us_min(node->id); - node->id = NULL; - } - tex = BLI_findlink(&bmain->tex, node->menunr - 1); - - node->id = &tex->id; - id_us_plus(node->id); - BLI_strncpy(node->name, node->id->name + 2, sizeof(node->name)); - - nodeSetActive(ntree, node); - - if (ntree->type == NTREE_TEXTURE) { - ntreeTexCheckCyclics(ntree); - } - - // allqueue(REDRAWBUTSSHADING, 0); - // allqueue(REDRAWNODE, 0); - NodeTagChanged(ntree, node); - - node->menunr = 0; -} -#endif - static void node_buts_texture(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr) { bNode *node = ptr->data; diff --git a/source/blender/editors/space_node/node_draw.c b/source/blender/editors/space_node/node_draw.c index 5a2eb0cc3a0..d3fec7257f5 100644 --- a/source/blender/editors/space_node/node_draw.c +++ b/source/blender/editors/space_node/node_draw.c @@ -1620,7 +1620,6 @@ void node_draw_nodetree(const bContext *C, } bNodeInstanceKey key = BKE_node_instance_key(parent_key, ntree, node); - node->nr = a; /* index of node in list, used for exec event code */ node_draw(C, region, snode, ntree, node, key); } @@ -1643,7 +1642,6 @@ void node_draw_nodetree(const bContext *C, } bNodeInstanceKey key = BKE_node_instance_key(parent_key, ntree, node); - node->nr = a; /* index of node in list, used for exec event code */ node_draw(C, region, snode, ntree, node, key); } } -- cgit v1.2.3 From 6942dd9f49003ead61f9a0e52b398ebc74a5e3cb Mon Sep 17 00:00:00 2001 From: Hans Goudey Date: Fri, 18 Dec 2020 17:13:15 -0600 Subject: Fix T83868: Button animation states no longer visible without emboss This bug was caused by making it so that non-embossed modifier icon buttons could become an operator button and retain their red highlight for disabled modifiers. The icon button needs emboss turned off, but in earlier versions of Blender, `UI_EMBOSS_NONE` would be overridden by animation or red alert states. Instead of abusing "NONE" to mean "none unless there is animation or red alert", this commit adds a new emboss flag for that situation, `UI_EMBOSS_NONE_OR_STATUS`, which uses no emboss unless there is an animation state, or another status. There are only a few situations where this is necessary, so the change isn't too big. Differential Revision: https://developer.blender.org/D9902 --- source/blender/editors/include/UI_interface.h | 5 +++++ source/blender/editors/interface/interface_templates.c | 2 +- source/blender/editors/interface/interface_widgets.c | 17 ++++++++++++----- source/blender/editors/space_nla/nla_buttons.c | 2 +- source/blender/editors/space_outliner/outliner_draw.c | 6 +++--- 5 files changed, 22 insertions(+), 10 deletions(-) (limited to 'source/blender/editors') diff --git a/source/blender/editors/include/UI_interface.h b/source/blender/editors/include/UI_interface.h index ced411ef75f..05bedd526ed 100644 --- a/source/blender/editors/include/UI_interface.h +++ b/source/blender/editors/include/UI_interface.h @@ -108,6 +108,11 @@ enum { UI_EMBOSS_NONE = 1, /* Nothing, only icon and/or text */ UI_EMBOSS_PULLDOWN = 2, /* Pulldown menu style */ UI_EMBOSS_RADIAL = 3, /* Pie Menu */ + /** + * The same as #UI_EMBOSS_NONE, unless the the button has + * a coloring status like an animation state or red alert. + */ + UI_EMBOSS_NONE_OR_STATUS = 4, UI_EMBOSS_UNDEFINED = 255, /* For layout engine, use emboss from block. */ }; diff --git a/source/blender/editors/interface/interface_templates.c b/source/blender/editors/interface/interface_templates.c index 6e96704271f..404ae0df6a1 100644 --- a/source/blender/editors/interface/interface_templates.c +++ b/source/blender/editors/interface/interface_templates.c @@ -2915,7 +2915,7 @@ static void draw_constraint_header(uiLayout *layout, Object *ob, bConstraint *co } else { /* enabled */ - UI_block_emboss_set(block, UI_EMBOSS_NONE); + UI_block_emboss_set(block, UI_EMBOSS_NONE_OR_STATUS); uiItemR(layout, &ptr, "mute", 0, "", 0); UI_block_emboss_set(block, UI_EMBOSS); diff --git a/source/blender/editors/interface/interface_widgets.c b/source/blender/editors/interface/interface_widgets.c index e92c32bb1bd..7e883851876 100644 --- a/source/blender/editors/interface/interface_widgets.c +++ b/source/blender/editors/interface/interface_widgets.c @@ -2520,8 +2520,14 @@ static void widget_active_color(uiWidgetColors *wcol) static const uchar *widget_color_blend_from_flags(const uiWidgetStateColors *wcol_state, int state, - int drawflag) + int drawflag, + const char emboss) { + /* Explicitly require #UI_EMBOSS_NONE_OR_STATUS for color blending with no emboss. */ + if (emboss == UI_EMBOSS_NONE) { + return NULL; + } + if (drawflag & UI_BUT_ANIMATED_CHANGED) { return wcol_state->inner_changed_sel; } @@ -2557,7 +2563,7 @@ static void widget_state(uiWidgetType *wt, int state, int drawflag, char emboss) wt->wcol = *(wt->wcol_theme); - const uchar *color_blend = widget_color_blend_from_flags(wcol_state, state, drawflag); + const uchar *color_blend = widget_color_blend_from_flags(wcol_state, state, drawflag, emboss); if (state & UI_SELECT) { copy_v4_v4_uchar(wt->wcol.inner, wt->wcol.inner_sel); @@ -2626,7 +2632,7 @@ static void widget_state_numslider(uiWidgetType *wt, int state, int drawflag, ch /* call this for option button */ widget_state(wt, state, drawflag, emboss); - const uchar *color_blend = widget_color_blend_from_flags(wcol_state, state, drawflag); + const uchar *color_blend = widget_color_blend_from_flags(wcol_state, state, drawflag, emboss); if (color_blend != NULL) { /* Set the slider 'item' so that it reflects state settings too. * De-saturate so the color of the slider doesn't conflict with the blend color, @@ -4524,8 +4530,9 @@ void ui_draw_but(const bContext *C, struct ARegion *region, uiStyle *style, uiBu break; } } - else if (but->emboss == UI_EMBOSS_NONE) { - /* "nothing" */ + else if (ELEM(but->emboss, UI_EMBOSS_NONE, UI_EMBOSS_NONE_OR_STATUS)) { + /* Use the same widget types for both no emboss types. Later on, + * #UI_EMBOSS_NONE_OR_STATUS will blend state colors if they apply. */ switch (but->type) { case UI_BTYPE_LABEL: wt = widget_type(UI_WTYPE_ICON_LABEL); diff --git a/source/blender/editors/space_nla/nla_buttons.c b/source/blender/editors/space_nla/nla_buttons.c index 1d7e5448b92..218fc3b7141 100644 --- a/source/blender/editors/space_nla/nla_buttons.c +++ b/source/blender/editors/space_nla/nla_buttons.c @@ -346,7 +346,7 @@ static void nla_panel_stripname(const bContext *C, Panel *panel) uiItemR(row, &strip_ptr, "name", 0, "", ICON_NLA); - UI_block_emboss_set(block, UI_EMBOSS_NONE); + UI_block_emboss_set(block, UI_EMBOSS_NONE_OR_STATUS); uiItemR(row, &strip_ptr, "mute", 0, "", ICON_NONE); UI_block_emboss_set(block, UI_EMBOSS); } diff --git a/source/blender/editors/space_outliner/outliner_draw.c b/source/blender/editors/space_outliner/outliner_draw.c index d2381cf30db..9223da136e1 100644 --- a/source/blender/editors/space_outliner/outliner_draw.c +++ b/source/blender/editors/space_outliner/outliner_draw.c @@ -1996,7 +1996,7 @@ static void outliner_draw_mode_column_toggle(uiBlock *block, "Change the object in the current mode\n" "* Ctrl to add to the current mode"); } - + UI_block_emboss_set(block, UI_EMBOSS_NONE_OR_STATUS); uiBut *but = uiDefIconBut(block, UI_BTYPE_ICON_TOGGLE, 0, @@ -3646,7 +3646,7 @@ void draw_outliner(const bContext *C) outliner_tree_dimensions(space_outliner, &tree_width, &tree_height); /* Default to no emboss for outliner UI. */ - UI_block_emboss_set(block, UI_EMBOSS_NONE); + UI_block_emboss_set(block, UI_EMBOSS_NONE_OR_STATUS); if (space_outliner->outlinevis == SO_DATA_API) { int buttons_start_x = outliner_data_api_buttons_start_x(tree_width); @@ -3655,7 +3655,7 @@ void draw_outliner(const bContext *C) UI_block_emboss_set(block, UI_EMBOSS); outliner_draw_rnabuts(block, region, space_outliner, buttons_start_x, &space_outliner->tree); - UI_block_emboss_set(block, UI_EMBOSS_NONE); + UI_block_emboss_set(block, UI_EMBOSS_NONE_OR_STATUS); } else if (space_outliner->outlinevis == SO_ID_ORPHANS) { /* draw user toggle columns */ -- cgit v1.2.3 From 046ca0749a9389ec52da90b29c8b2032f3225c51 Mon Sep 17 00:00:00 2001 From: Richard Antalik Date: Sat, 19 Dec 2020 05:57:27 +0100 Subject: Cleanup: Rename BKE_sequencer functions API functions get SEQ_ prefix. Intern functions get seq_ prefix Functions also have appropriate category included in name. --- source/blender/editors/animation/anim_deps.c | 4 +- source/blender/editors/animation/anim_filter.c | 6 +- source/blender/editors/animation/anim_ops.c | 2 +- source/blender/editors/render/render_internal.c | 6 +- source/blender/editors/screen/screen_context.c | 6 +- source/blender/editors/sound/sound_ops.c | 2 +- .../editors/space_outliner/outliner_select.c | 8 +- .../blender/editors/space_outliner/outliner_sync.c | 4 +- .../editors/space_outliner/outliner_tools.c | 2 +- .../space_outliner/tree/tree_display_sequencer.cc | 2 +- .../editors/space_sequencer/sequencer_add.c | 92 ++--- .../editors/space_sequencer/sequencer_draw.c | 28 +- .../editors/space_sequencer/sequencer_edit.c | 395 ++++++++++----------- .../editors/space_sequencer/sequencer_modifier.c | 34 +- .../editors/space_sequencer/sequencer_proxy.c | 12 +- .../editors/space_sequencer/sequencer_select.c | 37 +- .../editors/space_sequencer/sequencer_view.c | 6 +- .../editors/space_sequencer/space_sequencer.c | 2 +- .../transform/transform_convert_sequencer.c | 76 ++-- source/blender/editors/transform/transform_snap.c | 2 +- source/blender/editors/util/ed_util_imbuf.c | 2 +- 21 files changed, 363 insertions(+), 365 deletions(-) (limited to 'source/blender/editors') diff --git a/source/blender/editors/animation/anim_deps.c b/source/blender/editors/animation/anim_deps.c index 32ce78e405e..fbd55592729 100644 --- a/source/blender/editors/animation/anim_deps.c +++ b/source/blender/editors/animation/anim_deps.c @@ -212,7 +212,7 @@ static void animchan_sync_fcurve_scene(bAnimListElem *ale) return; } - Editing *ed = BKE_sequencer_editing_get(scene, false); + Editing *ed = SEQ_editing_get(scene, false); /* get strip name, and check if this strip is selected */ char *seq_name = BLI_str_quoted_substrN(fcu->rna_path, "sequences_all["); @@ -220,7 +220,7 @@ static void animchan_sync_fcurve_scene(bAnimListElem *ale) return; } - Sequence *seq = BKE_sequence_get_by_name(ed->seqbasep, seq_name, false); + Sequence *seq = SEQ_get_sequence_by_name(ed->seqbasep, seq_name, false); MEM_freeN(seq_name); if (seq == NULL) { diff --git a/source/blender/editors/animation/anim_filter.c b/source/blender/editors/animation/anim_filter.c index f4a487140ff..83665d7a053 100644 --- a/source/blender/editors/animation/anim_filter.c +++ b/source/blender/editors/animation/anim_filter.c @@ -225,7 +225,7 @@ static bool actedit_get_context(bAnimContext *ac, SpaceAction *saction) { /* TODO, other methods to get the mask */ #if 0 - Sequence *seq = BKE_sequencer_active_get(ac->scene); + Sequence *seq = SEQ_select_active_get(ac->scene); MovieClip *clip = ac->scene->clip; struct Mask *mask = seq ? seq->mask : NULL; #endif @@ -1103,14 +1103,14 @@ static bool skip_fcurve_selected_data(bDopeSheet *ads, FCurve *fcu, ID *owner_id /* only consider if F-Curve involves sequence_editor.sequences */ if ((fcu->rna_path) && strstr(fcu->rna_path, "sequences_all")) { - Editing *ed = BKE_sequencer_editing_get(scene, false); + Editing *ed = SEQ_editing_get(scene, false); Sequence *seq = NULL; if (ed) { /* get strip name, and check if this strip is selected */ char *seq_name = BLI_str_quoted_substrN(fcu->rna_path, "sequences_all["); if (seq_name) { - seq = BKE_sequence_get_by_name(ed->seqbasep, seq_name, false); + seq = SEQ_get_sequence_by_name(ed->seqbasep, seq_name, false); MEM_freeN(seq_name); } } diff --git a/source/blender/editors/animation/anim_ops.c b/source/blender/editors/animation/anim_ops.c index 0db3e984b60..07601414fb0 100644 --- a/source/blender/editors/animation/anim_ops.c +++ b/source/blender/editors/animation/anim_ops.c @@ -93,7 +93,7 @@ static void change_frame_apply(bContext *C, wmOperator *op) if (do_snap) { if (CTX_wm_space_seq(C)) { - frame = BKE_sequencer_find_next_prev_edit(scene, frame, SEQ_SIDE_BOTH, true, false, false); + frame = SEQ_time_find_next_prev_edit(scene, frame, SEQ_SIDE_BOTH, true, false, false); } else { frame = BKE_scene_frame_snap_by_seconds(scene, 1.0, frame); diff --git a/source/blender/editors/render/render_internal.c b/source/blender/editors/render/render_internal.c index 69c1e887392..46680f649cd 100644 --- a/source/blender/editors/render/render_internal.c +++ b/source/blender/editors/render/render_internal.c @@ -363,7 +363,7 @@ static int screen_render_exec(bContext *C, wmOperator *op) * otherwise, invalidated cache entries can make their way into * the output rendering. We can't put that into RE_RenderFrame, * since sequence rendering can call that recursively... (peter) */ - BKE_sequencer_cache_cleanup(scene); + SEQ_cache_cleanup(scene); RE_SetReports(re, op->reports); @@ -935,7 +935,7 @@ static int screen_render_invoke(bContext *C, wmOperator *op, const wmEvent *even /* Reports are done inside check function, and it will return false if there are other strips to * render. */ - if ((scene->r.scemode & R_DOSEQ) && BKE_sequencer_check_scene_recursion(scene, op->reports)) { + if ((scene->r.scemode & R_DOSEQ) && SEQ_relations_check_scene_recursion(scene, op->reports)) { return OPERATOR_CANCELLED; } @@ -957,7 +957,7 @@ static int screen_render_invoke(bContext *C, wmOperator *op, const wmEvent *even * otherwise, invalidated cache entries can make their way into * the output rendering. We can't put that into RE_RenderFrame, * since sequence rendering can call that recursively... (peter) */ - BKE_sequencer_cache_cleanup(scene); + SEQ_cache_cleanup(scene); /* store spare * get view3d layer, local layer, make this nice api call to render diff --git a/source/blender/editors/screen/screen_context.c b/source/blender/editors/screen/screen_context.c index fb7606d1fe5..1dfe606be78 100644 --- a/source/blender/editors/screen/screen_context.c +++ b/source/blender/editors/screen/screen_context.c @@ -604,7 +604,7 @@ static eContextResult screen_ctx_sequences(const bContext *C, bContextDataResult { wmWindow *win = CTX_wm_window(C); Scene *scene = WM_window_get_active_scene(win); - Editing *ed = BKE_sequencer_editing_get(scene, false); + Editing *ed = SEQ_editing_get(scene, false); if (ed) { LISTBASE_FOREACH (Sequence *, seq, ed->seqbasep) { CTX_data_list_add(result, &scene->id, &RNA_Sequence, seq); @@ -618,7 +618,7 @@ static eContextResult screen_ctx_selected_sequences(const bContext *C, bContextD { wmWindow *win = CTX_wm_window(C); Scene *scene = WM_window_get_active_scene(win); - Editing *ed = BKE_sequencer_editing_get(scene, false); + Editing *ed = SEQ_editing_get(scene, false); if (ed) { LISTBASE_FOREACH (Sequence *, seq, ed->seqbasep) { if (seq->flag & SELECT) { @@ -635,7 +635,7 @@ static eContextResult screen_ctx_selected_editable_sequences(const bContext *C, { wmWindow *win = CTX_wm_window(C); Scene *scene = WM_window_get_active_scene(win); - Editing *ed = BKE_sequencer_editing_get(scene, false); + Editing *ed = SEQ_editing_get(scene, false); if (ed) { LISTBASE_FOREACH (Sequence *, seq, ed->seqbasep) { if (seq->flag & SELECT && !(seq->flag & SEQ_LOCK)) { diff --git a/source/blender/editors/sound/sound_ops.c b/source/blender/editors/sound/sound_ops.c index 8dac90c2346..5bc13ec1b75 100644 --- a/source/blender/editors/sound/sound_ops.c +++ b/source/blender/editors/sound/sound_ops.c @@ -259,7 +259,7 @@ static void sound_update_animation_flags(Scene *scene) scene->id.tag |= LIB_TAG_DOIT; SEQ_ALL_BEGIN (scene->ed, seq) { - BKE_sequencer_recursive_apply(seq, sound_update_animation_flags_fn, scene); + SEQ_iterator_recursive_apply(seq, sound_update_animation_flags_fn, scene); } SEQ_ALL_END; diff --git a/source/blender/editors/space_outliner/outliner_select.c b/source/blender/editors/space_outliner/outliner_select.c index 658e6adbe33..a1df922b335 100644 --- a/source/blender/editors/space_outliner/outliner_select.c +++ b/source/blender/editors/space_outliner/outliner_select.c @@ -870,13 +870,13 @@ static eOLDrawState tree_element_active_sequence(bContext *C, const eOLSetState set) { Sequence *seq = (Sequence *)te->directdata; - Editing *ed = BKE_sequencer_editing_get(scene, false); + Editing *ed = SEQ_editing_get(scene, false); if (set != OL_SETSEL_NONE) { /* only check on setting */ if (BLI_findindex(ed->seqbasep, seq) != -1) { if (set == OL_SETSEL_EXTEND) { - BKE_sequencer_active_set(scene, NULL); + SEQ_select_active_set(scene, NULL); } ED_sequencer_deselect_all(scene); @@ -885,7 +885,7 @@ static eOLDrawState tree_element_active_sequence(bContext *C, } else { seq->flag |= SELECT; - BKE_sequencer_active_set(scene, seq); + SEQ_select_active_set(scene, seq); } } @@ -905,7 +905,7 @@ static eOLDrawState tree_element_active_sequence_dup(Scene *scene, const eOLSetState set) { Sequence *seq, *p; - Editing *ed = BKE_sequencer_editing_get(scene, false); + Editing *ed = SEQ_editing_get(scene, false); seq = (Sequence *)te->directdata; if (set == OL_SETSEL_NONE) { diff --git a/source/blender/editors/space_outliner/outliner_sync.c b/source/blender/editors/space_outliner/outliner_sync.c index 0f5c74a9168..b3e8761f60b 100644 --- a/source/blender/editors/space_outliner/outliner_sync.c +++ b/source/blender/editors/space_outliner/outliner_sync.c @@ -305,7 +305,7 @@ static void outliner_select_sync_to_sequence(Scene *scene, TreeStoreElem *tselem Sequence *seq = (Sequence *)tselem->id; if (tselem->flag & TSE_ACTIVE) { - BKE_sequencer_active_set(scene, seq); + SEQ_select_active_set(scene, seq); } if (tselem->flag & TSE_SELECTED) { @@ -542,7 +542,7 @@ static void get_sync_select_active_data(const bContext *C, SyncSelectActiveData active_data->object = OBACT(view_layer); active_data->edit_bone = CTX_data_active_bone(C); active_data->pose_channel = CTX_data_active_pose_bone(C); - active_data->sequence = BKE_sequencer_active_get(scene); + active_data->sequence = SEQ_select_active_get(scene); } /* If outliner is dirty sync selection from view layer and sequwncer */ diff --git a/source/blender/editors/space_outliner/outliner_tools.c b/source/blender/editors/space_outliner/outliner_tools.c index 492fc5c23bc..d4784a509bf 100644 --- a/source/blender/editors/space_outliner/outliner_tools.c +++ b/source/blender/editors/space_outliner/outliner_tools.c @@ -1206,7 +1206,7 @@ static void sequence_fn(int event, TreeElement *te, TreeStoreElem *tselem, void Sequence *seq = (Sequence *)te->directdata; if (event == OL_DOP_SELECT) { Scene *scene = (Scene *)scene_ptr; - Editing *ed = BKE_sequencer_editing_get(scene, false); + Editing *ed = SEQ_editing_get(scene, false); if (BLI_findindex(ed->seqbasep, seq) != -1) { ED_sequencer_select_sequence_single(scene, seq, true); } diff --git a/source/blender/editors/space_outliner/tree/tree_display_sequencer.cc b/source/blender/editors/space_outliner/tree/tree_display_sequencer.cc index 48f0322ccb9..40f329d72c3 100644 --- a/source/blender/editors/space_outliner/tree/tree_display_sequencer.cc +++ b/source/blender/editors/space_outliner/tree/tree_display_sequencer.cc @@ -43,7 +43,7 @@ ListBase TreeDisplaySequencer::buildTree(const TreeSourceData &source_data) { ListBase tree = {nullptr}; - Editing *ed = BKE_sequencer_editing_get(source_data.scene, false); + Editing *ed = SEQ_editing_get(source_data.scene, false); if (ed == nullptr) { return tree; } diff --git a/source/blender/editors/space_sequencer/sequencer_add.c b/source/blender/editors/space_sequencer/sequencer_add.c index 71433a6978a..e40e9f5429d 100644 --- a/source/blender/editors/space_sequencer/sequencer_add.c +++ b/source/blender/editors/space_sequencer/sequencer_add.c @@ -149,7 +149,7 @@ static void sequencer_generic_invoke_path__internal(bContext *C, { if (RNA_struct_find_property(op->ptr, identifier)) { Scene *scene = CTX_data_scene(C); - Sequence *last_seq = BKE_sequencer_active_get(scene); + Sequence *last_seq = SEQ_select_active_get(scene); if (last_seq && last_seq->strip && SEQ_HAS_PATH(last_seq)) { Main *bmain = CTX_data_main(C); char path[FILE_MAX]; @@ -165,7 +165,7 @@ static int sequencer_generic_invoke_xy_guess_channel(bContext *C, int type) Sequence *tgt = NULL; Sequence *seq; Scene *scene = CTX_data_scene(C); - Editing *ed = BKE_sequencer_editing_get(scene, true); + Editing *ed = SEQ_editing_get(scene, true); int timeline_frame = (int)CFRA; int proximity = INT_MAX; @@ -306,11 +306,11 @@ static void seq_load_operator_info(SeqLoadInfo *seq_load, bContext *C, wmOperato static void sequencer_add_apply_overlap(bContext *C, wmOperator *op, Sequence *seq) { Scene *scene = CTX_data_scene(C); - Editing *ed = BKE_sequencer_editing_get(scene, false); + Editing *ed = SEQ_editing_get(scene, false); if (RNA_boolean_get(op->ptr, "overlap") == false) { - if (BKE_sequence_test_overlap(ed->seqbasep, seq)) { - BKE_sequence_base_shuffle(ed->seqbasep, seq, scene); + if (SEQ_transform_test_overlap(ed->seqbasep, seq)) { + SEQ_transform_seqbase_shuffle(ed->seqbasep, seq, scene); } } } @@ -321,7 +321,7 @@ static void sequencer_add_apply_replace_sel(bContext *C, wmOperator *op, Sequenc if (RNA_boolean_get(op->ptr, "replace_sel")) { ED_sequencer_deselect_all(scene); - BKE_sequencer_active_set(scene, seq); + SEQ_select_active_set(scene, seq); seq->flag |= SELECT; } } @@ -334,7 +334,7 @@ static bool seq_effect_add_properties_poll(const bContext *UNUSED(C), int type = RNA_enum_get(op->ptr, "type"); /* Hide start/end frames for effect strips that are locked to their parents' location. */ - if (BKE_sequence_effect_get_num_inputs(type) != 0) { + if (SEQ_effect_get_num_inputs(type) != 0) { if (STR_ELEM(prop_id, "frame_start", "frame_end")) { return false; } @@ -350,7 +350,7 @@ static int sequencer_add_scene_strip_exec(bContext *C, wmOperator *op) { Main *bmain = CTX_data_main(C); Scene *scene = CTX_data_scene(C); - Editing *ed = BKE_sequencer_editing_get(scene, true); + Editing *ed = SEQ_editing_get(scene, true); Scene *sce_seq; Sequence *seq; @@ -364,20 +364,20 @@ static int sequencer_add_scene_strip_exec(bContext *C, wmOperator *op) return OPERATOR_CANCELLED; } - seq = BKE_sequence_alloc(ed->seqbasep, start_frame, channel, SEQ_TYPE_SCENE); + seq = SEQ_sequence_alloc(ed->seqbasep, start_frame, channel, SEQ_TYPE_SCENE); seq->blend_mode = SEQ_TYPE_CROSS; seq->scene = sce_seq; seq->len = sce_seq->r.efra - sce_seq->r.sfra + 1; BLI_strncpy(seq->name + 2, sce_seq->id.name + 2, sizeof(seq->name) - 2); - BKE_sequence_base_unique_name_recursive(&ed->seqbase, seq); + SEQ_sequence_base_unique_name_recursive(&ed->seqbase, seq); - BKE_sequence_calc_disp(scene, seq); - BKE_sequencer_sort(scene); + SEQ_time_update_sequence_bounds(scene, seq); + SEQ_sort(scene); sequencer_add_apply_replace_sel(C, op, seq); sequencer_add_apply_overlap(C, op, seq); - BKE_sequence_invalidate_cache_composite(scene, seq); + SEQ_relations_invalidate_cache_composite(scene, seq); DEG_id_tag_update(&scene->id, ID_RECALC_SEQUENCER_STRIPS); DEG_relations_tag_update(bmain); @@ -424,7 +424,7 @@ static int sequencer_add_movieclip_strip_exec(bContext *C, wmOperator *op) { Main *bmain = CTX_data_main(C); Scene *scene = CTX_data_scene(C); - Editing *ed = BKE_sequencer_editing_get(scene, true); + Editing *ed = SEQ_editing_get(scene, true); MovieClip *clip; Sequence *seq; @@ -438,7 +438,7 @@ static int sequencer_add_movieclip_strip_exec(bContext *C, wmOperator *op) return OPERATOR_CANCELLED; } - seq = BKE_sequence_alloc(ed->seqbasep, start_frame, channel, SEQ_TYPE_MOVIECLIP); + seq = SEQ_sequence_alloc(ed->seqbasep, start_frame, channel, SEQ_TYPE_MOVIECLIP); seq->blend_mode = SEQ_TYPE_CROSS; seq->clip = clip; seq->len = BKE_movieclip_get_duration(clip); @@ -446,14 +446,14 @@ static int sequencer_add_movieclip_strip_exec(bContext *C, wmOperator *op) id_us_ensure_real(&seq->clip->id); BLI_strncpy(seq->name + 2, clip->id.name + 2, sizeof(seq->name) - 2); - BKE_sequence_base_unique_name_recursive(&ed->seqbase, seq); + SEQ_sequence_base_unique_name_recursive(&ed->seqbase, seq); - BKE_sequence_calc_disp(scene, seq); - BKE_sequencer_sort(scene); + SEQ_time_update_sequence_bounds(scene, seq); + SEQ_sort(scene); sequencer_add_apply_replace_sel(C, op, seq); sequencer_add_apply_overlap(C, op, seq); - BKE_sequence_invalidate_cache_composite(scene, seq); + SEQ_relations_invalidate_cache_composite(scene, seq); DEG_id_tag_update(&scene->id, ID_RECALC_SEQUENCER_STRIPS); WM_event_add_notifier(C, NC_SCENE | ND_SEQUENCER, scene); @@ -500,7 +500,7 @@ static int sequencer_add_mask_strip_exec(bContext *C, wmOperator *op) { Main *bmain = CTX_data_main(C); Scene *scene = CTX_data_scene(C); - Editing *ed = BKE_sequencer_editing_get(scene, true); + Editing *ed = SEQ_editing_get(scene, true); Mask *mask; Sequence *seq; @@ -514,7 +514,7 @@ static int sequencer_add_mask_strip_exec(bContext *C, wmOperator *op) return OPERATOR_CANCELLED; } - seq = BKE_sequence_alloc(ed->seqbasep, start_frame, channel, SEQ_TYPE_MASK); + seq = SEQ_sequence_alloc(ed->seqbasep, start_frame, channel, SEQ_TYPE_MASK); seq->blend_mode = SEQ_TYPE_CROSS; seq->mask = mask; seq->len = BKE_mask_get_duration(mask); @@ -522,14 +522,14 @@ static int sequencer_add_mask_strip_exec(bContext *C, wmOperator *op) id_us_ensure_real(&seq->mask->id); BLI_strncpy(seq->name + 2, mask->id.name + 2, sizeof(seq->name) - 2); - BKE_sequence_base_unique_name_recursive(&ed->seqbase, seq); + SEQ_sequence_base_unique_name_recursive(&ed->seqbase, seq); - BKE_sequence_calc_disp(scene, seq); - BKE_sequencer_sort(scene); + SEQ_time_update_sequence_bounds(scene, seq); + SEQ_sort(scene); sequencer_add_apply_replace_sel(C, op, seq); sequencer_add_apply_overlap(C, op, seq); - BKE_sequence_invalidate_cache_composite(scene, seq); + SEQ_relations_invalidate_cache_composite(scene, seq); DEG_id_tag_update(&scene->id, ID_RECALC_SEQUENCER_STRIPS); WM_event_add_notifier(C, NC_SCENE | ND_SEQUENCER, scene); @@ -574,7 +574,7 @@ void SEQUENCER_OT_mask_strip_add(struct wmOperatorType *ot) static int sequencer_add_generic_strip_exec(bContext *C, wmOperator *op, SeqLoadFn seq_load_fn) { Scene *scene = CTX_data_scene(C); - Editing *ed = BKE_sequencer_editing_get(scene, true); + Editing *ed = SEQ_editing_get(scene, true); SeqLoadInfo seq_load; int tot_files; @@ -632,7 +632,7 @@ static int sequencer_add_generic_strip_exec(bContext *C, wmOperator *op, SeqLoad return OPERATOR_CANCELLED; } - BKE_sequencer_sort(scene); + SEQ_sort(scene); DEG_id_tag_update(&scene->id, ID_RECALC_SEQUENCER_STRIPS); WM_event_add_notifier(C, NC_SCENE | ND_SEQUENCER, scene); @@ -664,7 +664,7 @@ static bool sequencer_add_draw_check_fn(PointerRNA *UNUSED(ptr), static int sequencer_add_movie_strip_exec(bContext *C, wmOperator *op) { - return sequencer_add_generic_strip_exec(C, op, BKE_sequencer_add_movie_strip); + return sequencer_add_generic_strip_exec(C, op, SEQ_add_movie_strip); } static int sequencer_add_movie_strip_invoke(bContext *C, @@ -673,7 +673,7 @@ static int sequencer_add_movie_strip_invoke(bContext *C, { PropertyRNA *prop; Scene *scene = CTX_data_scene(C); - Editing *ed = BKE_sequencer_editing_get(scene, false); + Editing *ed = SEQ_editing_get(scene, false); /* Only enable "use_framerate" if there aren't any existing strips, unless overridden by user. */ if (ed && ed->seqbasep && ed->seqbasep->first) { @@ -757,7 +757,7 @@ void SEQUENCER_OT_movie_strip_add(struct wmOperatorType *ot) static int sequencer_add_sound_strip_exec(bContext *C, wmOperator *op) { - return sequencer_add_generic_strip_exec(C, op, BKE_sequencer_add_sound_strip); + return sequencer_add_generic_strip_exec(C, op, SEQ_add_sound_strip); } static int sequencer_add_sound_strip_invoke(bContext *C, @@ -871,7 +871,7 @@ static int sequencer_add_image_strip_exec(bContext *C, wmOperator *op) { int minframe, numdigits; Scene *scene = CTX_data_scene(C); - Editing *ed = BKE_sequencer_editing_get(scene, true); + Editing *ed = SEQ_editing_get(scene, true); SeqLoadInfo seq_load; Sequence *seq; Strip *strip; @@ -899,7 +899,7 @@ static int sequencer_add_image_strip_exec(bContext *C, wmOperator *op) } /* Main adding function. */ - seq = BKE_sequencer_add_image_strip(C, ed->seqbasep, &seq_load); + seq = SEQ_add_image_strip(C, ed->seqbasep, &seq_load); strip = seq->strip; se = strip->stripdata; seq->blend_mode = SEQ_TYPE_ALPHAOVER; @@ -924,8 +924,8 @@ static int sequencer_add_image_strip_exec(bContext *C, wmOperator *op) } SEQ_render_init_colorspace(seq); - BKE_sequence_calc_disp(scene, seq); - BKE_sequencer_sort(scene); + SEQ_time_update_sequence_bounds(scene, seq); + SEQ_sort(scene); /* Last active name. */ BLI_strncpy(ed->act_imagedir, strip->dir, sizeof(ed->act_imagedir)); @@ -935,7 +935,7 @@ static int sequencer_add_image_strip_exec(bContext *C, wmOperator *op) MEM_freeN(op->customdata); } - BKE_sequence_invalidate_cache_composite(scene, seq); + SEQ_relations_invalidate_cache_composite(scene, seq); DEG_id_tag_update(&scene->id, ID_RECALC_SEQUENCER_STRIPS); WM_event_add_notifier(C, NC_SCENE | ND_SEQUENCER, scene); @@ -1009,7 +1009,7 @@ void SEQUENCER_OT_image_strip_add(struct wmOperatorType *ot) static int sequencer_add_effect_strip_exec(bContext *C, wmOperator *op) { Scene *scene = CTX_data_scene(C); - Editing *ed = BKE_sequencer_editing_get(scene, true); + Editing *ed = SEQ_editing_get(scene, true); Sequence *seq; struct SeqEffectHandle sh; Sequence *seq1, *seq2, *seq3; @@ -1032,11 +1032,11 @@ static int sequencer_add_effect_strip_exec(bContext *C, wmOperator *op) RNA_int_set(op->ptr, "frame_end", end_frame); } - seq = BKE_sequence_alloc(ed->seqbasep, start_frame, channel, type); - BLI_strncpy(seq->name + 2, BKE_sequence_give_name(seq), sizeof(seq->name) - 2); - BKE_sequence_base_unique_name_recursive(&ed->seqbase, seq); + seq = SEQ_sequence_alloc(ed->seqbasep, start_frame, channel, type); + BLI_strncpy(seq->name + 2, SEQ_sequence_give_name(seq), sizeof(seq->name) - 2); + SEQ_sequence_base_unique_name_recursive(&ed->seqbase, seq); - sh = BKE_sequence_get_effect(seq); + sh = SEQ_effect_handle_get(seq); sh.init(seq); seq->seq1 = seq1; seq->seq2 = seq2; @@ -1044,11 +1044,11 @@ static int sequencer_add_effect_strip_exec(bContext *C, wmOperator *op) if (!seq1) { seq->len = 1; /* Effect is generator, set non zero length. */ - BKE_sequence_tx_set_final_right(seq, end_frame); + SEQ_transform_set_right_handle_frame(seq, end_frame); } seq->flag |= SEQ_USE_EFFECT_DEFAULT_FADE; - BKE_sequence_calc(scene, seq); + SEQ_time_update_sequence(scene, seq); if (seq->type == SEQ_TYPE_COLOR) { SolidColorVars *colvars = (SolidColorVars *)seq->effectdata; @@ -1077,10 +1077,10 @@ static int sequencer_add_effect_strip_exec(bContext *C, wmOperator *op) sequencer_add_apply_replace_sel(C, op, seq); sequencer_add_apply_overlap(C, op, seq); - BKE_sequencer_update_changed_seq_and_deps(scene, seq, 1, 1); /* Runs BKE_sequence_calc. */ - BKE_sequencer_sort(scene); + SEQ_relations_update_changed_seq_and_deps(scene, seq, 1, 1); /* Runs SEQ_time_update_sequence. */ + SEQ_sort(scene); - BKE_sequence_invalidate_cache_composite(scene, seq); + SEQ_relations_invalidate_cache_composite(scene, seq); DEG_id_tag_update(&scene->id, ID_RECALC_SEQUENCER_STRIPS); WM_event_add_notifier(C, NC_SCENE | ND_SEQUENCER, scene); @@ -1100,7 +1100,7 @@ static int sequencer_add_effect_strip_invoke(bContext *C, /* When invoking an effect strip which uses inputs, skip initializing the channel from the * mouse. */ - if (BKE_sequence_effect_get_num_inputs(type) != 0) { + if (SEQ_effect_get_num_inputs(type) != 0) { prop_flag |= SEQPROP_NOCHAN; } } diff --git a/source/blender/editors/space_sequencer/sequencer_draw.c b/source/blender/editors/space_sequencer/sequencer_draw.c index d7d601a3c76..2f146690416 100644 --- a/source/blender/editors/space_sequencer/sequencer_draw.c +++ b/source/blender/editors/space_sequencer/sequencer_draw.c @@ -371,7 +371,7 @@ static void drawmeta_contents(Scene *scene, Sequence *seqm, float x1, float y1, ListBase *seqbase; int offset; - seqbase = BKE_sequence_seqbase_get(seqm, &offset); + seqbase = SEQ_get_seqbase_from_sequence(seqm, &offset); if (!seqbase || BLI_listbase_is_empty(seqbase)) { return; } @@ -488,7 +488,7 @@ static void draw_seq_handle(View2D *v2d, whichsel = SEQ_RIGHTSEL; } - if (!(seq->type & SEQ_TYPE_EFFECT) || BKE_sequence_effect_get_num_inputs(seq->type) == 0) { + if (!(seq->type & SEQ_TYPE_EFFECT) || SEQ_effect_get_num_inputs(seq->type) == 0) { GPU_blend(GPU_BLEND_ALPHA); GPU_blend(GPU_BLEND_ALPHA); @@ -607,7 +607,7 @@ static const char *draw_seq_text_get_name(Sequence *seq) { const char *name = seq->name + 2; if (name[0] == '\0') { - name = BKE_sequence_give_name(seq); + name = SEQ_sequence_give_name(seq); } return name; } @@ -840,9 +840,9 @@ static void draw_seq_background(Scene *scene, /* Draw the main strip body. */ if (is_single_image) { immRectf(pos, - BKE_sequence_tx_get_final_left(seq, false), + SEQ_transform_get_left_handle_frame(seq, false), y1, - BKE_sequence_tx_get_final_right(seq, false), + SEQ_transform_get_right_handle_frame(seq, false), y2); } else { @@ -1067,7 +1067,7 @@ static void draw_seq_strip(const bContext *C, float pixely = BLI_rctf_size_y(&v2d->cur) / BLI_rcti_size_y(&v2d->mask); /* Check if we are doing "solo preview". */ - bool is_single_image = (char)BKE_sequence_single_check(seq); + bool is_single_image = (char)SEQ_transform_single_image_check(seq); /* Draw strip body. */ x1 = (seq->startstill) ? seq->start : seq->startdisp; @@ -1143,7 +1143,7 @@ static void draw_seq_strip(const bContext *C, } /* Draw Red line on the top of invalid strip (Missing media). */ - if (!BKE_sequence_is_valid_check(seq)) { + if (!SEQ_sequence_has_source(seq)) { draw_seq_invalid(x1, x2, y2, text_margin_y); } @@ -1441,7 +1441,7 @@ void sequencer_draw_maskedit(const bContext *C, Scene *scene, ARegion *region, S // if (sc->mode == SC_MODE_MASKEDIT) if (0 && sseq->mainb == SEQ_DRAW_IMG_IMBUF) { - Mask *mask = BKE_sequencer_mask_get(scene); + Mask *mask = SEQ_active_mask_get(scene); if (mask) { int width, height; @@ -1473,7 +1473,7 @@ void sequencer_draw_maskedit(const bContext *C, Scene *scene, ARegion *region, S /* Force redraw, when prefetching and using cache view. */ static void seq_prefetch_wm_notify(const bContext *C, Scene *scene) { - if (BKE_sequencer_prefetch_need_redraw(CTX_data_main(C), scene)) { + if (SEQ_prefetch_need_redraw(CTX_data_main(C), scene)) { WM_event_add_notifier(C, NC_SCENE | ND_SEQUENCER, NULL); } } @@ -1913,7 +1913,7 @@ static void draw_seq_strips(const bContext *C, Editing *ed, ARegion *region) Scene *scene = CTX_data_scene(C); View2D *v2d = ®ion->v2d; SpaceSeq *sseq = CTX_wm_space_seq(C); - Sequence *last_seq = BKE_sequencer_active_get(scene); + Sequence *last_seq = SEQ_select_active_get(scene); int sel = 0, j; float pixelx = BLI_rctf_size_x(&v2d->cur) / BLI_rcti_size_x(&v2d->mask); @@ -1956,7 +1956,7 @@ static void draw_seq_strips(const bContext *C, Editing *ed, ARegion *region) draw_seq_strip(C, sseq, scene, region, last_seq, pixelx, true); /* When active strip is an effect, highlight its inputs. */ - if (BKE_sequence_effect_get_num_inputs(last_seq->type) > 0) { + if (SEQ_effect_get_num_inputs(last_seq->type) > 0) { draw_effect_inputs_highlight(last_seq); } /* When active is a Multi-cam strip, highlight its source channel. */ @@ -2000,7 +2000,7 @@ static void draw_seq_strips(const bContext *C, Editing *ed, ARegion *region) static void seq_draw_sfra_efra(Scene *scene, View2D *v2d) { - const Editing *ed = BKE_sequencer_editing_get(scene, false); + const Editing *ed = SEQ_editing_get(scene, false); const int frame_sta = scene->r.sfra; const int frame_end = scene->r.efra + 1; @@ -2265,7 +2265,7 @@ static void draw_cache_view(const bContext *C) userdata.composite_vbo = GPU_vertbuf_create_with_format(&format); userdata.final_out_vbo = GPU_vertbuf_create_with_format(&format); - BKE_sequencer_cache_iterate(scene, &userdata, draw_cache_view_init_fn, draw_cache_view_iter_fn); + SEQ_cache_iterate(scene, &userdata, draw_cache_view_init_fn, draw_cache_view_iter_fn); draw_cache_view_batch(userdata.raw_vbo, userdata.raw_vert_count, 1.0f, 0.1f, 0.02f, 0.4f); draw_cache_view_batch( @@ -2282,7 +2282,7 @@ static void draw_cache_view(const bContext *C) void draw_timeline_seq(const bContext *C, ARegion *region) { Scene *scene = CTX_data_scene(C); - Editing *ed = BKE_sequencer_editing_get(scene, false); + Editing *ed = SEQ_editing_get(scene, false); SpaceSeq *sseq = CTX_wm_space_seq(C); View2D *v2d = ®ion->v2d; short cfra_flag = 0; diff --git a/source/blender/editors/space_sequencer/sequencer_edit.c b/source/blender/editors/space_sequencer/sequencer_edit.c index ddc9ba2e0f6..f78b602ceda 100644 --- a/source/blender/editors/space_sequencer/sequencer_edit.c +++ b/source/blender/editors/space_sequencer/sequencer_edit.c @@ -96,7 +96,7 @@ bool ED_space_sequencer_maskedit_mask_poll(bContext *C) bool ED_space_sequencer_check_show_maskedit(SpaceSeq *sseq, Scene *scene) { if (sseq && sseq->mainb == SEQ_DRAW_IMG_IMBUF) { - return (BKE_sequencer_mask_get(scene) != NULL); + return (SEQ_active_mask_get(scene) != NULL); } return false; @@ -136,14 +136,14 @@ bool ED_space_sequencer_check_show_strip(SpaceSeq *sseq) /* Operator functions. */ bool sequencer_edit_poll(bContext *C) { - return (BKE_sequencer_editing_get(CTX_data_scene(C), false) != NULL); + return (SEQ_editing_get(CTX_data_scene(C), false) != NULL); } #if 0 /* UNUSED */ bool sequencer_strip_poll(bContext *C) { Editing *ed; - return (((ed = BKE_sequencer_editing_get(CTX_data_scene(C), false)) != NULL) && + return (((ed = SEQ_editing_get(CTX_data_scene(C), false)) != NULL) && (ed->act_seq != NULL)); } #endif @@ -152,14 +152,14 @@ bool sequencer_strip_has_path_poll(bContext *C) { Editing *ed; Sequence *seq; - return (((ed = BKE_sequencer_editing_get(CTX_data_scene(C), false)) != NULL) && + return (((ed = SEQ_editing_get(CTX_data_scene(C), false)) != NULL) && ((seq = ed->act_seq) != NULL) && (SEQ_HAS_PATH(seq))); } bool sequencer_view_preview_poll(bContext *C) { SpaceSeq *sseq = CTX_wm_space_seq(C); - Editing *ed = BKE_sequencer_editing_get(CTX_data_scene(C), false); + Editing *ed = SEQ_editing_get(CTX_data_scene(C), false); if (ed && sseq && (sseq->mainb == SEQ_DRAW_IMG_IMBUF)) { return 1; } @@ -187,7 +187,7 @@ static int sequencer_gap_remove_exec(bContext *C, wmOperator *op) { Scene *scene = CTX_data_scene(C); const bool do_all = RNA_boolean_get(op->ptr, "all"); - const Editing *ed = BKE_sequencer_editing_get(scene, false); + const Editing *ed = SEQ_editing_get(scene, false); SEQ_edit_remove_gaps(scene, ed->seqbasep, CFRA, do_all); @@ -227,8 +227,8 @@ static int sequencer_gap_insert_exec(bContext *C, wmOperator *op) { Scene *scene = CTX_data_scene(C); const int frames = RNA_int_get(op->ptr, "frames"); - const Editing *ed = BKE_sequencer_editing_get(scene, false); - SEQ_offset_after_frame(scene, ed->seqbasep, frames, CFRA); + const Editing *ed = SEQ_editing_get(scene, false); + SEQ_transform_offset_after_frame(scene, ed->seqbasep, frames, CFRA); WM_event_add_notifier(C, NC_SCENE | ND_SEQUENCER, scene); @@ -273,7 +273,7 @@ static int sequencer_snap_exec(bContext *C, wmOperator *op) { Scene *scene = CTX_data_scene(C); - Editing *ed = BKE_sequencer_editing_get(scene, false); + Editing *ed = SEQ_editing_get(scene, false); Sequence *seq; int snap_frame; @@ -282,22 +282,22 @@ static int sequencer_snap_exec(bContext *C, wmOperator *op) /* Check metas. */ for (seq = ed->seqbasep->first; seq; seq = seq->next) { if (seq->flag & SELECT && !(seq->depth == 0 && seq->flag & SEQ_LOCK) && - BKE_sequence_tx_test(seq)) { + SEQ_transform_sequence_can_be_translated(seq)) { if ((seq->flag & (SEQ_LEFTSEL + SEQ_RIGHTSEL)) == 0) { - BKE_sequence_translate( + SEQ_transform_translate_sequence( scene, seq, (snap_frame - seq->startofs + seq->startstill) - seq->start); } else { if (seq->flag & SEQ_LEFTSEL) { - BKE_sequence_tx_set_final_left(seq, snap_frame); + SEQ_transform_set_left_handle_frame(seq, snap_frame); } else { /* SEQ_RIGHTSEL */ - BKE_sequence_tx_set_final_right(seq, snap_frame); + SEQ_transform_set_right_handle_frame(seq, snap_frame); } - BKE_sequence_tx_handle_xlimits(seq, seq->flag & SEQ_LEFTSEL, seq->flag & SEQ_RIGHTSEL); - BKE_sequence_single_fix(seq); + SEQ_transform_handle_xlimits(seq, seq->flag & SEQ_LEFTSEL, seq->flag & SEQ_RIGHTSEL); + SEQ_transform_fix_single_image_seq_offsets(seq); } - BKE_sequence_calc(scene, seq); + SEQ_time_update_sequence(scene, seq); } } @@ -306,8 +306,8 @@ static int sequencer_snap_exec(bContext *C, wmOperator *op) for (seq = ed->seqbasep->first; seq; seq = seq->next) { if (seq->flag & SELECT && !(seq->depth == 0 && seq->flag & SEQ_LOCK)) { seq->flag &= ~SEQ_OVERLAP; - if (BKE_sequence_test_overlap(ed->seqbasep, seq)) { - BKE_sequence_base_shuffle(ed->seqbasep, seq, scene); + if (SEQ_transform_test_overlap(ed->seqbasep, seq)) { + SEQ_transform_seqbase_shuffle(ed->seqbasep, seq, scene); } } } @@ -316,21 +316,21 @@ static int sequencer_snap_exec(bContext *C, wmOperator *op) for (seq = ed->seqbasep->first; seq; seq = seq->next) { if (seq->type & SEQ_TYPE_EFFECT) { if (seq->seq1 && (seq->seq1->flag & SELECT)) { - BKE_sequencer_offset_animdata(scene, seq, (snap_frame - seq->startdisp)); - BKE_sequence_calc(scene, seq); + SEQ_offset_animdata(scene, seq, (snap_frame - seq->startdisp)); + SEQ_time_update_sequence(scene, seq); } else if (seq->seq2 && (seq->seq2->flag & SELECT)) { - BKE_sequencer_offset_animdata(scene, seq, (snap_frame - seq->startdisp)); - BKE_sequence_calc(scene, seq); + SEQ_offset_animdata(scene, seq, (snap_frame - seq->startdisp)); + SEQ_time_update_sequence(scene, seq); } else if (seq->seq3 && (seq->seq3->flag & SELECT)) { - BKE_sequencer_offset_animdata(scene, seq, (snap_frame - seq->startdisp)); - BKE_sequence_calc(scene, seq); + SEQ_offset_animdata(scene, seq, (snap_frame - seq->startdisp)); + SEQ_time_update_sequence(scene, seq); } } } - BKE_sequencer_sort(scene); + SEQ_sort(scene); DEG_id_tag_update(&scene->id, ID_RECALC_SEQUENCER_STRIPS); WM_event_add_notifier(C, NC_SCENE | ND_SEQUENCER, scene); @@ -470,7 +470,7 @@ static int sequencer_slip_invoke(bContext *C, wmOperator *op, const wmEvent *eve { SlipData *data; Scene *scene = CTX_data_scene(C); - Editing *ed = BKE_sequencer_editing_get(scene, false); + Editing *ed = SEQ_editing_get(scene, false); float mouseloc[2]; int num_seq; View2D *v2d = UI_view2d_fromcontext(C); @@ -518,7 +518,7 @@ static int sequencer_slip_invoke(bContext *C, wmOperator *op, const wmEvent *eve static bool sequencer_slip_recursively(Scene *scene, SlipData *data, int offset) { /* Only data types supported for now. */ - Editing *ed = BKE_sequencer_editing_get(scene, false); + Editing *ed = SEQ_editing_get(scene, false); bool changed = false; /* Iterate in reverse so meta-strips are iterated after their children. */ @@ -568,11 +568,11 @@ static bool sequencer_slip_recursively(Scene *scene, SlipData *data, int offset) * we can skip calculating for effects. * This way we can avoid an extra loop just for effects. */ if (!(seq->type & SEQ_TYPE_EFFECT)) { - BKE_sequence_calc(scene, seq); + SEQ_time_update_sequence(scene, seq); } } if (changed) { - BKE_sequencer_free_imbuf(scene, &ed->seqbase, false); + SEQ_relations_free_imbuf(scene, &ed->seqbase, false); } return changed; } @@ -602,7 +602,7 @@ static void sequencer_slip_apply_limits(SlipData *data, int *offset) static int sequencer_slip_exec(bContext *C, wmOperator *op) { Scene *scene = CTX_data_scene(C); - Editing *ed = BKE_sequencer_editing_get(scene, false); + Editing *ed = SEQ_editing_get(scene, false); int offset = RNA_int_get(op->ptr, "offset"); bool success = false; @@ -737,7 +737,7 @@ static int sequencer_slip_modal(bContext *C, wmOperator *op, const wmEvent *even case EVT_ESCKEY: case RIGHTMOUSE: { - Editing *ed = BKE_sequencer_editing_get(scene, false); + Editing *ed = SEQ_editing_get(scene, false); for (int i = 0; i < data->num_seq; i++) { transseq_restore(data->ts + i, data->seq_array[i]); @@ -745,8 +745,8 @@ static int sequencer_slip_modal(bContext *C, wmOperator *op, const wmEvent *even for (int i = 0; i < data->num_seq; i++) { Sequence *seq = data->seq_array[i]; - BKE_sequence_reload_new_file(bmain, scene, seq, false); - BKE_sequence_calc(scene, seq); + SEQ_add_reload_new_file(bmain, scene, seq, false); + SEQ_time_update_sequence(scene, seq); } MEM_freeN(data->seq_array); @@ -757,7 +757,7 @@ static int sequencer_slip_modal(bContext *C, wmOperator *op, const wmEvent *even WM_event_add_notifier(C, NC_SCENE | ND_SEQUENCER, scene); - BKE_sequencer_free_imbuf(scene, &ed->seqbase, false); + SEQ_relations_free_imbuf(scene, &ed->seqbase, false); if (area) { ED_area_status_text(area, NULL); @@ -839,7 +839,7 @@ void SEQUENCER_OT_slip(struct wmOperatorType *ot) static int sequencer_mute_exec(bContext *C, wmOperator *op) { Scene *scene = CTX_data_scene(C); - Editing *ed = BKE_sequencer_editing_get(scene, false); + Editing *ed = SEQ_editing_get(scene, false); Sequence *seq; bool selected; @@ -850,13 +850,13 @@ static int sequencer_mute_exec(bContext *C, wmOperator *op) if (selected) { if (seq->flag & SELECT) { seq->flag |= SEQ_MUTE; - BKE_sequence_invalidate_dependent(scene, seq); + SEQ_relations_invalidate_dependent(scene, seq); } } else { if ((seq->flag & SELECT) == 0) { seq->flag |= SEQ_MUTE; - BKE_sequence_invalidate_dependent(scene, seq); + SEQ_relations_invalidate_dependent(scene, seq); } } } @@ -895,7 +895,7 @@ void SEQUENCER_OT_mute(struct wmOperatorType *ot) static int sequencer_unmute_exec(bContext *C, wmOperator *op) { Scene *scene = CTX_data_scene(C); - Editing *ed = BKE_sequencer_editing_get(scene, false); + Editing *ed = SEQ_editing_get(scene, false); Sequence *seq; bool selected; @@ -906,13 +906,13 @@ static int sequencer_unmute_exec(bContext *C, wmOperator *op) if (selected) { if (seq->flag & SELECT) { seq->flag &= ~SEQ_MUTE; - BKE_sequence_invalidate_dependent(scene, seq); + SEQ_relations_invalidate_dependent(scene, seq); } } else { if ((seq->flag & SELECT) == 0) { seq->flag &= ~SEQ_MUTE; - BKE_sequence_invalidate_dependent(scene, seq); + SEQ_relations_invalidate_dependent(scene, seq); } } } @@ -951,7 +951,7 @@ void SEQUENCER_OT_unmute(struct wmOperatorType *ot) static int sequencer_lock_exec(bContext *C, wmOperator *UNUSED(op)) { Scene *scene = CTX_data_scene(C); - Editing *ed = BKE_sequencer_editing_get(scene, false); + Editing *ed = SEQ_editing_get(scene, false); Sequence *seq; for (seq = ed->seqbasep->first; seq; seq = seq->next) { @@ -989,7 +989,7 @@ void SEQUENCER_OT_lock(struct wmOperatorType *ot) static int sequencer_unlock_exec(bContext *C, wmOperator *UNUSED(op)) { Scene *scene = CTX_data_scene(C); - Editing *ed = BKE_sequencer_editing_get(scene, false); + Editing *ed = SEQ_editing_get(scene, false); Sequence *seq; for (seq = ed->seqbasep->first; seq; seq = seq->next) { @@ -1028,18 +1028,18 @@ static int sequencer_reload_exec(bContext *C, wmOperator *op) { Main *bmain = CTX_data_main(C); Scene *scene = CTX_data_scene(C); - Editing *ed = BKE_sequencer_editing_get(scene, false); + Editing *ed = SEQ_editing_get(scene, false); Sequence *seq; const bool adjust_length = RNA_boolean_get(op->ptr, "adjust_length"); for (seq = ed->seqbasep->first; seq; seq = seq->next) { if (seq->flag & SELECT) { - BKE_sequencer_update_changed_seq_and_deps(scene, seq, 0, 1); - BKE_sequence_reload_new_file(bmain, scene, seq, !adjust_length); + SEQ_relations_update_changed_seq_and_deps(scene, seq, 0, 1); + SEQ_add_reload_new_file(bmain, scene, seq, !adjust_length); if (adjust_length) { - if (BKE_sequence_test_overlap(ed->seqbasep, seq)) { - BKE_sequence_base_shuffle(ed->seqbasep, seq, scene); + if (SEQ_transform_test_overlap(ed->seqbasep, seq)) { + SEQ_transform_seqbase_shuffle(ed->seqbasep, seq, scene); } } } @@ -1091,9 +1091,9 @@ static bool sequencer_refresh_all_poll(bContext *C) static int sequencer_refresh_all_exec(bContext *C, wmOperator *UNUSED(op)) { Scene *scene = CTX_data_scene(C); - Editing *ed = BKE_sequencer_editing_get(scene, false); + Editing *ed = SEQ_editing_get(scene, false); - BKE_sequencer_free_imbuf(scene, &ed->seqbase, false); + SEQ_relations_free_imbuf(scene, &ed->seqbase, false); WM_event_add_notifier(C, NC_SCENE | ND_SEQUENCER, scene); @@ -1126,18 +1126,18 @@ int seq_effect_find_selected(Scene *scene, Sequence **r_selseq3, const char **r_error_str) { - Editing *ed = BKE_sequencer_editing_get(scene, false); + Editing *ed = SEQ_editing_get(scene, false); Sequence *seq1 = NULL, *seq2 = NULL, *seq3 = NULL, *seq; *r_error_str = NULL; if (!activeseq) { - seq2 = BKE_sequencer_active_get(scene); + seq2 = SEQ_select_active_get(scene); } for (seq = ed->seqbasep->first; seq; seq = seq->next) { if (seq->flag & SELECT) { - if (seq->type == SEQ_TYPE_SOUND_RAM && BKE_sequence_effect_get_num_inputs(type) != 0) { + if (seq->type == SEQ_TYPE_SOUND_RAM && SEQ_effect_get_num_inputs(type) != 0) { *r_error_str = N_("Cannot apply effects to audio sequence strips"); return 0; } @@ -1167,7 +1167,7 @@ int seq_effect_find_selected(Scene *scene, seq3 = tmp; } - switch (BKE_sequence_effect_get_num_inputs(type)) { + switch (SEQ_effect_get_num_inputs(type)) { case 0: *r_selseq1 = *r_selseq2 = *r_selseq3 = NULL; return 1; /* Success. */ @@ -1204,10 +1204,10 @@ int seq_effect_find_selected(Scene *scene, *r_selseq3 = seq3; /* TODO(Richard): This function needs some refactoring, this is just quick hack for T73828. */ - if (BKE_sequence_effect_get_num_inputs(type) < 3) { + if (SEQ_effect_get_num_inputs(type) < 3) { *r_selseq3 = NULL; } - if (BKE_sequence_effect_get_num_inputs(type) < 2) { + if (SEQ_effect_get_num_inputs(type) < 2) { *r_selseq2 = NULL; } @@ -1217,24 +1217,24 @@ int seq_effect_find_selected(Scene *scene, static int sequencer_reassign_inputs_exec(bContext *C, wmOperator *op) { Scene *scene = CTX_data_scene(C); - Sequence *seq1, *seq2, *seq3, *last_seq = BKE_sequencer_active_get(scene); + Sequence *seq1, *seq2, *seq3, *last_seq = SEQ_select_active_get(scene); const char *error_msg; - if (BKE_sequence_effect_get_num_inputs(last_seq->type) == 0) { + if (SEQ_effect_get_num_inputs(last_seq->type) == 0) { BKE_report(op->reports, RPT_ERROR, "Cannot reassign inputs: strip has no inputs"); return OPERATOR_CANCELLED; } if (!seq_effect_find_selected( scene, last_seq, last_seq->type, &seq1, &seq2, &seq3, &error_msg) || - BKE_sequence_effect_get_num_inputs(last_seq->type) == 0) { + SEQ_effect_get_num_inputs(last_seq->type) == 0) { BKE_report(op->reports, RPT_ERROR, error_msg); return OPERATOR_CANCELLED; } /* Check if reassigning would create recursivity. */ - if (BKE_sequencer_render_loop_check(seq1, last_seq) || - BKE_sequencer_render_loop_check(seq2, last_seq) || - BKE_sequencer_render_loop_check(seq3, last_seq)) { + if (SEQ_relations_render_loop_check(seq1, last_seq) || + SEQ_relations_render_loop_check(seq2, last_seq) || + SEQ_relations_render_loop_check(seq3, last_seq)) { BKE_report(op->reports, RPT_ERROR, "Cannot reassign inputs: recursion detected"); return OPERATOR_CANCELLED; } @@ -1243,7 +1243,7 @@ static int sequencer_reassign_inputs_exec(bContext *C, wmOperator *op) last_seq->seq2 = seq2; last_seq->seq3 = seq3; - BKE_sequencer_update_changed_seq_and_deps(scene, last_seq, 1, 1); + SEQ_relations_update_changed_seq_and_deps(scene, last_seq, 1, 1); WM_event_add_notifier(C, NC_SCENE | ND_SEQUENCER, scene); @@ -1253,10 +1253,10 @@ static int sequencer_reassign_inputs_exec(bContext *C, wmOperator *op) static bool sequencer_effect_poll(bContext *C) { Scene *scene = CTX_data_scene(C); - Editing *ed = BKE_sequencer_editing_get(scene, false); + Editing *ed = SEQ_editing_get(scene, false); if (ed) { - Sequence *last_seq = BKE_sequencer_active_get(scene); + Sequence *last_seq = SEQ_select_active_get(scene); if (last_seq && (last_seq->type & SEQ_TYPE_EFFECT)) { return 1; } @@ -1289,7 +1289,7 @@ void SEQUENCER_OT_reassign_inputs(struct wmOperatorType *ot) static int sequencer_swap_inputs_exec(bContext *C, wmOperator *op) { Scene *scene = CTX_data_scene(C); - Sequence *seq, *last_seq = BKE_sequencer_active_get(scene); + Sequence *seq, *last_seq = SEQ_select_active_get(scene); if (last_seq->seq1 == NULL || last_seq->seq2 == NULL) { BKE_report(op->reports, RPT_ERROR, "No valid inputs to swap"); @@ -1300,7 +1300,7 @@ static int sequencer_swap_inputs_exec(bContext *C, wmOperator *op) last_seq->seq1 = last_seq->seq2; last_seq->seq2 = seq; - BKE_sequencer_update_changed_seq_and_deps(scene, last_seq, 1, 1); + SEQ_relations_update_changed_seq_and_deps(scene, last_seq, 1, 1); WM_event_add_notifier(C, NC_SCENE | ND_SEQUENCER, scene); @@ -1360,7 +1360,7 @@ static int sequencer_split_exec(bContext *C, wmOperator *op) { Main *bmain = CTX_data_main(C); Scene *scene = CTX_data_scene(C); - Editing *ed = BKE_sequencer_editing_get(scene, false); + Editing *ed = SEQ_editing_get(scene, false); bool changed = false; bool seq_selected = false; @@ -1371,7 +1371,7 @@ static int sequencer_split_exec(bContext *C, wmOperator *op) const int split_side = RNA_enum_get(op->ptr, "side"); const bool ignore_selection = RNA_boolean_get(op->ptr, "ignore_selection"); - BKE_sequencer_prefetch_stop(scene); + SEQ_prefetch_stop(scene); LISTBASE_FOREACH_BACKWARD (Sequence *, seq, ed->seqbasep) { if (use_cursor_position && seq->machine != split_channel) { @@ -1423,7 +1423,7 @@ static int sequencer_split_exec(bContext *C, wmOperator *op) } } - BKE_sequencer_sort(scene); + SEQ_sort(scene); } if (changed) { WM_event_add_notifier(C, NC_SCENE | ND_SEQUENCER, scene); @@ -1566,15 +1566,15 @@ static int apply_unique_name_fn(Sequence *seq, void *arg_pt) char name[sizeof(seq->name) - 2]; BLI_strncpy_utf8(name, seq->name + 2, sizeof(name)); - BKE_sequence_base_unique_name_recursive(&scene->ed->seqbase, seq); - BKE_sequencer_dupe_animdata(scene, name, seq->name + 2); + SEQ_sequence_base_unique_name_recursive(&scene->ed->seqbase, seq); + SEQ_dupe_animdata(scene, name, seq->name + 2); return 1; } static int sequencer_add_duplicate_exec(bContext *C, wmOperator *UNUSED(op)) { Scene *scene = CTX_data_scene(C); - Editing *ed = BKE_sequencer_editing_get(scene, false); + Editing *ed = SEQ_editing_get(scene, false); ListBase nseqbase = {NULL, NULL}; @@ -1582,16 +1582,16 @@ static int sequencer_add_duplicate_exec(bContext *C, wmOperator *UNUSED(op)) return OPERATOR_CANCELLED; } - BKE_sequence_base_dupli_recursive(scene, scene, &nseqbase, ed->seqbasep, SEQ_DUPE_CONTEXT, 0); + SEQ_sequence_base_dupli_recursive(scene, scene, &nseqbase, ed->seqbasep, SEQ_DUPE_CONTEXT, 0); if (nseqbase.first) { Sequence *seq = nseqbase.first; /* Rely on the nseqbase list being added at the end. - * Their UUIDs has been re-generated by the BKE_sequence_base_dupli_recursive(), */ + * Their UUIDs has been re-generated by the SEQ_sequence_base_dupli_recursive(), */ BLI_movelisttolist(ed->seqbasep, &nseqbase); for (; seq; seq = seq->next) { - BKE_sequencer_recursive_apply(seq, apply_unique_name_fn, scene); + SEQ_iterator_recursive_apply(seq, apply_unique_name_fn, scene); } WM_event_add_notifier(C, NC_SCENE | ND_SEQUENCER, scene); @@ -1626,18 +1626,18 @@ static int sequencer_delete_exec(bContext *C, wmOperator *UNUSED(op)) { Main *bmain = CTX_data_main(C); Scene *scene = CTX_data_scene(C); - Editing *ed = BKE_sequencer_editing_get(scene, false); + Editing *ed = SEQ_editing_get(scene, false); Sequence *seq; - BKE_sequencer_prefetch_stop(scene); + SEQ_prefetch_stop(scene); SEQ_CURRENT_BEGIN (scene->ed, seq) { if (seq->flag & SELECT) { - BKE_sequencer_flag_for_removal(scene, ed->seqbasep, seq); + SEQ_edit_flag_for_removal(scene, ed->seqbasep, seq); } } SEQ_CURRENT_END; - BKE_sequencer_remove_flagged_sequences(scene, ed->seqbasep); + SEQ_edit_remove_flagged_sequences(scene, ed->seqbasep); DEG_id_tag_update(&scene->id, ID_RECALC_SEQUENCER_STRIPS); DEG_relations_tag_update(bmain); @@ -1687,7 +1687,7 @@ void SEQUENCER_OT_delete(wmOperatorType *ot) static int sequencer_offset_clear_exec(bContext *C, wmOperator *UNUSED(op)) { Scene *scene = CTX_data_scene(C); - Editing *ed = BKE_sequencer_editing_get(scene, false); + Editing *ed = SEQ_editing_get(scene, false); Sequence *seq; /* For effects, try to find a replacement input. */ @@ -1700,14 +1700,14 @@ static int sequencer_offset_clear_exec(bContext *C, wmOperator *UNUSED(op)) /* Update lengths, etc. */ seq = ed->seqbasep->first; while (seq) { - BKE_sequence_calc(scene, seq); + SEQ_time_update_sequence(scene, seq); seq = seq->next; } for (seq = ed->seqbasep->first; seq; seq = seq->next) { if ((seq->type & SEQ_TYPE_EFFECT) == 0 && (seq->flag & SELECT)) { - if (BKE_sequence_test_overlap(ed->seqbasep, seq)) { - BKE_sequence_base_shuffle(ed->seqbasep, seq, scene); + if (SEQ_transform_test_overlap(ed->seqbasep, seq)) { + SEQ_transform_seqbase_shuffle(ed->seqbasep, seq, scene); } } } @@ -1742,7 +1742,7 @@ void SEQUENCER_OT_offset_clear(wmOperatorType *ot) static int sequencer_separate_images_exec(bContext *C, wmOperator *op) { Scene *scene = CTX_data_scene(C); - Editing *ed = BKE_sequencer_editing_get(scene, false); + Editing *ed = SEQ_editing_get(scene, false); Sequence *seq, *seq_new; Strip *strip_new; @@ -1752,7 +1752,7 @@ static int sequencer_separate_images_exec(bContext *C, wmOperator *op) seq = ed->seqbasep->first; /* Poll checks this is valid. */ - BKE_sequencer_prefetch_stop(scene); + SEQ_prefetch_stop(scene); while (seq) { if ((seq->flag & SELECT) && (seq->type == SEQ_TYPE_IMAGE) && (seq->len > 1)) { @@ -1764,14 +1764,14 @@ static int sequencer_separate_images_exec(bContext *C, wmOperator *op) /* if (seq->ipo) id_us_min(&seq->ipo->id); */ /* XXX, remove fcurve and assign to split image strips */ - start_ofs = timeline_frame = BKE_sequence_tx_get_final_left(seq, false); - frame_end = BKE_sequence_tx_get_final_right(seq, false); + start_ofs = timeline_frame = SEQ_transform_get_left_handle_frame(seq, false); + frame_end = SEQ_transform_get_right_handle_frame(seq, false); while (timeline_frame < frame_end) { /* New seq. */ se = SEQ_render_give_stripelem(seq, timeline_frame); - seq_new = BKE_sequence_dupli_recursive( + seq_new = SEQ_sequence_dupli_recursive( scene, scene, ed->seqbasep, seq, SEQ_DUPE_UNIQUE_NAME); seq_new->start = start_ofs; @@ -1790,12 +1790,12 @@ static int sequencer_separate_images_exec(bContext *C, wmOperator *op) BLI_strncpy(se_new->name, se->name, sizeof(se_new->name)); strip_new->stripdata = se_new; - BKE_sequence_calc(scene, seq_new); + SEQ_time_update_sequence(scene, seq_new); if (step > 1) { seq_new->flag &= ~SEQ_OVERLAP; - if (BKE_sequence_test_overlap(ed->seqbasep, seq_new)) { - BKE_sequence_base_shuffle(ed->seqbasep, seq_new, scene); + if (SEQ_transform_test_overlap(ed->seqbasep, seq_new)) { + SEQ_transform_seqbase_shuffle(ed->seqbasep, seq_new, scene); } } @@ -1806,7 +1806,7 @@ static int sequencer_separate_images_exec(bContext *C, wmOperator *op) } seq_next = seq->next; - BKE_sequence_free(scene, seq, true); + SEQ_sequence_free(scene, seq, true); seq = seq_next; } else { @@ -1814,7 +1814,7 @@ static int sequencer_separate_images_exec(bContext *C, wmOperator *op) } } - BKE_sequencer_sort(scene); + SEQ_sort(scene); WM_event_add_notifier(C, NC_SCENE | ND_SEQUENCER, scene); @@ -1873,8 +1873,8 @@ void recurs_sel_seq(Sequence *seqm) static int sequencer_meta_toggle_exec(bContext *C, wmOperator *UNUSED(op)) { Scene *scene = CTX_data_scene(C); - Editing *ed = BKE_sequencer_editing_get(scene, false); - Sequence *last_seq = BKE_sequencer_active_get(scene); + Editing *ed = SEQ_editing_get(scene, false); + Sequence *last_seq = SEQ_select_active_get(scene); MetaStack *ms; if (last_seq && last_seq->type == SEQ_TYPE_META && last_seq->flag & SELECT) { @@ -1887,7 +1887,7 @@ static int sequencer_meta_toggle_exec(bContext *C, wmOperator *UNUSED(op)) ed->seqbasep = &last_seq->seqbase; - BKE_sequencer_active_set(scene, NULL); + SEQ_select_active_set(scene, NULL); } else { /* Exit metastrip if possible. */ @@ -1910,23 +1910,23 @@ static int sequencer_meta_toggle_exec(bContext *C, wmOperator *UNUSED(op)) /* Recalc all: the meta can have effects connected to it. */ for (seq = ed->seqbasep->first; seq; seq = seq->next) { - BKE_sequence_calc(scene, seq); + SEQ_time_update_sequence(scene, seq); } /* 2.73+, keeping endpoints is important! * Moving them around means you can't usefully use metas in a complex edit. */ #if 1 - BKE_sequence_tx_set_final_left(ms->parseq, ms->disp_range[0]); - BKE_sequence_tx_set_final_right(ms->parseq, ms->disp_range[1]); - BKE_sequence_single_fix(ms->parseq); - BKE_sequence_calc(scene, ms->parseq); + SEQ_transform_set_left_handle_frame(ms->parseq, ms->disp_range[0]); + SEQ_transform_set_right_handle_frame(ms->parseq, ms->disp_range[1]); + SEQ_transform_fix_single_image_seq_offsets(ms->parseq); + SEQ_time_update_sequence(scene, ms->parseq); #else - if (BKE_sequence_test_overlap(ed->seqbasep, ms->parseq)) { - BKE_sequence_base_shuffle(ed->seqbasep, ms->parseq, scene); + if (SEQ_transform_test_overlap(ed->seqbasep, ms->parseq)) { + SEQ_transform_seqbase_shuffle(ed->seqbasep, ms->parseq, scene); } #endif - BKE_sequencer_active_set(scene, ms->parseq); + SEQ_select_active_set(scene, ms->parseq); ms->parseq->flag |= SELECT; recurs_sel_seq(ms->parseq); @@ -1964,21 +1964,21 @@ void SEQUENCER_OT_meta_toggle(wmOperatorType *ot) static int sequencer_meta_make_exec(bContext *C, wmOperator *op) { Scene *scene = CTX_data_scene(C); - Editing *ed = BKE_sequencer_editing_get(scene, false); + Editing *ed = SEQ_editing_get(scene, false); - Sequence *seq, *seqm, *next, *last_seq = BKE_sequencer_active_get(scene); + Sequence *seq, *seqm, *next, *last_seq = SEQ_select_active_get(scene); int channel_max = 1; - if (BKE_sequence_base_isolated_sel_check(ed->seqbasep) == false) { + if (SEQ_transform_seqbase_isolated_sel_check(ed->seqbasep) == false) { BKE_report(op->reports, RPT_ERROR, "Please select all related strips"); return OPERATOR_CANCELLED; } - BKE_sequencer_prefetch_stop(scene); + SEQ_prefetch_stop(scene); /* Remove all selected from main list, and put in meta. */ - seqm = BKE_sequence_alloc(ed->seqbasep, 1, 1, SEQ_TYPE_META); /* Channel number set later. */ + seqm = SEQ_sequence_alloc(ed->seqbasep, 1, 1, SEQ_TYPE_META); /* Channel number set later. */ strcpy(seqm->name + 2, "MetaStrip"); seqm->flag = SELECT; @@ -1986,7 +1986,7 @@ static int sequencer_meta_make_exec(bContext *C, wmOperator *op) while (seq) { next = seq->next; if (seq != seqm && (seq->flag & SELECT)) { - BKE_sequence_invalidate_cache_composite(scene, seq); + SEQ_relations_invalidate_cache_composite(scene, seq); channel_max = max_ii(seq->machine, channel_max); /* Sequence is moved within the same edit, no need to re-generate the UUID. */ BLI_remlink(ed->seqbasep, seq); @@ -1995,18 +1995,18 @@ static int sequencer_meta_make_exec(bContext *C, wmOperator *op) seq = next; } seqm->machine = last_seq ? last_seq->machine : channel_max; - BKE_sequence_calc(scene, seqm); + SEQ_time_update_sequence(scene, seqm); - BKE_sequencer_active_set(scene, seqm); + SEQ_select_active_set(scene, seqm); - if (BKE_sequence_test_overlap(ed->seqbasep, seqm)) { - BKE_sequence_base_shuffle(ed->seqbasep, seqm, scene); + if (SEQ_transform_test_overlap(ed->seqbasep, seqm)) { + SEQ_transform_seqbase_shuffle(ed->seqbasep, seqm, scene); } DEG_id_tag_update(&scene->id, ID_RECALC_SEQUENCER_STRIPS); - BKE_sequence_base_unique_name_recursive(&scene->ed->seqbase, seqm); - BKE_sequence_invalidate_cache_composite(scene, seqm); + SEQ_sequence_base_unique_name_recursive(&scene->ed->seqbase, seqm); + SEQ_relations_invalidate_cache_composite(scene, seqm); WM_event_add_notifier(C, NC_SCENE | ND_SEQUENCER, scene); return OPERATOR_FINISHED; @@ -2053,7 +2053,7 @@ static int seq_depends_on_meta(Sequence *seq, Sequence *seqm) static void recurs_del_seq_flag(Scene *scene, ListBase *lb, short flag, short deleteall) { Sequence *seq, *seqn; - Sequence *last_seq = BKE_sequencer_active_get(scene); + Sequence *last_seq = SEQ_select_active_get(scene); seq = lb->first; while (seq) { @@ -2061,12 +2061,12 @@ static void recurs_del_seq_flag(Scene *scene, ListBase *lb, short flag, short de if ((seq->flag & flag) || deleteall) { BLI_remlink(lb, seq); if (seq == last_seq) { - BKE_sequencer_active_set(scene, NULL); + SEQ_select_active_set(scene, NULL); } if (seq->type == SEQ_TYPE_META) { recurs_del_seq_flag(scene, &seq->seqbase, flag, 1); } - BKE_sequence_free(scene, seq, true); + SEQ_sequence_free(scene, seq, true); } seq = seqn; } @@ -2075,18 +2075,18 @@ static void recurs_del_seq_flag(Scene *scene, ListBase *lb, short flag, short de static int sequencer_meta_separate_exec(bContext *C, wmOperator *UNUSED(op)) { Scene *scene = CTX_data_scene(C); - Editing *ed = BKE_sequencer_editing_get(scene, false); + Editing *ed = SEQ_editing_get(scene, false); - Sequence *seq, *last_seq = BKE_sequencer_active_get(scene); /* last_seq checks (ed == NULL) */ + Sequence *seq, *last_seq = SEQ_select_active_get(scene); /* last_seq checks (ed == NULL) */ if (last_seq == NULL || last_seq->type != SEQ_TYPE_META) { return OPERATOR_CANCELLED; } - BKE_sequencer_prefetch_stop(scene); + SEQ_prefetch_stop(scene); for (seq = last_seq->seqbase.first; seq != NULL; seq = seq->next) { - BKE_sequence_invalidate_cache_composite(scene, seq); + SEQ_relations_invalidate_cache_composite(scene, seq); } /* This moves strips from meta to parent, sating within same edit and no new strips are @@ -2097,7 +2097,7 @@ static int sequencer_meta_separate_exec(bContext *C, wmOperator *UNUSED(op)) BLI_listbase_clear(&last_seq->seqbase); BLI_remlink(ed->seqbasep, last_seq); - BKE_sequence_free(scene, last_seq, true); + SEQ_sequence_free(scene, last_seq, true); /* Empty meta strip, delete all effects depending on it. */ for (seq = ed->seqbasep->first; seq; seq = seq->next) { @@ -2113,13 +2113,13 @@ static int sequencer_meta_separate_exec(bContext *C, wmOperator *UNUSED(op)) for (seq = ed->seqbasep->first; seq; seq = seq->next) { if (seq->flag & SELECT) { seq->flag &= ~SEQ_OVERLAP; - if (BKE_sequence_test_overlap(ed->seqbasep, seq)) { - BKE_sequence_base_shuffle(ed->seqbasep, seq, scene); + if (SEQ_transform_test_overlap(ed->seqbasep, seq)) { + SEQ_transform_seqbase_shuffle(ed->seqbasep, seq, scene); } } } - BKE_sequencer_sort(scene); + SEQ_sort(scene); DEG_id_tag_update(&scene->id, ID_RECALC_SEQUENCER_STRIPS); WM_event_add_notifier(C, NC_SCENE | ND_SEQUENCER, scene); @@ -2155,7 +2155,7 @@ static bool strip_jump_internal(Scene *scene, { bool changed = false; int timeline_frame = CFRA; - int next_frame = BKE_sequencer_find_next_prev_edit( + int next_frame = SEQ_time_find_next_prev_edit( scene, timeline_frame, side, do_skip_mute, do_center, false); if (next_frame != timeline_frame) { @@ -2230,19 +2230,19 @@ static void swap_sequence(Scene *scene, Sequence *seqa, Sequence *seqb) int seq_b_start; seq_b_start = (seqb->start - seqb->startdisp) + seqa->startdisp; - BKE_sequence_translate(scene, seqb, seq_b_start - seqb->start); - BKE_sequence_calc(scene, seqb); + SEQ_transform_translate_sequence(scene, seqb, seq_b_start - seqb->start); + SEQ_time_update_sequence(scene, seqb); seq_a_start = (seqa->start - seqa->startdisp) + seqb->enddisp + gap; - BKE_sequence_translate(scene, seqa, seq_a_start - seqa->start); - BKE_sequence_calc(scene, seqa); + SEQ_transform_translate_sequence(scene, seqa, seq_a_start - seqa->start); + SEQ_time_update_sequence(scene, seqa); } static Sequence *find_next_prev_sequence(Scene *scene, Sequence *test, int lr, int sel) { /* sel: 0==unselected, 1==selected, -1==don't care. */ Sequence *seq, *best_seq = NULL; - Editing *ed = BKE_sequencer_editing_get(scene, false); + Editing *ed = SEQ_editing_get(scene, false); int dist, best_dist; best_dist = MAXFRAME * 2; @@ -2292,8 +2292,8 @@ static bool seq_is_parent(Sequence *par, Sequence *seq) static int sequencer_swap_exec(bContext *C, wmOperator *op) { Scene *scene = CTX_data_scene(C); - Editing *ed = BKE_sequencer_editing_get(scene, false); - Sequence *active_seq = BKE_sequencer_active_get(scene); + Editing *ed = SEQ_editing_get(scene, false); + Sequence *active_seq = SEQ_select_active_get(scene); Sequence *seq, *iseq; int side = RNA_enum_get(op->ptr, "side"); @@ -2306,11 +2306,11 @@ static int sequencer_swap_exec(bContext *C, wmOperator *op) if (seq) { /* Disallow effect strips. */ - if (BKE_sequence_effect_get_num_inputs(seq->type) >= 1 && + if (SEQ_effect_get_num_inputs(seq->type) >= 1 && (seq->effectdata || seq->seq1 || seq->seq2 || seq->seq3)) { return OPERATOR_CANCELLED; } - if ((BKE_sequence_effect_get_num_inputs(active_seq->type) >= 1) && + if ((SEQ_effect_get_num_inputs(active_seq->type) >= 1) && (active_seq->effectdata || active_seq->seq1 || active_seq->seq2 || active_seq->seq3)) { return OPERATOR_CANCELLED; } @@ -2328,7 +2328,7 @@ static int sequencer_swap_exec(bContext *C, wmOperator *op) for (iseq = scene->ed->seqbasep->first; iseq; iseq = iseq->next) { if ((iseq->type & SEQ_TYPE_EFFECT) && (seq_is_parent(iseq, active_seq) || seq_is_parent(iseq, seq))) { - BKE_sequence_calc(scene, iseq); + SEQ_time_update_sequence(scene, iseq); } } @@ -2337,13 +2337,13 @@ static int sequencer_swap_exec(bContext *C, wmOperator *op) if ((iseq->type & SEQ_TYPE_EFFECT) && (seq_is_parent(iseq, active_seq) || seq_is_parent(iseq, seq))) { /* This may now overlap. */ - if (BKE_sequence_test_overlap(ed->seqbasep, iseq)) { - BKE_sequence_base_shuffle(ed->seqbasep, iseq, scene); + if (SEQ_transform_test_overlap(ed->seqbasep, iseq)) { + SEQ_transform_seqbase_shuffle(ed->seqbasep, iseq, scene); } } } - BKE_sequencer_sort(scene); + SEQ_sort(scene); WM_event_add_notifier(C, NC_SCENE | ND_SEQUENCER, scene); @@ -2382,7 +2382,7 @@ static int sequencer_rendersize_exec(bContext *C, wmOperator *UNUSED(op)) { int retval = OPERATOR_CANCELLED; Scene *scene = CTX_data_scene(C); - Sequence *active_seq = BKE_sequencer_active_get(scene); + Sequence *active_seq = SEQ_select_active_get(scene); StripElem *se = NULL; if (active_seq == NULL) { @@ -2458,11 +2458,11 @@ static int sequencer_copy_exec(bContext *C, wmOperator *op) { Main *bmain = CTX_data_main(C); Scene *scene = CTX_data_scene(C); - Editing *ed = BKE_sequencer_editing_get(scene, false); + Editing *ed = SEQ_editing_get(scene, false); - BKE_sequencer_free_clipboard(); + SEQ_clipboard_free(); - if (BKE_sequence_base_isolated_sel_check(ed->seqbasep) == false) { + if (SEQ_transform_seqbase_isolated_sel_check(ed->seqbasep) == false) { BKE_report(op->reports, RPT_ERROR, "Please select all related strips"); return OPERATOR_CANCELLED; } @@ -2470,7 +2470,7 @@ static int sequencer_copy_exec(bContext *C, wmOperator *op) /* NOTE: The UUID is re-generated on paste, so we can keep UUID in the clipboard since * nobody can reach them anyway. * This reduces chance or running out of UUIDs if a cat falls asleep on Ctrl-C. */ - BKE_sequence_base_dupli_recursive(scene, + SEQ_sequence_base_dupli_recursive(scene, scene, &seqbase_clipboard, ed->seqbasep, @@ -2486,7 +2486,7 @@ static int sequencer_copy_exec(bContext *C, wmOperator *op) /* Replace datablock pointers with copies, to keep things working in case * data-blocks get deleted or another .blend file is opened. */ - BKE_sequencer_base_clipboard_pointers_store(bmain, &seqbase_clipboard); + SEQ_clipboard_pointers_store(bmain, &seqbase_clipboard); return OPERATOR_FINISHED; } @@ -2515,7 +2515,7 @@ void SEQUENCER_OT_copy(wmOperatorType *ot) void ED_sequencer_deselect_all(Scene *scene) { Sequence *seq; - Editing *ed = BKE_sequencer_editing_get(scene, false); + Editing *ed = SEQ_editing_get(scene, false); if (ed == NULL) { return; @@ -2531,7 +2531,7 @@ static int sequencer_paste_exec(bContext *C, wmOperator *op) { Main *bmain = CTX_data_main(C); Scene *scene = CTX_data_scene(C); - Editing *ed = BKE_sequencer_editing_get(scene, true); /* Create if needed. */ + Editing *ed = SEQ_editing_get(scene, true); /* Create if needed. */ ListBase nseqbase = {NULL, NULL}; int ofs; Sequence *iseq, *iseq_first; @@ -2559,25 +2559,25 @@ static int sequencer_paste_exec(bContext *C, wmOperator *op) /* Copy strips, temporarily restoring pointers to actual data-blocks. This * must happen on the clipboard itself, so that copying does user counting * on the actual data-blocks. */ - BKE_sequencer_base_clipboard_pointers_restore(&seqbase_clipboard, bmain); - BKE_sequence_base_dupli_recursive(scene, scene, &nseqbase, &seqbase_clipboard, 0, 0); - BKE_sequencer_base_clipboard_pointers_store(bmain, &seqbase_clipboard); + SEQ_clipboard_pointers_restore(&seqbase_clipboard, bmain); + SEQ_sequence_base_dupli_recursive(scene, scene, &nseqbase, &seqbase_clipboard, 0, 0); + SEQ_clipboard_pointers_store(bmain, &seqbase_clipboard); iseq_first = nseqbase.first; - /* NOTE: BKE_sequence_base_dupli_recursive() takes care of generating new UUIDs for sequences + /* NOTE: SEQ_sequence_base_dupli_recursive() takes care of generating new UUIDs for sequences * in the new list. */ BLI_movelisttolist(ed->seqbasep, &nseqbase); for (iseq = iseq_first; iseq; iseq = iseq->next) { /* Make sure, that pasted strips have unique names. */ - BKE_sequencer_recursive_apply(iseq, apply_unique_name_fn, scene); + SEQ_iterator_recursive_apply(iseq, apply_unique_name_fn, scene); /* Translate after name has been changed, otherwise this will affect animdata of original * strip. */ - BKE_sequence_translate(scene, iseq, ofs); + SEQ_transform_translate_sequence(scene, iseq, ofs); /* Ensure, that pasted strips don't overlap. */ - if (BKE_sequence_test_overlap(ed->seqbasep, iseq)) { - BKE_sequence_base_shuffle(ed->seqbasep, iseq, scene); + if (SEQ_transform_test_overlap(ed->seqbasep, iseq)) { + SEQ_transform_seqbase_shuffle(ed->seqbasep, iseq, scene); } } @@ -2622,12 +2622,12 @@ static int sequencer_swap_data_exec(bContext *C, wmOperator *op) Sequence *seq_other; const char *error_msg; - if (BKE_sequencer_active_get_pair(scene, &seq_act, &seq_other) == 0) { + if (SEQ_select_active_get_pair(scene, &seq_act, &seq_other) == 0) { BKE_report(op->reports, RPT_ERROR, "Please select two strips"); return OPERATOR_CANCELLED; } - if (BKE_sequence_swap(seq_act, seq_other, &error_msg) == 0) { + if (SEQ_edit_sequence_swap(seq_act, seq_other, &error_msg) == 0) { BKE_report(op->reports, RPT_ERROR, error_msg); return OPERATOR_CANCELLED; } @@ -2643,8 +2643,8 @@ static int sequencer_swap_data_exec(bContext *C, wmOperator *op) seq_act->scene_sound = NULL; seq_other->scene_sound = NULL; - BKE_sequence_calc(scene, seq_act); - BKE_sequence_calc(scene, seq_other); + SEQ_time_update_sequence(scene, seq_act); + SEQ_time_update_sequence(scene, seq_other); if (seq_act->sound) { BKE_sound_add_scene_sound_defaults(scene, seq_act); @@ -2653,8 +2653,8 @@ static int sequencer_swap_data_exec(bContext *C, wmOperator *op) BKE_sound_add_scene_sound_defaults(scene, seq_other); } - BKE_sequence_invalidate_cache_raw(scene, seq_act); - BKE_sequence_invalidate_cache_raw(scene, seq_other); + SEQ_relations_invalidate_cache_raw(scene, seq_act); + SEQ_relations_invalidate_cache_raw(scene, seq_other); WM_event_add_notifier(C, NC_SCENE | ND_SEQUENCER, scene); @@ -2692,8 +2692,8 @@ static const EnumPropertyItem prop_change_effect_input_types[] = { static int sequencer_change_effect_input_exec(bContext *C, wmOperator *op) { Scene *scene = CTX_data_scene(C); - Editing *ed = BKE_sequencer_editing_get(scene, false); - Sequence *seq = BKE_sequencer_active_get(scene); + Editing *ed = SEQ_editing_get(scene, false); + Sequence *seq = SEQ_select_active_get(scene); Sequence **seq_1, **seq_2; @@ -2719,10 +2719,10 @@ static int sequencer_change_effect_input_exec(bContext *C, wmOperator *op) SWAP(Sequence *, *seq_1, *seq_2); - BKE_sequencer_update_changed_seq_and_deps(scene, seq, 0, 1); + SEQ_relations_update_changed_seq_and_deps(scene, seq, 0, 1); /* Invalidate cache. */ - BKE_sequencer_free_imbuf(scene, &ed->seqbase, false); + SEQ_relations_free_imbuf(scene, &ed->seqbase, false); WM_event_add_notifier(C, NC_SCENE | ND_SEQUENCER, scene); return OPERATOR_FINISHED; @@ -2776,8 +2776,8 @@ EnumPropertyItem sequencer_prop_effect_types[] = { static int sequencer_change_effect_type_exec(bContext *C, wmOperator *op) { Scene *scene = CTX_data_scene(C); - Editing *ed = BKE_sequencer_editing_get(scene, false); - Sequence *seq = BKE_sequencer_active_get(scene); + Editing *ed = SEQ_editing_get(scene, false); + Sequence *seq = SEQ_select_active_get(scene); const int new_type = RNA_enum_get(op->ptr, "type"); /* Free previous effect and init new effect. */ @@ -2789,23 +2789,22 @@ static int sequencer_change_effect_type_exec(bContext *C, wmOperator *op) /* Can someone explain the logic behind only allowing to increase this, * copied from 2.4x - campbell */ - if (BKE_sequence_effect_get_num_inputs(seq->type) < - BKE_sequence_effect_get_num_inputs(new_type)) { + if (SEQ_effect_get_num_inputs(seq->type) < SEQ_effect_get_num_inputs(new_type)) { BKE_report(op->reports, RPT_ERROR, "New effect needs more input strips"); return OPERATOR_CANCELLED; } - sh = BKE_sequence_get_effect(seq); + sh = SEQ_effect_handle_get(seq); sh.free(seq, true); seq->type = new_type; - sh = BKE_sequence_get_effect(seq); + sh = SEQ_effect_handle_get(seq); sh.init(seq); - BKE_sequencer_update_changed_seq_and_deps(scene, seq, 0, 1); + SEQ_relations_update_changed_seq_and_deps(scene, seq, 0, 1); /* Invalidate cache. */ - BKE_sequencer_free_imbuf(scene, &ed->seqbase, false); + SEQ_relations_free_imbuf(scene, &ed->seqbase, false); WM_event_add_notifier(C, NC_SCENE | ND_SEQUENCER, scene); @@ -2843,8 +2842,8 @@ static int sequencer_change_path_exec(bContext *C, wmOperator *op) { Main *bmain = CTX_data_main(C); Scene *scene = CTX_data_scene(C); - Editing *ed = BKE_sequencer_editing_get(scene, false); - Sequence *seq = BKE_sequencer_active_get(scene); + Editing *ed = SEQ_editing_get(scene, false); + Sequence *seq = SEQ_select_active_get(scene); const bool is_relative_path = RNA_boolean_get(op->ptr, "relative_path"); const bool use_placeholders = RNA_boolean_get(op->ptr, "use_placeholders"); int minext_frameme, numdigits; @@ -2897,12 +2896,12 @@ static int sequencer_change_path_exec(bContext *C, wmOperator *op) /* Correct start/end frames so we don't move. * Important not to set seq->len = len; allow the function to handle it. */ - BKE_sequence_reload_new_file(bmain, scene, seq, true); + SEQ_add_reload_new_file(bmain, scene, seq, true); - BKE_sequence_calc(scene, seq); + SEQ_time_update_sequence(scene, seq); /* Invalidate cache. */ - BKE_sequencer_free_imbuf(scene, &ed->seqbase, false); + SEQ_relations_free_imbuf(scene, &ed->seqbase, false); } else if (ELEM(seq->type, SEQ_TYPE_SOUND_RAM, SEQ_TYPE_SOUND_HD)) { bSound *sound = seq->sound; @@ -2936,7 +2935,7 @@ static int sequencer_change_path_exec(bContext *C, wmOperator *op) static int sequencer_change_path_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event)) { Scene *scene = CTX_data_scene(C); - Sequence *seq = BKE_sequencer_active_get(scene); + Sequence *seq = SEQ_select_active_get(scene); char filepath[FILE_MAX]; BLI_join_dirfile(filepath, sizeof(filepath), seq->strip->dir, seq->strip->stripdata->name); @@ -3020,7 +3019,7 @@ static int sequencer_export_subtitles_exec(bContext *C, wmOperator *op) { Scene *scene = CTX_data_scene(C); Sequence *seq, *seq_next; - Editing *ed = BKE_sequencer_editing_get(scene, false); + Editing *ed = SEQ_editing_get(scene, false); ListBase text_seq = {0}; int iter = 0; FILE *file; @@ -3059,7 +3058,7 @@ static int sequencer_export_subtitles_exec(bContext *C, wmOperator *op) return OPERATOR_CANCELLED; } - BLI_listbase_sort(&text_seq, BKE_sequencer_cmp_time_startdisp); + BLI_listbase_sort(&text_seq, SEQ_time_cmp_time_startdisp); /* Open and write file. */ file = BLI_fopen(filepath, "w"); @@ -3098,7 +3097,7 @@ static bool sequencer_strip_is_text_poll(bContext *C) { Editing *ed; Sequence *seq; - return (((ed = BKE_sequencer_editing_get(CTX_data_scene(C), false)) != NULL) && + return (((ed = SEQ_editing_get(CTX_data_scene(C), false)) != NULL) && ((seq = ed->act_seq) != NULL) && (seq->type == SEQ_TYPE_TEXT)); } @@ -3135,7 +3134,7 @@ void SEQUENCER_OT_export_subtitles(struct wmOperatorType *ot) static int sequencer_set_range_to_strips_exec(bContext *C, wmOperator *op) { Scene *scene = CTX_data_scene(C); - Editing *ed = BKE_sequencer_editing_get(scene, false); + Editing *ed = SEQ_editing_get(scene, false); Sequence *seq; int sfra = MAXFRAME; @@ -3206,7 +3205,7 @@ void SEQUENCER_OT_set_range_to_strips(struct wmOperatorType *ot) static void set_filter_seq(Scene *scene) { Sequence *seq; - Editing *ed = BKE_sequencer_editing_get(scene, false); + Editing *ed = SEQ_editing_get(scene, false); if (ed == NULL) { return; @@ -3220,8 +3219,8 @@ static void set_filter_seq(Scene *scene) if (seq->flag & SELECT) { if (seq->type == SEQ_TYPE_MOVIE) { seq->flag |= SEQ_FILTERY; - BKE_sequence_reload_new_file(bmain, scene, seq, false); - BKE_sequence_calc(scene, seq); + SEQ_add_reload_new_file(bmain, scene, seq, false); + SEQ_time_update_sequence(scene, seq); } } } @@ -3230,8 +3229,8 @@ static void set_filter_seq(Scene *scene) static void UNUSED_FUNCTION(seq_remap_paths)(Scene *scene) { - Sequence *seq, *last_seq = BKE_sequencer_active_get(scene); - Editing *ed = BKE_sequencer_editing_get(scene, false); + Sequence *seq, *last_seq = SEQ_select_active_get(scene); + Editing *ed = SEQ_editing_get(scene, false); char from[FILE_MAX], to[FILE_MAX], stripped[FILE_MAX]; if (last_seq == NULL) { @@ -3270,7 +3269,7 @@ static void UNUSED_FUNCTION(seq_remap_paths)(Scene *scene) static Sequence *sequence_find_parent(Scene *scene, Sequence *child) { - Editing *ed = BKE_sequencer_editing_get(scene, false); + Editing *ed = SEQ_editing_get(scene, false); Sequence *parent = NULL; Sequence *seq; @@ -3322,7 +3321,7 @@ Sequence *find_neighboring_sequence(Scene *scene, Sequence *test, int lr, int se { /* sel: 0==unselected, 1==selected, -1==don't care. */ Sequence *seq; - Editing *ed = BKE_sequencer_editing_get(scene, false); + Editing *ed = SEQ_editing_get(scene, false); if (ed == NULL) { return NULL; @@ -3356,7 +3355,7 @@ Sequence *find_neighboring_sequence(Scene *scene, Sequence *test, int lr, int se Sequence *find_nearest_seq(Scene *scene, View2D *v2d, int *hand, const int mval[2]) { Sequence *seq; - Editing *ed = BKE_sequencer_editing_get(scene, false); + Editing *ed = SEQ_editing_get(scene, false); float x, y; float pixelx; float handsize; @@ -3378,7 +3377,7 @@ Sequence *find_nearest_seq(Scene *scene, View2D *v2d, int *hand, const int mval[ /* Check for both normal strips, and strips that have been flipped horizontally. */ if (((seq->startdisp < seq->enddisp) && (seq->startdisp <= x && seq->enddisp >= x)) || ((seq->startdisp > seq->enddisp) && (seq->startdisp >= x && seq->enddisp <= x))) { - if (BKE_sequence_tx_test(seq)) { + if (SEQ_transform_sequence_can_be_translated(seq)) { /* Clamp handles to defined size in pixel space. */ handsize = 2.0f * sequence_handle_size_get_clamped(seq, pixelx); @@ -3437,7 +3436,7 @@ static const EnumPropertyItem transform_reset_properties[] = { static int sequencer_strip_transform_clear_exec(bContext *C, wmOperator *op) { Scene *scene = CTX_data_scene(C); - const Editing *ed = BKE_sequencer_editing_get(scene, false); + const Editing *ed = SEQ_editing_get(scene, false); Sequence *seq; const int property = RNA_enum_get(op->ptr, "property"); @@ -3464,7 +3463,7 @@ static int sequencer_strip_transform_clear_exec(bContext *C, wmOperator *op) transform->rotation = 0.0f; break; } - BKE_sequence_invalidate_cache_preprocessed(scene, seq); + SEQ_relations_invalidate_cache_preprocessed(scene, seq); } } @@ -3510,7 +3509,7 @@ static const EnumPropertyItem scale_fit_methods[] = { static int sequencer_strip_transform_fit_exec(bContext *C, wmOperator *op) { Scene *scene = CTX_data_scene(C); - const Editing *ed = BKE_sequencer_editing_get(scene, false); + const Editing *ed = SEQ_editing_get(scene, false); Sequence *seq; const eSeqImageFitMethod fit_method = RNA_enum_get(op->ptr, "fit_method"); @@ -3529,7 +3528,7 @@ static int sequencer_strip_transform_fit_exec(bContext *C, wmOperator *op) scene->r.xsch, scene->r.ysch, fit_method); - BKE_sequence_invalidate_cache_preprocessed(scene, seq); + SEQ_relations_invalidate_cache_preprocessed(scene, seq); } } diff --git a/source/blender/editors/space_sequencer/sequencer_modifier.c b/source/blender/editors/space_sequencer/sequencer_modifier.c index fb09afc6ca5..e8f4fac1920 100644 --- a/source/blender/editors/space_sequencer/sequencer_modifier.c +++ b/source/blender/editors/space_sequencer/sequencer_modifier.c @@ -44,13 +44,13 @@ static bool strip_modifier_active_poll(bContext *C) { Scene *scene = CTX_data_scene(C); - Editing *ed = BKE_sequencer_editing_get(scene, false); + Editing *ed = SEQ_editing_get(scene, false); if (ed) { - Sequence *seq = BKE_sequencer_active_get(scene); + Sequence *seq = SEQ_select_active_get(scene); if (seq) { - return BKE_sequence_supports_modifiers(seq); + return SEQ_sequence_supports_modifiers(seq); } } @@ -60,12 +60,12 @@ static bool strip_modifier_active_poll(bContext *C) static int strip_modifier_add_exec(bContext *C, wmOperator *op) { Scene *scene = CTX_data_scene(C); - Sequence *seq = BKE_sequencer_active_get(scene); + Sequence *seq = SEQ_select_active_get(scene); int type = RNA_enum_get(op->ptr, "type"); - BKE_sequence_modifier_new(seq, NULL, type); + SEQ_modifier_new(seq, NULL, type); - BKE_sequence_invalidate_cache_preprocessed(scene, seq); + SEQ_relations_invalidate_cache_preprocessed(scene, seq); WM_event_add_notifier(C, NC_SCENE | ND_SEQUENCER, scene); return OPERATOR_FINISHED; @@ -102,21 +102,21 @@ void SEQUENCER_OT_strip_modifier_add(wmOperatorType *ot) static int strip_modifier_remove_exec(bContext *C, wmOperator *op) { Scene *scene = CTX_data_scene(C); - Sequence *seq = BKE_sequencer_active_get(scene); + Sequence *seq = SEQ_select_active_get(scene); char name[MAX_NAME]; SequenceModifierData *smd; RNA_string_get(op->ptr, "name", name); - smd = BKE_sequence_modifier_find_by_name(seq, name); + smd = SEQ_modifier_find_by_name(seq, name); if (!smd) { return OPERATOR_CANCELLED; } BLI_remlink(&seq->modifiers, smd); - BKE_sequence_modifier_free(smd); + SEQ_modifier_free(smd); - BKE_sequence_invalidate_cache_preprocessed(scene, seq); + SEQ_relations_invalidate_cache_preprocessed(scene, seq); WM_event_add_notifier(C, NC_SCENE | ND_SEQUENCER, scene); return OPERATOR_FINISHED; @@ -153,7 +153,7 @@ enum { static int strip_modifier_move_exec(bContext *C, wmOperator *op) { Scene *scene = CTX_data_scene(C); - Sequence *seq = BKE_sequencer_active_get(scene); + Sequence *seq = SEQ_select_active_get(scene); char name[MAX_NAME]; int direction; SequenceModifierData *smd; @@ -161,7 +161,7 @@ static int strip_modifier_move_exec(bContext *C, wmOperator *op) RNA_string_get(op->ptr, "name", name); direction = RNA_enum_get(op->ptr, "direction"); - smd = BKE_sequence_modifier_find_by_name(seq, name); + smd = SEQ_modifier_find_by_name(seq, name); if (!smd) { return OPERATOR_CANCELLED; } @@ -179,7 +179,7 @@ static int strip_modifier_move_exec(bContext *C, wmOperator *op) } } - BKE_sequence_invalidate_cache_preprocessed(scene, seq); + SEQ_relations_invalidate_cache_preprocessed(scene, seq); WM_event_add_notifier(C, NC_SCENE | ND_SEQUENCER, scene); return OPERATOR_FINISHED; @@ -225,7 +225,7 @@ static int strip_modifier_copy_exec(bContext *C, wmOperator *op) { Scene *scene = CTX_data_scene(C); Editing *ed = scene->ed; - Sequence *seq = BKE_sequencer_active_get(scene); + Sequence *seq = SEQ_select_active_get(scene); Sequence *seq_iter; const int type = RNA_enum_get(op->ptr, "type"); @@ -245,19 +245,19 @@ static int strip_modifier_copy_exec(bContext *C, wmOperator *op) while (smd) { smd_tmp = smd->next; BLI_remlink(&seq_iter->modifiers, smd); - BKE_sequence_modifier_free(smd); + SEQ_modifier_free(smd); smd = smd_tmp; } BLI_listbase_clear(&seq_iter->modifiers); } } - BKE_sequence_modifier_list_copy(seq_iter, seq); + SEQ_modifier_list_copy(seq_iter, seq); } } SEQ_CURRENT_END; - BKE_sequence_invalidate_cache_preprocessed(scene, seq); + SEQ_relations_invalidate_cache_preprocessed(scene, seq); WM_event_add_notifier(C, NC_SCENE | ND_SEQUENCER, scene); return OPERATOR_FINISHED; diff --git a/source/blender/editors/space_sequencer/sequencer_proxy.c b/source/blender/editors/space_sequencer/sequencer_proxy.c index 2d23520814a..032885c2719 100644 --- a/source/blender/editors/space_sequencer/sequencer_proxy.c +++ b/source/blender/editors/space_sequencer/sequencer_proxy.c @@ -90,14 +90,14 @@ static void proxy_startjob(void *pjv, short *stop, short *do_update, float *prog static void proxy_endjob(void *pjv) { ProxyJob *pj = pjv; - Editing *ed = BKE_sequencer_editing_get(pj->scene, false); + Editing *ed = SEQ_editing_get(pj->scene, false); LinkData *link; for (link = pj->queue.first; link; link = link->next) { SEQ_proxy_rebuild_finish(link->data, pj->stop); } - BKE_sequencer_free_imbuf(pj->scene, &ed->seqbase, false); + SEQ_relations_free_imbuf(pj->scene, &ed->seqbase, false); WM_main_add_notifier(NC_SCENE | ND_SEQUENCER, pj->scene); } @@ -108,7 +108,7 @@ static void seq_proxy_build_job(const bContext *C, ReportList *reports) ProxyJob *pj; struct Depsgraph *depsgraph = CTX_data_depsgraph_pointer(C); Scene *scene = CTX_data_scene(C); - Editing *ed = BKE_sequencer_editing_get(scene, false); + Editing *ed = SEQ_editing_get(scene, false); ScrArea *area = CTX_wm_area(C); Sequence *seq; GSet *file_list; @@ -201,7 +201,7 @@ static int sequencer_rebuild_proxy_exec(bContext *C, wmOperator *UNUSED(op)) Main *bmain = CTX_data_main(C); struct Depsgraph *depsgraph = CTX_data_ensure_evaluated_depsgraph(C); Scene *scene = CTX_data_scene(C); - Editing *ed = BKE_sequencer_editing_get(scene, false); + Editing *ed = SEQ_editing_get(scene, false); Sequence *seq; GSet *file_list; @@ -225,7 +225,7 @@ static int sequencer_rebuild_proxy_exec(bContext *C, wmOperator *UNUSED(op)) SEQ_proxy_rebuild(context, &stop, &do_update, &progress); SEQ_proxy_rebuild_finish(context, 0); } - BKE_sequencer_free_imbuf(scene, &ed->seqbase, false); + SEQ_relations_free_imbuf(scene, &ed->seqbase, false); } } SEQ_CURRENT_END; @@ -266,7 +266,7 @@ static int sequencer_enable_proxies_invoke(bContext *C, static int sequencer_enable_proxies_exec(bContext *C, wmOperator *op) { Scene *scene = CTX_data_scene(C); - Editing *ed = BKE_sequencer_editing_get(scene, false); + Editing *ed = SEQ_editing_get(scene, false); Sequence *seq; bool proxy_25 = RNA_boolean_get(op->ptr, "proxy_25"); bool proxy_50 = RNA_boolean_get(op->ptr, "proxy_50"); diff --git a/source/blender/editors/space_sequencer/sequencer_select.c b/source/blender/editors/space_sequencer/sequencer_select.c index a6b2d7feae3..6534a63f03e 100644 --- a/source/blender/editors/space_sequencer/sequencer_select.c +++ b/source/blender/editors/space_sequencer/sequencer_select.c @@ -198,13 +198,13 @@ void select_surround_from_last(Scene *scene) void ED_sequencer_select_sequence_single(Scene *scene, Sequence *seq, bool deselect_all) { - Editing *ed = BKE_sequencer_editing_get(scene, false); + Editing *ed = SEQ_editing_get(scene, false); if (deselect_all) { ED_sequencer_deselect_all(scene); } - BKE_sequencer_active_set(scene, seq); + SEQ_select_active_set(scene, seq); if (ELEM(seq->type, SEQ_TYPE_IMAGE, SEQ_TYPE_MOVIE)) { if (seq->strip) { @@ -223,7 +223,7 @@ void ED_sequencer_select_sequence_single(Scene *scene, Sequence *seq, bool desel #if 0 static void select_neighbor_from_last(Scene *scene, int lr) { - Sequence *seq = BKE_sequencer_active_get(scene); + Sequence *seq = SEQ_select_active_get(scene); Sequence *neighbor; bool changed = false; if (seq) { @@ -264,7 +264,7 @@ static int sequencer_de_select_all_exec(bContext *C, wmOperator *op) int action = RNA_enum_get(op->ptr, "action"); Scene *scene = CTX_data_scene(C); - Editing *ed = BKE_sequencer_editing_get(scene, false); + Editing *ed = SEQ_editing_get(scene, false); Sequence *seq; if (action == SEL_TOGGLE) { @@ -331,7 +331,7 @@ void SEQUENCER_OT_select_all(struct wmOperatorType *ot) static int sequencer_select_inverse_exec(bContext *C, wmOperator *UNUSED(op)) { Scene *scene = CTX_data_scene(C); - Editing *ed = BKE_sequencer_editing_get(scene, false); + Editing *ed = SEQ_editing_get(scene, false); Sequence *seq; for (seq = ed->seqbasep->first; seq; seq = seq->next) { @@ -376,7 +376,7 @@ static int sequencer_select_exec(bContext *C, wmOperator *op) { View2D *v2d = UI_view2d_fromcontext(C); Scene *scene = CTX_data_scene(C); - Editing *ed = BKE_sequencer_editing_get(scene, false); + Editing *ed = SEQ_editing_get(scene, false); const bool extend = RNA_boolean_get(op->ptr, "extend"); const bool deselect_all = RNA_boolean_get(op->ptr, "deselect_all"); const bool linked_handle = RNA_boolean_get(op->ptr, "linked_handle"); @@ -464,7 +464,7 @@ static int sequencer_select_exec(bContext *C, wmOperator *op) ret_value = OPERATOR_FINISHED; } - BKE_sequencer_active_set(scene, seq); + SEQ_select_active_set(scene, seq); if (ELEM(seq->type, SEQ_TYPE_IMAGE, SEQ_TYPE_MOVIE)) { if (seq->strip) { @@ -667,7 +667,7 @@ void SEQUENCER_OT_select(wmOperatorType *ot) /* Run recursively to select linked. */ static bool select_more_less_seq__internal(Scene *scene, bool sel, const bool linked) { - Editing *ed = BKE_sequencer_editing_get(scene, false); + Editing *ed = SEQ_editing_get(scene, false); Sequence *seq, *neighbor; bool changed = false; int isel; @@ -903,7 +903,7 @@ void SEQUENCER_OT_select_linked(wmOperatorType *ot) static int sequencer_select_handles_exec(bContext *C, wmOperator *op) { Scene *scene = CTX_data_scene(C); - Editing *ed = BKE_sequencer_editing_get(scene, false); + Editing *ed = SEQ_editing_get(scene, false); Sequence *seq; int sel_side = RNA_enum_get(op->ptr, "side"); @@ -964,7 +964,7 @@ void SEQUENCER_OT_select_handles(wmOperatorType *ot) static int sequencer_select_side_of_frame_exec(bContext *C, wmOperator *op) { Scene *scene = CTX_data_scene(C); - Editing *ed = BKE_sequencer_editing_get(scene, false); + Editing *ed = SEQ_editing_get(scene, false); const bool extend = RNA_boolean_get(op->ptr, "extend"); const int side = RNA_enum_get(op->ptr, "side"); Sequence *seq; @@ -1038,7 +1038,7 @@ void SEQUENCER_OT_select_side_of_frame(wmOperatorType *ot) static int sequencer_select_side_exec(bContext *C, wmOperator *op) { Scene *scene = CTX_data_scene(C); - Editing *ed = BKE_sequencer_editing_get(scene, false); + Editing *ed = SEQ_editing_get(scene, false); const int sel_side = RNA_enum_get(op->ptr, "side"); const int frame_init = sel_side == SEQ_SIDE_LEFT ? INT_MIN : INT_MAX; @@ -1109,7 +1109,7 @@ static int sequencer_box_select_exec(bContext *C, wmOperator *op) { Scene *scene = CTX_data_scene(C); View2D *v2d = UI_view2d_fromcontext(C); - Editing *ed = BKE_sequencer_editing_get(scene, false); + Editing *ed = SEQ_editing_get(scene, false); if (ed == NULL) { return OPERATOR_CANCELLED; @@ -1454,8 +1454,7 @@ static bool select_grouped_effect_link(Editing *ed, Sequence *actseq, const int actseq->tmp = POINTER_FROM_INT(true); - for (BKE_sequence_iterator_begin(ed, &iter, true); iter.valid; - BKE_sequence_iterator_next(&iter)) { + for (SEQ_iterator_begin(ed, &iter, true); iter.valid; SEQ_iterator_next(&iter)) { seq = iter.seq; /* Ignore all seqs already selected. */ @@ -1486,8 +1485,8 @@ static bool select_grouped_effect_link(Editing *ed, Sequence *actseq, const int changed = true; /* Unfortunately, we must restart checks from the beginning. */ - BKE_sequence_iterator_end(&iter); - BKE_sequence_iterator_begin(ed, &iter, true); + SEQ_iterator_end(&iter); + SEQ_iterator_begin(ed, &iter, true); } /* Video strips below active one, or any strip for audio (order doesn't matter here). */ @@ -1496,7 +1495,7 @@ static bool select_grouped_effect_link(Editing *ed, Sequence *actseq, const int changed = true; } } - BKE_sequence_iterator_end(&iter); + SEQ_iterator_end(&iter); return changed; } @@ -1508,8 +1507,8 @@ static bool select_grouped_effect_link(Editing *ed, Sequence *actseq, const int static int sequencer_select_grouped_exec(bContext *C, wmOperator *op) { Scene *scene = CTX_data_scene(C); - Editing *ed = BKE_sequencer_editing_get(scene, false); - Sequence *seq, *actseq = BKE_sequencer_active_get(scene); + Editing *ed = SEQ_editing_get(scene, false); + Sequence *seq, *actseq = SEQ_select_active_get(scene); if (actseq == NULL) { BKE_report(op->reports, RPT_ERROR, "No active sequence!"); diff --git a/source/blender/editors/space_sequencer/sequencer_view.c b/source/blender/editors/space_sequencer/sequencer_view.c index e12c43b7804..250a0afc717 100644 --- a/source/blender/editors/space_sequencer/sequencer_view.c +++ b/source/blender/editors/space_sequencer/sequencer_view.c @@ -88,7 +88,7 @@ static int sequencer_view_all_exec(bContext *C, wmOperator *op) const int smooth_viewtx = WM_operator_smooth_viewtx_get(op); Scene *scene = CTX_data_scene(C); - const Editing *ed = BKE_sequencer_editing_get(scene, false); + const Editing *ed = SEQ_editing_get(scene, false); SEQ_timeline_boundbox(scene, SEQ_active_seqbase_get(ed), &box); UI_view2d_smooth_view(C, region, &box, smooth_viewtx); @@ -272,8 +272,8 @@ static int sequencer_view_selected_exec(bContext *C, wmOperator *op) Scene *scene = CTX_data_scene(C); View2D *v2d = UI_view2d_fromcontext(C); ARegion *region = CTX_wm_region(C); - Editing *ed = BKE_sequencer_editing_get(scene, false); - Sequence *last_seq = BKE_sequencer_active_get(scene); + Editing *ed = SEQ_editing_get(scene, false); + Sequence *last_seq = SEQ_select_active_get(scene); Sequence *seq; rctf cur_new = v2d->cur; diff --git a/source/blender/editors/space_sequencer/space_sequencer.c b/source/blender/editors/space_sequencer/space_sequencer.c index 2bf4741e4f5..19146db3719 100644 --- a/source/blender/editors/space_sequencer/space_sequencer.c +++ b/source/blender/editors/space_sequencer/space_sequencer.c @@ -471,7 +471,7 @@ static int /*eContextResult*/ sequencer_context(const bContext *C, return CTX_RESULT_OK; } if (CTX_data_equals(member, "edit_mask")) { - Mask *mask = BKE_sequencer_mask_get(scene); + Mask *mask = SEQ_active_mask_get(scene); if (mask) { CTX_data_id_pointer_set(result, &mask->id); } diff --git a/source/blender/editors/transform/transform_convert_sequencer.c b/source/blender/editors/transform/transform_convert_sequencer.c index 3f86ef3e81b..83e384010bd 100644 --- a/source/blender/editors/transform/transform_convert_sequencer.c +++ b/source/blender/editors/transform/transform_convert_sequencer.c @@ -84,8 +84,8 @@ static void SeqTransInfo(TransInfo *t, Sequence *seq, int *r_recursive, int *r_c Scene *scene = t->scene; int cfra = CFRA; - int left = BKE_sequence_tx_get_final_left(seq, true); - int right = BKE_sequence_tx_get_final_right(seq, true); + int left = SEQ_transform_get_left_handle_frame(seq, true); + int right = SEQ_transform_get_right_handle_frame(seq, true); if (seq->depth == 0 && ((seq->flag & SELECT) == 0 || (seq->flag & SEQ_LOCK))) { *r_recursive = false; @@ -186,7 +186,7 @@ static void SeqTransInfo(TransInfo *t, Sequence *seq, int *r_recursive, int *r_c /* Meta's can only directly be moved between channels since they * don't have their start and length set directly (children affect that) * since this Meta is nested we don't need any of its data in fact. - * BKE_sequence_calc() will update its settings when run on the top-level meta. */ + * SEQ_time_update_sequence() will update its settings when run on the top-level meta. */ *r_flag = 0; *r_count = 0; *r_recursive = true; @@ -235,16 +235,16 @@ static TransData *SeqToTransData( /* Use seq_tx_get_final_left() and an offset here * so transform has the left hand location of the strip. * tdsq->start_offset is used when flushing the tx data back */ - start_left = BKE_sequence_tx_get_final_left(seq, false); + start_left = SEQ_transform_get_left_handle_frame(seq, false); td2d->loc[0] = start_left; tdsq->start_offset = start_left - seq->start; /* use to apply the original location */ break; case SEQ_LEFTSEL: - start_left = BKE_sequence_tx_get_final_left(seq, false); + start_left = SEQ_transform_get_left_handle_frame(seq, false); td2d->loc[0] = start_left; break; case SEQ_RIGHTSEL: - td2d->loc[0] = BKE_sequence_tx_get_final_right(seq, false); + td2d->loc[0] = SEQ_transform_get_right_handle_frame(seq, false); break; } @@ -366,7 +366,7 @@ static void SeqTransDataBounds(TransInfo *t, ListBase *seqbase, TransSeq *ts) static void freeSeqData(TransInfo *t, TransDataContainer *tc, TransCustomData *custom_data) { - Editing *ed = BKE_sequencer_editing_get(t->scene, false); + Editing *ed = SEQ_editing_get(t->scene, false); if (ed != NULL) { @@ -388,7 +388,7 @@ static void freeSeqData(TransInfo *t, TransDataContainer *tc, TransCustomData *c for (a = 0; a < t->total; a++, td++) { if ((seq != seq_prev) && (seq->depth == 0) && (seq->flag & SEQ_OVERLAP)) { seq = ((TransDataSeq *)td->extra)->seq; - BKE_sequence_base_shuffle(seqbasep, seq, t->scene); + SEQ_transform_seqbase_shuffle(seqbasep, seq, t->scene); } seq_prev = seq; @@ -429,7 +429,7 @@ static void freeSeqData(TransInfo *t, TransDataContainer *tc, TransCustomData *c } else { /* Tag seq with a non zero value, used by - * BKE_sequence_base_shuffle_time to identify the ones to shuffle */ + * SEQ_transform_seqbase_shuffle_time to identify the ones to shuffle */ if (seq->depth == 0) { seq->tmp = (void *)1; } @@ -455,7 +455,7 @@ static void freeSeqData(TransInfo *t, TransDataContainer *tc, TransCustomData *c } } - BKE_sequence_base_shuffle_time(seqbasep, t->scene, markers, use_sync_markers); + SEQ_transform_seqbase_shuffle_time(seqbasep, t->scene, markers, use_sync_markers); for (seq = seqbasep->first; seq; seq = seq->next) { if (seq->machine >= MAXSEQ * 2) { @@ -467,10 +467,10 @@ static void freeSeqData(TransInfo *t, TransDataContainer *tc, TransCustomData *c } } - BKE_sequence_base_shuffle_time(seqbasep, t->scene, markers, use_sync_markers); + SEQ_transform_seqbase_shuffle_time(seqbasep, t->scene, markers, use_sync_markers); } else { - BKE_sequence_base_shuffle_time(seqbasep, t->scene, markers, use_sync_markers); + SEQ_transform_seqbase_shuffle_time(seqbasep, t->scene, markers, use_sync_markers); } if (has_effect_any) { @@ -480,7 +480,7 @@ static void freeSeqData(TransInfo *t, TransDataContainer *tc, TransCustomData *c seq = ((TransDataSeq *)td->extra)->seq; if ((seq != seq_prev)) { if ((seq->type & SEQ_TYPE_EFFECT) && seq->seq1) { - BKE_sequence_calc(t->scene, seq); + SEQ_time_update_sequence(t->scene, seq); } } } @@ -493,8 +493,8 @@ static void freeSeqData(TransInfo *t, TransDataContainer *tc, TransCustomData *c seq = ((TransDataSeq *)td->extra)->seq; if ((seq != seq_prev) && (seq->depth == 0)) { if ((seq->type & SEQ_TYPE_EFFECT) && seq->seq1) { - if (BKE_sequence_test_overlap(seqbasep, seq)) { - BKE_sequence_base_shuffle(seqbasep, seq, t->scene); + if (SEQ_transform_test_overlap(seqbasep, seq)) { + SEQ_transform_seqbase_shuffle(seqbasep, seq, t->scene); } } } @@ -509,18 +509,18 @@ static void freeSeqData(TransInfo *t, TransDataContainer *tc, TransCustomData *c /* We might want to build a list of effects that need to be updated during transform */ if (seq->type & SEQ_TYPE_EFFECT) { if (seq->seq1 && seq->seq1->flag & SELECT) { - BKE_sequence_calc(t->scene, seq); + SEQ_time_update_sequence(t->scene, seq); } else if (seq->seq2 && seq->seq2->flag & SELECT) { - BKE_sequence_calc(t->scene, seq); + SEQ_time_update_sequence(t->scene, seq); } else if (seq->seq3 && seq->seq3->flag & SELECT) { - BKE_sequence_calc(t->scene, seq); + SEQ_time_update_sequence(t->scene, seq); } } } - BKE_sequencer_sort(t->scene); + SEQ_sort(t->scene); } else { /* Canceled, need to update the strips display */ @@ -528,10 +528,10 @@ static void freeSeqData(TransInfo *t, TransDataContainer *tc, TransCustomData *c seq = ((TransDataSeq *)td->extra)->seq; if ((seq != seq_prev) && (seq->depth == 0)) { if (seq->flag & SEQ_OVERLAP) { - BKE_sequence_base_shuffle(seqbasep, seq, t->scene); + SEQ_transform_seqbase_shuffle(seqbasep, seq, t->scene); } - BKE_sequence_calc_disp(t->scene, seq); + SEQ_time_update_sequence_bounds(t->scene, seq); } seq_prev = seq; } @@ -553,7 +553,7 @@ void createTransSeqData(TransInfo *t) #define XXX_DURIAN_ANIM_TX_HACK Scene *scene = t->scene; - Editing *ed = BKE_sequencer_editing_get(t->scene, false); + Editing *ed = SEQ_editing_get(t->scene, false); TransData *td = NULL; TransData2D *td2d = NULL; TransDataSeq *tdsq = NULL; @@ -640,21 +640,21 @@ BLI_INLINE void trans_update_seq(Scene *sce, Sequence *seq, int old_start, int s /* Calculate this strip and all nested strips. * Children are ALWAYS transformed first so we don't need to do this in another loop. */ - BKE_sequence_calc(sce, seq); + SEQ_time_update_sequence(sce, seq); } else { - BKE_sequence_calc_disp(sce, seq); + SEQ_time_update_sequence_bounds(sce, seq); } if (sel_flag == SELECT) { - BKE_sequencer_offset_animdata(sce, seq, seq->start - old_start); + SEQ_offset_animdata(sce, seq, seq->start - old_start); } } static void flushTransSeq(TransInfo *t) { /* Editing null check already done */ - ListBase *seqbasep = BKE_sequencer_editing_get(t->scene, false)->seqbasep; + ListBase *seqbasep = SEQ_editing_get(t->scene, false)->seqbasep; int a, new_frame; TransData *td = NULL; @@ -681,7 +681,7 @@ static void flushTransSeq(TransInfo *t) switch (tdsq->sel_flag) { case SELECT: #ifdef SEQ_TX_NESTED_METAS - if ((seq->depth != 0 || BKE_sequence_tx_test(seq))) { + if ((seq->depth != 0 || SEQ_transform_sequence_can_be_translated(seq))) { /* for meta's, their children move */ seq->start = new_frame - tdsq->start_offset; } @@ -697,18 +697,18 @@ static void flushTransSeq(TransInfo *t) } break; case SEQ_LEFTSEL: /* no vertical transform */ - BKE_sequence_tx_set_final_left(seq, new_frame); - BKE_sequence_tx_handle_xlimits(seq, tdsq->flag & SEQ_LEFTSEL, tdsq->flag & SEQ_RIGHTSEL); + SEQ_transform_set_left_handle_frame(seq, new_frame); + SEQ_transform_handle_xlimits(seq, tdsq->flag & SEQ_LEFTSEL, tdsq->flag & SEQ_RIGHTSEL); /* todo - move this into aftertrans update? - old seq tx needed it anyway */ - BKE_sequence_single_fix(seq); + SEQ_transform_fix_single_image_seq_offsets(seq); break; case SEQ_RIGHTSEL: /* no vertical transform */ - BKE_sequence_tx_set_final_right(seq, new_frame); - BKE_sequence_tx_handle_xlimits(seq, tdsq->flag & SEQ_LEFTSEL, tdsq->flag & SEQ_RIGHTSEL); + SEQ_transform_set_right_handle_frame(seq, new_frame); + SEQ_transform_handle_xlimits(seq, tdsq->flag & SEQ_LEFTSEL, tdsq->flag & SEQ_RIGHTSEL); /* todo - move this into aftertrans update? - old seq tx needed it anyway */ - BKE_sequence_single_fix(seq); + SEQ_transform_fix_single_image_seq_offsets(seq); break; } @@ -743,12 +743,12 @@ static void flushTransSeq(TransInfo *t) /* calc all meta's then effects T27953. */ for (seq = seqbasep->first; seq; seq = seq->next) { if (seq->type == SEQ_TYPE_META && seq->flag & SELECT) { - BKE_sequence_calc(t->scene, seq); + SEQ_time_update_sequence(t->scene, seq); } } for (seq = seqbasep->first; seq; seq = seq->next) { if (seq->seq1 || seq->seq2 || seq->seq3) { - BKE_sequence_calc(t->scene, seq); + SEQ_time_update_sequence(t->scene, seq); } } @@ -759,7 +759,7 @@ static void flushTransSeq(TransInfo *t) seq = tdsq->seq; if ((seq != seq_prev) && (seq->depth != 0)) { if (seq->seq1 || seq->seq2 || seq->seq3) { - BKE_sequence_calc(t->scene, seq); + SEQ_time_update_sequence(t->scene, seq); } } } @@ -777,7 +777,7 @@ static void flushTransSeq(TransInfo *t) if (seq->depth == 0) { /* test overlap, displays red outline */ seq->flag &= ~SEQ_OVERLAP; - if (BKE_sequence_test_overlap(seqbasep, seq)) { + if (SEQ_transform_test_overlap(seqbasep, seq)) { seq->flag |= SEQ_OVERLAP; } } @@ -800,7 +800,7 @@ void recalcData_sequencer(TransInfo *t) Sequence *seq = tdsq->seq; if (seq != seq_prev) { - BKE_sequence_invalidate_cache_composite(t->scene, seq); + SEQ_relations_invalidate_cache_composite(t->scene, seq); } seq_prev = seq; diff --git a/source/blender/editors/transform/transform_snap.c b/source/blender/editors/transform/transform_snap.c index f1c4c243780..8d20f1686f2 100644 --- a/source/blender/editors/transform/transform_snap.c +++ b/source/blender/editors/transform/transform_snap.c @@ -1409,7 +1409,7 @@ void snapSequenceBounds(TransInfo *t, const int mval[2]) const int frame_curr = round_fl_to_int(xmouse); /* Now find the closest sequence. */ - const int frame_near = BKE_sequencer_find_next_prev_edit( + const int frame_near = SEQ_time_find_next_prev_edit( t->scene, frame_curr, SEQ_SIDE_BOTH, true, false, true); const int frame_snap = transform_convert_sequencer_get_snap_bound(t); diff --git a/source/blender/editors/util/ed_util_imbuf.c b/source/blender/editors/util/ed_util_imbuf.c index b832d9a1d86..ca97a7b21c3 100644 --- a/source/blender/editors/util/ed_util_imbuf.c +++ b/source/blender/editors/util/ed_util_imbuf.c @@ -564,7 +564,7 @@ bool ED_imbuf_sample_poll(bContext *C) return false; } - return sseq && BKE_sequencer_editing_get(CTX_data_scene(C), false) != NULL; + return sseq && SEQ_editing_get(CTX_data_scene(C), false) != NULL; } return false; -- cgit v1.2.3 From a5a302bd18061e833c4d629fffd06f57e7447d39 Mon Sep 17 00:00:00 2001 From: Richard Antalik Date: Sat, 19 Dec 2020 06:44:57 +0100 Subject: Cleanup: Split SEQ_sequencer.h file --- source/blender/editors/animation/anim_deps.c | 1 + source/blender/editors/animation/anim_filter.c | 1 + source/blender/editors/animation/anim_ops.c | 1 + source/blender/editors/render/render_internal.c | 2 +- source/blender/editors/render/render_opengl.c | 2 +- source/blender/editors/sound/sound_ops.c | 2 +- source/blender/editors/space_outliner/outliner_select.c | 1 + source/blender/editors/space_outliner/outliner_sync.c | 2 +- source/blender/editors/space_sequencer/sequencer_add.c | 8 ++++++++ source/blender/editors/space_sequencer/sequencer_draw.c | 9 +++++++++ source/blender/editors/space_sequencer/sequencer_edit.c | 12 ++++++++++++ source/blender/editors/space_sequencer/sequencer_modifier.c | 4 ++++ source/blender/editors/space_sequencer/sequencer_proxy.c | 3 +++ source/blender/editors/space_sequencer/sequencer_select.c | 2 ++ source/blender/editors/space_sequencer/sequencer_view.c | 2 ++ source/blender/editors/space_sequencer/space_sequencer.c | 1 + .../blender/editors/transform/transform_convert_sequencer.c | 4 ++++ source/blender/editors/transform/transform_snap.c | 1 + source/blender/editors/util/ed_util_imbuf.c | 1 + 19 files changed, 55 insertions(+), 4 deletions(-) (limited to 'source/blender/editors') diff --git a/source/blender/editors/animation/anim_deps.c b/source/blender/editors/animation/anim_deps.c index fbd55592729..17251587d3b 100644 --- a/source/blender/editors/animation/anim_deps.c +++ b/source/blender/editors/animation/anim_deps.c @@ -50,6 +50,7 @@ #include "RNA_access.h" #include "SEQ_sequencer.h" +#include "SEQ_utils.h" #include "ED_anim_api.h" diff --git a/source/blender/editors/animation/anim_filter.c b/source/blender/editors/animation/anim_filter.c index 83665d7a053..f2022194ed5 100644 --- a/source/blender/editors/animation/anim_filter.c +++ b/source/blender/editors/animation/anim_filter.c @@ -101,6 +101,7 @@ #include "ED_markers.h" #include "SEQ_sequencer.h" +#include "SEQ_utils.h" #include "UI_resources.h" /* for TH_KEYFRAME_SCALE lookup */ diff --git a/source/blender/editors/animation/anim_ops.c b/source/blender/editors/animation/anim_ops.c index 07601414fb0..a5514f6517e 100644 --- a/source/blender/editors/animation/anim_ops.c +++ b/source/blender/editors/animation/anim_ops.c @@ -56,6 +56,7 @@ #include "DEG_depsgraph_query.h" #include "SEQ_sequencer.h" +#include "SEQ_time.h" #include "anim_intern.h" diff --git a/source/blender/editors/render/render_internal.c b/source/blender/editors/render/render_internal.c index 46680f649cd..10cf4131584 100644 --- a/source/blender/editors/render/render_internal.c +++ b/source/blender/editors/render/render_internal.c @@ -83,7 +83,7 @@ #include "RNA_access.h" #include "RNA_define.h" -#include "SEQ_sequencer.h" +#include "SEQ_relations.h" #include "BLO_undofile.h" diff --git a/source/blender/editors/render/render_opengl.c b/source/blender/editors/render/render_opengl.c index f7275b06804..1069f942a7a 100644 --- a/source/blender/editors/render/render_opengl.c +++ b/source/blender/editors/render/render_opengl.c @@ -77,7 +77,7 @@ #include "RNA_access.h" #include "RNA_define.h" -#include "SEQ_sequencer.h" +#include "SEQ_render.h" #include "GPU_framebuffer.h" #include "GPU_matrix.h" diff --git a/source/blender/editors/sound/sound_ops.c b/source/blender/editors/sound/sound_ops.c index 5bc13ec1b75..34617804888 100644 --- a/source/blender/editors/sound/sound_ops.c +++ b/source/blender/editors/sound/sound_ops.c @@ -52,7 +52,7 @@ #include "RNA_define.h" #include "RNA_enum_types.h" -#include "SEQ_sequencer.h" +#include "SEQ_iterator.h" #include "UI_interface.h" diff --git a/source/blender/editors/space_outliner/outliner_select.c b/source/blender/editors/space_outliner/outliner_select.c index a1df922b335..6380bb9505e 100644 --- a/source/blender/editors/space_outliner/outliner_select.c +++ b/source/blender/editors/space_outliner/outliner_select.c @@ -72,6 +72,7 @@ #include "ED_sequencer.h" #include "ED_undo.h" +#include "SEQ_select.h" #include "SEQ_sequencer.h" #include "WM_api.h" diff --git a/source/blender/editors/space_outliner/outliner_sync.c b/source/blender/editors/space_outliner/outliner_sync.c index b3e8761f60b..0b2d1ce34ec 100644 --- a/source/blender/editors/space_outliner/outliner_sync.c +++ b/source/blender/editors/space_outliner/outliner_sync.c @@ -46,7 +46,7 @@ #include "ED_object.h" #include "ED_outliner.h" -#include "SEQ_sequencer.h" +#include "SEQ_select.h" #include "WM_api.h" #include "WM_types.h" diff --git a/source/blender/editors/space_sequencer/sequencer_add.c b/source/blender/editors/space_sequencer/sequencer_add.c index e40e9f5429d..f9076145f2f 100644 --- a/source/blender/editors/space_sequencer/sequencer_add.c +++ b/source/blender/editors/space_sequencer/sequencer_add.c @@ -50,7 +50,15 @@ #include "RNA_define.h" #include "RNA_enum_types.h" +#include "SEQ_add.h" +#include "SEQ_effects.h" +#include "SEQ_relations.h" +#include "SEQ_render.h" +#include "SEQ_select.h" #include "SEQ_sequencer.h" +#include "SEQ_time.h" +#include "SEQ_transform.h" +#include "SEQ_utils.h" /* For menu, popup, icons, etc. */ #include "ED_screen.h" diff --git a/source/blender/editors/space_sequencer/sequencer_draw.c b/source/blender/editors/space_sequencer/sequencer_draw.c index 2f146690416..1b213746add 100644 --- a/source/blender/editors/space_sequencer/sequencer_draw.c +++ b/source/blender/editors/space_sequencer/sequencer_draw.c @@ -68,7 +68,16 @@ #include "BIF_glutil.h" +#include "SEQ_effects.h" +#include "SEQ_prefetch.h" +#include "SEQ_proxy.h" +#include "SEQ_relations.h" +#include "SEQ_render.h" +#include "SEQ_select.h" #include "SEQ_sequencer.h" +#include "SEQ_time.h" +#include "SEQ_transform.h" +#include "SEQ_utils.h" #include "UI_interface.h" #include "UI_resources.h" diff --git a/source/blender/editors/space_sequencer/sequencer_edit.c b/source/blender/editors/space_sequencer/sequencer_edit.c index f78b602ceda..c3553ac88ad 100644 --- a/source/blender/editors/space_sequencer/sequencer_edit.c +++ b/source/blender/editors/space_sequencer/sequencer_edit.c @@ -45,7 +45,19 @@ #include "BKE_report.h" #include "BKE_sound.h" +#include "SEQ_add.h" +#include "SEQ_clipboard.h" +#include "SEQ_edit.h" +#include "SEQ_effects.h" +#include "SEQ_iterator.h" +#include "SEQ_prefetch.h" +#include "SEQ_relations.h" +#include "SEQ_render.h" +#include "SEQ_select.h" #include "SEQ_sequencer.h" +#include "SEQ_time.h" +#include "SEQ_transform.h" +#include "SEQ_utils.h" #include "WM_api.h" #include "WM_types.h" diff --git a/source/blender/editors/space_sequencer/sequencer_modifier.c b/source/blender/editors/space_sequencer/sequencer_modifier.c index e8f4fac1920..f11a879912c 100644 --- a/source/blender/editors/space_sequencer/sequencer_modifier.c +++ b/source/blender/editors/space_sequencer/sequencer_modifier.c @@ -34,6 +34,10 @@ #include "RNA_define.h" #include "RNA_enum_types.h" +#include "SEQ_iterator.h" +#include "SEQ_modifier.h" +#include "SEQ_relations.h" +#include "SEQ_select.h" #include "SEQ_sequencer.h" /* Own include. */ diff --git a/source/blender/editors/space_sequencer/sequencer_proxy.c b/source/blender/editors/space_sequencer/sequencer_proxy.c index 032885c2719..b04363a4f33 100644 --- a/source/blender/editors/space_sequencer/sequencer_proxy.c +++ b/source/blender/editors/space_sequencer/sequencer_proxy.c @@ -34,6 +34,9 @@ #include "BKE_main.h" #include "BKE_report.h" +#include "SEQ_iterator.h" +#include "SEQ_proxy.h" +#include "SEQ_relations.h" #include "SEQ_sequencer.h" #include "WM_api.h" diff --git a/source/blender/editors/space_sequencer/sequencer_select.c b/source/blender/editors/space_sequencer/sequencer_select.c index 6534a63f03e..a6027a2472c 100644 --- a/source/blender/editors/space_sequencer/sequencer_select.c +++ b/source/blender/editors/space_sequencer/sequencer_select.c @@ -39,6 +39,8 @@ #include "RNA_define.h" +#include "SEQ_iterator.h" +#include "SEQ_select.h" #include "SEQ_sequencer.h" /* For menu, popup, icons, etc. */ diff --git a/source/blender/editors/space_sequencer/sequencer_view.c b/source/blender/editors/space_sequencer/sequencer_view.c index 250a0afc717..8805d5af227 100644 --- a/source/blender/editors/space_sequencer/sequencer_view.c +++ b/source/blender/editors/space_sequencer/sequencer_view.c @@ -38,7 +38,9 @@ #include "RNA_define.h" +#include "SEQ_select.h" #include "SEQ_sequencer.h" +#include "SEQ_time.h" /* For menu, popup, icons, etc. */ #include "ED_anim_api.h" diff --git a/source/blender/editors/space_sequencer/space_sequencer.c b/source/blender/editors/space_sequencer/space_sequencer.c index 19146db3719..b11e2a32b87 100644 --- a/source/blender/editors/space_sequencer/space_sequencer.c +++ b/source/blender/editors/space_sequencer/space_sequencer.c @@ -52,6 +52,7 @@ #include "RNA_access.h" #include "SEQ_sequencer.h" +#include "SEQ_utils.h" #include "UI_interface.h" #include "UI_resources.h" diff --git a/source/blender/editors/transform/transform_convert_sequencer.c b/source/blender/editors/transform/transform_convert_sequencer.c index 83e384010bd..ebb0b6823a3 100644 --- a/source/blender/editors/transform/transform_convert_sequencer.c +++ b/source/blender/editors/transform/transform_convert_sequencer.c @@ -32,7 +32,11 @@ #include "ED_markers.h" +#include "SEQ_relations.h" #include "SEQ_sequencer.h" +#include "SEQ_time.h" +#include "SEQ_transform.h" +#include "SEQ_utils.h" #include "UI_view2d.h" diff --git a/source/blender/editors/transform/transform_snap.c b/source/blender/editors/transform/transform_snap.c index 8d20f1686f2..d407cea0033 100644 --- a/source/blender/editors/transform/transform_snap.c +++ b/source/blender/editors/transform/transform_snap.c @@ -42,6 +42,7 @@ #include "RNA_access.h" #include "SEQ_sequencer.h" +#include "SEQ_time.h" #include "WM_types.h" diff --git a/source/blender/editors/util/ed_util_imbuf.c b/source/blender/editors/util/ed_util_imbuf.c index ca97a7b21c3..0f2e280251f 100644 --- a/source/blender/editors/util/ed_util_imbuf.c +++ b/source/blender/editors/util/ed_util_imbuf.c @@ -42,6 +42,7 @@ #include "IMB_imbuf.h" #include "IMB_imbuf_types.h" +#include "SEQ_render.h" #include "SEQ_sequencer.h" #include "UI_view2d.h" -- cgit v1.2.3 From 09be4a0917fbdb391341a6bfcc1e918fb75d0fd2 Mon Sep 17 00:00:00 2001 From: Hans Goudey Date: Sat, 19 Dec 2020 10:07:13 -0600 Subject: Cleanup: Use typedef for UI emboss type enum Previously both `char` and `int` were used to represent this enum. Differential Revision: https://developer.blender.org/D9903 --- source/blender/editors/include/UI_interface.h | 12 +++++------ source/blender/editors/interface/interface.c | 4 ++-- .../blender/editors/interface/interface_intern.h | 8 ++++---- .../blender/editors/interface/interface_layout.c | 10 +++++----- .../blender/editors/interface/interface_widgets.c | 23 ++++++++++++---------- 5 files changed, 30 insertions(+), 27 deletions(-) (limited to 'source/blender/editors') diff --git a/source/blender/editors/include/UI_interface.h b/source/blender/editors/include/UI_interface.h index 05bedd526ed..2705dd27756 100644 --- a/source/blender/editors/include/UI_interface.h +++ b/source/blender/editors/include/UI_interface.h @@ -103,7 +103,7 @@ typedef struct uiPopupBlockHandle uiPopupBlockHandle; #define UI_SCREEN_MARGIN 10 /** #uiBlock.emboss and #uiBut.emboss */ -enum { +typedef enum eUIEmbossType { UI_EMBOSS = 0, /* use widget style for drawing */ UI_EMBOSS_NONE = 1, /* Nothing, only icon and/or text */ UI_EMBOSS_PULLDOWN = 2, /* Pulldown menu style */ @@ -115,7 +115,7 @@ enum { UI_EMBOSS_NONE_OR_STATUS = 4, UI_EMBOSS_UNDEFINED = 255, /* For layout engine, use emboss from block. */ -}; +} eUIEmbossType; /* uiBlock->direction */ enum { @@ -671,7 +671,7 @@ bool UI_popup_block_name_exists(const struct bScreen *screen, const char *name); uiBlock *UI_block_begin(const struct bContext *C, struct ARegion *region, const char *name, - char emboss); + eUIEmbossType emboss); void UI_block_end_ex(const struct bContext *C, uiBlock *block, const int xy[2], int r_xy[2]); void UI_block_end(const struct bContext *C, uiBlock *block); void UI_block_draw(const struct bContext *C, struct uiBlock *block); @@ -685,7 +685,7 @@ enum { }; void UI_block_theme_style_set(uiBlock *block, char theme_style); char UI_block_emboss_get(uiBlock *block); -void UI_block_emboss_set(uiBlock *block, char emboss); +void UI_block_emboss_set(uiBlock *block, eUIEmbossType emboss); bool UI_block_is_search_only(const uiBlock *block); void UI_block_set_search_only(uiBlock *block, bool search_only); @@ -1923,7 +1923,7 @@ void uiLayoutSetScaleX(uiLayout *layout, float scale); void uiLayoutSetScaleY(uiLayout *layout, float scale); void uiLayoutSetUnitsX(uiLayout *layout, float unit); void uiLayoutSetUnitsY(uiLayout *layout, float unit); -void uiLayoutSetEmboss(uiLayout *layout, char emboss); +void uiLayoutSetEmboss(uiLayout *layout, eUIEmbossType emboss); void uiLayoutSetPropSep(uiLayout *layout, bool is_sep); void uiLayoutSetPropDecorate(uiLayout *layout, bool is_sep); int uiLayoutGetLocalDir(const uiLayout *layout); @@ -1942,7 +1942,7 @@ float uiLayoutGetScaleX(uiLayout *layout); float uiLayoutGetScaleY(uiLayout *layout); float uiLayoutGetUnitsX(uiLayout *layout); float uiLayoutGetUnitsY(uiLayout *layout); -int uiLayoutGetEmboss(uiLayout *layout); +eUIEmbossType uiLayoutGetEmboss(uiLayout *layout); bool uiLayoutGetPropSep(uiLayout *layout); bool uiLayoutGetPropDecorate(uiLayout *layout); diff --git a/source/blender/editors/interface/interface.c b/source/blender/editors/interface/interface.c index 26fd75cc74c..7713efd1c78 100644 --- a/source/blender/editors/interface/interface.c +++ b/source/blender/editors/interface/interface.c @@ -3478,7 +3478,7 @@ void UI_block_region_set(uiBlock *block, ARegion *region) block->oldblock = oldblock; } -uiBlock *UI_block_begin(const bContext *C, ARegion *region, const char *name, char emboss) +uiBlock *UI_block_begin(const bContext *C, ARegion *region, const char *name, eUIEmbossType emboss) { wmWindow *window = CTX_wm_window(C); Scene *scene = CTX_data_scene(C); @@ -3529,7 +3529,7 @@ char UI_block_emboss_get(uiBlock *block) return block->emboss; } -void UI_block_emboss_set(uiBlock *block, char emboss) +void UI_block_emboss_set(uiBlock *block, eUIEmbossType emboss) { block->emboss = emboss; } diff --git a/source/blender/editors/interface/interface_intern.h b/source/blender/editors/interface/interface_intern.h index a35d9d5d336..c005b456b6a 100644 --- a/source/blender/editors/interface/interface_intern.h +++ b/source/blender/editors/interface/interface_intern.h @@ -220,8 +220,8 @@ struct uiBut { const char *disabled_info; BIFIconID icon; - /** emboss: UI_EMBOSS, UI_EMBOSS_NONE ... etc, copied from the #uiBlock.emboss */ - char emboss; + /** Copied from the #uiBlock.emboss */ + eUIEmbossType emboss; /** direction in a pie menu, used for collision detection (RadialDirection) */ signed char pie_dir; /** could be made into a single flag */ @@ -502,8 +502,8 @@ struct uiBlock { char direction; /** UI_BLOCK_THEME_STYLE_* */ char theme_style; - /** UI_EMBOSS, UI_EMBOSS_NONE ... etc, copied to #uiBut.emboss */ - char emboss; + /** Copied to #uiBut.emboss */ + eUIEmbossType emboss; bool auto_open; char _pad[5]; double auto_open_last; diff --git a/source/blender/editors/interface/interface_layout.c b/source/blender/editors/interface/interface_layout.c index 3b366688e59..3ea7a5f5973 100644 --- a/source/blender/editors/interface/interface_layout.c +++ b/source/blender/editors/interface/interface_layout.c @@ -172,7 +172,7 @@ struct uiLayout { /** For layouts inside gridflow, they and their items shall never have a fixed maximal size. */ bool variable_size; char alignment; - char emboss; + eUIEmbossType emboss; /** for fixed width or height to avoid UI size changes */ float units[2]; }; @@ -1189,7 +1189,7 @@ static uiBut *uiItemFullO_ptr_ex(uiLayout *layout, const int w = ui_text_icon_width(layout, name, icon, 0); - const int prev_emboss = layout->emboss; + const eUIEmbossType prev_emboss = layout->emboss; if (flag & UI_ITEM_R_NO_BG) { layout->emboss = UI_EMBOSS_NONE; } @@ -2120,7 +2120,7 @@ void uiItemFullR(uiLayout *layout, int w, h; ui_item_rna_size(layout, name, icon, ptr, prop, index, icon_only, compact, &w, &h); - const int prev_emboss = layout->emboss; + const eUIEmbossType prev_emboss = layout->emboss; if (no_bg) { layout->emboss = UI_EMBOSS_NONE; } @@ -4914,7 +4914,7 @@ void uiLayoutSetUnitsY(uiLayout *layout, float unit) layout->units[1] = unit; } -void uiLayoutSetEmboss(uiLayout *layout, char emboss) +void uiLayoutSetEmboss(uiLayout *layout, eUIEmbossType emboss) { layout->emboss = emboss; } @@ -4999,7 +4999,7 @@ float uiLayoutGetUnitsY(uiLayout *layout) return layout->units[1]; } -int uiLayoutGetEmboss(uiLayout *layout) +eUIEmbossType uiLayoutGetEmboss(uiLayout *layout) { if (layout->emboss == UI_EMBOSS_UNDEFINED) { return layout->root->block->emboss; diff --git a/source/blender/editors/interface/interface_widgets.c b/source/blender/editors/interface/interface_widgets.c index 7e883851876..4d81b1edf0c 100644 --- a/source/blender/editors/interface/interface_widgets.c +++ b/source/blender/editors/interface/interface_widgets.c @@ -264,7 +264,7 @@ typedef struct uiWidgetType { /* converted colors for state */ uiWidgetColors wcol; - void (*state)(struct uiWidgetType *, int state, int drawflag, char emboss); + void (*state)(struct uiWidgetType *, int state, int drawflag, eUIEmbossType emboss); void (*draw)(uiWidgetColors *, rcti *, int state, int roundboxalign); void (*custom)(uiBut *, uiWidgetColors *, rcti *, int state, int roundboxalign); void (*text)(const uiFontStyle *, const uiWidgetColors *, uiBut *, rcti *); @@ -2521,7 +2521,7 @@ static void widget_active_color(uiWidgetColors *wcol) static const uchar *widget_color_blend_from_flags(const uiWidgetStateColors *wcol_state, int state, int drawflag, - const char emboss) + const eUIEmbossType emboss) { /* Explicitly require #UI_EMBOSS_NONE_OR_STATUS for color blending with no emboss. */ if (emboss == UI_EMBOSS_NONE) { @@ -2547,7 +2547,7 @@ static const uchar *widget_color_blend_from_flags(const uiWidgetStateColors *wco } /* copy colors from theme, and set changes in it based on state */ -static void widget_state(uiWidgetType *wt, int state, int drawflag, char emboss) +static void widget_state(uiWidgetType *wt, int state, int drawflag, eUIEmbossType emboss) { uiWidgetStateColors *wcol_state = wt->wcol_state; @@ -2625,7 +2625,7 @@ static void widget_state(uiWidgetType *wt, int state, int drawflag, char emboss) * \{ */ /* sliders use special hack which sets 'item' as inner when drawing filling */ -static void widget_state_numslider(uiWidgetType *wt, int state, int drawflag, char emboss) +static void widget_state_numslider(uiWidgetType *wt, int state, int drawflag, eUIEmbossType emboss) { uiWidgetStateColors *wcol_state = wt->wcol_state; @@ -2648,7 +2648,10 @@ static void widget_state_numslider(uiWidgetType *wt, int state, int drawflag, ch } /* labels use theme colors for text */ -static void widget_state_option_menu(uiWidgetType *wt, int state, int drawflag, char emboss) +static void widget_state_option_menu(uiWidgetType *wt, + int state, + int drawflag, + eUIEmbossType emboss) { const bTheme *btheme = UI_GetTheme(); @@ -2668,7 +2671,7 @@ static void widget_state_option_menu(uiWidgetType *wt, int state, int drawflag, static void widget_state_nothing(uiWidgetType *wt, int UNUSED(state), int UNUSED(drawflag), - char UNUSED(emboss)) + eUIEmbossType UNUSED(emboss)) { wt->wcol = *(wt->wcol_theme); } @@ -2677,7 +2680,7 @@ static void widget_state_nothing(uiWidgetType *wt, static void widget_state_pulldown(uiWidgetType *wt, int UNUSED(state), int UNUSED(drawflag), - char UNUSED(emboss)) + eUIEmbossType UNUSED(emboss)) { wt->wcol = *(wt->wcol_theme); } @@ -2686,7 +2689,7 @@ static void widget_state_pulldown(uiWidgetType *wt, static void widget_state_pie_menu_item(uiWidgetType *wt, int state, int UNUSED(drawflag), - char UNUSED(emboss)) + eUIEmbossType UNUSED(emboss)) { wt->wcol = *(wt->wcol_theme); @@ -2721,7 +2724,7 @@ static void widget_state_pie_menu_item(uiWidgetType *wt, static void widget_state_menu_item(uiWidgetType *wt, int state, int UNUSED(drawflag), - char UNUSED(emboss)) + eUIEmbossType UNUSED(emboss)) { wt->wcol = *(wt->wcol_theme); @@ -4070,7 +4073,7 @@ static void widget_optionbut(uiWidgetColors *wcol, } /* labels use Editor theme colors for text */ -static void widget_state_label(uiWidgetType *wt, int state, int drawflag, char emboss) +static void widget_state_label(uiWidgetType *wt, int state, int drawflag, eUIEmbossType emboss) { if (state & UI_BUT_LIST_ITEM) { /* Override default label theme's colors. */ -- cgit v1.2.3 From 38b77ef8b22173835b3bc80efc218c3e05b9e37d Mon Sep 17 00:00:00 2001 From: Richard Antalik Date: Sun, 20 Dec 2020 03:58:38 +0100 Subject: VSE: Remove cost calculation from cache This value was meant to be used for keeping images that are slowest to render in cache. Method of measurement was flawed, because it doesn't take UI overhead into consideration. Cache panel is to be removed because users should not have to tweak settings like this. It is not useful for development either, therefore it is removed completely. --- source/blender/editors/space_sequencer/sequencer_draw.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'source/blender/editors') diff --git a/source/blender/editors/space_sequencer/sequencer_draw.c b/source/blender/editors/space_sequencer/sequencer_draw.c index 1b213746add..2ee0dcea5e5 100644 --- a/source/blender/editors/space_sequencer/sequencer_draw.c +++ b/source/blender/editors/space_sequencer/sequencer_draw.c @@ -2111,8 +2111,10 @@ static bool draw_cache_view_init_fn(void *userdata, size_t item_count) } /* Called as a callback */ -static bool draw_cache_view_iter_fn( - void *userdata, struct Sequence *seq, int timeline_frame, int cache_type, float UNUSED(cost)) +static bool draw_cache_view_iter_fn(void *userdata, + struct Sequence *seq, + int timeline_frame, + int cache_type) { CacheDrawData *drawdata = userdata; struct View2D *v2d = drawdata->v2d; -- cgit v1.2.3 From 864c8068639a1341220f5a97b683f6834928ad76 Mon Sep 17 00:00:00 2001 From: Yevgeny Makarov Date: Sat, 19 Dec 2020 21:52:45 -0600 Subject: UI: Reorder enums in render results image editor header The convention is to put the label at the bottom of the enum, or in the spot furthest away from the button. This commit reorders the items in the "Slot", "Layer", and "Pass" menus to be consistent with this convention. It also reorders the numbering so that higher numbers are lower. The original patch was by Adrian Newton (@TFS), with slight changes and additions. Differential Revision: https://developer.blender.org/D7142 --- source/blender/editors/space_image/image_buttons.c | 142 ++++++++++----------- 1 file changed, 68 insertions(+), 74 deletions(-) (limited to 'source/blender/editors') diff --git a/source/blender/editors/space_image/image_buttons.c b/source/blender/editors/space_image/image_buttons.c index f8f25e399eb..1996f05b36a 100644 --- a/source/blender/editors/space_image/image_buttons.c +++ b/source/blender/editors/space_image/image_buttons.c @@ -86,26 +86,9 @@ static void ui_imageuser_slot_menu(bContext *UNUSED(C), uiLayout *layout, void * { uiBlock *block = uiLayoutGetBlock(layout); Image *image = image_p; - int slot_id; - uiDefBut(block, - UI_BTYPE_LABEL, - 0, - IFACE_("Slot"), - 0, - 0, - UI_UNIT_X * 5, - UI_UNIT_Y, - NULL, - 0.0, - 0.0, - 0, - 0, - ""); - uiItemS(layout); - - slot_id = BLI_listbase_count(&image->renderslots) - 1; - for (RenderSlot *slot = image->renderslots.last; slot; slot = slot->prev) { + int slot_id; + LISTBASE_FOREACH_INDEX (RenderSlot *, slot, &image->renderslots, slot_id) { char str[64]; if (slot->name[0] != '\0') { BLI_strncpy(str, slot->name, sizeof(str)); @@ -127,8 +110,23 @@ static void ui_imageuser_slot_menu(bContext *UNUSED(C), uiLayout *layout, void * 0, -1, ""); - slot_id--; } + + uiItemS(layout); + uiDefBut(block, + UI_BTYPE_LABEL, + 0, + IFACE_("Slot"), + 0, + 0, + UI_UNIT_X * 5, + UI_UNIT_Y, + NULL, + 0.0, + 0.0, + 0, + 0, + ""); } static bool ui_imageuser_slot_menu_step(bContext *C, int direction, void *image_p) @@ -175,14 +173,9 @@ static void ui_imageuser_layer_menu(bContext *UNUSED(C), uiLayout *layout, void Image *image = rnd_data->image; ImageUser *iuser = rnd_data->iuser; Scene *scene = iuser->scene; - RenderResult *rr; - RenderLayer *rl; - RenderLayer rl_fake = {NULL}; - const char *fake_name; - int nr; - /* may have been freed since drawing */ - rr = BKE_image_acquire_renderresult(scene, image); + /* May have been freed since drawing. */ + RenderResult *rr = BKE_image_acquire_renderresult(scene, image); if (UNLIKELY(rr == NULL)) { return; } @@ -190,32 +183,26 @@ static void ui_imageuser_layer_menu(bContext *UNUSED(C), uiLayout *layout, void UI_block_layout_set_current(block, layout); uiLayoutColumn(layout, false); - uiDefBut(block, - UI_BTYPE_LABEL, - 0, - IFACE_("Layer"), - 0, - 0, - UI_UNIT_X * 5, - UI_UNIT_Y, - NULL, - 0.0, - 0.0, - 0, - 0, - ""); - uiItemS(layout); - - nr = BLI_listbase_count(&rr->layers) - 1; - fake_name = ui_imageuser_layer_fake_name(rr); - + const char *fake_name = ui_imageuser_layer_fake_name(rr); if (fake_name) { - BLI_strncpy(rl_fake.name, fake_name, sizeof(rl_fake.name)); - nr += 1; + uiDefButS(block, + UI_BTYPE_BUT_MENU, + B_NOP, + fake_name, + 0, + 0, + UI_UNIT_X * 5, + UI_UNIT_X, + &iuser->layer, + 0.0, + 0.0, + 0, + -1, + ""); } - for (rl = rr->layers.last; rl; rl = rl->prev, nr--) { - final: + int nr = fake_name ? 1 : 0; + for (RenderLayer *rl = rr->layers.first; rl; rl = rl->next, nr++) { uiDefButS(block, UI_BTYPE_BUT_MENU, B_NOP, @@ -232,13 +219,21 @@ static void ui_imageuser_layer_menu(bContext *UNUSED(C), uiLayout *layout, void ""); } - if (fake_name) { - fake_name = NULL; - rl = &rl_fake; - goto final; - } - - BLI_assert(nr == -1); + uiItemS(layout); + uiDefBut(block, + UI_BTYPE_LABEL, + 0, + IFACE_("Layer"), + 0, + 0, + UI_UNIT_X * 5, + UI_UNIT_Y, + NULL, + 0.0, + 0.0, + 0, + 0, + ""); BKE_image_release_renderresult(scene, image); } @@ -268,23 +263,6 @@ static void ui_imageuser_pass_menu(bContext *UNUSED(C), uiLayout *layout, void * UI_block_layout_set_current(block, layout); uiLayoutColumn(layout, false); - uiDefBut(block, - UI_BTYPE_LABEL, - 0, - IFACE_("Pass"), - 0, - 0, - UI_UNIT_X * 5, - UI_UNIT_Y, - NULL, - 0.0, - 0.0, - 0, - 0, - ""); - - uiItemS(layout); - nr = (rl == NULL) ? 1 : 0; ListBase added_passes; @@ -315,6 +293,22 @@ static void ui_imageuser_pass_menu(bContext *UNUSED(C), uiLayout *layout, void * ""); } + uiItemS(layout); + uiDefBut(block, + UI_BTYPE_LABEL, + 0, + IFACE_("Pass"), + 0, + 0, + UI_UNIT_X * 5, + UI_UNIT_Y, + NULL, + 0.0, + 0.0, + 0, + 0, + ""); + BLI_freelistN(&added_passes); BKE_image_release_renderresult(scene, image); -- cgit v1.2.3 From 5a69f707516e858bb177fc95e49a942384326538 Mon Sep 17 00:00:00 2001 From: Peter Fog Date: Sun, 20 Dec 2020 06:23:08 +0100 Subject: VSE: Add options to select neighboring handles Options added to `sequencer.select_handles()` operator. Reviewed By: ISS Differential Revision: https://developer.blender.org/D7707 --- .../editors/space_sequencer/sequencer_select.c | 67 ++++++++++++++++++++-- 1 file changed, 62 insertions(+), 5 deletions(-) (limited to 'source/blender/editors') diff --git a/source/blender/editors/space_sequencer/sequencer_select.c b/source/blender/editors/space_sequencer/sequencer_select.c index a6027a2472c..edbffa8f693 100644 --- a/source/blender/editors/space_sequencer/sequencer_select.c +++ b/source/blender/editors/space_sequencer/sequencer_select.c @@ -902,6 +902,25 @@ void SEQUENCER_OT_select_linked(wmOperatorType *ot) /** \name Select Handles Operator * \{ */ +enum { + SEQ_SELECT_HANDLES_SIDE_LEFT, + SEQ_SELECT_HANDLES_SIDE_RIGHT, + SEQ_SELECT_HANDLES_SIDE_BOTH, + SEQ_SELECT_HANDLES_SIDE_LEFT_NEIGHBOR, + SEQ_SELECT_HANDLES_SIDE_RIGHT_NEIGHBOR, + SEQ_SELECT_HANDLES_SIDE_BOTH_NEIGHBORS, +}; + +static const EnumPropertyItem prop_select_handles_side_types[] = { + {SEQ_SELECT_HANDLES_SIDE_LEFT, "LEFT", 0, "Left", ""}, + {SEQ_SELECT_HANDLES_SIDE_RIGHT, "RIGHT", 0, "Right", ""}, + {SEQ_SELECT_HANDLES_SIDE_BOTH, "BOTH", 0, "Both", ""}, + {SEQ_SELECT_HANDLES_SIDE_LEFT_NEIGHBOR, "LEFT_NEIGHBOR", 0, "Left Neighbor", ""}, + {SEQ_SELECT_HANDLES_SIDE_RIGHT_NEIGHBOR, "RIGHT_NEIGHBOR", 0, "Right Neighbor", ""}, + {SEQ_SELECT_HANDLES_SIDE_BOTH_NEIGHBORS, "BOTH_NEIGHBORS", 0, "Both Neighbors", ""}, + {0, NULL, 0, NULL, NULL}, +}; + static int sequencer_select_handles_exec(bContext *C, wmOperator *op) { Scene *scene = CTX_data_scene(C); @@ -911,18 +930,56 @@ static int sequencer_select_handles_exec(bContext *C, wmOperator *op) for (seq = ed->seqbasep->first; seq; seq = seq->next) { if (seq->flag & SELECT) { + Sequence *l_neighbor = find_neighboring_sequence(scene, seq, SEQ_SIDE_LEFT, -1); + Sequence *r_neighbor = find_neighboring_sequence(scene, seq, SEQ_SIDE_RIGHT, -1); + switch (sel_side) { - case SEQ_SIDE_LEFT: + case SEQ_SELECT_HANDLES_SIDE_LEFT: seq->flag &= ~SEQ_RIGHTSEL; seq->flag |= SEQ_LEFTSEL; break; - case SEQ_SIDE_RIGHT: + case SEQ_SELECT_HANDLES_SIDE_RIGHT: seq->flag &= ~SEQ_LEFTSEL; seq->flag |= SEQ_RIGHTSEL; break; - case SEQ_SIDE_BOTH: + case SEQ_SELECT_HANDLES_SIDE_BOTH: seq->flag |= SEQ_LEFTSEL | SEQ_RIGHTSEL; break; + case SEQ_SELECT_HANDLES_SIDE_LEFT_NEIGHBOR: + if (l_neighbor) { + if (!(l_neighbor->flag & SELECT)) { + l_neighbor->flag |= SEQ_RIGHTSEL; + } + } + break; + case SEQ_SELECT_HANDLES_SIDE_RIGHT_NEIGHBOR: + if (r_neighbor) { + if (!(r_neighbor->flag & SELECT)) { + r_neighbor->flag |= SEQ_LEFTSEL; + } + } + break; + case SEQ_SELECT_HANDLES_SIDE_BOTH_NEIGHBORS: + if (l_neighbor) { + if (!(l_neighbor->flag & SELECT)) { + l_neighbor->flag |= SEQ_RIGHTSEL; + } + } + if (r_neighbor) { + if (!(r_neighbor->flag & SELECT)) { + r_neighbor->flag |= SEQ_LEFTSEL; + } + break; + } + } + } + } + /* Select strips */ + for (seq = ed->seqbasep->first; seq; seq = seq->next) { + if ((seq->flag & SEQ_LEFTSEL) || (seq->flag & SEQ_RIGHTSEL)) { + if (!(seq->flag & SELECT)) { + seq->flag |= SELECT; + recurs_sel_seq(seq); } } } @@ -951,8 +1008,8 @@ void SEQUENCER_OT_select_handles(wmOperatorType *ot) /* Properties. */ RNA_def_enum(ot->srna, "side", - prop_side_types, - SEQ_SIDE_BOTH, + prop_select_handles_side_types, + SEQ_SELECT_HANDLES_SIDE_BOTH, "Side", "The side of the handle that is selected"); } -- cgit v1.2.3 From d283a093d6643fc63264d95bed46af0646788277 Mon Sep 17 00:00:00 2001 From: Gaia Clary Date: Sun, 20 Dec 2020 18:48:07 +0100 Subject: fix T83880: Added check for valid context object to avoid null pointer exception when no object in scene --- source/blender/editors/object/object_vgroup.c | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) (limited to 'source/blender/editors') diff --git a/source/blender/editors/object/object_vgroup.c b/source/blender/editors/object/object_vgroup.c index 23f1718cb2e..fc4969019b5 100644 --- a/source/blender/editors/object/object_vgroup.c +++ b/source/blender/editors/object/object_vgroup.c @@ -736,17 +736,19 @@ const EnumPropertyItem *ED_object_vgroup_selection_itemf_helper(const bContext * RNA_enum_items_add_value(&item, &totitem, WT_vertex_group_select_item, WT_VGROUP_ACTIVE); } - if (BKE_object_pose_armature_get(ob)) { - if (selection_mask & (1 << WT_VGROUP_BONE_SELECT)) { - RNA_enum_items_add_value( - &item, &totitem, WT_vertex_group_select_item, WT_VGROUP_BONE_SELECT); + if (ob) { + if (BKE_object_pose_armature_get(ob)) { + if (selection_mask & (1 << WT_VGROUP_BONE_SELECT)) { + RNA_enum_items_add_value( + &item, &totitem, WT_vertex_group_select_item, WT_VGROUP_BONE_SELECT); + } } - } - if (BKE_modifiers_is_deformed_by_armature(ob)) { - if (selection_mask & (1 << WT_VGROUP_BONE_DEFORM)) { - RNA_enum_items_add_value( - &item, &totitem, WT_vertex_group_select_item, WT_VGROUP_BONE_DEFORM); + if (BKE_modifiers_is_deformed_by_armature(ob)) { + if (selection_mask & (1 << WT_VGROUP_BONE_DEFORM)) { + RNA_enum_items_add_value( + &item, &totitem, WT_vertex_group_select_item, WT_VGROUP_BONE_DEFORM); + } } } -- cgit v1.2.3