Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'source/blender/editors')
-rw-r--r--source/blender/editors/animation/anim_channels_edit.c13
-rw-r--r--source/blender/editors/animation/anim_filter.c26
-rw-r--r--source/blender/editors/datafiles/CMakeLists.txt4
-rw-r--r--source/blender/editors/include/ED_anim_api.h5
-rw-r--r--source/blender/editors/include/ED_mesh.h22
-rw-r--r--source/blender/editors/include/ED_object.h3
-rw-r--r--source/blender/editors/include/ED_screen.h18
-rw-r--r--source/blender/editors/include/ED_view3d.h25
-rw-r--r--source/blender/editors/include/UI_icons.h22
-rw-r--r--source/blender/editors/include/UI_interface.h4
-rw-r--r--source/blender/editors/interface/CMakeLists.txt3
-rw-r--r--source/blender/editors/interface/interface.c11
-rw-r--r--source/blender/editors/interface/interface_context_menu.c756
-rw-r--r--source/blender/editors/interface/interface_handlers.c648
-rw-r--r--source/blender/editors/interface/interface_icons.c7
-rw-r--r--source/blender/editors/interface/interface_intern.h5
-rw-r--r--source/blender/editors/interface/interface_layout.c31
-rw-r--r--source/blender/editors/interface/interface_ops.c1
-rw-r--r--source/blender/editors/interface/interface_panel.c2
-rw-r--r--source/blender/editors/interface/interface_region_hud.c3
-rw-r--r--source/blender/editors/interface/interface_region_menu_popup.c15
-rw-r--r--source/blender/editors/interface/interface_templates.c33
-rw-r--r--source/blender/editors/interface/interface_widgets.c71
-rw-r--r--source/blender/editors/interface/resources.c8
-rw-r--r--source/blender/editors/mesh/editface.c37
-rw-r--r--source/blender/editors/mesh/editmesh_bevel.c2
-rw-r--r--source/blender/editors/mesh/editmesh_utils.c2
-rw-r--r--source/blender/editors/mesh/mesh_data.c4
-rw-r--r--source/blender/editors/mesh/mesh_mirror.c149
-rw-r--r--source/blender/editors/mesh/meshtools.c182
-rw-r--r--source/blender/editors/object/object_add.c29
-rw-r--r--source/blender/editors/object/object_bake.c8
-rw-r--r--source/blender/editors/object/object_data_transfer.c23
-rw-r--r--source/blender/editors/object/object_edit.c249
-rw-r--r--source/blender/editors/object/object_group.c7
-rw-r--r--source/blender/editors/object/object_intern.h3
-rw-r--r--source/blender/editors/object/object_modifier.c21
-rw-r--r--source/blender/editors/object/object_ops.c19
-rw-r--r--source/blender/editors/object/object_relations.c3
-rw-r--r--source/blender/editors/object/object_select.c18
-rw-r--r--source/blender/editors/physics/particle_edit.c29
-rw-r--r--source/blender/editors/physics/rigidbody_constraint.c6
-rw-r--r--source/blender/editors/physics/rigidbody_object.c1
-rw-r--r--source/blender/editors/render/render_internal.c2
-rw-r--r--source/blender/editors/render/render_preview.c50
-rw-r--r--source/blender/editors/screen/CMakeLists.txt1
-rw-r--r--source/blender/editors/screen/screen_context.c6
-rw-r--r--source/blender/editors/screen/screen_edit.c7
-rw-r--r--source/blender/editors/screen/screen_intern.h3
-rw-r--r--source/blender/editors/screen/screen_ops.c164
-rw-r--r--source/blender/editors/screen/screen_user_menu.c164
-rw-r--r--source/blender/editors/sculpt_paint/paint_curve.c2
-rw-r--r--source/blender/editors/sculpt_paint/paint_hide.c1
-rw-r--r--source/blender/editors/sculpt_paint/paint_image.c17
-rw-r--r--source/blender/editors/sculpt_paint/paint_image_proj.c2
-rw-r--r--source/blender/editors/sculpt_paint/paint_mask.c1
-rw-r--r--source/blender/editors/sculpt_paint/paint_vertex_proj.c39
-rw-r--r--source/blender/editors/sculpt_paint/paint_vertex_weight_ops.c23
-rw-r--r--source/blender/editors/sculpt_paint/sculpt_undo.c2
-rw-r--r--source/blender/editors/space_action/space_action.c37
-rw-r--r--source/blender/editors/space_api/spacetypes.c2
-rw-r--r--source/blender/editors/space_clip/clip_buttons.c2
-rw-r--r--source/blender/editors/space_graph/graph_utils.c45
-rw-r--r--source/blender/editors/space_graph/space_graph.c28
-rw-r--r--source/blender/editors/space_image/image_buttons.c2
-rw-r--r--source/blender/editors/space_image/space_image.c2
-rw-r--r--source/blender/editors/space_info/info_stats.c18
-rw-r--r--source/blender/editors/space_nla/nla_channels.c2
-rw-r--r--source/blender/editors/space_nla/space_nla.c4
-rw-r--r--source/blender/editors/space_node/space_node.c1
-rw-r--r--source/blender/editors/space_outliner/outliner_collections.c22
-rw-r--r--source/blender/editors/space_outliner/outliner_draw.c340
-rw-r--r--source/blender/editors/space_outliner/outliner_edit.c52
-rw-r--r--source/blender/editors/space_outliner/outliner_intern.h16
-rw-r--r--source/blender/editors/space_outliner/outliner_ops.c7
-rw-r--r--source/blender/editors/space_outliner/outliner_select.c18
-rw-r--r--source/blender/editors/space_outliner/outliner_tools.c29
-rw-r--r--source/blender/editors/space_outliner/outliner_tree.c22
-rw-r--r--source/blender/editors/space_view3d/space_view3d.c12
-rw-r--r--source/blender/editors/space_view3d/view3d_buttons.c15
-rw-r--r--source/blender/editors/space_view3d/view3d_draw.c10
-rw-r--r--source/blender/editors/space_view3d/view3d_draw_legacy.c2
-rw-r--r--source/blender/editors/space_view3d/view3d_edit.c121
-rw-r--r--source/blender/editors/space_view3d/view3d_intern.h1
-rw-r--r--source/blender/editors/space_view3d/view3d_ops.c2
-rw-r--r--source/blender/editors/space_view3d/view3d_select.c2
-rw-r--r--source/blender/editors/space_view3d/view3d_toolbar.c130
-rw-r--r--source/blender/editors/space_view3d/view3d_view.c3
-rw-r--r--source/blender/editors/transform/transform_constraints.c2
-rw-r--r--source/blender/editors/transform/transform_manipulator_3d.c131
-rw-r--r--source/blender/editors/transform/transform_snap.c1
-rw-r--r--source/blender/editors/undo/ed_undo.c2
-rw-r--r--source/blender/editors/uvedit/uvedit_draw.c2
-rw-r--r--source/blender/editors/uvedit/uvedit_unwrap_ops.c2
94 files changed, 2474 insertions, 1625 deletions
diff --git a/source/blender/editors/animation/anim_channels_edit.c b/source/blender/editors/animation/anim_channels_edit.c
index ebe977420c6..ed4c574537b 100644
--- a/source/blender/editors/animation/anim_channels_edit.c
+++ b/source/blender/editors/animation/anim_channels_edit.c
@@ -2300,18 +2300,9 @@ static int animchannels_find_exec(bContext *C, wmOperator *op)
if (ANIM_animdata_get_context(C, &ac) == 0)
return OPERATOR_CANCELLED;
- /* update filter text, and ensure that filter is enabled if there's something there
- * NOTE: we turn the filter off if there's nothing (this is a quick shortcut for dismissing)
- */
+ /* update filter text */
RNA_string_get(op->ptr, "query", ac.ads->searchstr);
- if (ac.ads->searchstr[0]) {
- ac.ads->filterflag |= ADS_FILTER_BY_FCU_NAME;
- }
- else {
- ac.ads->filterflag &= ~ADS_FILTER_BY_FCU_NAME;
- }
-
/* redraw */
WM_event_add_notifier(C, NC_ANIMATION | ND_ANIMCHAN | NA_EDITED, NULL);
@@ -2693,7 +2684,7 @@ static int mouse_anim_channels(bContext *C, bAnimContext *ac, int channel_index,
AnimData *adt = ob->adt;
/* set selection status */
- if (base->flag & BASE_SELECTABLED) {
+ if (base->flag & BASE_SELECTABLE) {
if (selectmode == SELECT_INVERT) {
/* swap select */
ED_object_base_select(base, BA_INVERT);
diff --git a/source/blender/editors/animation/anim_filter.c b/source/blender/editors/animation/anim_filter.c
index 8892fed025a..c59d24bbdf8 100644
--- a/source/blender/editors/animation/anim_filter.c
+++ b/source/blender/editors/animation/anim_filter.c
@@ -245,6 +245,18 @@ static bool actedit_get_context(bAnimContext *ac, SpaceAction *saction)
/* update scene-pointer (no need to check for pinning yet, as not implemented) */
saction->ads.source = (ID *)ac->scene;
+ /* sync scene's "selected keys only" flag with our "only selected" flag
+ * XXX: This is a workaround for T55525. We shouldn't really be syncing the flags like this,
+ * but it's a simpler fix for now than also figuring out how the next/prev keyframe tools
+ * should work in the 3D View if we allowed full access to the timeline's dopesheet filters
+ * (i.e. we'd have to figure out where to host those settings, to be on a scene level like
+ * this flag currently is, along with several other unknowns)
+ */
+ if (ac->scene->flag & SCE_KEYS_NO_SELONLY)
+ saction->ads.filterflag &= ~ADS_FILTER_ONLYSEL;
+ else
+ saction->ads.filterflag |= ADS_FILTER_ONLYSEL;
+
ac->datatype = ANIMCONT_TIMELINE;
ac->data = &saction->ads;
@@ -1209,7 +1221,7 @@ static FCurve *animfilter_fcurve_next(bDopeSheet *ads, FCurve *first, eAnim_Chan
/* only include if this curve is active */
if (!(filter_mode & ANIMFILTER_ACTIVE) || (fcu->flag & FCURVE_ACTIVE)) {
/* name based filtering... */
- if ( ((ads) && (ads->filterflag & ADS_FILTER_BY_FCU_NAME)) && (owner_id) ) {
+ if ( ((ads) && (ads->searchstr[0] != '\0')) && (owner_id) ) {
if (skip_fcurve_with_name(ads, fcu, channel_type, owner, owner_id))
continue;
}
@@ -1441,7 +1453,7 @@ static size_t animfilter_nla(bAnimContext *UNUSED(ac), ListBase *anim_data, bDop
/* only include if this track is active */
if (!(filter_mode & ANIMFILTER_ACTIVE) || (nlt->flag & NLATRACK_ACTIVE)) {
/* name based filtering... */
- if (((ads) && (ads->filterflag & ADS_FILTER_BY_FCU_NAME)) && (owner_id)) {
+ if (((ads) && (ads->searchstr[0] != '\0')) && (owner_id)) {
bool track_ok = false, strip_ok = false;
/* check if the name of the track, or the strips it has are ok... */
@@ -1621,7 +1633,7 @@ static size_t animdata_filter_gpencil_layers_data(ListBase *anim_data, bDopeShee
/* active... */
if (!(filter_mode & ANIMFILTER_ACTIVE) || (gpl->flag & GP_LAYER_ACTIVE)) {
/* skip layer if the name doesn't match the filter string */
- if ((ads) && (ads->filterflag & ADS_FILTER_BY_FCU_NAME)) {
+ if ((ads) && (ads->searchstr[0] != '\0')) {
if (name_matches_dopesheet_filter(ads, gpl->info) == false)
continue;
}
@@ -1713,7 +1725,7 @@ static size_t animdata_filter_gpencil(bAnimContext *ac, ListBase *anim_data, voi
*/
if ((filter_mode & ANIMFILTER_DATA_VISIBLE) && !(ads->filterflag & ADS_FILTER_INCL_HIDDEN)) {
/* layer visibility - we check both object and base, since these may not be in sync yet */
- if ((base->flag & BASE_VISIBLED) == 0) continue;
+ if ((base->flag & BASE_VISIBLE) == 0) continue;
/* outliner restrict-flag */
if (ob->restrictflag & OB_RESTRICT_VIEW) continue;
@@ -1729,7 +1741,7 @@ static size_t animdata_filter_gpencil(bAnimContext *ac, ListBase *anim_data, voi
* objects by the grouped status is on
* - used to ease the process of doing multiple-character choreographies
*/
- if (ads->filterflag & ADS_FILTER_ONLYOBGROUP) {
+ if (ads->filter_grp != NULL) {
if (BKE_collection_has_object_recursive(ads->filter_grp, ob) == 0)
continue;
}
@@ -2852,7 +2864,7 @@ static bool animdata_filter_base_is_ok(bDopeSheet *ads, Base *base, int filter_m
*/
if ((filter_mode & ANIMFILTER_DATA_VISIBLE) && !(ads->filterflag & ADS_FILTER_INCL_HIDDEN)) {
/* layer visibility - we check both object and base, since these may not be in sync yet */
- if ((base->flag & BASE_VISIBLED) == 0)
+ if ((base->flag & BASE_VISIBLE) == 0)
return false;
/* outliner restrict-flag */
@@ -2896,7 +2908,7 @@ static bool animdata_filter_base_is_ok(bDopeSheet *ads, Base *base, int filter_m
* objects by the grouped status is on
* - used to ease the process of doing multiple-character choreographies
*/
- if (ads->filterflag & ADS_FILTER_ONLYOBGROUP) {
+ if (ads->filter_grp != NULL) {
if (BKE_collection_has_object_recursive(ads->filter_grp, ob) == 0)
return false;
}
diff --git a/source/blender/editors/datafiles/CMakeLists.txt b/source/blender/editors/datafiles/CMakeLists.txt
index 98b57fcbd71..640239ccc60 100644
--- a/source/blender/editors/datafiles/CMakeLists.txt
+++ b/source/blender/editors/datafiles/CMakeLists.txt
@@ -202,6 +202,10 @@ set(ICON_NAMES
group_uvs
rna
rna_add
+ mouse_lmb
+ mouse_mmb
+ mouse_rmb
+ mouse_drag
outliner_ob_empty
outliner_ob_mesh
outliner_ob_curve
diff --git a/source/blender/editors/include/ED_anim_api.h b/source/blender/editors/include/ED_anim_api.h
index 943191c8892..fee336ea768 100644
--- a/source/blender/editors/include/ED_anim_api.h
+++ b/source/blender/editors/include/ED_anim_api.h
@@ -690,6 +690,7 @@ void ANIM_list_elem_update(struct Main *bmain, struct Scene *scene, bAnimListEle
void ANIM_sync_animchannels_to_data(const struct bContext *C);
void ANIM_center_frame(struct bContext *C, int smooth_viewtx);
+
/* ************************************************* */
/* OPERATORS */
@@ -716,6 +717,10 @@ void ED_animedit_unlink_action(struct bContext *C, struct ID *id,
struct AnimData *adt, struct bAction *act,
struct ReportList *reports, bool force_delete);
+
+/* Drivers Editor - Utility to set up UI correctly */
+void ED_drivers_editor_init(struct bContext *C, struct ScrArea *sa);
+
/* ************************************************ */
#endif /* __ED_ANIM_API_H__ */
diff --git a/source/blender/editors/include/ED_mesh.h b/source/blender/editors/include/ED_mesh.h
index a9c9e8c0fbd..32504db6498 100644
--- a/source/blender/editors/include/ED_mesh.h
+++ b/source/blender/editors/include/ED_mesh.h
@@ -225,14 +225,9 @@ typedef struct MirrTopoStore_t {
} MirrTopoStore_t;
bool ED_mesh_mirrtopo_recalc_check(
- struct Mesh *me, struct DerivedMesh *dm, MirrTopoStore_t *mesh_topo_store);
-bool ED_mesh_mirrtopo_recalc_check__real_mesh(
- struct Mesh *me, struct Mesh *dm, MirrTopoStore_t *mesh_topo_store);
+ struct Mesh *me, struct Mesh *me_eval, MirrTopoStore_t *mesh_topo_store);
void ED_mesh_mirrtopo_init(
- struct Mesh *me, struct DerivedMesh *dm, MirrTopoStore_t *mesh_topo_store,
- const bool skip_em_vert_array_init);
-void ED_mesh_mirrtopo_init__real_mesh(
- struct Mesh *me, struct Mesh *dm, MirrTopoStore_t *mesh_topo_store,
+ struct Mesh *me, struct Mesh *me_eval, MirrTopoStore_t *mesh_topo_store,
const bool skip_em_vert_array_init);
void ED_mesh_mirrtopo_free(MirrTopoStore_t *mesh_topo_store);
@@ -322,22 +317,17 @@ int join_mesh_shapes_exec(struct bContext *C, struct wmOperator *op);
/* mirror lookup api */
int ED_mesh_mirror_spatial_table(
- struct Object *ob, struct BMEditMesh *em, struct DerivedMesh *dm, const float co[3], char mode);
-int ED_mesh_mirror_spatial_table__real_mesh(
- struct Object *ob, struct BMEditMesh *em, struct Mesh *mesh, const float co[3], char mode);
-int ED_mesh_mirror_topo_table(struct Object *ob, struct DerivedMesh *dm, char mode);
-int ED_mesh_mirror_topo_table__real_mesh(struct Object *ob, struct Mesh *mesh, char mode);
+ struct Object *ob, struct BMEditMesh *em, struct Mesh *me_eval, const float co[3], char mode);
+int ED_mesh_mirror_topo_table(struct Object *ob, struct Mesh *me_eval, char mode);
/* retrieves mirrored cache vert, or NULL if there isn't one.
* note: calling this without ensuring the mirror cache state
* is bad.*/
-int mesh_get_x_mirror_vert(struct Object *ob, struct DerivedMesh *dm, int index, const bool use_topology);
-int mesh_get_x_mirror_vert__real_mesh(struct Object *ob, struct Mesh *mesh, int index, const bool use_topology);
+int mesh_get_x_mirror_vert(struct Object *ob, struct Mesh *me_eval, int index, const bool use_topology);
struct BMVert *editbmesh_get_x_mirror_vert(struct Object *ob, struct BMEditMesh *em,
struct BMVert *eve, const float co[3],
int index, const bool use_topology);
-int *mesh_get_x_mirror_faces(struct Object *ob, struct BMEditMesh *em, struct DerivedMesh *dm);
-int *mesh_get_x_mirror_faces__real_mesh(struct Object *ob, struct BMEditMesh *em, struct Mesh *mesh);
+int *mesh_get_x_mirror_faces(struct Object *ob, struct BMEditMesh *em, struct Mesh *me_eval);
int ED_mesh_mirror_get_vert(struct Object *ob, int index);
diff --git a/source/blender/editors/include/ED_object.h b/source/blender/editors/include/ED_object.h
index d8a31e93a87..29f7edaebf0 100644
--- a/source/blender/editors/include/ED_object.h
+++ b/source/blender/editors/include/ED_object.h
@@ -40,6 +40,7 @@ struct Base;
struct EnumPropertyItem;
struct ID;
struct Main;
+struct Menu;
struct ModifierData;
struct Object;
struct ReportList;
@@ -58,12 +59,14 @@ struct PointerRNA;
struct PropertyRNA;
struct EnumPropertyItem;
struct Depsgraph;
+struct uiLayout;
#include "DNA_object_enums.h"
/* object_edit.c */
struct Object *ED_object_context(struct bContext *C); /* context.object */
struct Object *ED_object_active_context(struct bContext *C); /* context.object or context.active_object */
+void ED_hide_collections_menu_draw(const struct bContext *C, struct uiLayout *layout);
/* object_ops.c */
void ED_operatortypes_object(void);
diff --git a/source/blender/editors/include/ED_screen.h b/source/blender/editors/include/ED_screen.h
index 9fcefc1e4b1..cb4048ac63e 100644
--- a/source/blender/editors/include/ED_screen.h
+++ b/source/blender/editors/include/ED_screen.h
@@ -60,6 +60,8 @@ struct Main;
struct wmMsgBus;
struct wmMsgSubscribeKey;
struct wmMsgSubscribeValue;
+struct wmOperatorType;
+struct IDProperty;
/* regions */
void ED_region_do_listen(
@@ -311,6 +313,21 @@ int ED_operator_posemode_local(struct bContext *C);
int ED_operator_mask(struct bContext *C);
int ED_operator_camera(struct bContext *C);
+/* screen_user_menu.c */
+
+struct bUserMenu *ED_screen_user_menu_find(struct bContext *C);
+struct bUserMenu *ED_screen_user_menu_ensure(struct bContext *C);
+
+
+struct bUserMenuItem_Op *ED_screen_user_menu_item_find_operator(
+ struct ListBase *lb,
+ struct wmOperatorType *ot, struct IDProperty *prop, short opcontext);
+void ED_screen_user_menu_item_add_operator(
+ struct ListBase *lb, const char *ui_name,
+ struct wmOperatorType *ot, struct IDProperty *prop, short opcontext);
+void ED_screen_user_menu_item_remove(
+ struct ListBase *lb, struct bUserMenuItem *umi);
+void ED_screen_user_menu_register(void);
/* Cache display helpers */
@@ -333,4 +350,3 @@ void ED_area_type_hud_ensure(struct bContext *C, struct ScrArea *sa);
#define ED_KEYMAP_HEADER 64
#endif /* __ED_SCREEN_H__ */
-
diff --git a/source/blender/editors/include/ED_view3d.h b/source/blender/editors/include/ED_view3d.h
index 343bffa0082..68aeccdcc32 100644
--- a/source/blender/editors/include/ED_view3d.h
+++ b/source/blender/editors/include/ED_view3d.h
@@ -98,11 +98,28 @@ typedef struct ViewDepths {
bool damaged;
} ViewDepths;
+
+/* Rotate 3D cursor on placement. */
+enum eV3DCursorOrient {
+ V3D_CURSOR_ORIENT_NONE = 0,
+ V3D_CURSOR_ORIENT_VIEW,
+ V3D_CURSOR_ORIENT_GEOM,
+};
+
struct View3DCursor *ED_view3d_cursor3d_get(struct Scene *scene, struct View3D *v3d);
-void ED_view3d_cursor3d_calc_mat3(const struct Scene *scene, const struct View3D *v3d, float mat[3][3]);
-void ED_view3d_cursor3d_calc_mat4(const struct Scene *scene, const struct View3D *v3d, float mat[4][4]);
-void ED_view3d_cursor3d_position(struct bContext *C, float fp[3], const int mval[2]);
-void ED_view3d_cursor3d_update(struct bContext *C, const int mval[2]);
+void ED_view3d_cursor3d_calc_mat3(const struct Scene *scene, const struct View3D *v3d, float mat[3][3]);
+void ED_view3d_cursor3d_calc_mat4(const struct Scene *scene, const struct View3D *v3d, float mat[4][4]);
+void ED_view3d_cursor3d_position(
+ struct bContext *C, const int mval[2],
+ const bool use_depth,
+ float cursor_co[3]);
+void ED_view3d_cursor3d_position_rotation(
+ struct bContext *C, const int mval[2],
+ const bool use_depth, enum eV3DCursorOrient orientation,
+ float cursor_co[3], float cursor_quat[4]);
+void ED_view3d_cursor3d_update(
+ struct bContext *C, const int mval[2],
+ bool use_depth, enum eV3DCursorOrient orientation);
struct Camera *ED_view3d_camera_data_get(struct View3D *v3d, struct RegionView3D *rv3d);
diff --git a/source/blender/editors/include/UI_icons.h b/source/blender/editors/include/UI_icons.h
index 659f6c97696..75e835ff1d3 100644
--- a/source/blender/editors/include/UI_icons.h
+++ b/source/blender/editors/include/UI_icons.h
@@ -273,10 +273,14 @@ DEF_ICON(RNA_ADD)
DEF_ICON(BLANK093)
DEF_ICON(BLANK094)
DEF_ICON(BLANK095)
- DEF_ICON(BLANK096)
- DEF_ICON(BLANK097)
- DEF_ICON(BLANK098)
- DEF_ICON(BLANK099)
+#endif
+
+DEF_ICON(MOUSE_LMB)
+DEF_ICON(MOUSE_MMB)
+DEF_ICON(MOUSE_RMB)
+DEF_ICON(MOUSE_DRAG)
+
+#ifndef DEF_ICON_BLANK_SKIP
DEF_ICON(BLANK100)
DEF_ICON(BLANK101)
DEF_ICON(BLANK102)
@@ -292,8 +296,10 @@ DEF_ICON(RNA_ADD)
DEF_ICON(BLANK112)
DEF_ICON(BLANK113)
DEF_ICON(BLANK114)
- DEF_ICON(BLANK115)
- DEF_ICON(BLANK116)
+#endif
+DEF_ICON(RESTRICT_VIEW_OFF)
+DEF_ICON(RESTRICT_VIEW_ON)
+#ifndef DEF_ICON_BLANK_SKIP
DEF_ICON(BLANK116b)
#endif
@@ -319,8 +325,8 @@ DEF_ICON(OUTLINER_OB_LIGHTPROBE)
#endif
DEF_ICON(RESTRICT_COLOR_OFF)
DEF_ICON(RESTRICT_COLOR_ON)
-DEF_ICON(RESTRICT_VIEW_OFF)
-DEF_ICON(RESTRICT_VIEW_ON)
+DEF_ICON(HIDE_OFF)
+DEF_ICON(HIDE_ON)
DEF_ICON(RESTRICT_SELECT_OFF)
DEF_ICON(RESTRICT_SELECT_ON)
DEF_ICON(RESTRICT_RENDER_OFF)
diff --git a/source/blender/editors/include/UI_interface.h b/source/blender/editors/include/UI_interface.h
index 0b4817c8049..d4285f5a96e 100644
--- a/source/blender/editors/include/UI_interface.h
+++ b/source/blender/editors/include/UI_interface.h
@@ -418,6 +418,7 @@ uiPopupMenu *UI_popup_menu_begin_ex(
struct bContext *C, const char *title, const char *block_name,
int icon) ATTR_NONNULL();
void UI_popup_menu_end(struct bContext *C, struct uiPopupMenu *head);
+bool UI_popup_menu_end_or_cancel(struct bContext *C, struct uiPopupMenu *head);
struct uiLayout *UI_popup_menu_layout(uiPopupMenu *head);
void UI_popup_menu_reports(struct bContext *C, struct ReportList *reports) ATTR_NONNULL();
@@ -534,6 +535,8 @@ void UI_block_flag_enable(uiBlock *block, int flag);
void UI_block_flag_disable(uiBlock *block, int flag);
void UI_block_translate(uiBlock *block, int x, int y);
+bool UI_block_is_empty(const uiBlock *block);
+
int UI_but_return_value_get(uiBut *but);
void UI_but_drag_set_id(uiBut *but, struct ID *id);
@@ -1062,6 +1065,7 @@ void uiTemplateHeader3D_mode(uiLayout *layout, struct bContext *C);
void uiTemplateHeader3D(uiLayout *layout, struct bContext *C);
void uiTemplateEditModeSelection(uiLayout *layout, struct bContext *C);
void uiTemplateReportsBanner(uiLayout *layout, struct bContext *C);
+void uiTemplateCursorKeymap(uiLayout *layout, struct bContext *C);
void uiTemplateKeymapItemProperties(uiLayout *layout, struct PointerRNA *ptr);
void uiTemplateComponentMenu(uiLayout *layout, struct PointerRNA *ptr, const char *propname, const char *name);
void uiTemplateNodeSocket(uiLayout *layout, struct bContext *C, float *color);
diff --git a/source/blender/editors/interface/CMakeLists.txt b/source/blender/editors/interface/CMakeLists.txt
index 07ba3b90e11..882db88879d 100644
--- a/source/blender/editors/interface/CMakeLists.txt
+++ b/source/blender/editors/interface/CMakeLists.txt
@@ -44,6 +44,7 @@ set(SRC
interface.c
interface_align.c
interface_anim.c
+ interface_context_menu.c
interface_draw.c
interface_eyedropper.c
interface_eyedropper_color.c
@@ -56,7 +57,6 @@ set(SRC
interface_layout.c
interface_ops.c
interface_panel.c
- interface_regions.c
interface_region_color_picker.c
interface_region_hud.c
interface_region_menu_pie.c
@@ -65,6 +65,7 @@ set(SRC
interface_region_popup.c
interface_region_search.c
interface_region_tooltip.c
+ interface_regions.c
interface_style.c
interface_templates.c
interface_utils.c
diff --git a/source/blender/editors/interface/interface.c b/source/blender/editors/interface/interface.c
index 8c37054098b..a36f534807c 100644
--- a/source/blender/editors/interface/interface.c
+++ b/source/blender/editors/interface/interface.c
@@ -4031,6 +4031,16 @@ int UI_blocklist_min_y_get(ListBase *lb)
return min;
}
+bool UI_block_is_empty(const uiBlock *block)
+{
+ for (const uiBut *but = block->buttons.first; but; but = but->next) {
+ if (!ELEM(but->type, UI_BTYPE_SEPR, UI_BTYPE_SEPR_LINE)) {
+ return false;
+ }
+ }
+ return true;
+}
+
void UI_block_direction_set(uiBlock *block, char direction)
{
block->direction = direction;
@@ -4780,4 +4790,3 @@ void UI_exit(void)
ui_resources_free();
ui_but_clipboard_free();
}
-
diff --git a/source/blender/editors/interface/interface_context_menu.c b/source/blender/editors/interface/interface_context_menu.c
new file mode 100644
index 00000000000..cda81ba79cf
--- /dev/null
+++ b/source/blender/editors/interface/interface_context_menu.c
@@ -0,0 +1,756 @@
+/*
+ * ***** 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 *****
+ */
+
+/** \file blender/editors/interface/interface_context_menu.c
+ * \ingroup edinterface
+ *
+ * Generic context popup menus.
+ */
+
+#include <string.h>
+
+#include "MEM_guardedalloc.h"
+
+#include "DNA_scene_types.h"
+#include "DNA_screen_types.h"
+
+#include "BLI_path_util.h"
+#include "BLI_string.h"
+#include "BLI_utildefines.h"
+
+#include "BLT_translation.h"
+
+#include "BKE_addon.h"
+#include "BKE_context.h"
+#include "BKE_idprop.h"
+#include "BKE_screen.h"
+
+#include "ED_screen.h"
+#include "ED_keyframing.h"
+
+#include "UI_interface.h"
+
+#include "interface_intern.h"
+
+#include "RNA_access.h"
+
+#include "WM_api.h"
+#include "WM_types.h"
+
+/* This hack is needed because we don't have a good way to re-reference keymap items once added: T42944 */
+#define USE_KEYMAP_ADD_HACK
+
+/* -------------------------------------------------------------------- */
+/** \name Button Context Menu
+ * \{ */
+
+static void but_shortcut_name_func(bContext *C, void *arg1, int UNUSED(event))
+{
+ uiBut *but = (uiBut *)arg1;
+
+ if (but->optype) {
+ char shortcut_str[128];
+
+ IDProperty *prop = (but->opptr) ? but->opptr->data : NULL;
+
+ /* complex code to change name of button */
+ if (WM_key_event_operator_string(
+ C, but->optype->idname, but->opcontext, prop, true,
+ shortcut_str, sizeof(shortcut_str)))
+ {
+ ui_but_add_shortcut(but, shortcut_str, true);
+ }
+ else {
+ /* simply strip the shortcut */
+ ui_but_add_shortcut(but, NULL, true);
+ }
+ }
+}
+
+static uiBlock *menu_change_shortcut(bContext *C, ARegion *ar, void *arg)
+{
+ wmWindowManager *wm = CTX_wm_manager(C);
+ uiBlock *block;
+ uiBut *but = (uiBut *)arg;
+ wmKeyMap *km;
+ wmKeyMapItem *kmi;
+ PointerRNA ptr;
+ uiLayout *layout;
+ uiStyle *style = UI_style_get_dpi();
+ IDProperty *prop = (but->opptr) ? but->opptr->data : NULL;
+
+ kmi = WM_key_event_operator(C, but->optype->idname, but->opcontext, prop, true, &km);
+ BLI_assert(kmi != NULL);
+
+ RNA_pointer_create(&wm->id, &RNA_KeyMapItem, kmi, &ptr);
+
+ block = UI_block_begin(C, ar, "_popup", UI_EMBOSS);
+ UI_block_func_handle_set(block, but_shortcut_name_func, but);
+ UI_block_flag_enable(block, UI_BLOCK_MOVEMOUSE_QUIT);
+ UI_block_direction_set(block, UI_DIR_CENTER_Y);
+
+ layout = UI_block_layout(block, UI_LAYOUT_VERTICAL, UI_LAYOUT_PANEL, 0, 0, 200, 20, 0, style);
+
+ uiItemR(layout, &ptr, "type", UI_ITEM_R_FULL_EVENT | UI_ITEM_R_IMMEDIATE, "", ICON_NONE);
+
+ UI_block_bounds_set_popup(block, 6, -50, 26);
+
+ return block;
+}
+
+#ifdef USE_KEYMAP_ADD_HACK
+static int g_kmi_id_hack;
+#endif
+
+static uiBlock *menu_add_shortcut(bContext *C, ARegion *ar, void *arg)
+{
+ wmWindowManager *wm = CTX_wm_manager(C);
+ uiBlock *block;
+ uiBut *but = (uiBut *)arg;
+ wmKeyMap *km;
+ wmKeyMapItem *kmi;
+ PointerRNA ptr;
+ uiLayout *layout;
+ uiStyle *style = UI_style_get_dpi();
+ IDProperty *prop = (but->opptr) ? but->opptr->data : NULL;
+ int kmi_id;
+
+ /* XXX this guess_opname can potentially return a different keymap than being found on adding later... */
+ km = WM_keymap_guess_opname(C, but->optype->idname);
+ kmi = WM_keymap_add_item(km, but->optype->idname, AKEY, KM_PRESS, 0, 0);
+ kmi_id = kmi->id;
+
+ /* copy properties, prop can be NULL for reset */
+ if (prop)
+ prop = IDP_CopyProperty(prop);
+ WM_keymap_properties_reset(kmi, prop);
+
+ /* update and get pointers again */
+ WM_keyconfig_update(wm);
+
+ km = WM_keymap_guess_opname(C, but->optype->idname);
+ kmi = WM_keymap_item_find_id(km, kmi_id);
+
+ RNA_pointer_create(&wm->id, &RNA_KeyMapItem, kmi, &ptr);
+
+ block = UI_block_begin(C, ar, "_popup", UI_EMBOSS);
+ UI_block_func_handle_set(block, but_shortcut_name_func, but);
+ UI_block_direction_set(block, UI_DIR_CENTER_Y);
+
+ layout = UI_block_layout(block, UI_LAYOUT_VERTICAL, UI_LAYOUT_PANEL, 0, 0, 200, 20, 0, style);
+
+ uiItemR(layout, &ptr, "type", UI_ITEM_R_FULL_EVENT | UI_ITEM_R_IMMEDIATE, "", ICON_NONE);
+
+ UI_block_bounds_set_popup(block, 6, -50, 26);
+
+#ifdef USE_KEYMAP_ADD_HACK
+ g_kmi_id_hack = kmi_id;
+#endif
+ return block;
+}
+
+static void menu_add_shortcut_cancel(struct bContext *C, void *arg1)
+{
+ uiBut *but = (uiBut *)arg1;
+ wmKeyMap *km;
+ wmKeyMapItem *kmi;
+#ifndef USE_KEYMAP_ADD_HACK
+ IDProperty *prop;
+#endif
+ int kmi_id;
+
+#ifdef USE_KEYMAP_ADD_HACK
+ km = WM_keymap_guess_opname(C, but->optype->idname);
+ kmi_id = g_kmi_id_hack;
+ UNUSED_VARS(but);
+#else
+ prop = (but->opptr) ? but->opptr->data : NULL;
+ kmi_id = WM_key_event_operator_id(C, but->optype->idname, but->opcontext, prop, true, &km);
+#endif
+
+ kmi = WM_keymap_item_find_id(km, kmi_id);
+ WM_keymap_remove_item(km, kmi);
+}
+
+static void popup_change_shortcut_func(bContext *C, void *arg1, void *UNUSED(arg2))
+{
+ uiBut *but = (uiBut *)arg1;
+ UI_popup_block_invoke(C, menu_change_shortcut, but);
+}
+
+static void remove_shortcut_func(bContext *C, void *arg1, void *UNUSED(arg2))
+{
+ uiBut *but = (uiBut *)arg1;
+ wmKeyMap *km;
+ wmKeyMapItem *kmi;
+ IDProperty *prop = (but->opptr) ? but->opptr->data : NULL;
+
+ kmi = WM_key_event_operator(C, but->optype->idname, but->opcontext, prop, true, &km);
+ BLI_assert(kmi != NULL);
+
+ WM_keymap_remove_item(km, kmi);
+
+ but_shortcut_name_func(C, but, 0);
+}
+
+static void popup_add_shortcut_func(bContext *C, void *arg1, void *UNUSED(arg2))
+{
+ uiBut *but = (uiBut *)arg1;
+ UI_popup_block_ex(C, menu_add_shortcut, NULL, menu_add_shortcut_cancel, but, NULL);
+}
+
+static void popup_user_menu_add_or_replace_func(bContext *C, void *arg1, void *UNUSED(arg2))
+{
+ uiBut *but = arg1;
+ bUserMenu *um = ED_screen_user_menu_ensure(C);
+
+ char drawstr[sizeof(but->drawstr)];
+ STRNCPY(drawstr, but->drawstr);
+ if (but->flag & UI_BUT_HAS_SEP_CHAR) {
+ char *sep = strrchr(drawstr, UI_SEP_CHAR);
+ if (sep) {
+ *sep = '\0';
+ }
+ }
+ ED_screen_user_menu_item_add_operator(
+ &um->items, drawstr,
+ but->optype, but->opptr ? but->opptr->data : NULL, but->opcontext);
+}
+
+static void popup_user_menu_remove_func(bContext *UNUSED(C), void *arg1, void *arg2)
+{
+ bUserMenu *um = arg1;
+ bUserMenuItem *umi = arg2;
+ ED_screen_user_menu_item_remove(&um->items, umi);
+}
+
+static void ui_but_menu_add_path_operators(uiLayout *layout, PointerRNA *ptr, PropertyRNA *prop)
+{
+ const PropertySubType subtype = RNA_property_subtype(prop);
+ wmOperatorType *ot = WM_operatortype_find("WM_OT_path_open", true);
+ char filepath[FILE_MAX];
+ char dir[FILE_MAXDIR];
+ char file[FILE_MAXFILE];
+ PointerRNA props_ptr;
+
+ BLI_assert(ELEM(subtype, PROP_FILEPATH, PROP_DIRPATH));
+ UNUSED_VARS_NDEBUG(subtype);
+
+ RNA_property_string_get(ptr, prop, filepath);
+ BLI_split_dirfile(filepath, dir, file, sizeof(dir), sizeof(file));
+
+ if (file[0]) {
+ BLI_assert(subtype == PROP_FILEPATH);
+ uiItemFullO_ptr(
+ layout, ot, CTX_IFACE_(BLT_I18NCONTEXT_OPERATOR_DEFAULT, "Open File Externally"),
+ ICON_NONE, NULL, WM_OP_INVOKE_DEFAULT, 0, &props_ptr);
+ RNA_string_set(&props_ptr, "filepath", filepath);
+ }
+
+ uiItemFullO_ptr(
+ layout, ot, CTX_IFACE_(BLT_I18NCONTEXT_OPERATOR_DEFAULT, "Open Location Externally"),
+ ICON_NONE, NULL, WM_OP_INVOKE_DEFAULT, 0, &props_ptr);
+ RNA_string_set(&props_ptr, "filepath", dir);
+}
+
+bool ui_popup_context_menu_for_button(bContext *C, uiBut *but)
+{
+ /* having this menu for some buttons makes no sense */
+ if (but->type == UI_BTYPE_IMAGE) {
+ return false;
+ }
+
+ uiPopupMenu *pup;
+ uiLayout *layout;
+
+ {
+ uiStringInfo label = {BUT_GET_LABEL, NULL};
+
+ /* highly unlikely getting the label ever fails */
+ UI_but_string_info_get(C, but, &label, NULL);
+
+ pup = UI_popup_menu_begin(C, label.strinfo ? label.strinfo : "", ICON_NONE);
+ layout = UI_popup_menu_layout(pup);
+ if (label.strinfo) {
+ MEM_freeN(label.strinfo);
+ }
+ uiLayoutSetOperatorContext(layout, WM_OP_INVOKE_DEFAULT);
+ }
+
+ if (but->rnapoin.data && but->rnaprop) {
+ PointerRNA *ptr = &but->rnapoin;
+ PropertyRNA *prop = but->rnaprop;
+ const PropertyType type = RNA_property_type(prop);
+ const PropertySubType subtype = RNA_property_subtype(prop);
+ bool is_anim = RNA_property_animateable(ptr, prop);
+ bool is_editable = RNA_property_editable(ptr, prop);
+ /*bool is_idprop = RNA_property_is_idprop(prop);*/ /* XXX does not work as expected, not strictly needed */
+ bool is_set = RNA_property_is_set(ptr, prop);
+
+ /* second slower test, saved people finding keyframe items in menus when its not possible */
+ if (is_anim)
+ is_anim = RNA_property_path_from_ID_check(&but->rnapoin, but->rnaprop);
+
+ /* determine if we can key a single component of an array */
+ const bool is_array = RNA_property_array_length(&but->rnapoin, but->rnaprop) != 0;
+ const bool is_array_component = (is_array && but->rnaindex != -1);
+
+ const int static_override_status = RNA_property_static_override_status(ptr, prop, -1);
+ const bool is_static_overridable = (static_override_status & RNA_OVERRIDE_STATUS_OVERRIDABLE) != 0;
+
+ const int dynamic_override_status = RNA_property_dynamic_override_status(ptr, prop, -1);
+ const bool is_dynamic_overridable = (dynamic_override_status & RNA_OVERRIDE_STATUS_OVERRIDABLE) != 0;
+
+ /* Keyframes */
+ if (but->flag & UI_BUT_ANIMATED_KEY) {
+ /* Set the (button_pointer, button_prop) and pointer data for Python access to the hovered ui element. */
+ uiLayoutSetContextFromBut(layout, but);
+
+ /* replace/delete keyfraemes */
+ if (is_array_component) {
+ uiItemBooleanO(
+ layout, CTX_IFACE_(BLT_I18NCONTEXT_OPERATOR_DEFAULT, "Replace Keyframes"),
+ ICON_KEY_HLT, "ANIM_OT_keyframe_insert_button", "all", 1);
+ uiItemBooleanO(
+ layout, CTX_IFACE_(BLT_I18NCONTEXT_OPERATOR_DEFAULT, "Replace Single Keyframe"),
+ ICON_NONE, "ANIM_OT_keyframe_insert_button", "all", 0);
+ uiItemBooleanO(
+ layout, CTX_IFACE_(BLT_I18NCONTEXT_OPERATOR_DEFAULT, "Delete Keyframes"),
+ ICON_NONE, "ANIM_OT_keyframe_delete_button", "all", 1);
+ uiItemBooleanO(
+ layout, CTX_IFACE_(BLT_I18NCONTEXT_OPERATOR_DEFAULT, "Delete Single Keyframe"),
+ ICON_NONE, "ANIM_OT_keyframe_delete_button", "all", 0);
+ }
+ else {
+ uiItemBooleanO(
+ layout, CTX_IFACE_(BLT_I18NCONTEXT_OPERATOR_DEFAULT, "Replace Keyframe"),
+ ICON_KEY_HLT, "ANIM_OT_keyframe_insert_button", "all", 1);
+ uiItemBooleanO(
+ layout, CTX_IFACE_(BLT_I18NCONTEXT_OPERATOR_DEFAULT, "Delete Keyframe"),
+ ICON_NONE, "ANIM_OT_keyframe_delete_button", "all", 1);
+ }
+
+ /* keyframe settings */
+ uiItemS(layout);
+
+
+ }
+ else if (but->flag & UI_BUT_DRIVEN) {
+ /* pass */
+ }
+ else if (is_anim) {
+ if (is_array_component) {
+ uiItemBooleanO(
+ layout, CTX_IFACE_(BLT_I18NCONTEXT_OPERATOR_DEFAULT, "Insert Keyframes"),
+ ICON_KEY_HLT, "ANIM_OT_keyframe_insert_button", "all", 1);
+ uiItemBooleanO(
+ layout, CTX_IFACE_(BLT_I18NCONTEXT_OPERATOR_DEFAULT, "Insert Single Keyframe"),
+ ICON_NONE, "ANIM_OT_keyframe_insert_button", "all", 0);
+ }
+ else {
+ uiItemBooleanO(
+ layout, CTX_IFACE_(BLT_I18NCONTEXT_OPERATOR_DEFAULT, "Insert Keyframe"),
+ ICON_KEY_HLT, "ANIM_OT_keyframe_insert_button", "all", 1);
+ }
+ }
+
+ if ((but->flag & UI_BUT_ANIMATED) && (but->rnapoin.type != &RNA_NlaStrip)) {
+ if (is_array_component) {
+ uiItemBooleanO(
+ layout, CTX_IFACE_(BLT_I18NCONTEXT_OPERATOR_DEFAULT, "Clear Keyframes"),
+ ICON_KEY_DEHLT, "ANIM_OT_keyframe_clear_button", "all", 1);
+ uiItemBooleanO(
+ layout, CTX_IFACE_(BLT_I18NCONTEXT_OPERATOR_DEFAULT, "Clear Single Keyframes"),
+ ICON_NONE, "ANIM_OT_keyframe_clear_button", "all", 0);
+ }
+ else {
+ uiItemBooleanO(
+ layout, CTX_IFACE_(BLT_I18NCONTEXT_OPERATOR_DEFAULT, "Clear Keyframes"),
+ ICON_KEY_DEHLT, "ANIM_OT_keyframe_clear_button", "all", 1);
+ }
+ }
+
+ /* Drivers */
+ if (but->flag & UI_BUT_DRIVEN) {
+ uiItemS(layout);
+
+ if (is_array_component) {
+ uiItemBooleanO(
+ layout, CTX_IFACE_(BLT_I18NCONTEXT_OPERATOR_DEFAULT, "Delete Drivers"),
+ ICON_X, "ANIM_OT_driver_button_remove", "all", 1);
+ uiItemBooleanO(
+ layout, CTX_IFACE_(BLT_I18NCONTEXT_OPERATOR_DEFAULT, "Delete Single Driver"),
+ ICON_NONE, "ANIM_OT_driver_button_remove", "all", 0);
+ }
+ else {
+ uiItemBooleanO(
+ layout, CTX_IFACE_(BLT_I18NCONTEXT_OPERATOR_DEFAULT, "Delete Driver"),
+ ICON_X, "ANIM_OT_driver_button_remove", "all", 1);
+ }
+
+ uiItemO(layout, CTX_IFACE_(BLT_I18NCONTEXT_OPERATOR_DEFAULT, "Copy Driver"),
+ ICON_NONE, "ANIM_OT_copy_driver_button");
+ if (ANIM_driver_can_paste()) {
+ uiItemO(layout, CTX_IFACE_(BLT_I18NCONTEXT_OPERATOR_DEFAULT, "Paste Driver"),
+ ICON_NONE, "ANIM_OT_paste_driver_button");
+ }
+
+ uiItemO(layout, CTX_IFACE_(BLT_I18NCONTEXT_OPERATOR_DEFAULT, "Edit Driver"),
+ ICON_DRIVER, "ANIM_OT_driver_button_edit");
+
+ uiItemO(layout, CTX_IFACE_(BLT_I18NCONTEXT_OPERATOR_DEFAULT, "Open Drivers Editor"),
+ ICON_NONE, "SCREEN_OT_drivers_editor_show");
+ }
+ else if (but->flag & (UI_BUT_ANIMATED_KEY | UI_BUT_ANIMATED)) {
+ /* pass */
+ }
+ else if (is_anim) {
+ uiItemS(layout);
+
+ uiItemO(layout, CTX_IFACE_(BLT_I18NCONTEXT_OPERATOR_DEFAULT, "Add Driver"),
+ ICON_DRIVER, "ANIM_OT_driver_button_add");
+
+ if (ANIM_driver_can_paste()) {
+ uiItemO(layout, CTX_IFACE_(BLT_I18NCONTEXT_OPERATOR_DEFAULT, "Paste Driver"),
+ ICON_NONE, "ANIM_OT_paste_driver_button");
+ }
+
+ uiItemO(layout, CTX_IFACE_(BLT_I18NCONTEXT_OPERATOR_DEFAULT, "Open Drivers Editor"),
+ ICON_NONE, "SCREEN_OT_drivers_editor_show");
+ }
+
+ /* Keying Sets */
+ /* TODO: check on modifyability of Keying Set when doing this */
+ if (is_anim) {
+ uiItemS(layout);
+
+ if (is_array_component) {
+ uiItemBooleanO(
+ layout, CTX_IFACE_(BLT_I18NCONTEXT_OPERATOR_DEFAULT, "Add All to Keying Set"),
+ ICON_KEYINGSET, "ANIM_OT_keyingset_button_add", "all", 1);
+ uiItemBooleanO(
+ layout, CTX_IFACE_(BLT_I18NCONTEXT_OPERATOR_DEFAULT, "Add Single to Keying Set"),
+ ICON_NONE, "ANIM_OT_keyingset_button_add", "all", 0);
+ uiItemO(layout, CTX_IFACE_(BLT_I18NCONTEXT_OPERATOR_DEFAULT, "Remove from Keying Set"),
+ ICON_NONE, "ANIM_OT_keyingset_button_remove");
+ }
+ else {
+ uiItemBooleanO(
+ layout, CTX_IFACE_(BLT_I18NCONTEXT_OPERATOR_DEFAULT, "Add to Keying Set"),
+ ICON_KEYINGSET, "ANIM_OT_keyingset_button_add", "all", 1);
+ uiItemO(layout, CTX_IFACE_(BLT_I18NCONTEXT_OPERATOR_DEFAULT, "Remove from Keying Set"),
+ ICON_NONE, "ANIM_OT_keyingset_button_remove");
+ }
+ }
+
+ /* Dynamic Override Operators */
+ if (is_editable && is_dynamic_overridable) {
+ uiItemS(layout);
+ uiItemFullO(layout, "SCENE_OT_view_layer_override_add", NULL, ICON_NONE, NULL, WM_OP_INVOKE_DEFAULT, 0, NULL);
+ }
+
+ if (is_static_overridable) {
+ wmOperatorType *ot;
+ PointerRNA op_ptr;
+ /* Override Operators */
+ uiItemS(layout);
+
+ if (but->flag & UI_BUT_OVERRIDEN) {
+ if (is_array_component) {
+#if 0 /* Disabled for now. */
+ ot = WM_operatortype_find("UI_OT_override_type_set_button", false);
+ uiItemFullO_ptr(
+ layout, ot, "Overrides Type", ICON_NONE,
+ NULL, WM_OP_INVOKE_DEFAULT, 0, &op_ptr);
+ RNA_boolean_set(&op_ptr, "all", true);
+ uiItemFullO_ptr(
+ layout, ot, "Single Override Type", ICON_NONE,
+ NULL, WM_OP_INVOKE_DEFAULT, 0, &op_ptr);
+ RNA_boolean_set(&op_ptr, "all", false);
+#endif
+ uiItemBooleanO(
+ layout, CTX_IFACE_(BLT_I18NCONTEXT_OPERATOR_DEFAULT, "Remove Overrides"),
+ ICON_X, "UI_OT_override_remove_button", "all", true);
+ uiItemBooleanO(
+ layout, CTX_IFACE_(BLT_I18NCONTEXT_OPERATOR_DEFAULT, "Remove Single Override"),
+ ICON_X, "UI_OT_override_remove_button", "all", false);
+ }
+ else {
+#if 0 /* Disabled for now. */
+ uiItemFullO(
+ layout, "UI_OT_override_type_set_button", "Override Type", ICON_NONE,
+ NULL, WM_OP_INVOKE_DEFAULT, 0, &op_ptr);
+ RNA_boolean_set(&op_ptr, "all", false);
+#endif
+ uiItemBooleanO(
+ layout, CTX_IFACE_(BLT_I18NCONTEXT_OPERATOR_DEFAULT, "Remove Override"),
+ ICON_X, "UI_OT_override_remove_button", "all", true);
+ }
+ }
+ else {
+ if (is_array_component) {
+ ot = WM_operatortype_find("UI_OT_override_type_set_button", false);
+ uiItemFullO_ptr(
+ layout, ot, "Define Overrides", ICON_NONE,
+ NULL, WM_OP_INVOKE_DEFAULT, 0, &op_ptr);
+ RNA_boolean_set(&op_ptr, "all", true);
+ uiItemFullO_ptr(
+ layout, ot, "Define Single Override", ICON_NONE,
+ NULL, WM_OP_INVOKE_DEFAULT, 0, &op_ptr);
+ RNA_boolean_set(&op_ptr, "all", false);
+ }
+ else {
+ uiItemFullO(
+ layout, "UI_OT_override_type_set_button", "Define Override", ICON_NONE,
+ NULL, WM_OP_INVOKE_DEFAULT, 0, &op_ptr);
+ RNA_boolean_set(&op_ptr, "all", false);
+ }
+ }
+ }
+
+ uiItemS(layout);
+
+ /* Property Operators */
+
+ /* Copy Property Value
+ * Paste Property Value */
+
+ if (is_array_component) {
+ uiItemBooleanO(
+ layout, CTX_IFACE_(BLT_I18NCONTEXT_OPERATOR_DEFAULT, "Reset All to Default Values"),
+ ICON_LOOP_BACK, "UI_OT_reset_default_button", "all", 1);
+ uiItemBooleanO(
+ layout, CTX_IFACE_(BLT_I18NCONTEXT_OPERATOR_DEFAULT, "Reset Single to Default Value"),
+ ICON_NONE, "UI_OT_reset_default_button", "all", 0);
+ }
+ else {
+ uiItemBooleanO(layout, CTX_IFACE_(BLT_I18NCONTEXT_OPERATOR_DEFAULT, "Reset to Default Value"),
+ ICON_LOOP_BACK, "UI_OT_reset_default_button", "all", 1);
+ }
+ if (is_editable /*&& is_idprop*/ && is_set) {
+ uiItemO(layout, CTX_IFACE_(BLT_I18NCONTEXT_OPERATOR_DEFAULT, "Unset"),
+ ICON_NONE, "UI_OT_unset_property_button");
+ }
+
+ if (is_array_component) {
+ uiItemBooleanO(
+ layout, CTX_IFACE_(BLT_I18NCONTEXT_OPERATOR_DEFAULT, "Copy All To Selected"),
+ ICON_NONE, "UI_OT_copy_to_selected_button", "all", true);
+ uiItemBooleanO(
+ layout, CTX_IFACE_(BLT_I18NCONTEXT_OPERATOR_DEFAULT, "Copy Single To Selected"),
+ ICON_NONE, "UI_OT_copy_to_selected_button", "all", false);
+ }
+ else {
+ uiItemBooleanO(
+ layout, CTX_IFACE_(BLT_I18NCONTEXT_OPERATOR_DEFAULT, "Copy To Selected"),
+ ICON_NONE, "UI_OT_copy_to_selected_button", "all", true);
+ }
+
+ uiItemO(layout, CTX_IFACE_(BLT_I18NCONTEXT_OPERATOR_DEFAULT, "Copy Data Path"),
+ ICON_NONE, "UI_OT_copy_data_path_button");
+
+ uiItemS(layout);
+
+ if (type == PROP_STRING && ELEM(subtype, PROP_FILEPATH, PROP_DIRPATH)) {
+ ui_but_menu_add_path_operators(layout, ptr, prop);
+ uiItemS(layout);
+ }
+ }
+
+ /* Operator buttons */
+ if (but->optype) {
+ uiBlock *block = uiLayoutGetBlock(layout);
+ uiBut *but2;
+ IDProperty *prop = (but->opptr) ? but->opptr->data : NULL;
+ int w = uiLayoutGetWidth(layout);
+ wmKeyMap *km;
+ /* We want to know if this op has a shortcut, be it hotkey or not. */
+ wmKeyMapItem *kmi = WM_key_event_operator(C, but->optype->idname, but->opcontext, prop, false, &km);
+
+ /* We do have a shortcut, but only keyboard ones are editbale that way... */
+ if (kmi) {
+ if (ISKEYBOARD(kmi->type)) {
+#if 0 /* would rather use a block but, but gets weirdly positioned... */
+ uiDefBlockBut(
+ block, menu_change_shortcut, but, "Change Shortcut",
+ 0, 0, uiLayoutGetWidth(layout), UI_UNIT_Y, "");
+#endif
+
+ but2 = uiDefIconTextBut(
+ block, UI_BTYPE_BUT, 0, ICON_HAND,
+ CTX_IFACE_(BLT_I18NCONTEXT_OPERATOR_DEFAULT, "Change Shortcut"),
+ 0, 0, w, UI_UNIT_Y, NULL, 0, 0, 0, 0, "");
+ UI_but_func_set(but2, popup_change_shortcut_func, but, NULL);
+
+ but2 = uiDefIconTextBut(
+ block, UI_BTYPE_BUT, 0, ICON_NONE,
+ CTX_IFACE_(BLT_I18NCONTEXT_OPERATOR_DEFAULT, "Remove Shortcut"),
+ 0, 0, w, UI_UNIT_Y, NULL, 0, 0, 0, 0, "");
+ UI_but_func_set(but2, remove_shortcut_func, but, NULL);
+ }
+ else {
+ but2 = uiDefIconTextBut(
+ block, UI_BTYPE_BUT, 0, ICON_HAND, IFACE_("Non-Keyboard Shortcut"),
+ 0, 0, w, UI_UNIT_Y, NULL, 0, 0, 0, 0,
+ TIP_("Only keyboard shortcuts can be edited that way, "
+ "please use User Preferences otherwise"));
+ UI_but_flag_enable(but2, UI_BUT_DISABLED);
+ }
+ }
+ /* only show 'add' if there's a suitable key map for it to go in */
+ else if (WM_keymap_guess_opname(C, but->optype->idname)) {
+ but2 = uiDefIconTextBut(
+ block, UI_BTYPE_BUT, 0, ICON_HAND,
+ CTX_IFACE_(BLT_I18NCONTEXT_OPERATOR_DEFAULT, "Add Shortcut"),
+ 0, 0, w, UI_UNIT_Y, NULL, 0, 0, 0, 0, "");
+ UI_but_func_set(but2, popup_add_shortcut_func, but, NULL);
+ }
+
+ uiItemS(layout);
+
+ {
+ but2 = uiDefIconTextBut(
+ block, UI_BTYPE_BUT, 0, ICON_MENU_PANEL,
+ CTX_IFACE_(BLT_I18NCONTEXT_OPERATOR_DEFAULT, "Add to Favorites Menu"),
+ 0, 0, w, UI_UNIT_Y, NULL, 0, 0, 0, 0,
+ "Add to a user defined context menu (stored in the user preferences)");
+ UI_but_func_set(but2, popup_user_menu_add_or_replace_func, but, NULL);
+
+ bUserMenu *um = ED_screen_user_menu_find(C);
+ if (um) {
+ bUserMenuItem_Op *umi_op = ED_screen_user_menu_item_find_operator(
+ &um->items, but->optype, prop, but->opcontext);
+ if (umi_op != NULL) {
+ but2 = uiDefIconTextBut(
+ block, UI_BTYPE_BUT, 0, ICON_CANCEL,
+ CTX_IFACE_(BLT_I18NCONTEXT_OPERATOR_DEFAULT, "Remove from Favorites Menu"),
+ 0, 0, w, UI_UNIT_Y, NULL, 0, 0, 0, 0, "");
+ UI_but_func_set(but2, popup_user_menu_remove_func, um, umi_op);
+ }
+ }
+ }
+
+ /* Set the operator pointer for python access */
+ uiLayoutSetContextFromBut(layout, but);
+
+ uiItemS(layout);
+ }
+
+ /* Show header tools for header buttons. */
+ if (ui_block_is_menu(but->block) == false) {
+ ARegion *ar = CTX_wm_region(C);
+ if (ar && (ar->regiontype == RGN_TYPE_HEADER)) {
+ uiItemMenuF(layout, IFACE_("Header"), ICON_NONE, ED_screens_header_tools_menu_create, NULL);
+ uiItemS(layout);
+ }
+ }
+
+ { /* Docs */
+ char buf[512];
+
+ if (UI_but_online_manual_id(but, buf, sizeof(buf))) {
+ PointerRNA ptr_props;
+ uiItemO(layout, CTX_IFACE_(BLT_I18NCONTEXT_OPERATOR_DEFAULT, "Online Manual"),
+ ICON_URL, "WM_OT_doc_view_manual_ui_context");
+
+ uiItemFullO(
+ layout, "WM_OT_doc_view",
+ CTX_IFACE_(BLT_I18NCONTEXT_OPERATOR_DEFAULT, "Online Python Reference"),
+ ICON_NONE, NULL, WM_OP_EXEC_DEFAULT, 0, &ptr_props);
+ RNA_string_set(&ptr_props, "doc_id", buf);
+
+ /* XXX inactive option, not for public! */
+#if 0
+ uiItemFullO(
+ layout, "WM_OT_doc_edit", "Submit Description", ICON_NONE,
+ NULL, WM_OP_INVOKE_DEFAULT, 0, &ptr_props);
+ RNA_string_set(&ptr_props, "doc_id", buf);
+ RNA_string_set(&ptr_props, "doc_new", RNA_property_description(but->rnaprop));
+#endif
+ }
+ }
+
+ if (but->optype) {
+ uiItemO(layout, NULL,
+ ICON_NONE, "UI_OT_copy_python_command_button");
+ }
+
+ /* perhaps we should move this into (G.debug & G_DEBUG) - campbell */
+ if (U.flag & USER_DEVELOPER_UI) {
+ if (ui_block_is_menu(but->block) == false) {
+ uiItemFullO(layout, "UI_OT_editsource", NULL, ICON_NONE, NULL, WM_OP_INVOKE_DEFAULT, 0, NULL);
+ }
+ }
+
+ if (BKE_addon_find(&U.addons, "ui_translate")) {
+ uiItemFullO(layout, "UI_OT_edittranslation_init", NULL, ICON_NONE, NULL, WM_OP_INVOKE_DEFAULT, 0, NULL);
+ }
+
+ MenuType *mt = WM_menutype_find("WM_MT_button_context", true);
+ if (mt) {
+ UI_menutype_draw(C, mt, uiLayoutColumn(layout, false));
+ }
+
+ return UI_popup_menu_end_or_cancel(C, pup);
+}
+
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Panel Context Menu
+ * \{ */
+
+/**
+ * menu to show when right clicking on the panel header
+ */
+void ui_popup_context_menu_for_panel(bContext *C, ARegion *ar, Panel *pa)
+{
+ bScreen *sc = CTX_wm_screen(C);
+ const bool has_panel_category = UI_panel_category_is_visible(ar);
+ const bool any_item_visible = has_panel_category;
+ PointerRNA ptr;
+ uiPopupMenu *pup;
+ uiLayout *layout;
+
+ if (!any_item_visible) {
+ return;
+ }
+
+ RNA_pointer_create(&sc->id, &RNA_Panel, pa, &ptr);
+
+ pup = UI_popup_menu_begin(C, IFACE_("Panel"), ICON_NONE);
+ layout = UI_popup_menu_layout(pup);
+
+ if (has_panel_category) {
+ char tmpstr[80];
+ BLI_snprintf(tmpstr, sizeof(tmpstr), "%s" UI_SEP_CHAR_S "%s", IFACE_("Pin"), IFACE_("Shift+Left Mouse"));
+ uiItemR(layout, &ptr, "use_pin", 0, tmpstr, ICON_NONE);
+
+ /* evil, force shortcut flag */
+ {
+ uiBlock *block = uiLayoutGetBlock(layout);
+ uiBut *but = block->buttons.last;
+ but->flag |= UI_BUT_HAS_SEP_CHAR;
+ }
+ }
+ UI_popup_menu_end(C, pup);
+}
+
+/** \} */
diff --git a/source/blender/editors/interface/interface_handlers.c b/source/blender/editors/interface/interface_handlers.c
index 1ff05fa85cc..bb54f26131a 100644
--- a/source/blender/editors/interface/interface_handlers.c
+++ b/source/blender/editors/interface/interface_handlers.c
@@ -27,7 +27,6 @@
* \ingroup edinterface
*/
-
#include <float.h>
#include <limits.h>
#include <math.h>
@@ -40,22 +39,18 @@
#include "DNA_brush_types.h"
-#include "DNA_object_types.h"
#include "DNA_scene_types.h"
#include "DNA_screen_types.h"
#include "BLI_math.h"
#include "BLI_listbase.h"
#include "BLI_linklist.h"
-#include "BLI_path_util.h"
#include "BLI_string.h"
#include "BLI_string_utf8.h"
#include "BLI_string_cursor_utf8.h"
#include "BLI_rect.h"
#include "BLI_utildefines.h"
-#include "BLT_translation.h"
-
#include "PIL_time.h"
#include "BKE_colorband.h"
@@ -63,7 +58,6 @@
#include "BKE_brush.h"
#include "BKE_colortools.h"
#include "BKE_context.h"
-#include "BKE_idprop.h"
#include "BKE_report.h"
#include "BKE_screen.h"
#include "BKE_tracking.h"
@@ -72,7 +66,6 @@
#include "ED_screen.h"
#include "ED_undo.h"
-#include "ED_keyframing.h"
#include "UI_interface.h"
#include "UI_view2d.h"
@@ -89,6 +82,7 @@
#ifdef WITH_INPUT_IME
# include "wm_window.h"
+# include "BLT_translation.h"
# include "BLT_lang.h"
#endif
@@ -111,9 +105,6 @@
#define UI_MAX_PASSWORD_STR 128
-/* This hack is needed because we don't have a good way to re-reference keymap items once added: T42944 */
-#define USE_KEYMAP_ADD_HACK
-
/* proto */
static int ui_do_but_EXIT(bContext *C, uiBut *but, struct uiHandleButtonData *data, const wmEvent *event);
static bool ui_but_find_select_in_enum__cmp(const uiBut *but_a, const uiBut *but_b);
@@ -1300,7 +1291,6 @@ typedef struct uiDragToggleHandle {
bool is_init;
bool is_set;
float but_cent_start[2];
- eButType but_type_start;
bool xy_lock[2];
int xy_init[2];
@@ -1308,7 +1298,7 @@ typedef struct uiDragToggleHandle {
} uiDragToggleHandle;
static bool ui_drag_toggle_set_xy_xy(
- bContext *C, ARegion *ar, const bool is_set, const eButType but_type_start,
+ bContext *C, ARegion *ar, const bool is_set,
const int xy_src[2], const int xy_dst[2])
{
/* popups such as layers won't re-evaluate on redraw */
@@ -1332,7 +1322,7 @@ static bool ui_drag_toggle_set_xy_xy(
if (BLI_rctf_isect_segment(&but->rect, xy_a_block, xy_b_block)) {
/* execute the button */
- if (ui_drag_toggle_but_is_supported(but) && but->type == but_type_start) {
+ if (ui_drag_toggle_but_is_supported(but)) {
/* is it pressed? */
bool is_set_but = ui_drag_toggle_but_is_pushed(but);
if (is_set_but != is_set) {
@@ -1404,7 +1394,7 @@ static void ui_drag_toggle_set(bContext *C, uiDragToggleHandle *drag_info, const
/* touch all buttons between last mouse coord and this one */
- do_draw = ui_drag_toggle_set_xy_xy(C, ar, drag_info->is_set, drag_info->but_type_start, drag_info->xy_last, xy);
+ do_draw = ui_drag_toggle_set_xy_xy(C, ar, drag_info->is_set, drag_info->xy_last, xy);
if (do_draw) {
ED_region_tag_redraw(ar);
@@ -1783,7 +1773,6 @@ static bool ui_but_drag_init(
drag_info->is_set = ui_drag_toggle_but_is_pushed(but);
drag_info->but_cent_start[0] = BLI_rctf_cent_x(&but->rect);
drag_info->but_cent_start[1] = BLI_rctf_cent_y(&but->rect);
- drag_info->but_type_start = but->type;
copy_v2_v2_int(drag_info->xy_init, &event->x);
copy_v2_v2_int(drag_info->xy_last, &event->x);
@@ -6495,602 +6484,6 @@ static int ui_do_but_TRACKPREVIEW(
return WM_UI_HANDLER_CONTINUE;
}
-static void but_shortcut_name_func(bContext *C, void *arg1, int UNUSED(event))
-{
- uiBut *but = (uiBut *)arg1;
-
- if (but->optype) {
- char shortcut_str[128];
-
- IDProperty *prop = (but->opptr) ? but->opptr->data : NULL;
-
- /* complex code to change name of button */
- if (WM_key_event_operator_string(
- C, but->optype->idname, but->opcontext, prop, true,
- shortcut_str, sizeof(shortcut_str)))
- {
- ui_but_add_shortcut(but, shortcut_str, true);
- }
- else {
- /* simply strip the shortcut */
- ui_but_add_shortcut(but, NULL, true);
- }
- }
-}
-
-static uiBlock *menu_change_shortcut(bContext *C, ARegion *ar, void *arg)
-{
- wmWindowManager *wm = CTX_wm_manager(C);
- uiBlock *block;
- uiBut *but = (uiBut *)arg;
- wmKeyMap *km;
- wmKeyMapItem *kmi;
- PointerRNA ptr;
- uiLayout *layout;
- uiStyle *style = UI_style_get_dpi();
- IDProperty *prop = (but->opptr) ? but->opptr->data : NULL;
-
- kmi = WM_key_event_operator(C, but->optype->idname, but->opcontext, prop, true, &km);
- BLI_assert(kmi != NULL);
-
- RNA_pointer_create(&wm->id, &RNA_KeyMapItem, kmi, &ptr);
-
- block = UI_block_begin(C, ar, "_popup", UI_EMBOSS);
- UI_block_func_handle_set(block, but_shortcut_name_func, but);
- UI_block_flag_enable(block, UI_BLOCK_MOVEMOUSE_QUIT);
- UI_block_direction_set(block, UI_DIR_CENTER_Y);
-
- layout = UI_block_layout(block, UI_LAYOUT_VERTICAL, UI_LAYOUT_PANEL, 0, 0, 200, 20, 0, style);
-
- uiItemR(layout, &ptr, "type", UI_ITEM_R_FULL_EVENT | UI_ITEM_R_IMMEDIATE, "", ICON_NONE);
-
- UI_block_bounds_set_popup(block, 6, -50, 26);
-
- return block;
-}
-
-#ifdef USE_KEYMAP_ADD_HACK
-static int g_kmi_id_hack;
-#endif
-
-static uiBlock *menu_add_shortcut(bContext *C, ARegion *ar, void *arg)
-{
- wmWindowManager *wm = CTX_wm_manager(C);
- uiBlock *block;
- uiBut *but = (uiBut *)arg;
- wmKeyMap *km;
- wmKeyMapItem *kmi;
- PointerRNA ptr;
- uiLayout *layout;
- uiStyle *style = UI_style_get_dpi();
- IDProperty *prop = (but->opptr) ? but->opptr->data : NULL;
- int kmi_id;
-
- /* XXX this guess_opname can potentially return a different keymap than being found on adding later... */
- km = WM_keymap_guess_opname(C, but->optype->idname);
- kmi = WM_keymap_add_item(km, but->optype->idname, AKEY, KM_PRESS, 0, 0);
- kmi_id = kmi->id;
-
- /* copy properties, prop can be NULL for reset */
- if (prop)
- prop = IDP_CopyProperty(prop);
- WM_keymap_properties_reset(kmi, prop);
-
- /* update and get pointers again */
- WM_keyconfig_update(wm);
-
- km = WM_keymap_guess_opname(C, but->optype->idname);
- kmi = WM_keymap_item_find_id(km, kmi_id);
-
- RNA_pointer_create(&wm->id, &RNA_KeyMapItem, kmi, &ptr);
-
- block = UI_block_begin(C, ar, "_popup", UI_EMBOSS);
- UI_block_func_handle_set(block, but_shortcut_name_func, but);
- UI_block_direction_set(block, UI_DIR_CENTER_Y);
-
- layout = UI_block_layout(block, UI_LAYOUT_VERTICAL, UI_LAYOUT_PANEL, 0, 0, 200, 20, 0, style);
-
- uiItemR(layout, &ptr, "type", UI_ITEM_R_FULL_EVENT | UI_ITEM_R_IMMEDIATE, "", ICON_NONE);
-
- UI_block_bounds_set_popup(block, 6, -50, 26);
-
-#ifdef USE_KEYMAP_ADD_HACK
- g_kmi_id_hack = kmi_id;
-#endif
- return block;
-}
-
-static void menu_add_shortcut_cancel(struct bContext *C, void *arg1)
-{
- uiBut *but = (uiBut *)arg1;
- wmKeyMap *km;
- wmKeyMapItem *kmi;
-#ifndef USE_KEYMAP_ADD_HACK
- IDProperty *prop;
-#endif
- int kmi_id;
-
-#ifdef USE_KEYMAP_ADD_HACK
- km = WM_keymap_guess_opname(C, but->optype->idname);
- kmi_id = g_kmi_id_hack;
- UNUSED_VARS(but);
-#else
- prop = (but->opptr) ? but->opptr->data : NULL;
- kmi_id = WM_key_event_operator_id(C, but->optype->idname, but->opcontext, prop, true, &km);
-#endif
-
- kmi = WM_keymap_item_find_id(km, kmi_id);
- WM_keymap_remove_item(km, kmi);
-}
-
-static void popup_change_shortcut_func(bContext *C, void *arg1, void *UNUSED(arg2))
-{
- uiBut *but = (uiBut *)arg1;
- UI_popup_block_invoke(C, menu_change_shortcut, but);
-}
-
-static void remove_shortcut_func(bContext *C, void *arg1, void *UNUSED(arg2))
-{
- uiBut *but = (uiBut *)arg1;
- wmKeyMap *km;
- wmKeyMapItem *kmi;
- IDProperty *prop = (but->opptr) ? but->opptr->data : NULL;
-
- kmi = WM_key_event_operator(C, but->optype->idname, but->opcontext, prop, true, &km);
- BLI_assert(kmi != NULL);
-
- WM_keymap_remove_item(km, kmi);
-
- but_shortcut_name_func(C, but, 0);
-}
-
-static void popup_add_shortcut_func(bContext *C, void *arg1, void *UNUSED(arg2))
-{
- uiBut *but = (uiBut *)arg1;
- UI_popup_block_ex(C, menu_add_shortcut, NULL, menu_add_shortcut_cancel, but, NULL);
-}
-
-/**
- * menu to chow when right clicking on the panel header
- */
-void ui_panel_menu(bContext *C, ARegion *ar, Panel *pa)
-{
- bScreen *sc = CTX_wm_screen(C);
- const bool has_panel_category = UI_panel_category_is_visible(ar);
- const bool any_item_visible = has_panel_category;
- PointerRNA ptr;
- uiPopupMenu *pup;
- uiLayout *layout;
-
- if (!any_item_visible) {
- return;
- }
-
- RNA_pointer_create(&sc->id, &RNA_Panel, pa, &ptr);
-
- pup = UI_popup_menu_begin(C, IFACE_("Panel"), ICON_NONE);
- layout = UI_popup_menu_layout(pup);
-
- if (has_panel_category) {
- char tmpstr[80];
- BLI_snprintf(tmpstr, sizeof(tmpstr), "%s" UI_SEP_CHAR_S "%s", IFACE_("Pin"), IFACE_("Shift+Left Mouse"));
- uiItemR(layout, &ptr, "use_pin", 0, tmpstr, ICON_NONE);
-
- /* evil, force shortcut flag */
- {
- uiBlock *block = uiLayoutGetBlock(layout);
- uiBut *but = block->buttons.last;
- but->flag |= UI_BUT_HAS_SEP_CHAR;
- }
- }
- UI_popup_menu_end(C, pup);
-}
-
-static void ui_but_menu_add_path_operators(uiLayout *layout, PointerRNA *ptr, PropertyRNA *prop)
-{
- const PropertySubType subtype = RNA_property_subtype(prop);
- wmOperatorType *ot = WM_operatortype_find("WM_OT_path_open", true);
- char filepath[FILE_MAX];
- char dir[FILE_MAXDIR];
- char file[FILE_MAXFILE];
- PointerRNA props_ptr;
-
- BLI_assert(ELEM(subtype, PROP_FILEPATH, PROP_DIRPATH));
- UNUSED_VARS_NDEBUG(subtype);
-
- RNA_property_string_get(ptr, prop, filepath);
- BLI_split_dirfile(filepath, dir, file, sizeof(dir), sizeof(file));
-
- if (file[0]) {
- BLI_assert(subtype == PROP_FILEPATH);
- uiItemFullO_ptr(
- layout, ot, CTX_IFACE_(BLT_I18NCONTEXT_OPERATOR_DEFAULT, "Open File Externally"),
- ICON_NONE, NULL, WM_OP_INVOKE_DEFAULT, 0, &props_ptr);
- RNA_string_set(&props_ptr, "filepath", filepath);
- }
-
- uiItemFullO_ptr(
- layout, ot, CTX_IFACE_(BLT_I18NCONTEXT_OPERATOR_DEFAULT, "Open Location Externally"),
- ICON_NONE, NULL, WM_OP_INVOKE_DEFAULT, 0, &props_ptr);
- RNA_string_set(&props_ptr, "filepath", dir);
-}
-
-static bool ui_but_menu(bContext *C, uiBut *but)
-{
- uiPopupMenu *pup;
- uiLayout *layout;
- MenuType *mt = WM_menutype_find("WM_MT_button_context", true);
- bool is_array, is_array_component;
- uiStringInfo label = {BUT_GET_LABEL, NULL};
- wmOperatorType *ot;
- PointerRNA op_ptr;
-
-/* if ((but->rnapoin.data && but->rnaprop) == 0 && but->optype == NULL)*/
-/* return 0;*/
-
- /* having this menu for some buttons makes no sense */
- if (but->type == UI_BTYPE_IMAGE) {
- return false;
- }
-
- /* highly unlikely getting the label ever fails */
- UI_but_string_info_get(C, but, &label, NULL);
-
- pup = UI_popup_menu_begin(C, label.strinfo ? label.strinfo : "", ICON_NONE);
- layout = UI_popup_menu_layout(pup);
- if (label.strinfo)
- MEM_freeN(label.strinfo);
-
- uiLayoutSetOperatorContext(layout, WM_OP_INVOKE_DEFAULT);
-
- if (but->rnapoin.data && but->rnaprop) {
- PointerRNA *ptr = &but->rnapoin;
- PropertyRNA *prop = but->rnaprop;
- const PropertyType type = RNA_property_type(prop);
- const PropertySubType subtype = RNA_property_subtype(prop);
- bool is_anim = RNA_property_animateable(ptr, prop);
- bool is_editable = RNA_property_editable(ptr, prop);
- /*bool is_idprop = RNA_property_is_idprop(prop);*/ /* XXX does not work as expected, not strictly needed */
- bool is_set = RNA_property_is_set(ptr, prop);
-
- const int static_override_status = RNA_property_static_override_status(ptr, prop, -1);
- const bool is_static_overridable = (static_override_status & RNA_OVERRIDE_STATUS_OVERRIDABLE) != 0;
-
- const int dynamic_override_status = RNA_property_dynamic_override_status(ptr, prop, -1);
- const bool is_dynamic_overridable = (dynamic_override_status & RNA_OVERRIDE_STATUS_OVERRIDABLE) != 0;
-
- /* second slower test, saved people finding keyframe items in menus when its not possible */
- if (is_anim)
- is_anim = RNA_property_path_from_ID_check(&but->rnapoin, but->rnaprop);
-
- /* determine if we can key a single component of an array */
- is_array = RNA_property_array_length(&but->rnapoin, but->rnaprop) != 0;
- is_array_component = (is_array && but->rnaindex != -1);
-
- /* Keyframes */
- if (but->flag & UI_BUT_ANIMATED_KEY) {
- /* replace/delete keyfraemes */
- if (is_array_component) {
- uiItemBooleanO(layout, CTX_IFACE_(BLT_I18NCONTEXT_OPERATOR_DEFAULT, "Replace Keyframes"),
- ICON_KEY_HLT, "ANIM_OT_keyframe_insert_button", "all", 1);
- uiItemBooleanO(layout, CTX_IFACE_(BLT_I18NCONTEXT_OPERATOR_DEFAULT, "Replace Single Keyframe"),
- ICON_NONE, "ANIM_OT_keyframe_insert_button", "all", 0);
- uiItemBooleanO(layout, CTX_IFACE_(BLT_I18NCONTEXT_OPERATOR_DEFAULT, "Delete Keyframes"),
- ICON_NONE, "ANIM_OT_keyframe_delete_button", "all", 1);
- uiItemBooleanO(layout, CTX_IFACE_(BLT_I18NCONTEXT_OPERATOR_DEFAULT, "Delete Single Keyframe"),
- ICON_NONE, "ANIM_OT_keyframe_delete_button", "all", 0);
- }
- else {
- uiItemBooleanO(layout, CTX_IFACE_(BLT_I18NCONTEXT_OPERATOR_DEFAULT, "Replace Keyframe"),
- ICON_KEY_HLT, "ANIM_OT_keyframe_insert_button", "all", 1);
- uiItemBooleanO(layout, CTX_IFACE_(BLT_I18NCONTEXT_OPERATOR_DEFAULT, "Delete Keyframe"),
- ICON_NONE, "ANIM_OT_keyframe_delete_button", "all", 1);
- }
-
- /* keyframe settings */
- uiItemS(layout);
-
-
- }
- else if (but->flag & UI_BUT_DRIVEN) {
- /* pass */
- }
- else if (is_anim) {
- if (is_array_component) {
- uiItemBooleanO(layout, CTX_IFACE_(BLT_I18NCONTEXT_OPERATOR_DEFAULT, "Insert Keyframes"),
- ICON_KEY_HLT, "ANIM_OT_keyframe_insert_button", "all", 1);
- uiItemBooleanO(layout, CTX_IFACE_(BLT_I18NCONTEXT_OPERATOR_DEFAULT, "Insert Single Keyframe"),
- ICON_NONE, "ANIM_OT_keyframe_insert_button", "all", 0);
- }
- else {
- uiItemBooleanO(layout, CTX_IFACE_(BLT_I18NCONTEXT_OPERATOR_DEFAULT, "Insert Keyframe"),
- ICON_KEY_HLT, "ANIM_OT_keyframe_insert_button", "all", 1);
- }
- }
-
- if ((but->flag & UI_BUT_ANIMATED) && (but->rnapoin.type != &RNA_NlaStrip)) {
- if (is_array_component) {
- uiItemBooleanO(layout, CTX_IFACE_(BLT_I18NCONTEXT_OPERATOR_DEFAULT, "Clear Keyframes"),
- ICON_KEY_DEHLT, "ANIM_OT_keyframe_clear_button", "all", 1);
- uiItemBooleanO(layout, CTX_IFACE_(BLT_I18NCONTEXT_OPERATOR_DEFAULT, "Clear Single Keyframes"),
- ICON_NONE, "ANIM_OT_keyframe_clear_button", "all", 0);
- }
- else {
- uiItemBooleanO(layout, CTX_IFACE_(BLT_I18NCONTEXT_OPERATOR_DEFAULT, "Clear Keyframes"),
- ICON_KEY_DEHLT, "ANIM_OT_keyframe_clear_button", "all", 1);
- }
- }
-
- /* Drivers */
- if (but->flag & UI_BUT_DRIVEN) {
- uiItemS(layout);
-
- if (is_array_component) {
- uiItemBooleanO(layout, CTX_IFACE_(BLT_I18NCONTEXT_OPERATOR_DEFAULT, "Delete Drivers"),
- ICON_X, "ANIM_OT_driver_button_remove", "all", 1);
- uiItemBooleanO(layout, CTX_IFACE_(BLT_I18NCONTEXT_OPERATOR_DEFAULT, "Delete Single Driver"),
- ICON_NONE, "ANIM_OT_driver_button_remove", "all", 0);
- }
- else {
- uiItemBooleanO(layout, CTX_IFACE_(BLT_I18NCONTEXT_OPERATOR_DEFAULT, "Delete Driver"),
- ICON_X, "ANIM_OT_driver_button_remove", "all", 1);
- }
-
- uiItemO(layout, CTX_IFACE_(BLT_I18NCONTEXT_OPERATOR_DEFAULT, "Copy Driver"),
- ICON_NONE, "ANIM_OT_copy_driver_button");
- if (ANIM_driver_can_paste()) {
- uiItemO(layout, CTX_IFACE_(BLT_I18NCONTEXT_OPERATOR_DEFAULT, "Paste Driver"),
- ICON_NONE, "ANIM_OT_paste_driver_button");
- }
-
- uiItemO(layout, CTX_IFACE_(BLT_I18NCONTEXT_OPERATOR_DEFAULT, "Edit Driver"),
- ICON_DRIVER, "ANIM_OT_driver_button_edit");
-
- uiItemO(layout, CTX_IFACE_(BLT_I18NCONTEXT_OPERATOR_DEFAULT, "Open Drivers Editor"),
- ICON_NONE, "SCREEN_OT_drivers_editor_show");
- }
- else if (but->flag & (UI_BUT_ANIMATED_KEY | UI_BUT_ANIMATED)) {
- /* pass */
- }
- else if (is_anim) {
- uiItemS(layout);
-
- uiItemO(layout, CTX_IFACE_(BLT_I18NCONTEXT_OPERATOR_DEFAULT, "Add Driver"),
- ICON_DRIVER, "ANIM_OT_driver_button_add");
-
- if (ANIM_driver_can_paste()) {
- uiItemO(layout, CTX_IFACE_(BLT_I18NCONTEXT_OPERATOR_DEFAULT, "Paste Driver"),
- ICON_NONE, "ANIM_OT_paste_driver_button");
- }
-
- uiItemO(layout, CTX_IFACE_(BLT_I18NCONTEXT_OPERATOR_DEFAULT, "Open Drivers Editor"),
- ICON_NONE, "SCREEN_OT_drivers_editor_show");
- }
-
- /* Keying Sets */
- /* TODO: check on modifyability of Keying Set when doing this */
- if (is_anim) {
- uiItemS(layout);
-
- if (is_array_component) {
- uiItemBooleanO(layout, CTX_IFACE_(BLT_I18NCONTEXT_OPERATOR_DEFAULT, "Add All to Keying Set"),
- ICON_KEYINGSET, "ANIM_OT_keyingset_button_add", "all", 1);
- uiItemBooleanO(layout, CTX_IFACE_(BLT_I18NCONTEXT_OPERATOR_DEFAULT, "Add Single to Keying Set"),
- ICON_NONE, "ANIM_OT_keyingset_button_add", "all", 0);
- uiItemO(layout, CTX_IFACE_(BLT_I18NCONTEXT_OPERATOR_DEFAULT, "Remove from Keying Set"),
- ICON_NONE, "ANIM_OT_keyingset_button_remove");
- }
- else {
- uiItemBooleanO(layout, CTX_IFACE_(BLT_I18NCONTEXT_OPERATOR_DEFAULT, "Add to Keying Set"),
- ICON_KEYINGSET, "ANIM_OT_keyingset_button_add", "all", 1);
- uiItemO(layout, CTX_IFACE_(BLT_I18NCONTEXT_OPERATOR_DEFAULT, "Remove from Keying Set"),
- ICON_NONE, "ANIM_OT_keyingset_button_remove");
- }
- }
-
- /* Dynamic Override Operators */
- if (is_editable && is_dynamic_overridable) {
- uiItemS(layout);
- uiItemFullO(layout, "SCENE_OT_view_layer_override_add", NULL, ICON_NONE, NULL, WM_OP_INVOKE_DEFAULT, 0, NULL);
- }
-
- if (is_static_overridable) {
- /* Static Override Operators */
- uiItemS(layout);
-
- if (but->flag & UI_BUT_OVERRIDEN) {
- if (is_array_component) {
-#if 0 /* Disabled for now. */
- ot = WM_operatortype_find("UI_OT_override_type_set_button", false);
- uiItemFullO_ptr(layout, ot, "Overrides Type", ICON_NONE,
- NULL, WM_OP_INVOKE_DEFAULT, 0, &op_ptr);
- RNA_boolean_set(&op_ptr, "all", true);
- uiItemFullO_ptr(layout, ot, "Single Override Type", ICON_NONE,
- NULL, WM_OP_INVOKE_DEFAULT, 0, &op_ptr);
- RNA_boolean_set(&op_ptr, "all", false);
-#endif
- uiItemBooleanO(layout, CTX_IFACE_(BLT_I18NCONTEXT_OPERATOR_DEFAULT, "Remove Overrides"),
- ICON_X, "UI_OT_override_remove_button", "all", true);
- uiItemBooleanO(layout, CTX_IFACE_(BLT_I18NCONTEXT_OPERATOR_DEFAULT, "Remove Single Override"),
- ICON_X, "UI_OT_override_remove_button", "all", false);
- }
- else {
-#if 0 /* Disabled for now. */
- uiItemFullO(layout, "UI_OT_override_type_set_button", "Override Type", ICON_NONE,
- NULL, WM_OP_INVOKE_DEFAULT, 0, &op_ptr);
- RNA_boolean_set(&op_ptr, "all", false);
-#endif
- uiItemBooleanO(layout, CTX_IFACE_(BLT_I18NCONTEXT_OPERATOR_DEFAULT, "Remove Override"),
- ICON_X, "UI_OT_override_remove_button", "all", true);
- }
- }
- else {
- if (is_array_component) {
- ot = WM_operatortype_find("UI_OT_override_type_set_button", false);
- uiItemFullO_ptr(layout, ot, "Define Overrides", ICON_NONE,
- NULL, WM_OP_INVOKE_DEFAULT, 0, &op_ptr);
- RNA_boolean_set(&op_ptr, "all", true);
- uiItemFullO_ptr(layout, ot, "Define Single Override", ICON_NONE,
- NULL, WM_OP_INVOKE_DEFAULT, 0, &op_ptr);
- RNA_boolean_set(&op_ptr, "all", false);
- }
- else {
- uiItemFullO(layout, "UI_OT_override_type_set_button", "Define Override", ICON_NONE,
- NULL, WM_OP_INVOKE_DEFAULT, 0, &op_ptr);
- RNA_boolean_set(&op_ptr, "all", false);
- }
- }
- }
-
- uiItemS(layout);
-
- /* Property Operators */
-
- /* Copy Property Value
- * Paste Property Value */
-
- if (is_array_component) {
- uiItemBooleanO(layout, CTX_IFACE_(BLT_I18NCONTEXT_OPERATOR_DEFAULT, "Reset All to Default Values"),
- ICON_LOOP_BACK, "UI_OT_reset_default_button", "all", 1);
- uiItemBooleanO(layout, CTX_IFACE_(BLT_I18NCONTEXT_OPERATOR_DEFAULT, "Reset Single to Default Value"),
- ICON_NONE, "UI_OT_reset_default_button", "all", 0);
- }
- else {
- uiItemBooleanO(layout, CTX_IFACE_(BLT_I18NCONTEXT_OPERATOR_DEFAULT, "Reset to Default Value"),
- ICON_LOOP_BACK, "UI_OT_reset_default_button", "all", 1);
- }
- if (is_editable /*&& is_idprop*/ && is_set) {
- uiItemO(layout, CTX_IFACE_(BLT_I18NCONTEXT_OPERATOR_DEFAULT, "Unset"),
- ICON_NONE, "UI_OT_unset_property_button");
- }
-
- if (is_array_component) {
- uiItemBooleanO(layout, CTX_IFACE_(BLT_I18NCONTEXT_OPERATOR_DEFAULT, "Copy All To Selected"),
- ICON_NONE, "UI_OT_copy_to_selected_button", "all", true);
- uiItemBooleanO(layout, CTX_IFACE_(BLT_I18NCONTEXT_OPERATOR_DEFAULT, "Copy Single To Selected"),
- ICON_NONE, "UI_OT_copy_to_selected_button", "all", false);
- }
- else {
- uiItemBooleanO(layout, CTX_IFACE_(BLT_I18NCONTEXT_OPERATOR_DEFAULT, "Copy To Selected"),
- ICON_NONE, "UI_OT_copy_to_selected_button", "all", true);
- }
-
- uiItemO(layout, CTX_IFACE_(BLT_I18NCONTEXT_OPERATOR_DEFAULT, "Copy Data Path"),
- ICON_NONE, "UI_OT_copy_data_path_button");
-
- uiItemS(layout);
-
- if (type == PROP_STRING && ELEM(subtype, PROP_FILEPATH, PROP_DIRPATH)) {
- ui_but_menu_add_path_operators(layout, ptr, prop);
- uiItemS(layout);
- }
- }
-
- /* Operator buttons */
- if (but->optype) {
- uiBlock *block = uiLayoutGetBlock(layout);
- uiBut *but2;
- IDProperty *prop = (but->opptr) ? but->opptr->data : NULL;
- int w = uiLayoutGetWidth(layout);
- wmKeyMap *km;
- /* We want to know if this op has a shortcut, be it hotkey or not. */
- wmKeyMapItem *kmi = WM_key_event_operator(C, but->optype->idname, but->opcontext, prop, false, &km);
-
- /* We do have a shortcut, but only keyboard ones are editbale that way... */
- if (kmi) {
- if (ISKEYBOARD(kmi->type)) {
-#if 0 /* would rather use a block but, but gets weirdly positioned... */
- uiDefBlockBut(block, menu_change_shortcut, but, "Change Shortcut",
- 0, 0, uiLayoutGetWidth(layout), UI_UNIT_Y, "");
-#endif
-
- but2 = uiDefIconTextBut(block, UI_BTYPE_BUT, 0, ICON_HAND,
- CTX_IFACE_(BLT_I18NCONTEXT_OPERATOR_DEFAULT, "Change Shortcut"),
- 0, 0, w, UI_UNIT_Y, NULL, 0, 0, 0, 0, "");
- UI_but_func_set(but2, popup_change_shortcut_func, but, NULL);
-
- but2 = uiDefIconTextBut(block, UI_BTYPE_BUT, 0, ICON_NONE,
- CTX_IFACE_(BLT_I18NCONTEXT_OPERATOR_DEFAULT, "Remove Shortcut"),
- 0, 0, w, UI_UNIT_Y, NULL, 0, 0, 0, 0, "");
- UI_but_func_set(but2, remove_shortcut_func, but, NULL);
- }
- else {
- but2 = uiDefIconTextBut(block, UI_BTYPE_BUT, 0, ICON_HAND, IFACE_("Non-Keyboard Shortcut"),
- 0, 0, w, UI_UNIT_Y, NULL, 0, 0, 0, 0,
- TIP_("Only keyboard shortcuts can be edited that way, "
- "please use User Preferences otherwise"));
- UI_but_flag_enable(but2, UI_BUT_DISABLED);
- }
- }
- /* only show 'add' if there's a suitable key map for it to go in */
- else if (WM_keymap_guess_opname(C, but->optype->idname)) {
- but2 = uiDefIconTextBut(block, UI_BTYPE_BUT, 0, ICON_HAND,
- CTX_IFACE_(BLT_I18NCONTEXT_OPERATOR_DEFAULT, "Add Shortcut"),
- 0, 0, w, UI_UNIT_Y, NULL, 0, 0, 0, 0, "");
- UI_but_func_set(but2, popup_add_shortcut_func, but, NULL);
- }
-
- /* Set the operator pointer for python access */
- uiLayoutSetContextFromBut(layout, but);
-
- uiItemS(layout);
- }
-
- /* Show header tools for header buttons. */
- if (ui_block_is_menu(but->block) == false) {
- ARegion *ar = CTX_wm_region(C);
- if (ar && (ar->regiontype == RGN_TYPE_HEADER)) {
- uiItemMenuF(layout, IFACE_("Header"), ICON_NONE, ED_screens_header_tools_menu_create, NULL);
- uiItemS(layout);
- }
- }
-
- { /* Docs */
- char buf[512];
-
- if (UI_but_online_manual_id(but, buf, sizeof(buf))) {
- PointerRNA ptr_props;
- uiItemO(layout, CTX_IFACE_(BLT_I18NCONTEXT_OPERATOR_DEFAULT, "Online Manual"),
- ICON_URL, "WM_OT_doc_view_manual_ui_context");
-
- uiItemFullO(
- layout, "WM_OT_doc_view",
- CTX_IFACE_(BLT_I18NCONTEXT_OPERATOR_DEFAULT, "Online Python Reference"),
- ICON_NONE, NULL, WM_OP_EXEC_DEFAULT, 0, &ptr_props);
- RNA_string_set(&ptr_props, "doc_id", buf);
-
- /* XXX inactive option, not for public! */
-#if 0
- uiItemFullO(
- layout, "WM_OT_doc_edit", "Submit Description", ICON_NONE,
- NULL, WM_OP_INVOKE_DEFAULT, 0, &ptr_props);
- RNA_string_set(&ptr_props, "doc_id", buf);
- RNA_string_set(&ptr_props, "doc_new", RNA_property_description(but->rnaprop));
-#endif
- }
- }
-
- if (but->optype) {
- uiItemO(layout, NULL,
- ICON_NONE, "UI_OT_copy_python_command_button");
- }
-
- /* perhaps we should move this into (G.debug & G_DEBUG) - campbell */
- if (ui_block_is_menu(but->block) == false) {
- uiItemFullO(layout, "UI_OT_editsource", NULL, ICON_NONE, NULL, WM_OP_INVOKE_DEFAULT, 0, NULL);
- }
- uiItemFullO(layout, "UI_OT_edittranslation_init", NULL, ICON_NONE, NULL, WM_OP_INVOKE_DEFAULT, 0, NULL);
-
- mt = WM_menutype_find("WM_MT_button_context", true);
- if (mt) {
- UI_menutype_draw(C, mt, uiLayoutColumn(layout, false));
- }
-
- UI_popup_menu_end(C, pup);
-
- return true;
-}
-
static int ui_do_button(bContext *C, uiBlock *block, uiBut *but, const wmEvent *event)
{
uiHandleButtonData *data;
@@ -7134,7 +6527,7 @@ static int ui_do_button(bContext *C, uiBlock *block, uiBut *but, const wmEvent *
(event->val == KM_PRESS))
{
/* RMB has two options now */
- if (ui_but_menu(C, but)) {
+ if (ui_popup_context_menu_for_button(C, but)) {
return WM_UI_HANDLER_BREAK;
}
}
@@ -9602,6 +8995,11 @@ static int ui_handle_menu_event(
}
#endif
+ /* Don't handle double click events, rehandle as regular press/release. */
+ if (retval == WM_UI_HANDLER_CONTINUE && event->val == KM_DBL_CLICK) {
+ return retval;
+ }
+
/* if we set a menu return value, ensure we continue passing this on to
* lower menus and buttons, so always set continue then, and if we are
* inside the region otherwise, ensure we swallow the event */
@@ -10182,6 +9580,7 @@ static int ui_handler_region_menu(bContext *C, const wmEvent *event, void *UNUSE
{
ARegion *ar;
uiBut *but;
+ int retval = WM_UI_HANDLER_CONTINUE;
ar = CTX_wm_menu(C);
if (!ar)
@@ -10225,29 +9624,32 @@ static int ui_handler_region_menu(bContext *C, const wmEvent *event, void *UNUSE
if ((but_other->flag & UI_BUT_DISABLED) == 0) {
ui_handle_button_activate(C, ar, but_other, BUTTON_ACTIVATE_OVER);
button_activate_state(C, but_other, BUTTON_STATE_MENU_OPEN);
+ retval = WM_UI_HANDLER_BREAK;
}
}
else if (data->state == BUTTON_STATE_MENU_OPEN) {
- int retval;
-
/* handle events for menus and their buttons recursively,
* this will handle events from the top to the bottom menu */
- if (data->menu)
+ if (data->menu) {
retval = ui_handle_menus_recursive(C, event, data->menu, 0, false, false, false);
+ }
/* handle events for the activated button */
if ((data->menu && (retval == WM_UI_HANDLER_CONTINUE)) ||
(event->type == TIMER))
{
- if (data->menu && data->menu->menuretval)
+ if (data->menu && data->menu->menuretval) {
ui_handle_button_return_submenu(C, event, but);
- else
- ui_handle_button_event(C, event, but);
+ retval = WM_UI_HANDLER_BREAK;
+ }
+ else {
+ retval = ui_handle_button_event(C, event, but);
+ }
}
}
else {
/* handle events for the activated button */
- ui_handle_button_event(C, event, but);
+ retval = ui_handle_button_event(C, event, but);
}
}
@@ -10258,6 +9660,14 @@ static int ui_handler_region_menu(bContext *C, const wmEvent *event, void *UNUSE
/* delayed apply callbacks */
ui_apply_but_funcs_after(C);
+ /* Don't handle double-click events,
+ * these will be converted into regular clicks which we handle. */
+ if (retval == WM_UI_HANDLER_CONTINUE) {
+ if (event->val == KM_DBL_CLICK) {
+ return WM_UI_HANDLER_CONTINUE;
+ }
+ }
+
/* we block all events, this is modal interaction */
return WM_UI_HANDLER_BREAK;
}
diff --git a/source/blender/editors/interface/interface_icons.c b/source/blender/editors/interface/interface_icons.c
index 539dd05b242..a8feaedf717 100644
--- a/source/blender/editors/interface/interface_icons.c
+++ b/source/blender/editors/interface/interface_icons.c
@@ -858,10 +858,10 @@ static void ui_studiolight_kill_icon_preview_job(wmWindowManager *wm, int icon_i
icon->obj = NULL;
}
-static void ui_studiolight_free_function(StudioLight * sl, void* data)
+static void ui_studiolight_free_function(StudioLight *sl, void *data)
{
wmWindowManager *wm = data;
-
+
// get icons_id, get icons and kill wm jobs
if (sl->icon_id_radiance) {
ui_studiolight_kill_icon_preview_job(wm, sl->icon_id_radiance);
@@ -920,7 +920,7 @@ void ui_icon_ensure_deferred(const bContext *C, const int icon_id, const bool bi
di->data.buffer.image = img;
wmJob *wm_job = WM_jobs_get(wm, CTX_wm_window(C), icon, "StudioLight Icon", 0, WM_JOB_TYPE_STUDIOLIGHT);
- Icon** tmp = MEM_callocN(sizeof(Icon*), __func__);
+ Icon **tmp = MEM_callocN(sizeof(Icon *), __func__);
*tmp = icon;
WM_jobs_customdata_set(wm_job, tmp, MEM_freeN);
WM_jobs_timer(wm_job, 0.01, 0, NC_WINDOW);
@@ -1647,4 +1647,3 @@ void UI_icon_draw_preview_aspect_size(float x, float y, int icon_id, float aspec
{
icon_draw_size(x, y, icon_id, aspect, alpha, NULL, ICON_SIZE_PREVIEW, size, false);
}
-
diff --git a/source/blender/editors/interface/interface_intern.h b/source/blender/editors/interface/interface_intern.h
index 6f029b81e92..f29d73e564b 100644
--- a/source/blender/editors/interface/interface_intern.h
+++ b/source/blender/editors/interface/interface_intern.h
@@ -706,7 +706,6 @@ float ui_block_calc_pie_segment(struct uiBlock *block, const float event_xy[2]);
void ui_but_add_shortcut(uiBut *but, const char *key_str, const bool do_strip);
void ui_but_clipboard_free(void);
-void ui_panel_menu(struct bContext *C, ARegion *ar, Panel *pa);
uiBut *ui_but_find_old(uiBlock *block_old, const uiBut *but_new);
uiBut *ui_but_find_new(uiBlock *block_old, const uiBut *but_new);
@@ -818,6 +817,10 @@ void ui_but_anim_autokey(struct bContext *C, uiBut *but, struct Scene *scene, fl
void ui_but_anim_decorate_cb(struct bContext *C, void *arg_but, void *arg_dummy);
void ui_but_anim_decorate_update_from_flag(uiBut *but);
+/* interface_context_menu.c */
+bool ui_popup_context_menu_for_button(struct bContext *C, uiBut *but);
+void ui_popup_context_menu_for_panel(struct bContext *C, struct ARegion *ar, struct Panel *pa);
+
/* interface_eyedropper.c */
struct wmKeyMap *eyedropper_modal_keymap(struct wmKeyConfig *keyconf);
struct wmKeyMap *eyedropper_colorband_modal_keymap(struct wmKeyConfig *keyconf);
diff --git a/source/blender/editors/interface/interface_layout.c b/source/blender/editors/interface/interface_layout.c
index 3784ab635be..05af133616e 100644
--- a/source/blender/editors/interface/interface_layout.c
+++ b/source/blender/editors/interface/interface_layout.c
@@ -67,6 +67,9 @@
/* Show an icon button after each RNA button to use to quickly set keyframes,
* this is a way to display animation/driven/override status, see T54951. */
#define UI_PROP_DECORATE
+/* Alternate draw mode where some buttons can use single icon width,
+ * giving more room for the text at the expense of nicely aligned text. */
+#define UI_PROP_SEP_ICON_WIDTH_EXCEPTION
/************************ Structs and Defines *************************/
@@ -1595,9 +1598,19 @@ void uiItemFullR(uiLayout *layout, PointerRNA *ptr, PropertyRNA *prop, int index
}
else {
const PropertySubType subtype = RNA_property_subtype(prop);
- uiLayout *layout_split = uiLayoutSplit(
- layout_row ? layout_row : layout,
- UI_ITEM_PROP_SEP_DIVIDE, true);
+ uiLayout *layout_split;
+#ifdef UI_PROP_SEP_ICON_WIDTH_EXCEPTION
+ if (type == PROP_BOOLEAN && (icon == ICON_NONE) && !icon_only) {
+ w = UI_UNIT_X;
+ layout_split = uiLayoutRow(layout_row ? layout_row : layout, true);
+ }
+ else
+#endif /* UI_PROP_SEP_ICON_WIDTH_EXCEPTION */
+ {
+ layout_split = uiLayoutSplit(
+ layout_row ? layout_row : layout,
+ UI_ITEM_PROP_SEP_DIVIDE, true);
+ }
layout_split->space = 0;
uiLayout *layout_sub = uiLayoutColumn(layout_split, true);
layout_sub->space = 0;
@@ -3171,12 +3184,12 @@ static void ui_litem_estimate_grid_flow(uiLayout *litem)
.litem_y = litem->y,
.space_x = space_x,
.space_y = space_y,
- }),
+ }),
&((UILayoutGridFlowOutput) {
.tot_items = &gflow->tot_items,
.global_avg_w = &avg_w,
.global_max_h = &max_h,
- }));
+ }));
if (gflow->tot_items == 0) {
litem->w = litem->h = 0;
@@ -3258,11 +3271,11 @@ static void ui_litem_estimate_grid_flow(uiLayout *litem)
.space_y = space_y,
.tot_columns = gflow->tot_columns,
.tot_rows = gflow->tot_rows,
- }),
+ }),
&((UILayoutGridFlowOutput) {
.tot_w = &tot_w,
.tot_h = &tot_h,
- }));
+ }));
litem->w = tot_w;
litem->h = tot_h;
@@ -3306,13 +3319,13 @@ static void ui_litem_layout_grid_flow(uiLayout *litem)
.space_y = space_y,
.tot_columns = gflow->tot_columns,
.tot_rows = gflow->tot_rows,
- }),
+ }),
&((UILayoutGridFlowOutput) {
.cos_x_array = cos_x,
.cos_y_array = cos_y,
.widths_array = widths,
.heights_array = heights,
- }));
+ }));
for (item = litem->items.first, i = 0; item; item = item->next, i++) {
const int col = gflow->row_major ? i % gflow->tot_columns : i / gflow->tot_rows;
diff --git a/source/blender/editors/interface/interface_ops.c b/source/blender/editors/interface/interface_ops.c
index 6fcede58737..aad48d13277 100644
--- a/source/blender/editors/interface/interface_ops.c
+++ b/source/blender/editors/interface/interface_ops.c
@@ -1004,6 +1004,7 @@ static int editsource_exec(bContext *C, wmOperator *op)
ui_editsource_active_but_set(but);
/* redraw and get active button python info */
+ ED_region_do_layout(C, ar);
ED_region_do_draw(C, ar);
ar->do_draw = false;
diff --git a/source/blender/editors/interface/interface_panel.c b/source/blender/editors/interface/interface_panel.c
index e383ae42f8c..5d029685810 100644
--- a/source/blender/editors/interface/interface_panel.c
+++ b/source/blender/editors/interface/interface_panel.c
@@ -2254,7 +2254,7 @@ int ui_handler_panel_region(bContext *C, const wmEvent *event, ARegion *ar, cons
}
else if (event->type == RIGHTMOUSE) {
if (mouse_state == PANEL_MOUSE_INSIDE_HEADER) {
- ui_panel_menu(C, ar, block->panel);
+ ui_popup_context_menu_for_panel(C, ar, block->panel);
retval = WM_UI_HANDLER_BREAK;
break;
}
diff --git a/source/blender/editors/interface/interface_region_hud.c b/source/blender/editors/interface/interface_region_hud.c
index 569f50a9c75..1a49010ad9d 100644
--- a/source/blender/editors/interface/interface_region_hud.c
+++ b/source/blender/editors/interface/interface_region_hud.c
@@ -329,7 +329,10 @@ void ED_area_type_hud_ensure(bContext *C, ScrArea *sa)
/* We shouldn't need to do this every time :S */
/* XXX, this is evil! - it also makes the menu show on first draw. :( */
+ ARegion *ar_prev = CTX_wm_region(C);
+ CTX_wm_region_set((bContext *)C, ar);
hud_region_layout(C, ar);
+ CTX_wm_region_set((bContext *)C, ar_prev);
}
/** \} */
diff --git a/source/blender/editors/interface/interface_region_menu_popup.c b/source/blender/editors/interface/interface_region_menu_popup.c
index a6046e551c6..b9222a75803 100644
--- a/source/blender/editors/interface/interface_region_menu_popup.c
+++ b/source/blender/editors/interface/interface_region_menu_popup.c
@@ -458,6 +458,21 @@ void UI_popup_menu_end(bContext *C, uiPopupMenu *pup)
MEM_freeN(pup);
}
+bool UI_popup_menu_end_or_cancel(bContext *C, uiPopupMenu *pup)
+{
+ if (!UI_block_is_empty(pup->block)) {
+ UI_popup_menu_end(C, pup);
+ return true;
+ }
+ else {
+ UI_block_layout_resolve(pup->block, NULL, NULL);
+ MEM_freeN(pup->block->handle);
+ UI_block_free(C, pup->block);
+ MEM_freeN(pup);
+ return false;
+ }
+}
+
uiLayout *UI_popup_menu_layout(uiPopupMenu *pup)
{
return pup->layout;
diff --git a/source/blender/editors/interface/interface_templates.c b/source/blender/editors/interface/interface_templates.c
index 22487f29977..c2bea466015 100644
--- a/source/blender/editors/interface/interface_templates.c
+++ b/source/blender/editors/interface/interface_templates.c
@@ -1356,8 +1356,7 @@ static uiLayout *draw_modifier(
UI_block_emboss_set(block, UI_EMBOSS);
/* modifier name */
- md->scene = scene;
- if (mti->isDisabled && mti->isDisabled(md, 0)) {
+ if (mti->isDisabled && mti->isDisabled(scene, md, 0)) {
uiLayoutSetRedAlert(row, true);
}
uiItemR(row, &ptr, "name", 0, "", ICON_NONE);
@@ -1748,7 +1747,7 @@ static uiLayout *draw_constraint(uiLayout *layout, Object *ob, bConstraint *con)
/* enabled */
UI_block_emboss_set(block, UI_EMBOSS_NONE);
uiItemR(row, &ptr, "mute", 0, "",
- (con->flag & CONSTRAINT_OFF) ? ICON_RESTRICT_VIEW_ON : ICON_RESTRICT_VIEW_OFF);
+ (con->flag & CONSTRAINT_OFF) ? ICON_HIDE_ON : ICON_HIDE_OFF);
UI_block_emboss_set(block, UI_EMBOSS);
uiLayoutSetOperatorContext(row, WM_OP_INVOKE_DEFAULT);
@@ -4263,18 +4262,18 @@ void uiTemplateReportsBanner(uiLayout *layout, bContext *C)
/* make a box around the report to make it stand out */
UI_block_align_begin(block);
- but = uiDefBut(block, UI_BTYPE_ROUNDBOX, 0, "", 0, 0, UI_UNIT_X + 10, UI_UNIT_Y, NULL, 0.0f, 0.0f, 0, 0, "");
+ but = uiDefBut(block, UI_BTYPE_ROUNDBOX, 0, "", 0, 0, UI_UNIT_X + 5, UI_UNIT_Y, NULL, 0.0f, 0.0f, 0, 0, "");
/* set the report's bg color in but->col - UI_BTYPE_ROUNDBOX feature */
rgb_float_to_uchar(but->col, rti->col);
but->col[3] = 255;
- but = uiDefBut(block, UI_BTYPE_ROUNDBOX, 0, "", UI_UNIT_X + 10, 0, UI_UNIT_X + width, UI_UNIT_Y,
+ but = uiDefBut(block, UI_BTYPE_ROUNDBOX, 0, "", UI_UNIT_X + 5, 0, UI_UNIT_X + width, UI_UNIT_Y,
NULL, 0.0f, 0.0f, 0, 0, "");
- but->col[0] = but->col[1] = but->col[2] = unit_float_to_uchar_clamp(rti->grayscale);
- but->col[3] = 255;
UI_block_align_end(block);
+ UI_GetThemeColorShade3ubv(TH_BACK, 20, but->col);
+ but->col[3] = 255;
/* icon and report message on top */
icon = UI_icon_from_report_type(report->type);
@@ -4292,10 +4291,28 @@ void uiTemplateReportsBanner(uiLayout *layout, bContext *C)
UI_block_emboss_set(block, UI_EMBOSS);
- uiDefBut(block, UI_BTYPE_LABEL, 0, report->message, UI_UNIT_X + 10, 0, UI_UNIT_X + width, UI_UNIT_Y,
+ uiDefBut(block, UI_BTYPE_LABEL, 0, report->message, UI_UNIT_X + 5, 0, UI_UNIT_X + width, UI_UNIT_Y,
NULL, 0.0f, 0.0f, 0, 0, "");
}
+
+void uiTemplateCursorKeymap(uiLayout *layout, struct bContext *C)
+{
+ wmWindow *win = CTX_wm_window(C);
+ for (int i = 0; i < 3; i++) {
+ uiLayout *box = uiLayoutRow(layout, true);
+ for (int j = 0; j < 2; j++) {
+ const char *msg = WM_window_cursor_keymap_status_get(win, i, j);
+ if ((j == 0) || (msg != NULL)) {
+ uiItemL(box, msg, j == 0 ? (ICON_MOUSE_LMB + i) : ICON_MOUSE_DRAG);
+ }
+ }
+ if (i != 2) {
+ uiItemSpacer(layout);
+ }
+ }
+}
+
/********************************* Keymap *************************************/
static void keymap_item_modified(bContext *UNUSED(C), void *kmi_p, void *UNUSED(unused))
diff --git a/source/blender/editors/interface/interface_widgets.c b/source/blender/editors/interface/interface_widgets.c
index 4bc3aaaf842..a6f58fc056a 100644
--- a/source/blender/editors/interface/interface_widgets.c
+++ b/source/blender/editors/interface/interface_widgets.c
@@ -230,16 +230,16 @@ static const uint g_shape_preset_hold_action_face[2][3] = {{2, 0, 1}, {3, 5, 4}}
static const int tria_ofs[ROUNDBOX_TRIA_MAX] = {
[ROUNDBOX_TRIA_NONE] = 0,
[ROUNDBOX_TRIA_ARROWS] = 0,
- [ROUNDBOX_TRIA_SCROLL] = 6,
- [ROUNDBOX_TRIA_MENU] = 22,
- [ROUNDBOX_TRIA_CHECK] = 28,
- [ROUNDBOX_TRIA_HOLD_ACTION_ARROW] = 34,
+ [ROUNDBOX_TRIA_SCROLL] = 12,
+ [ROUNDBOX_TRIA_MENU] = 28,
+ [ROUNDBOX_TRIA_CHECK] = 34,
+ [ROUNDBOX_TRIA_HOLD_ACTION_ARROW] = 40,
};
static const int tria_vcount[ROUNDBOX_TRIA_MAX] = {
[ROUNDBOX_TRIA_NONE] = 0,
- [ROUNDBOX_TRIA_ARROWS] = 3,
+ [ROUNDBOX_TRIA_ARROWS] = 6,
[ROUNDBOX_TRIA_SCROLL] = 16,
- [ROUNDBOX_TRIA_MENU] = 3,
+ [ROUNDBOX_TRIA_MENU] = 6,
[ROUNDBOX_TRIA_CHECK] = 6,
[ROUNDBOX_TRIA_HOLD_ACTION_ARROW] = 3,
};
@@ -296,8 +296,8 @@ static uint32_t set_tria_vertex(
int tria_type, int tria_v, int tria_id, int jit_v)
{
uint32_t *data = GWN_vertbuf_raw_step(vflag_step);
- if (ELEM(tria_type, ROUNDBOX_TRIA_ARROWS, ROUNDBOX_TRIA_MENU)) {
- tria_v += tria_id * 3;
+ if (ELEM(tria_type, ROUNDBOX_TRIA_ARROWS)) {
+ tria_v += tria_id * tria_vcount[ROUNDBOX_TRIA_ARROWS];
}
*data = tria_ofs[tria_type] + tria_v;
*data |= jit_v << 6;
@@ -308,7 +308,7 @@ static uint32_t set_tria_vertex(
static void roundbox_batch_add_tria(Gwn_VertBufRaw *vflag_step, int tria, uint32_t last_data)
{
- const int tria_num = ELEM(tria, ROUNDBOX_TRIA_CHECK, ROUNDBOX_TRIA_HOLD_ACTION_ARROW) ? 1 : 2;
+ const int tria_num = ELEM(tria, ROUNDBOX_TRIA_CHECK, ROUNDBOX_TRIA_HOLD_ACTION_ARROW, ROUNDBOX_TRIA_MENU) ? 1 : 2;
/* for each tria */
for (int t = 0; t < tria_num; ++t) {
for (int j = 0; j < WIDGET_AA_JITTER; j++) {
@@ -335,7 +335,7 @@ Gwn_Batch *ui_batch_roundbox_widget_get(int tria)
vcount += ((WIDGET_CURVE_RESOLU * 2) * 2) * WIDGET_AA_JITTER; /* emboss */
if (tria) {
vcount += (tria_vcount[tria] + 2) * WIDGET_AA_JITTER; /* tria1 */
- if (!ELEM(tria, ROUNDBOX_TRIA_CHECK, ROUNDBOX_TRIA_HOLD_ACTION_ARROW)) {
+ if (!ELEM(tria, ROUNDBOX_TRIA_CHECK, ROUNDBOX_TRIA_HOLD_ACTION_ARROW, ROUNDBOX_TRIA_MENU)) {
vcount += (tria_vcount[tria] + 2) * WIDGET_AA_JITTER; /* tria2 */
}
}
@@ -1500,6 +1500,8 @@ float UI_text_clip_middle_ex(
BLF_disable(fstyle->uifont_id, BLF_KERNING_DEFAULT);
}
+ BLI_assert(strwidth <= okwidth);
+
return strwidth;
}
@@ -2657,18 +2659,22 @@ static void widget_state_pie_menu_item(uiWidgetType *wt, int state)
copy_v4_v4_char(wt->wcol.inner, wt->wcol.item);
wt->wcol.inner[3] = 64;
}
- /* regular disabled */
- else if (state & (UI_BUT_DISABLED | UI_BUT_INACTIVE)) {
- widget_state_blend(wt->wcol.text, wt->wcol.inner, 0.5f);
- }
- /* regular active */
- else if (state & UI_SELECT) {
- copy_v4_v4_char(wt->wcol.outline, wt->wcol.inner_sel);
- copy_v3_v3_char(wt->wcol.text, wt->wcol.text_sel);
- }
- else if (state & UI_ACTIVE) {
- copy_v4_v4_char(wt->wcol.inner, wt->wcol.item);
- copy_v3_v3_char(wt->wcol.text, wt->wcol.text_sel);
+ else {
+ /* regular active */
+ if (state & (UI_SELECT | UI_ACTIVE)) {
+ copy_v3_v3_char(wt->wcol.text, wt->wcol.text_sel);
+ }
+ else if (state & (UI_BUT_DISABLED | UI_BUT_INACTIVE)) {
+ /* regular disabled */
+ widget_state_blend(wt->wcol.text, wt->wcol.inner, 0.5f);
+ }
+
+ if (state & UI_SELECT) {
+ copy_v4_v4_char(wt->wcol.outline, wt->wcol.inner_sel);
+ }
+ else if (state & UI_ACTIVE) {
+ copy_v4_v4_char(wt->wcol.inner, wt->wcol.item);
+ }
}
}
@@ -2685,14 +2691,19 @@ static void widget_state_menu_item(uiWidgetType *wt, int state)
copy_v4_v4_char(wt->wcol.inner, wt->wcol.inner_sel);
wt->wcol.inner[3] = 64;
}
- /* regular disabled */
- else if (state & (UI_BUT_DISABLED | UI_BUT_INACTIVE)) {
- widget_state_blend(wt->wcol.text, wt->wcol.inner, 0.5f);
- }
- /* regular active */
- else if (state & UI_ACTIVE) {
- copy_v4_v4_char(wt->wcol.inner, wt->wcol.inner_sel);
- copy_v3_v3_char(wt->wcol.text, wt->wcol.text_sel);
+ else {
+ /* regular active */
+ if (state & UI_ACTIVE) {
+ copy_v3_v3_char(wt->wcol.text, wt->wcol.text_sel);
+ }
+ else if (state & (UI_BUT_DISABLED | UI_BUT_INACTIVE)) {
+ /* regular disabled */
+ widget_state_blend(wt->wcol.text, wt->wcol.inner, 0.5f);
+ }
+
+ if (state & UI_ACTIVE) {
+ copy_v4_v4_char(wt->wcol.inner, wt->wcol.inner_sel);
+ }
}
}
diff --git a/source/blender/editors/interface/resources.c b/source/blender/editors/interface/resources.c
index 8bd41b874f5..a04b25672de 100644
--- a/source/blender/editors/interface/resources.c
+++ b/source/blender/editors/interface/resources.c
@@ -48,9 +48,9 @@
#include "BKE_addon.h"
#include "BKE_appdir.h"
#include "BKE_colorband.h"
-#include "BKE_DerivedMesh.h"
#include "BKE_global.h"
#include "BKE_main.h"
+#include "BKE_mesh_runtime.h"
#include "BIF_gl.h"
@@ -1856,9 +1856,9 @@ void init_userdef_do_versions(Main *bmain)
U.fcu_inactive_alpha = 0.25f;
}
- /* signal for derivedmesh to use colorband */
+ /* signal for evaluated mesh to use colorband */
/* run in case this was on and is now off in the user prefs [#28096] */
- vDM_ColorBand_store((U.flag & USER_CUSTOM_RANGE) ? (&U.coba_weight) : NULL, UI_GetTheme()->tv3d.vertex_unreferenced);
+ BKE_mesh_runtime_color_band_store((U.flag & USER_CUSTOM_RANGE) ? (&U.coba_weight) : NULL, UI_GetTheme()->tv3d.vertex_unreferenced);
if (!USER_VERSION_ATLEAST(192, 0)) {
strcpy(U.sounddir, "/");
@@ -2920,7 +2920,7 @@ void init_userdef_do_versions(Main *bmain)
U.flag &= ~(
USER_FLAG_DEPRECATED_1 | USER_FLAG_DEPRECATED_2 | USER_FLAG_DEPRECATED_3 |
USER_FLAG_DEPRECATED_6 | USER_FLAG_DEPRECATED_7 |
- USER_FLAG_DEPRECATED_9 | USER_FLAG_DEPRECATED_10);
+ USER_FLAG_DEPRECATED_9 | USER_DEVELOPER_UI);
U.uiflag &= ~(
USER_UIFLAG_DEPRECATED_7);
U.transopts &= ~(
diff --git a/source/blender/editors/mesh/editface.c b/source/blender/editors/mesh/editface.c
index cf4d8ebf05d..405c19f1c1d 100644
--- a/source/blender/editors/mesh/editface.c
+++ b/source/blender/editors/mesh/editface.c
@@ -33,13 +33,14 @@
#include "IMB_imbuf_types.h"
#include "IMB_imbuf.h"
+#include "DNA_meshdata_types.h"
#include "DNA_mesh_types.h"
#include "DNA_object_types.h"
-#include "BKE_DerivedMesh.h"
+#include "BKE_context.h"
+#include "BKE_customdata.h"
#include "BKE_global.h"
#include "BKE_mesh.h"
-#include "BKE_context.h"
#include "BIF_gl.h"
@@ -61,7 +62,7 @@
void paintface_flush_flags(Object *ob, short flag)
{
Mesh *me = BKE_mesh_from_object(ob);
- DerivedMesh *dm = ob->derivedFinal;
+ Mesh *me_eval = ob->runtime.mesh_eval;
MPoly *polys, *mp_orig;
const int *index_array = NULL;
int totpoly;
@@ -80,14 +81,14 @@ void paintface_flush_flags(Object *ob, short flag)
BKE_mesh_flush_select_from_polys(me);
}
- if (dm == NULL)
+ if (me_eval == NULL)
return;
/* Mesh polys => Final derived polys */
- if ((index_array = CustomData_get_layer(&dm->polyData, CD_ORIGINDEX))) {
- polys = dm->getPolyArray(dm);
- totpoly = dm->getNumPolys(dm);
+ if ((index_array = CustomData_get_layer(&me_eval->pdata, CD_ORIGINDEX))) {
+ polys = me_eval->mpoly;
+ totpoly = me_eval->totpoly;
/* loop over final derived polys */
for (i = 0; i < totpoly; i++) {
@@ -474,8 +475,8 @@ int do_paintface_box_select(ViewContext *vc, rcti *rect, bool select, bool exten
void paintvert_flush_flags(Object *ob)
{
Mesh *me = BKE_mesh_from_object(ob);
- DerivedMesh *dm = ob->derivedFinal;
- MVert *dm_mvert, *dm_mv;
+ Mesh *me_eval = ob->runtime.mesh_eval;
+ MVert *mvert_eval, *mv;
const int *index_array = NULL;
int totvert;
int i;
@@ -487,28 +488,28 @@ void paintvert_flush_flags(Object *ob)
* since this could become slow for realtime updates (circle-select for eg) */
BKE_mesh_flush_select_from_verts(me);
- if (dm == NULL)
+ if (me_eval == NULL)
return;
- index_array = dm->getVertDataArray(dm, CD_ORIGINDEX);
+ index_array = CustomData_get_layer(&me_eval->vdata, CD_ORIGINDEX);
- dm_mvert = dm->getVertArray(dm);
- totvert = dm->getNumVerts(dm);
+ mvert_eval = me_eval->mvert;
+ totvert = me_eval->totvert;
- dm_mv = dm_mvert;
+ mv = mvert_eval;
if (index_array) {
int orig_index;
- for (i = 0; i < totvert; i++, dm_mv++) {
+ for (i = 0; i < totvert; i++, mv++) {
orig_index = index_array[i];
if (orig_index != ORIGINDEX_NONE) {
- dm_mv->flag = me->mvert[index_array[i]].flag;
+ mv->flag = me->mvert[index_array[i]].flag;
}
}
}
else {
- for (i = 0; i < totvert; i++, dm_mv++) {
- dm_mv->flag = me->mvert[i].flag;
+ for (i = 0; i < totvert; i++, mv++) {
+ mv->flag = me->mvert[i].flag;
}
}
diff --git a/source/blender/editors/mesh/editmesh_bevel.c b/source/blender/editors/mesh/editmesh_bevel.c
index c51a57e27b3..2041852c9ee 100644
--- a/source/blender/editors/mesh/editmesh_bevel.c
+++ b/source/blender/editors/mesh/editmesh_bevel.c
@@ -657,7 +657,7 @@ void MESH_OT_bevel(wmOperatorType *ot)
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_GRAB_CURSOR | OPTYPE_BLOCKING;
RNA_def_enum(ot->srna, "offset_type", offset_type_items, 0, "Amount Type", "What distance Amount measures");
- prop = RNA_def_float(ot->srna, "offset", 0.0f, -1e6f, 1e6f, "Amount", "", 0.0f, 1.0f);
+ prop = RNA_def_float(ot->srna, "offset", 0.0f, -1e6f, 1e6f, "Amount", "", 0.0f, 100.0f);
RNA_def_property_float_array_funcs_runtime(prop, NULL, NULL, mesh_ot_bevel_offset_range_func);
RNA_def_int(ot->srna, "segments", 1, 1, SEGMENTS_HARD_MAX, "Segments", "Segments for curved edge", 1, 8);
RNA_def_float(ot->srna, "profile", 0.5f, PROFILE_HARD_MIN, 1.0f, "Profile",
diff --git a/source/blender/editors/mesh/editmesh_utils.c b/source/blender/editors/mesh/editmesh_utils.c
index 64e6b477abe..5481c52269d 100644
--- a/source/blender/editors/mesh/editmesh_utils.c
+++ b/source/blender/editors/mesh/editmesh_utils.c
@@ -1035,7 +1035,7 @@ void EDBM_verts_mirror_cache_begin_ex(
BM_mesh_elem_index_ensure(bm, BM_VERT);
if (use_topology) {
- ED_mesh_mirrtopo_init__real_mesh(me, NULL, &mesh_topo_store, true);
+ ED_mesh_mirrtopo_init(me, NULL, &mesh_topo_store, true);
}
else {
tree = BLI_kdtree_new(bm->totvert);
diff --git a/source/blender/editors/mesh/mesh_data.c b/source/blender/editors/mesh/mesh_data.c
index 46b84f328cc..b4588257412 100644
--- a/source/blender/editors/mesh/mesh_data.c
+++ b/source/blender/editors/mesh/mesh_data.c
@@ -584,8 +584,8 @@ static int drop_named_image_invoke(bContext *C, wmOperator *op, const wmEvent *e
MEM_freeN(me->edit_btmesh);
me->edit_btmesh = NULL;
- /* load_editMesh free's pointers used by CustomData layers which might be used by DerivedMesh too,
- * so signal to re-create DerivedMesh here (sergey) */
+ /* load_editMesh free's pointers used by CustomData layers which might be used by evaluated mesh too,
+ * so signal to re-create evaluated mesh here (sergey) */
DEG_id_tag_update(&me->id, 0);
}
diff --git a/source/blender/editors/mesh/mesh_mirror.c b/source/blender/editors/mesh/mesh_mirror.c
index 4c078d2ac8b..4b526915551 100644
--- a/source/blender/editors/mesh/mesh_mirror.c
+++ b/source/blender/editors/mesh/mesh_mirror.c
@@ -32,9 +32,9 @@
#include "BLI_bitmap.h"
#include "DNA_mesh_types.h"
+#include "DNA_meshdata_types.h"
#include "DNA_object_types.h"
-#include "BKE_DerivedMesh.h"
#include "BLI_kdtree.h"
#include "BKE_editmesh.h"
#include "BKE_library.h"
@@ -52,11 +52,11 @@ static struct { void *tree; } MirrKdStore = {NULL};
/* mode is 's' start, or 'e' end, or 'u' use */
/* if end, ob can be NULL */
-int ED_mesh_mirror_spatial_table(Object *ob, BMEditMesh *em, DerivedMesh *dm, const float co[3], char mode)
+int ED_mesh_mirror_spatial_table(Object *ob, BMEditMesh *em, Mesh *me_eval, const float co[3], char mode)
{
if (mode == 'u') { /* use table */
if (MirrKdStore.tree == NULL)
- ED_mesh_mirror_spatial_table(ob, em, dm, NULL, 's');
+ ED_mesh_mirror_spatial_table(ob, em, me_eval, NULL, 's');
if (MirrKdStore.tree) {
KDTreeNearest nearest;
@@ -72,11 +72,11 @@ int ED_mesh_mirror_spatial_table(Object *ob, BMEditMesh *em, DerivedMesh *dm, co
}
else if (mode == 's') { /* start table */
Mesh *me = ob->data;
- const bool use_em = (!dm && em && me->edit_btmesh == em);
- const int totvert = use_em ? em->bm->totvert : dm ? dm->getNumVerts(dm) : me->totvert;
+ const bool use_em = (!me_eval && em && me->edit_btmesh == em);
+ const int totvert = use_em ? em->bm->totvert : me_eval ? me_eval->totvert : me->totvert;
if (MirrKdStore.tree) /* happens when entering this call without ending it */
- ED_mesh_mirror_spatial_table(ob, em, dm, co, 'e');
+ ED_mesh_mirror_spatial_table(ob, em, me_eval, co, 'e');
MirrKdStore.tree = BLI_kdtree_new(totvert);
@@ -93,73 +93,7 @@ int ED_mesh_mirror_spatial_table(Object *ob, BMEditMesh *em, DerivedMesh *dm, co
}
}
else {
- MVert *mvert = dm ? dm->getVertArray(dm) : me->mvert;
- int i;
-
- for (i = 0; i < totvert; i++, mvert++) {
- BLI_kdtree_insert(MirrKdStore.tree, i, mvert->co);
- }
- }
-
- BLI_kdtree_balance(MirrKdStore.tree);
- }
- else if (mode == 'e') { /* end table */
- if (MirrKdStore.tree) {
- BLI_kdtree_free(MirrKdStore.tree);
- MirrKdStore.tree = NULL;
- }
- }
- else {
- BLI_assert(0);
- }
-
- return 0;
-}
-
-/* mode is 's' start, or 'e' end, or 'u' use */
-/* if end, ob can be NULL */
-int ED_mesh_mirror_spatial_table__real_mesh(Object *ob, BMEditMesh *em, Mesh *mesh, const float co[3], char mode)
-{
- if (mode == 'u') { /* use table */
- if (MirrKdStore.tree == NULL)
- ED_mesh_mirror_spatial_table__real_mesh(ob, em, mesh, NULL, 's');
-
- if (MirrKdStore.tree) {
- KDTreeNearest nearest;
- const int i = BLI_kdtree_find_nearest(MirrKdStore.tree, co, &nearest);
-
- if (i != -1) {
- if (nearest.dist < KD_THRESH) {
- return i;
- }
- }
- }
- return -1;
- }
- else if (mode == 's') { /* start table */
- Mesh *me = ob->data;
- const bool use_em = (!mesh && em && me->edit_btmesh == em);
- const int totvert = use_em ? em->bm->totvert : mesh ? mesh->totvert : me->totvert;
-
- if (MirrKdStore.tree) /* happens when entering this call without ending it */
- ED_mesh_mirror_spatial_table__real_mesh(ob, em, mesh, co, 'e');
-
- MirrKdStore.tree = BLI_kdtree_new(totvert);
-
- if (use_em) {
- BMVert *eve;
- BMIter iter;
- int i;
-
- /* this needs to be valid for index lookups later (callers need) */
- BM_mesh_elem_table_ensure(em->bm, BM_VERT);
-
- BM_ITER_MESH_INDEX (eve, &iter, em->bm, BM_VERTS_OF_MESH, i) {
- BLI_kdtree_insert(MirrKdStore.tree, i, eve->co);
- }
- }
- else {
- MVert *mvert = mesh ? mesh->mvert : me->mvert;
+ MVert *mvert = me_eval ? me_eval->mvert : me->mvert;
int i;
for (i = 0; i < totvert; i++, mvert++) {
@@ -209,46 +143,15 @@ static int mirrtopo_vert_sort(const void *v1, const void *v2)
return 0;
}
-bool ED_mesh_mirrtopo_recalc_check(Mesh *me, DerivedMesh *dm, MirrTopoStore_t *mesh_topo_store)
-{
- const bool is_editmode = (me->edit_btmesh != NULL);
- int totvert;
- int totedge;
-
- if (dm) {
- totvert = dm->getNumVerts(dm);
- totedge = dm->getNumEdges(dm);
- }
- else if (me->edit_btmesh) {
- totvert = me->edit_btmesh->bm->totvert;
- totedge = me->edit_btmesh->bm->totedge;
- }
- else {
- totvert = me->totvert;
- totedge = me->totedge;
- }
-
- if ((mesh_topo_store->index_lookup == NULL) ||
- (mesh_topo_store->prev_is_editmode != is_editmode) ||
- (totvert != mesh_topo_store->prev_vert_tot) ||
- (totedge != mesh_topo_store->prev_edge_tot))
- {
- return true;
- }
- else {
- return false;
- }
-
-}
-bool ED_mesh_mirrtopo_recalc_check__real_mesh(Mesh *me, Mesh *dm, MirrTopoStore_t *mesh_topo_store)
+bool ED_mesh_mirrtopo_recalc_check(Mesh *me, Mesh *me_eval, MirrTopoStore_t *mesh_topo_store)
{
const bool is_editmode = (me->edit_btmesh != NULL);
int totvert;
int totedge;
- if (dm) {
- totvert = dm->totvert;
- totedge = dm->totedge;
+ if (me_eval) {
+ totvert = me_eval->totvert;
+ totedge = me_eval->totedge;
}
else if (me->edit_btmesh) {
totvert = me->edit_btmesh->bm->totvert;
@@ -272,33 +175,13 @@ bool ED_mesh_mirrtopo_recalc_check__real_mesh(Mesh *me, Mesh *dm, MirrTopoStore_
}
-
void ED_mesh_mirrtopo_init(
- Mesh *me, DerivedMesh *dm, MirrTopoStore_t *mesh_topo_store,
- const bool skip_em_vert_array_init)
-{
- Mesh *fake_mesh = NULL;
-
- if (dm != NULL) {
- /* ED_real_mesh_mirrtopo_init() only uses the counts, not the actual data */
- fake_mesh = BKE_mesh_new_nomain(dm->getNumVerts(dm), dm->getNumEdges(dm), dm->getNumTessFaces(dm),
- dm->getNumLoops(dm), dm->getNumPolys(dm));
- }
-
- ED_mesh_mirrtopo_init__real_mesh(me, fake_mesh, mesh_topo_store, skip_em_vert_array_init);
-
- if (dm != NULL) {
- BKE_id_free(NULL, fake_mesh);
- }
-}
-
-void ED_mesh_mirrtopo_init__real_mesh(
- Mesh *me, Mesh *dm, MirrTopoStore_t *mesh_topo_store,
+ Mesh *me, Mesh *me_eval, MirrTopoStore_t *mesh_topo_store,
const bool skip_em_vert_array_init)
{
const bool is_editmode = (me->edit_btmesh != NULL);
MEdge *medge = NULL, *med;
- BMEditMesh *em = dm ? NULL : me->edit_btmesh;
+ BMEditMesh *em = me_eval ? NULL : me->edit_btmesh;
/* editmode*/
BMEdge *eed;
@@ -327,7 +210,7 @@ void ED_mesh_mirrtopo_init__real_mesh(
totvert = em->bm->totvert;
}
else {
- totvert = dm ? dm->totvert : me->totvert;
+ totvert = me_eval ? me_eval->totvert : me->totvert;
}
topo_hash = MEM_callocN(totvert * sizeof(MirrTopoHash_t), "TopoMirr");
@@ -343,8 +226,8 @@ void ED_mesh_mirrtopo_init__real_mesh(
}
}
else {
- totedge = dm ? dm->totedge : me->totedge;
- medge = dm ? dm->medge : me->medge;
+ totedge = me_eval ? me_eval->totedge : me->totedge;
+ medge = me_eval ? me_eval->medge : me->medge;
for (a = 0, med = medge; a < totedge; a++, med++) {
const unsigned int i1 = med->v1, i2 = med->v2;
diff --git a/source/blender/editors/mesh/meshtools.c b/source/blender/editors/mesh/meshtools.c
index 6c8de1a481e..537056cd1ba 100644
--- a/source/blender/editors/mesh/meshtools.c
+++ b/source/blender/editors/mesh/meshtools.c
@@ -34,9 +34,10 @@
#include "MEM_guardedalloc.h"
-#include "DNA_mesh_types.h"
#include "DNA_key_types.h"
#include "DNA_material_types.h"
+#include "DNA_mesh_types.h"
+#include "DNA_meshdata_types.h"
#include "DNA_modifier_types.h"
#include "DNA_object_types.h"
#include "DNA_scene_types.h"
@@ -49,11 +50,11 @@
#include "BKE_context.h"
#include "BKE_deform.h"
-#include "BKE_DerivedMesh.h"
#include "BKE_key.h"
#include "BKE_library.h"
#include "BKE_main.h"
#include "BKE_mesh.h"
+#include "BKE_mesh_iterators.h"
#include "BKE_mesh_runtime.h"
#include "BKE_material.h"
#include "BKE_object.h"
@@ -612,7 +613,7 @@ int join_mesh_shapes_exec(bContext *C, wmOperator *op)
Depsgraph *depsgraph = CTX_data_depsgraph(C);
Mesh *me = (Mesh *)ob->data;
Mesh *selme = NULL;
- DerivedMesh *dm = NULL;
+ Mesh *me_deformed = NULL;
Key *key = me->key;
KeyBlock *kb;
bool ok = false, nonequal_verts = false;
@@ -646,7 +647,7 @@ int join_mesh_shapes_exec(bContext *C, wmOperator *op)
/* first key added, so it was the basis. initialize it with the existing mesh */
kb = BKE_keyblock_add(key, NULL);
- BKE_keyblock_convert_from_mesh(me, kb);
+ BKE_keyblock_convert_from_mesh(me, key, kb);
}
/* now ready to add new keys from selected meshes */
@@ -658,15 +659,15 @@ int join_mesh_shapes_exec(bContext *C, wmOperator *op)
selme = (Mesh *)base->object->data;
if (selme->totvert == me->totvert) {
- dm = mesh_get_derived_deform(depsgraph, scene, base->object, CD_MASK_BAREMESH);
+ me_deformed = mesh_get_eval_deform(depsgraph, scene, base->object, CD_MASK_BAREMESH);
- if (!dm) continue;
+ if (!me_deformed) {
+ continue;
+ }
kb = BKE_keyblock_add(key, base->object->id.name + 2);
- DM_to_meshkey(dm, me, kb);
-
- dm->release(dm);
+ BKE_mesh_runtime_eval_to_meshkey(me_deformed, me, kb);
}
}
}
@@ -690,40 +691,15 @@ static MirrTopoStore_t mesh_topo_store = {NULL, -1. - 1, -1};
/* mode is 's' start, or 'e' end, or 'u' use */
/* if end, ob can be NULL */
/* note, is supposed return -1 on error, which callers are currently checking for, but is not used so far */
-int ED_mesh_mirror_topo_table(
- Object *ob, DerivedMesh *dm, char mode)
+int ED_mesh_mirror_topo_table(Object *ob, Mesh *me_eval, char mode)
{
if (mode == 'u') { /* use table */
- if (ED_mesh_mirrtopo_recalc_check(ob->data, dm, &mesh_topo_store)) {
- ED_mesh_mirror_topo_table(ob, dm, 's');
+ if (ED_mesh_mirrtopo_recalc_check(ob->data, me_eval, &mesh_topo_store)) {
+ ED_mesh_mirror_topo_table(ob, me_eval, 's');
}
}
else if (mode == 's') { /* start table */
- ED_mesh_mirrtopo_init(ob->data, dm, &mesh_topo_store, false);
- }
- else if (mode == 'e') { /* end table */
- ED_mesh_mirrtopo_free(&mesh_topo_store);
- }
- else {
- BLI_assert(0);
- }
-
- return 0;
-}
-
-/* mode is 's' start, or 'e' end, or 'u' use */
-/* if end, ob can be NULL */
-/* note, is supposed return -1 on error, which callers are currently checking for, but is not used so far */
-int ED_mesh_mirror_topo_table__real_mesh(
- Object *ob, Mesh *mesh, char mode)
-{
- if (mode == 'u') { /* use table */
- if (ED_mesh_mirrtopo_recalc_check__real_mesh(ob->data, mesh, &mesh_topo_store)) {
- ED_mesh_mirror_topo_table__real_mesh(ob, mesh, 's');
- }
- }
- else if (mode == 's') { /* start table */
- ED_mesh_mirrtopo_init__real_mesh(ob->data, mesh, &mesh_topo_store, false);
+ ED_mesh_mirrtopo_init(ob->data, me_eval, &mesh_topo_store, false);
}
else if (mode == 'e') { /* end table */
ED_mesh_mirrtopo_free(&mesh_topo_store);
@@ -738,39 +714,7 @@ int ED_mesh_mirror_topo_table__real_mesh(
/** \} */
-static int mesh_get_x_mirror_vert_spatial(Object *ob, DerivedMesh *dm, int index)
-{
- Mesh *me = ob->data;
- MVert *mvert = dm ? dm->getVertArray(dm) : me->mvert;
- float vec[3];
-
- mvert = &mvert[index];
- vec[0] = -mvert->co[0];
- vec[1] = mvert->co[1];
- vec[2] = mvert->co[2];
-
- return ED_mesh_mirror_spatial_table(ob, NULL, dm, vec, 'u');
-}
-
-static int mesh_get_x_mirror_vert_topo(Object *ob, DerivedMesh *dm, int index)
-{
- if (ED_mesh_mirror_topo_table(ob, dm, 'u') == -1)
- return -1;
-
- return mesh_topo_store.index_lookup[index];
-}
-
-int mesh_get_x_mirror_vert(Object *ob, DerivedMesh *dm, int index, const bool use_topology)
-{
- if (use_topology) {
- return mesh_get_x_mirror_vert_topo(ob, dm, index);
- }
- else {
- return mesh_get_x_mirror_vert_spatial(ob, dm, index);
- }
-}
-
-static int mesh_get_x_mirror_vert_spatial__real_mesh(Object *ob, Mesh *mesh, int index)
+static int mesh_get_x_mirror_vert_spatial(Object *ob, Mesh *mesh, int index)
{
Mesh *me = ob->data;
MVert *mvert = mesh ? mesh->mvert : me->mvert;
@@ -781,24 +725,24 @@ static int mesh_get_x_mirror_vert_spatial__real_mesh(Object *ob, Mesh *mesh, int
vec[1] = mvert->co[1];
vec[2] = mvert->co[2];
- return ED_mesh_mirror_spatial_table__real_mesh(ob, NULL, mesh, vec, 'u');
+ return ED_mesh_mirror_spatial_table(ob, NULL, mesh, vec, 'u');
}
-static int mesh_get_x_mirror_vert_topo__real_mesh(Object *ob, Mesh *mesh, int index)
+static int mesh_get_x_mirror_vert_topo(Object *ob, Mesh *mesh, int index)
{
- if (ED_mesh_mirror_topo_table__real_mesh(ob, mesh, 'u') == -1)
+ if (ED_mesh_mirror_topo_table(ob, mesh, 'u') == -1)
return -1;
return mesh_topo_store.index_lookup[index];
}
-int mesh_get_x_mirror_vert__real_mesh(Object *ob, Mesh *mesh, int index, const bool use_topology)
+int mesh_get_x_mirror_vert(Object *ob, Mesh *me_eval, int index, const bool use_topology)
{
if (use_topology) {
- return mesh_get_x_mirror_vert_topo__real_mesh(ob, mesh, index);
+ return mesh_get_x_mirror_vert_topo(ob, me_eval, index);
}
else {
- return mesh_get_x_mirror_vert_spatial__real_mesh(ob, mesh, index);
+ return mesh_get_x_mirror_vert_spatial(ob, me_eval, index);
}
}
@@ -995,68 +939,8 @@ static bool mirror_facecmp(const void *a, const void *b)
return (mirror_facerotation((MFace *)a, (MFace *)b) == -1);
}
-/* BMESH_TODO, convert to MPoly (functions above also) */
-int *mesh_get_x_mirror_faces(Object *ob, BMEditMesh *em, DerivedMesh *dm)
-{
- Mesh *me = ob->data;
- MVert *mv, *mvert;
- MFace mirrormf, *mf, *hashmf, *mface;
- GHash *fhash;
- int *mirrorverts, *mirrorfaces;
-
- BLI_assert(em == NULL); /* Does not work otherwise, currently... */
-
- const bool use_topology = (me->editflag & ME_EDIT_MIRROR_TOPO) != 0;
- const int totvert = dm ? dm->getNumVerts(dm) : me->totvert;
- const int totface = dm ? dm->getNumTessFaces(dm) : me->totface;
- int a;
-
- mirrorverts = MEM_callocN(sizeof(int) * totvert, "MirrorVerts");
- mirrorfaces = MEM_callocN(sizeof(int) * 2 * totface, "MirrorFaces");
-
- mvert = dm ? dm->getVertArray(dm) : me->mvert;
- mface = dm ? dm->getTessFaceArray(dm) : me->mface;
-
- ED_mesh_mirror_spatial_table(ob, em, dm, NULL, 's');
-
- for (a = 0, mv = mvert; a < totvert; a++, mv++)
- mirrorverts[a] = mesh_get_x_mirror_vert(ob, dm, a, use_topology);
-
- ED_mesh_mirror_spatial_table(ob, em, dm, NULL, 'e');
-
- fhash = BLI_ghash_new_ex(mirror_facehash, mirror_facecmp, "mirror_facehash gh", me->totface);
- for (a = 0, mf = mface; a < totface; a++, mf++)
- BLI_ghash_insert(fhash, mf, mf);
-
- for (a = 0, mf = mface; a < totface; a++, mf++) {
- mirrormf.v1 = mirrorverts[mf->v3];
- mirrormf.v2 = mirrorverts[mf->v2];
- mirrormf.v3 = mirrorverts[mf->v1];
- mirrormf.v4 = (mf->v4) ? mirrorverts[mf->v4] : 0;
-
- /* make sure v4 is not 0 if a quad */
- if (mf->v4 && mirrormf.v4 == 0) {
- SWAP(unsigned int, mirrormf.v1, mirrormf.v3);
- SWAP(unsigned int, mirrormf.v2, mirrormf.v4);
- }
-
- hashmf = BLI_ghash_lookup(fhash, &mirrormf);
- if (hashmf) {
- mirrorfaces[a * 2] = hashmf - mface;
- mirrorfaces[a * 2 + 1] = mirror_facerotation(&mirrormf, hashmf);
- }
- else
- mirrorfaces[a * 2] = -1;
- }
-
- BLI_ghash_free(fhash, NULL, NULL);
- MEM_freeN(mirrorverts);
-
- return mirrorfaces;
-}
-
/* This is a Mesh-based copy of mesh_get_x_mirror_faces() */
-int *mesh_get_x_mirror_faces__real_mesh(Object *ob, BMEditMesh *em, Mesh *mesh)
+int *mesh_get_x_mirror_faces(Object *ob, BMEditMesh *em, Mesh *me_eval)
{
Mesh *me = ob->data;
MVert *mv, *mvert;
@@ -1067,22 +951,22 @@ int *mesh_get_x_mirror_faces__real_mesh(Object *ob, BMEditMesh *em, Mesh *mesh)
BLI_assert(em == NULL); /* Does not work otherwise, currently... */
const bool use_topology = (me->editflag & ME_EDIT_MIRROR_TOPO) != 0;
- const int totvert = mesh ? mesh->totvert : me->totvert;
- const int totface = mesh ? mesh->totface : me->totface;
+ const int totvert = me_eval ? me_eval->totvert : me->totvert;
+ const int totface = me_eval ? me_eval->totface : me->totface;
int a;
mirrorverts = MEM_callocN(sizeof(int) * totvert, "MirrorVerts");
mirrorfaces = MEM_callocN(sizeof(int) * 2 * totface, "MirrorFaces");
- mvert = mesh ? mesh->mvert : me->mvert;
- mface = mesh ? mesh->mface : me->mface;
+ mvert = me_eval ? me_eval->mvert : me->mvert;
+ mface = me_eval ? me_eval->mface : me->mface;
- ED_mesh_mirror_spatial_table__real_mesh(ob, em, mesh, NULL, 's');
+ ED_mesh_mirror_spatial_table(ob, em, me_eval, NULL, 's');
for (a = 0, mv = mvert; a < totvert; a++, mv++)
- mirrorverts[a] = mesh_get_x_mirror_vert__real_mesh(ob, mesh, a, use_topology);
+ mirrorverts[a] = mesh_get_x_mirror_vert(ob, me_eval, a, use_topology);
- ED_mesh_mirror_spatial_table__real_mesh(ob, em, mesh, NULL, 'e');
+ ED_mesh_mirror_spatial_table(ob, em, me_eval, NULL, 'e');
fhash = BLI_ghash_new_ex(mirror_facehash, mirror_facecmp, "mirror_facehash gh", me->totface);
for (a = 0, mf = mface; a < totface; a++, mf++)
@@ -1322,7 +1206,7 @@ bool ED_mesh_pick_vert(bContext *C, Object *ob, const int mval[2], unsigned int
}
else {
/* derived mesh to find deformed locations */
- DerivedMesh *dm = mesh_get_derived_final(vc.depsgraph, vc.scene, ob, CD_MASK_BAREMESH);
+ Mesh *me_eval = mesh_get_eval_final(vc.depsgraph, vc.scene, ob, CD_MASK_BAREMESH);
ARegion *ar = vc.ar;
RegionView3D *rv3d = ar->regiondata;
@@ -1334,7 +1218,7 @@ bool ED_mesh_pick_vert(bContext *C, Object *ob, const int mval[2], unsigned int
ED_view3d_init_mats_rv3d(ob, rv3d);
- if (dm == NULL) {
+ if (me_eval == NULL) {
return false;
}
@@ -1345,9 +1229,7 @@ bool ED_mesh_pick_vert(bContext *C, Object *ob, const int mval[2], unsigned int
data.len_best = FLT_MAX;
data.v_idx_best = -1;
- dm->foreachMappedVert(dm, ed_mesh_pick_vert__mapFunc, &data, DM_FOREACH_NOP);
-
- dm->release(dm);
+ BKE_mesh_foreach_mapped_vert(me_eval, ed_mesh_pick_vert__mapFunc, &data, MESH_FOREACH_NOP);
if (data.v_idx_best == -1) {
return false;
diff --git a/source/blender/editors/object/object_add.c b/source/blender/editors/object/object_add.c
index dd358b95722..ac3f8d58de8 100644
--- a/source/blender/editors/object/object_add.c
+++ b/source/blender/editors/object/object_add.c
@@ -946,7 +946,7 @@ static int empty_drop_named_image_invoke(bContext *C, wmOperator *op, const wmEv
/* add under the mouse */
ED_object_location_from_view(C, ob->loc);
- ED_view3d_cursor3d_position(C, ob->loc, event->mval);
+ ED_view3d_cursor3d_position(C, event->mval, false, ob->loc);
}
BKE_object_empty_draw_type_set(ob, OB_EMPTY_IMAGE);
@@ -1013,7 +1013,21 @@ static int object_lamp_add_exec(bContext *C, wmOperator *op)
return OPERATOR_CANCELLED;
ob = ED_object_add_type(C, OB_LAMP, get_lamp_defname(type), loc, rot, false, layer);
- BKE_object_obdata_size_init(ob, RNA_float_get(op->ptr, "radius"));
+
+ float size = RNA_float_get(op->ptr, "radius");
+ /* Better defaults for lamp size. */
+ switch (type) {
+ case LA_LOCAL:
+ case LA_SPOT:
+ break;
+ case LA_AREA:
+ size *= 4.0f;
+ break;
+ default:
+ size *= 0.5f;
+ break;
+ }
+ BKE_object_obdata_size_init(ob, size);
la = (Lamp *)ob->data;
la->type = type;
@@ -1070,7 +1084,7 @@ static int collection_instance_add_exec(bContext *C, wmOperator *op)
const int mval[2] = {event->x - ar->winrct.xmin,
event->y - ar->winrct.ymin};
ED_object_location_from_view(C, loc);
- ED_view3d_cursor3d_position(C, loc, mval);
+ ED_view3d_cursor3d_position(C, mval, false, loc);
RNA_float_set_array(op->ptr, "location", loc);
}
}
@@ -1097,8 +1111,6 @@ static int collection_instance_add_exec(bContext *C, wmOperator *op)
/* works without this except if you try render right after, see: 22027 */
DEG_relations_tag_update(bmain);
- DEG_id_tag_update(&collection->id, 0);
-
DEG_id_tag_update(&scene->id, DEG_TAG_SELECT_UPDATE);
WM_event_add_notifier(C, NC_SCENE | ND_OB_ACTIVE, scene);
@@ -2002,9 +2014,6 @@ static int convert_exec(bContext *C, wmOperator *op)
}
FOREACH_SCENE_OBJECT_END;
}
-
- /* delete object should renew depsgraph */
- DEG_relations_tag_update(bmain);
}
// XXX ED_object_editmode_enter(C, 0);
@@ -2079,7 +2088,7 @@ static Base *object_add_duplicate_internal(Main *bmain, Scene *scene, ViewLayer
DEG_id_tag_update(&obn->id, OB_RECALC_OB | OB_RECALC_DATA);
base = BKE_view_layer_base_find(view_layer, ob);
- if ((base != NULL) && (base->flag & BASE_VISIBLED)) {
+ if ((base != NULL) && (base->flag & BASE_VISIBLE)) {
BKE_collection_object_add_from(bmain, scene, ob, obn);
}
else {
@@ -2426,7 +2435,7 @@ static int add_named_exec(bContext *C, wmOperator *op)
const int mval[2] = {event->x - ar->winrct.xmin,
event->y - ar->winrct.ymin};
ED_object_location_from_view(C, basen->object->loc);
- ED_view3d_cursor3d_position(C, basen->object->loc, mval);
+ ED_view3d_cursor3d_position(C, mval, false, basen->object->loc);
}
ED_object_base_select(basen, BA_SELECT);
diff --git a/source/blender/editors/object/object_bake.c b/source/blender/editors/object/object_bake.c
index a8da5c038b4..8ad0d09a9fb 100644
--- a/source/blender/editors/object/object_bake.c
+++ b/source/blender/editors/object/object_bake.c
@@ -118,6 +118,7 @@ typedef struct MultiresBakerJobData {
/* data passing to multires-baker job */
typedef struct {
+ Scene *scene;
ListBase data;
bool bake_clear; /* Clear the images before baking */
int bake_filter; /* Bake-filter, aka margin */
@@ -241,7 +242,7 @@ static DerivedMesh *multiresbake_create_loresdm(Scene *scene, Object *ob, int *l
tmp_mmd.lvl = *lvl;
tmp_mmd.sculptlvl = *lvl;
- dm = multires_make_derived_from_derived(cddm, &tmp_mmd, ob, 0);
+ dm = multires_make_derived_from_derived(cddm, &tmp_mmd, scene, ob, 0);
cddm->release(cddm);
return dm;
@@ -268,7 +269,7 @@ static DerivedMesh *multiresbake_create_hiresdm(Scene *scene, Object *ob, int *l
tmp_mmd.lvl = mmd->totlvl;
tmp_mmd.sculptlvl = mmd->totlvl;
- dm = multires_make_derived_from_derived(cddm, &tmp_mmd, ob, 0);
+ dm = multires_make_derived_from_derived(cddm, &tmp_mmd, scene, ob, 0);
cddm->release(cddm);
return dm;
@@ -371,6 +372,7 @@ static int multiresbake_image_exec_locked(bContext *C, wmOperator *op)
multires_force_update(ob);
/* copy data stored in job descriptor */
+ bkr.scene = scene;
bkr.bake_filter = scene->r.bake_filter;
bkr.mode = scene->r.bake_mode;
bkr.use_lores_mesh = scene->r.bake_flag & R_BAKE_LORES_MESH;
@@ -413,6 +415,7 @@ static void init_multiresbake_job(bContext *C, MultiresBakeJob *bkj)
Object *ob;
/* backup scene settings, so their changing in UI would take no effect on baker */
+ bkj->scene = scene;
bkj->bake_filter = scene->r.bake_filter;
bkj->mode = scene->r.bake_mode;
bkj->use_lores_mesh = scene->r.bake_flag & R_BAKE_LORES_MESH;
@@ -474,6 +477,7 @@ static void multiresbake_startjob(void *bkv, short *stop, short *do_update, floa
MultiresBakeRender bkr = {NULL};
/* copy data stored in job descriptor */
+ bkr.scene = bkj->scene;
bkr.bake_filter = bkj->bake_filter;
bkr.mode = bkj->mode;
bkr.use_lores_mesh = bkj->use_lores_mesh;
diff --git a/source/blender/editors/object/object_data_transfer.c b/source/blender/editors/object/object_data_transfer.c
index db81c51cc90..788f0826848 100644
--- a/source/blender/editors/object/object_data_transfer.c
+++ b/source/blender/editors/object/object_data_transfer.c
@@ -40,7 +40,6 @@
#include "BKE_context.h"
#include "BKE_data_transfer.h"
-#include "BKE_DerivedMesh.h"
#include "BKE_mesh_mapping.h"
#include "BKE_mesh_remap.h"
#include "BKE_mesh_runtime.h"
@@ -137,20 +136,17 @@ static const EnumPropertyItem *dt_layers_select_src_itemf(
Scene *scene = CTX_data_scene(C);
if (ob_src) {
- DerivedMesh *dm_src;
- CustomData *ldata;
+ Mesh *me_eval;
int num_data, i;
- /* XXX Is this OK? */
- dm_src = mesh_get_derived_final(depsgraph, scene, ob_src, CD_MASK_BAREMESH | CD_MLOOPUV);
- ldata = dm_src->getLoopDataLayout(dm_src);
- num_data = CustomData_number_of_layers(ldata, CD_MLOOPUV);
+ me_eval = mesh_get_eval_final(depsgraph, scene, ob_src, CD_MASK_BAREMESH | CD_MLOOPUV);
+ num_data = CustomData_number_of_layers(&me_eval->ldata, CD_MLOOPUV);
RNA_enum_item_add_separator(&item, &totitem);
for (i = 0; i < num_data; i++) {
tmp_item.value = i;
- tmp_item.identifier = tmp_item.name = CustomData_get_layer_name(ldata, CD_MLOOPUV, i);
+ tmp_item.identifier = tmp_item.name = CustomData_get_layer_name(&me_eval->ldata, CD_MLOOPUV, i);
RNA_enum_item_add(&item, &totitem, &tmp_item);
}
}
@@ -160,20 +156,17 @@ static const EnumPropertyItem *dt_layers_select_src_itemf(
Scene *scene = CTX_data_scene(C);
if (ob_src) {
- DerivedMesh *dm_src;
- CustomData *ldata;
+ Mesh *me_eval;
int num_data, i;
- /* XXX Is this OK? */
- dm_src = mesh_get_derived_final(depsgraph, scene, ob_src, CD_MASK_BAREMESH | CD_MLOOPCOL);
- ldata = dm_src->getLoopDataLayout(dm_src);
- num_data = CustomData_number_of_layers(ldata, CD_MLOOPCOL);
+ me_eval = mesh_get_eval_final(depsgraph, scene, ob_src, CD_MASK_BAREMESH | CD_MLOOPCOL);
+ num_data = CustomData_number_of_layers(&me_eval->ldata, CD_MLOOPCOL);
RNA_enum_item_add_separator(&item, &totitem);
for (i = 0; i < num_data; i++) {
tmp_item.value = i;
- tmp_item.identifier = tmp_item.name = CustomData_get_layer_name(ldata, CD_MLOOPCOL, i);
+ tmp_item.identifier = tmp_item.name = CustomData_get_layer_name(&me_eval->ldata, CD_MLOOPCOL, i);
RNA_enum_item_add(&item, &totitem, &tmp_item);
}
}
diff --git a/source/blender/editors/object/object_edit.c b/source/blender/editors/object/object_edit.c
index 45ad4bfd196..e14842c0daa 100644
--- a/source/blender/editors/object/object_edit.c
+++ b/source/blender/editors/object/object_edit.c
@@ -146,6 +146,238 @@ Object *ED_object_active_context(bContext *C)
return ob;
}
+/* ********************** object hiding *************************** */
+
+static int object_hide_poll(bContext *C)
+{
+ if (CTX_wm_space_outliner(C) != NULL) {
+ return ED_outliner_collections_editor_poll(C);
+ }
+ else {
+ return ED_operator_view3d_active(C);
+ }
+}
+
+static int object_hide_view_clear_exec(bContext *C, wmOperator *op)
+{
+ Scene *scene = CTX_data_scene(C);
+ ViewLayer *view_layer = CTX_data_view_layer(C);
+ const bool select = RNA_boolean_get(op->ptr, "select");
+ bool changed = false;
+
+ for (Base *base = view_layer->object_bases.first; base; base = base->next) {
+ if (base->flag & BASE_HIDDEN) {
+ base->flag &= ~BASE_HIDDEN;
+ changed = true;
+
+ if (select) {
+ ED_object_base_select(base, BA_SELECT);
+ }
+ }
+ }
+
+ if (!changed) {
+ return OPERATOR_CANCELLED;
+ }
+
+ BKE_layer_collection_sync(scene, view_layer);
+ DEG_id_tag_update(&scene->id, DEG_TAG_BASE_FLAGS_UPDATE);
+ WM_event_add_notifier(C, NC_SCENE | ND_OB_SELECT, scene);
+
+ return OPERATOR_FINISHED;
+}
+
+void OBJECT_OT_hide_view_clear(wmOperatorType *ot)
+{
+ /* identifiers */
+ ot->name = "Show Hidden Objects";
+ ot->description = "Reveal temporarily hidden objects";
+ ot->idname = "OBJECT_OT_hide_view_clear";
+
+ /* api callbacks */
+ ot->exec = object_hide_view_clear_exec;
+ ot->poll = object_hide_poll;
+
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+
+ PropertyRNA *prop = RNA_def_boolean(ot->srna, "select", false, "Select", "");
+ RNA_def_property_flag(prop, PROP_SKIP_SAVE | PROP_HIDDEN);
+}
+
+static int object_hide_view_set_exec(bContext *C, wmOperator *op)
+{
+ Scene *scene = CTX_data_scene(C);
+ ViewLayer *view_layer = CTX_data_view_layer(C);
+ const bool unselected = RNA_boolean_get(op->ptr, "unselected");
+
+ /* Do nothing if no objects was selected. */
+ bool have_selected = false;
+ for (Base *base = view_layer->object_bases.first; base; base = base->next) {
+ if (base->flag & BASE_VISIBLE) {
+ if (base->flag & BASE_SELECTED) {
+ have_selected = true;
+ break;
+ }
+ }
+ }
+
+ if (!have_selected) {
+ return OPERATOR_CANCELLED;
+ }
+
+ /* Hide selected or unselected objects. */
+ for (Base *base = view_layer->object_bases.first; base; base = base->next) {
+ if (!(base->flag & BASE_VISIBLE)) {
+ continue;
+ }
+
+ if (!unselected) {
+ if (base->flag & BASE_SELECTED) {
+ ED_object_base_select(base, BA_DESELECT);
+ base->flag |= BASE_HIDDEN;
+ }
+ }
+ else {
+ if (!(base->flag & BASE_SELECTED)) {
+ ED_object_base_select(base, BA_DESELECT);
+ base->flag |= BASE_HIDDEN;
+ }
+ }
+ }
+
+ BKE_layer_collection_sync(scene, view_layer);
+ DEG_id_tag_update(&scene->id, DEG_TAG_BASE_FLAGS_UPDATE);
+ WM_event_add_notifier(C, NC_SCENE | ND_OB_SELECT, scene);
+
+ return OPERATOR_FINISHED;
+}
+
+void OBJECT_OT_hide_view_set(wmOperatorType *ot)
+{
+ /* identifiers */
+ ot->name = "Hide Objects";
+ ot->description = "Temporarily hide objects from the viewport";
+ ot->idname = "OBJECT_OT_hide_view_set";
+
+ /* api callbacks */
+ ot->exec = object_hide_view_set_exec;
+ ot->poll = object_hide_poll;
+
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+
+ PropertyRNA *prop;
+ prop = RNA_def_boolean(ot->srna, "unselected", 0, "Unselected", "Hide unselected rather than selected objects");
+ RNA_def_property_flag(prop, PROP_SKIP_SAVE | PROP_HIDDEN);
+}
+
+static int object_hide_collection_exec(bContext *C, wmOperator *op)
+{
+ int index = RNA_int_get(op->ptr, "collection_index");
+ bool extend = (CTX_wm_window(C)->eventstate->shift != 0);
+
+ if (CTX_wm_window(C)->eventstate->alt != 0) {
+ index += 10;
+ }
+
+ Scene *scene = CTX_data_scene(C);
+ ViewLayer *view_layer = CTX_data_view_layer(C);
+ LayerCollection *lc = BKE_layer_collection_from_index(view_layer, index);
+
+ if (!lc) {
+ return OPERATOR_CANCELLED;
+ }
+
+ BKE_layer_collection_set_visible(scene, view_layer, lc, extend);
+
+ DEG_id_tag_update(&scene->id, DEG_TAG_BASE_FLAGS_UPDATE);
+ WM_event_add_notifier(C, NC_SCENE | ND_OB_SELECT, scene);
+
+ return OPERATOR_FINISHED;
+}
+
+#define COLLECTION_INVALID_INDEX -1
+
+void ED_hide_collections_menu_draw(const bContext *C, uiLayout *layout)
+{
+ ViewLayer *view_layer = CTX_data_view_layer(C);
+ LayerCollection *lc_scene = view_layer->layer_collections.first;
+
+ uiLayoutSetOperatorContext(layout, WM_OP_EXEC_REGION_WIN);
+
+ for (LayerCollection *lc = lc_scene->layer_collections.first; lc; lc = lc->next) {
+ int index = BKE_layer_collection_findindex(view_layer, lc);
+ uiLayout *row = uiLayoutRow(layout, false);
+
+ if (lc->collection->flag & COLLECTION_RESTRICT_VIEW) {
+ continue;
+ }
+
+ if ((view_layer->runtime_flag & VIEW_LAYER_HAS_HIDE) &&
+ !(lc->runtime_flag & LAYER_COLLECTION_HAS_VISIBLE_OBJECTS))
+ {
+ uiLayoutSetActive(row, false);
+ }
+
+ int icon = ICON_NONE;
+ if (BKE_layer_collection_has_selected_objects(view_layer, lc)) {
+ icon = ICON_LAYER_ACTIVE;
+ }
+ else if (lc->runtime_flag & LAYER_COLLECTION_HAS_OBJECTS) {
+ icon = ICON_LAYER_USED;
+ }
+
+ uiItemIntO(row,
+ lc->collection->id.name + 2,
+ icon,
+ "OBJECT_OT_hide_collection",
+ "collection_index",
+ index);
+ }
+}
+
+static int object_hide_collection_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
+{
+ /* Immediately execute if collection index was specified. */
+ int index = RNA_int_get(op->ptr, "collection_index");
+ if (index != COLLECTION_INVALID_INDEX) {
+ return object_hide_collection_exec(C, op);
+ }
+
+ /* Open popup menu. */
+ const char *title = CTX_IFACE_(op->type->translation_context, op->type->name);
+ uiPopupMenu *pup = UI_popup_menu_begin(C, title, ICON_GROUP);
+ uiLayout *layout = UI_popup_menu_layout(pup);
+
+ ED_hide_collections_menu_draw(C, layout);
+
+ UI_popup_menu_end(C, pup);
+
+ return OPERATOR_INTERFACE;
+}
+
+void OBJECT_OT_hide_collection(wmOperatorType *ot)
+{
+ /* identifiers */
+ ot->name = "Hide Objects By Collection";
+ ot->description = "Show only objects in collection (Shift to extend)";
+ ot->idname = "OBJECT_OT_hide_collection";
+
+ /* api callbacks */
+ ot->exec = object_hide_collection_exec;
+ ot->invoke = object_hide_collection_invoke;
+ ot->poll = ED_operator_view3d_active;
+
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+
+ /* Properties. */
+ PropertyRNA *prop;
+ prop = RNA_def_int(ot->srna, "collection_index", COLLECTION_INVALID_INDEX, COLLECTION_INVALID_INDEX, INT_MAX,
+ "Collection Index", "Index of the collection to change visibility", 0, INT_MAX);
+ RNA_def_property_flag(prop, PROP_SKIP_SAVE | PROP_HIDDEN);
+}
/* ******************* toggle editmode operator ***************** */
@@ -654,7 +886,6 @@ static void copy_attr(Main *bmain, Scene *scene, ViewLayer *view_layer, short ev
Base *base;
Curve *cu, *cu1;
Nurb *nu;
- bool do_depgraph_update = false;
if (ID_IS_LINKED(scene)) return;
@@ -811,8 +1042,8 @@ static void copy_attr(Main *bmain, Scene *scene, ViewLayer *view_layer, short ev
else if (event == 22) {
/* Copy the constraint channels over */
BKE_constraints_copy(&base->object->constraints, &ob->constraints, true);
-
- do_depgraph_update = true;
+ DEG_id_tag_update(&base->object->id, DEG_TAG_COPY_ON_WRITE);
+ DEG_relations_tag_update(bmain);
}
else if (event == 23) {
base->object->softflag = ob->softflag;
@@ -823,6 +1054,9 @@ static void copy_attr(Main *bmain, Scene *scene, ViewLayer *view_layer, short ev
if (!modifiers_findByType(base->object, eModifierType_Softbody)) {
BLI_addhead(&base->object->modifiers, modifier_new(eModifierType_Softbody));
}
+
+ DEG_id_tag_update(&base->object->id, DEG_TAG_COPY_ON_WRITE);
+ DEG_relations_tag_update(bmain);
}
else if (event == 26) {
#if 0 // XXX old animation system
@@ -863,9 +1097,6 @@ static void copy_attr(Main *bmain, Scene *scene, ViewLayer *view_layer, short ev
}
}
}
-
- if (do_depgraph_update)
- DEG_relations_tag_update(bmain);
}
static void UNUSED_FUNCTION(copy_attr_menu) (Main *bmain, Scene *scene, ViewLayer *view_layer, Object *obedit)
@@ -1548,8 +1779,6 @@ bool ED_object_editmode_calc_active_center(Object *obedit, const bool select_onl
return false;
}
-#define COLLECTION_INVALID_INDEX -1
-
static int move_to_collection_poll(bContext *C)
{
if (CTX_wm_space_outliner(C) != NULL) {
@@ -1630,7 +1859,7 @@ static int move_to_collection_exec(bContext *C, wmOperator *op)
is_link ? "linked" : "moved",
collection->id.name + 2);
- DEG_relations_tag_update(CTX_data_main(C));
+ DEG_relations_tag_update(bmain);
DEG_id_tag_update(&scene->id, DEG_TAG_COPY_ON_WRITE | DEG_TAG_SELECT_UPDATE);
WM_event_add_notifier(C, NC_SCENE | ND_LAYER, scene);
@@ -1869,5 +2098,3 @@ void OBJECT_OT_link_to_collection(wmOperatorType *ot)
"Name of the newly added collection");
RNA_def_property_flag(prop, PROP_SKIP_SAVE);
}
-
-#undef COLLECTION_INVALID_INDEX
diff --git a/source/blender/editors/object/object_group.c b/source/blender/editors/object/object_group.c
index 8a52b6c5ef5..53cabe3759e 100644
--- a/source/blender/editors/object/object_group.c
+++ b/source/blender/editors/object/object_group.c
@@ -47,6 +47,7 @@
#include "BKE_report.h"
#include "BKE_object.h"
+#include "DEG_depsgraph.h"
#include "DEG_depsgraph_build.h"
#include "ED_screen.h"
@@ -153,6 +154,7 @@ static int objects_add_active_exec(bContext *C, wmOperator *op)
if (!BKE_collection_object_cyclic_check(bmain, base->object, collection)) {
BKE_collection_object_add(bmain, collection, base->object);
+ DEG_id_tag_update(&collection->id, DEG_TAG_COPY_ON_WRITE);
updated = true;
}
else {
@@ -223,6 +225,7 @@ static int objects_remove_active_exec(bContext *C, wmOperator *op)
CTX_DATA_BEGIN (C, Base *, base, selected_editable_bases)
{
BKE_collection_object_remove(bmain, collection, base->object, false);
+ DEG_id_tag_update(&collection->id, DEG_TAG_COPY_ON_WRITE);
ok = 1;
}
CTX_DATA_END;
@@ -315,6 +318,7 @@ static int collection_objects_remove_exec(bContext *C, wmOperator *op)
CTX_DATA_BEGIN (C, Base *, base, selected_editable_bases)
{
BKE_collection_object_remove(bmain, collection, base->object, false);
+ DEG_id_tag_update(&collection->id, DEG_TAG_COPY_ON_WRITE);
updated = true;
}
CTX_DATA_END;
@@ -366,6 +370,7 @@ static int collection_create_exec(bContext *C, wmOperator *op)
CTX_DATA_BEGIN (C, Base *, base, selected_bases)
{
BKE_collection_object_add(bmain, collection, base->object);
+ DEG_id_tag_update(&collection->id, DEG_TAG_COPY_ON_WRITE);
}
CTX_DATA_END;
@@ -555,7 +560,7 @@ static int select_grouped_exec(bContext *C, wmOperator *UNUSED(op)) /* Select o
CTX_DATA_BEGIN (C, Base *, base, visible_bases)
{
- if (((base->flag & BASE_SELECTED) == 0) && ((base->flag & BASE_SELECTABLED) != 0)) {
+ if (((base->flag & BASE_SELECTED) == 0) && ((base->flag & BASE_SELECTABLE) != 0)) {
if (BKE_collection_has_object_recursive(collection, base->object)) {
ED_object_base_select(base, BA_SELECT);
}
diff --git a/source/blender/editors/object/object_intern.h b/source/blender/editors/object/object_intern.h
index 18251a25b73..f7179912f52 100644
--- a/source/blender/editors/object/object_intern.h
+++ b/source/blender/editors/object/object_intern.h
@@ -76,6 +76,9 @@ void OBJECT_OT_drop_named_material(struct wmOperatorType *ot);
void OBJECT_OT_unlink_data(struct wmOperatorType *ot);
/* object_edit.c */
+void OBJECT_OT_hide_view_set(struct wmOperatorType *ot);
+void OBJECT_OT_hide_view_clear(struct wmOperatorType *ot);
+void OBJECT_OT_hide_collection(struct wmOperatorType *ot);
void OBJECT_OT_mode_set(struct wmOperatorType *ot);
void OBJECT_OT_mode_set_or_submode(struct wmOperatorType *ot);
void OBJECT_OT_editmode_toggle(struct wmOperatorType *ot);
diff --git a/source/blender/editors/object/object_modifier.c b/source/blender/editors/object/object_modifier.c
index 425a0acff17..9d7ca44ce16 100644
--- a/source/blender/editors/object/object_modifier.c
+++ b/source/blender/editors/object/object_modifier.c
@@ -324,8 +324,6 @@ static bool object_modifier_remove(Main *bmain, Object *ob, ModifierData *md,
ob->mode &= ~OB_MODE_PARTICLE_EDIT;
}
- DEG_relations_tag_update(bmain);
-
BLI_remlink(&ob->modifiers, md);
modifier_free(md);
BKE_object_free_derived_caches(ob);
@@ -529,9 +527,7 @@ static int modifier_apply_shape(
{
const ModifierTypeInfo *mti = modifierType_getInfo(md->type);
- md->scene = scene;
-
- if (mti->isDisabled && mti->isDisabled(md, 0)) {
+ if (mti->isDisabled && mti->isDisabled(scene, md, 0)) {
BKE_report(reports, RPT_ERROR, "Modifier is disabled, skipping apply");
return 0;
}
@@ -570,7 +566,7 @@ static int modifier_apply_shape(
/* if that was the first key block added, then it was the basis.
* Initialize it with the mesh, and add another for the modifier */
kb = BKE_keyblock_add(key, NULL);
- BKE_keyblock_convert_from_mesh(me, kb);
+ BKE_keyblock_convert_from_mesh(me, key, kb);
}
kb = BKE_keyblock_add(key, md->name);
@@ -589,9 +585,7 @@ static int modifier_apply_obdata(ReportList *reports, Depsgraph *depsgraph, Scen
{
const ModifierTypeInfo *mti = modifierType_getInfo(md->type);
- md->scene = scene;
-
- if (mti->isDisabled && mti->isDisabled(md, 0)) {
+ if (mti->isDisabled && mti->isDisabled(scene, md, 0)) {
BKE_report(reports, RPT_ERROR, "Modifier is disabled, skipping apply");
return 0;
}
@@ -1156,13 +1150,14 @@ static int multires_poll(bContext *C)
static int multires_higher_levels_delete_exec(bContext *C, wmOperator *op)
{
+ Scene *scene = CTX_data_scene(C);
Object *ob = ED_object_active_context(C);
MultiresModifierData *mmd = (MultiresModifierData *)edit_modifier_property_get(op, ob, eModifierType_Multires);
if (!mmd)
return OPERATOR_CANCELLED;
- multiresModifier_del_levels(mmd, ob, 1);
+ multiresModifier_del_levels(mmd, scene, ob, 1);
ED_object_iter_other(CTX_data_main(C), ob, true,
ED_object_multires_update_totlevels_cb,
@@ -1200,13 +1195,14 @@ void OBJECT_OT_multires_higher_levels_delete(wmOperatorType *ot)
static int multires_subdivide_exec(bContext *C, wmOperator *op)
{
+ Scene *scene = CTX_data_scene(C);
Object *ob = ED_object_active_context(C);
MultiresModifierData *mmd = (MultiresModifierData *)edit_modifier_property_get(op, ob, eModifierType_Multires);
if (!mmd)
return OPERATOR_CANCELLED;
- multiresModifier_subdivide(mmd, ob, 0, mmd->simple);
+ multiresModifier_subdivide(mmd, scene, ob, 0, mmd->simple);
ED_object_iter_other(CTX_data_main(C), ob, true,
ED_object_multires_update_totlevels_cb,
@@ -1423,13 +1419,14 @@ void OBJECT_OT_multires_external_pack(wmOperatorType *ot)
/********************* multires apply base ***********************/
static int multires_base_apply_exec(bContext *C, wmOperator *op)
{
+ Scene *scene = CTX_data_scene(C);
Object *ob = ED_object_active_context(C);
MultiresModifierData *mmd = (MultiresModifierData *)edit_modifier_property_get(op, ob, eModifierType_Multires);
if (!mmd)
return OPERATOR_CANCELLED;
- multiresModifier_base_apply(mmd, ob);
+ multiresModifier_base_apply(mmd, scene, ob);
DEG_id_tag_update(&ob->id, OB_RECALC_DATA);
WM_event_add_notifier(C, NC_OBJECT | ND_MODIFIER, ob);
diff --git a/source/blender/editors/object/object_ops.c b/source/blender/editors/object/object_ops.c
index c5df7fc21f8..89dd54b6f64 100644
--- a/source/blender/editors/object/object_ops.c
+++ b/source/blender/editors/object/object_ops.c
@@ -247,6 +247,10 @@ void ED_operatortypes_object(void)
WM_operatortype_append(OBJECT_OT_data_transfer);
WM_operatortype_append(OBJECT_OT_datalayout_transfer);
WM_operatortype_append(OBJECT_OT_surfacedeform_bind);
+
+ WM_operatortype_append(OBJECT_OT_hide_view_clear);
+ WM_operatortype_append(OBJECT_OT_hide_view_set);
+ WM_operatortype_append(OBJECT_OT_hide_collection);
}
void ED_operatormacros_object(void)
@@ -293,7 +297,7 @@ void ED_keymap_object(wmKeyConfig *keyconf)
RNA_enum_set(kmi->ptr, "mode", OB_MODE_EDIT);
RNA_boolean_set(kmi->ptr, "toggle", true);
- kmi = WM_keymap_add_menu_pie(keymap, "VIEW3D_PIE_object_mode", TABKEY, KM_CLICK_DRAG, 0, 0);
+ kmi = WM_keymap_add_menu_pie(keymap, "VIEW3D_MT_object_mode_pie", TABKEY, KM_CLICK_DRAG, 0, 0);
WM_keymap_add_item(keymap, "OBJECT_OT_origin_set", CKEY, KM_PRESS, KM_ALT | KM_SHIFT | KM_CTRL, 0);
@@ -404,6 +408,19 @@ void ED_keymap_object(wmKeyConfig *keyconf)
WM_keymap_add_item(keymap, "OBJECT_OT_move_to_collection", MKEY, KM_PRESS, 0, 0);
WM_keymap_add_item(keymap, "OBJECT_OT_link_to_collection", MKEY, KM_PRESS, KM_SHIFT, 0);
+
+ kmi = WM_keymap_add_item(keymap, "OBJECT_OT_hide_view_clear", HKEY, KM_PRESS, KM_ALT, 0);
+ kmi = WM_keymap_add_item(keymap, "OBJECT_OT_hide_view_set", HKEY, KM_PRESS, 0, 0);
+ RNA_boolean_set(kmi->ptr, "unselected", false);
+ kmi = WM_keymap_add_item(keymap, "OBJECT_OT_hide_view_set", HKEY, KM_PRESS, KM_SHIFT, 0);
+ RNA_boolean_set(kmi->ptr, "unselected", true);
+ kmi = WM_keymap_add_item(keymap, "OBJECT_OT_hide_collection", HKEY, KM_PRESS, KM_CTRL, 0);
+
+ /* Collection switching. */
+ for (int i = 0; i < 10; i++) {
+ kmi = WM_keymap_add_item(keymap, "OBJECT_OT_hide_collection", ZEROKEY + i, KM_PRESS, KM_ANY, 0);
+ RNA_int_set(kmi->ptr, "collection_index", (i == 0) ? 10 : i);
+ }
}
void ED_keymap_proportional_cycle(struct wmKeyConfig *UNUSED(keyconf), struct wmKeyMap *keymap)
diff --git a/source/blender/editors/object/object_relations.c b/source/blender/editors/object/object_relations.c
index a114b2cc6d5..f2e996237cf 100644
--- a/source/blender/editors/object/object_relations.c
+++ b/source/blender/editors/object/object_relations.c
@@ -1419,6 +1419,7 @@ static bool allow_make_links_data(const int type, Object *ob_src, Object *ob_dst
static int make_links_data_exec(bContext *C, wmOperator *op)
{
+ Scene *scene = CTX_data_scene(C);
Main *bmain = CTX_data_main(C);
const int type = RNA_enum_get(op->ptr, "type");
Object *ob_src;
@@ -1503,7 +1504,7 @@ static int make_links_data_exec(bContext *C, wmOperator *op)
}
break;
case MAKE_LINKS_MODIFIERS:
- BKE_object_link_modifiers(ob_dst, ob_src);
+ BKE_object_link_modifiers(scene, ob_dst, ob_src);
DEG_id_tag_update(&ob_dst->id, OB_RECALC_OB | OB_RECALC_DATA | OB_RECALC_TIME);
break;
case MAKE_LINKS_FONTS:
diff --git a/source/blender/editors/object/object_select.c b/source/blender/editors/object/object_select.c
index ce29125ac79..7d7871c0326 100644
--- a/source/blender/editors/object/object_select.c
+++ b/source/blender/editors/object/object_select.c
@@ -100,7 +100,7 @@ void ED_object_base_select(Base *base, eObjectSelect_Mode mode)
if (base) {
switch (mode) {
case BA_SELECT:
- if ((base->flag & BASE_SELECTABLED) != 0) {
+ if ((base->flag & BASE_SELECTABLE) != 0) {
base->flag |= BASE_SELECTED;
}
break;
@@ -229,7 +229,7 @@ static bool object_select_all_by_obdata(bContext *C, void *obdata)
CTX_DATA_BEGIN (C, Base *, base, visible_bases)
{
- if (((base->flag & BASE_SELECTED) == 0) && ((base->flag & BASE_SELECTABLED) != 0)) {
+ if (((base->flag & BASE_SELECTED) == 0) && ((base->flag & BASE_SELECTABLE) != 0)) {
if (base->object->data == obdata) {
ED_object_base_select(base, BA_SELECT);
changed = true;
@@ -247,7 +247,7 @@ static bool object_select_all_by_material(bContext *C, Material *mat)
CTX_DATA_BEGIN (C, Base *, base, visible_bases)
{
- if (((base->flag & BASE_SELECTED) == 0) && ((base->flag & BASE_SELECTABLED) != 0)) {
+ if (((base->flag & BASE_SELECTED) == 0) && ((base->flag & BASE_SELECTABLE) != 0)) {
Object *ob = base->object;
Material *mat1;
int a;
@@ -274,7 +274,7 @@ static bool object_select_all_by_dup_group(bContext *C, Object *ob)
CTX_DATA_BEGIN (C, Base *, base, visible_bases)
{
- if (((base->flag & BASE_SELECTED) == 0) && ((base->flag & BASE_SELECTABLED) != 0)) {
+ if (((base->flag & BASE_SELECTED) == 0) && ((base->flag & BASE_SELECTABLE) != 0)) {
Collection *dup_group_other = (base->object->transflag & OB_DUPLICOLLECTION) ? base->object->dup_group : NULL;
if (dup_group == dup_group_other) {
ED_object_base_select(base, BA_SELECT);
@@ -294,7 +294,7 @@ static bool object_select_all_by_particle(bContext *C, Object *ob)
CTX_DATA_BEGIN (C, Base *, base, visible_bases)
{
- if (((base->flag & BASE_SELECTED) == 0) && ((base->flag & BASE_SELECTABLED) != 0)) {
+ if (((base->flag & BASE_SELECTED) == 0) && ((base->flag & BASE_SELECTABLE) != 0)) {
/* loop through other particles*/
ParticleSystem *psys;
@@ -322,7 +322,7 @@ static bool object_select_all_by_library(bContext *C, Library *lib)
CTX_DATA_BEGIN (C, Base *, base, visible_bases)
{
- if (((base->flag & BASE_SELECTED) == 0) && ((base->flag & BASE_SELECTABLED) != 0)) {
+ if (((base->flag & BASE_SELECTED) == 0) && ((base->flag & BASE_SELECTABLE) != 0)) {
if (lib == base->object->id.lib) {
ED_object_base_select(base, BA_SELECT);
changed = true;
@@ -340,7 +340,7 @@ static bool object_select_all_by_library_obdata(bContext *C, Library *lib)
CTX_DATA_BEGIN (C, Base *, base, visible_bases)
{
- if (((base->flag & BASE_SELECTED) == 0) && ((base->flag & BASE_SELECTABLED) != 0)) {
+ if (((base->flag & BASE_SELECTED) == 0) && ((base->flag & BASE_SELECTABLE) != 0)) {
if (base->object->data && lib == ((ID *)base->object->data)->lib) {
ED_object_base_select(base, BA_SELECT);
changed = true;
@@ -568,7 +568,7 @@ static bool select_grouped_collection(bContext *C, Object *ob) /* Select object
collection = ob_collections[0];
CTX_DATA_BEGIN (C, Base *, base, visible_bases)
{
- if (((base->flag & BASE_SELECTED) == 0) && ((base->flag & BASE_SELECTABLED) != 0)) {
+ if (((base->flag & BASE_SELECTED) == 0) && ((base->flag & BASE_SELECTABLE) != 0)) {
if (BKE_collection_has_object(collection, base->object)) {
ED_object_base_select(base, BA_SELECT);
changed = true;
@@ -931,7 +931,7 @@ static int object_select_same_collection_exec(bContext *C, wmOperator *op)
CTX_DATA_BEGIN (C, Base *, base, visible_bases)
{
- if (((base->flag & BASE_SELECTED) == 0) && ((base->flag & BASE_SELECTABLED) != 0)) {
+ if (((base->flag & BASE_SELECTED) == 0) && ((base->flag & BASE_SELECTABLE) != 0)) {
if (BKE_collection_has_object(collection, base->object)) {
ED_object_base_select(base, BA_SELECT);
}
diff --git a/source/blender/editors/physics/particle_edit.c b/source/blender/editors/physics/particle_edit.c
index e926540408e..cfdeeffc434 100644
--- a/source/blender/editors/physics/particle_edit.c
+++ b/source/blender/editors/physics/particle_edit.c
@@ -410,6 +410,8 @@ typedef struct PEData {
BVHTreeFromMesh shape_bvh;
Depsgraph *depsgraph;
+ RNG *rng;
+
const int *mval;
rcti *rect;
float rad;
@@ -484,6 +486,22 @@ static void PE_free_shape_tree(PEData *data)
free_bvhtree_from_mesh(&data->shape_bvh);
}
+static void PE_create_random_generator(PEData *data)
+{
+ uint rng_seed = (uint)(PIL_check_seconds_timer_i() & UINT_MAX);
+ rng_seed ^= GET_UINT_FROM_POINTER(data->ob);
+ rng_seed ^= GET_UINT_FROM_POINTER(data->edit);
+ data->rng = BLI_rng_new(rng_seed);
+}
+
+static void PE_free_random_generator(PEData *data)
+{
+ if (data->rng != NULL) {
+ BLI_rng_free(data->rng);
+ data->rng = NULL;
+ }
+}
+
/*************************** selection utilities *******************************/
static bool key_test_depth(PEData *data, const float co[3], const int screen_co[2])
@@ -2999,7 +3017,7 @@ static void PE_mirror_x(
/* Note: In case psys uses Mesh tessface indices, we mirror final Mesh itself, not orig mesh. Avoids an (impossible)
* mesh -> orig -> mesh tessface indices conversion... */
- mirrorfaces = mesh_get_x_mirror_faces__real_mesh(ob, NULL, use_dm_final_indices ? psmd_eval->mesh_final : NULL);
+ mirrorfaces = mesh_get_x_mirror_faces(ob, NULL, use_dm_final_indices ? psmd_eval->mesh_final : NULL);
if (!edit->mirror_cache)
PE_update_mirror_cache(ob, psys);
@@ -3181,8 +3199,11 @@ static void brush_cut(PEData *data, int pa_index)
int k, cut, keys= (int)pow(2.0, (double)pset->draw_step);
int screen_co[2];
+ BLI_assert(data->rng != NULL);
/* blunt scissors */
- if (BLI_frand() > data->cutfac) return;
+ if (BLI_rng_get_float(data->rng) > data->cutfac) {
+ return;
+ }
/* don't cut hidden */
if (edit->points[pa_index].flag & PEP_HIDE)
@@ -4040,6 +4061,7 @@ static int brush_edit_init(bContext *C, wmOperator *op)
/* cache view depths and settings for re-use */
PE_set_view3d_data(C, &bedit->data);
+ PE_create_random_generator(&bedit->data);
return 1;
}
@@ -4088,7 +4110,7 @@ static void brush_edit_apply(bContext *C, wmOperator *op, PointerRNA *itemptr)
if (((pset->brushtype == PE_BRUSH_ADD) ?
(sqrtf(dx * dx + dy * dy) > pset->brush[PE_BRUSH_ADD].step) : (dx != 0 || dy != 0)) || bedit->first)
{
- PEData data= bedit->data;
+ PEData data = bedit->data;
data.context = C; // TODO(mai): why isnt this set in bedit->data?
view3d_operator_needs_opengl(C);
@@ -4273,6 +4295,7 @@ static void brush_edit_exit(wmOperator *op)
{
BrushEdit *bedit= op->customdata;
+ PE_free_random_generator(&bedit->data);
MEM_freeN(bedit);
}
diff --git a/source/blender/editors/physics/rigidbody_constraint.c b/source/blender/editors/physics/rigidbody_constraint.c
index f62b72679d0..1b6325e31bf 100644
--- a/source/blender/editors/physics/rigidbody_constraint.c
+++ b/source/blender/editors/physics/rigidbody_constraint.c
@@ -94,6 +94,8 @@ bool ED_rigidbody_constraint_add(Main *bmain, Scene *scene, Object *ob, int type
DEG_relations_tag_update(bmain);
DEG_id_tag_update(&ob->id, OB_RECALC_OB);
+ DEG_id_tag_update(&rbw->constraints->id, DEG_TAG_COPY_ON_WRITE);
+
return true;
}
@@ -102,8 +104,10 @@ void ED_rigidbody_constraint_remove(Main *bmain, Scene *scene, Object *ob)
RigidBodyWorld *rbw = BKE_rigidbody_get_world(scene);
BKE_rigidbody_remove_constraint(scene, ob);
- if (rbw)
+ if (rbw) {
BKE_collection_object_remove(bmain, rbw->constraints, ob, false);
+ DEG_id_tag_update(&rbw->constraints->id, DEG_TAG_COPY_ON_WRITE);
+ }
DEG_relations_tag_update(bmain);
DEG_id_tag_update(&ob->id, OB_RECALC_OB);
diff --git a/source/blender/editors/physics/rigidbody_object.c b/source/blender/editors/physics/rigidbody_object.c
index bdfbc47b22f..6ea0212199e 100644
--- a/source/blender/editors/physics/rigidbody_object.c
+++ b/source/blender/editors/physics/rigidbody_object.c
@@ -125,6 +125,7 @@ bool ED_rigidbody_object_add(Main *bmain, Scene *scene, Object *ob, int type, Re
DEG_relations_tag_update(bmain);
DEG_id_tag_update(&ob->id, OB_RECALC_OB);
+ DEG_id_tag_update(&rbw->group->id, DEG_TAG_COPY_ON_WRITE);
return true;
}
diff --git a/source/blender/editors/render/render_internal.c b/source/blender/editors/render/render_internal.c
index 6a5844e323f..1385baa51ad 100644
--- a/source/blender/editors/render/render_internal.c
+++ b/source/blender/editors/render/render_internal.c
@@ -819,7 +819,7 @@ static void screen_render_cancel(bContext *C, wmOperator *op)
static void clean_viewport_memory_base(Base *base)
{
- if ((base->flag & BASE_VISIBLED) == 0) {
+ if ((base->flag & BASE_VISIBLE) == 0) {
return;
}
diff --git a/source/blender/editors/render/render_preview.c b/source/blender/editors/render/render_preview.c
index cdd79f43a72..d47291ca82f 100644
--- a/source/blender/editors/render/render_preview.c
+++ b/source/blender/editors/render/render_preview.c
@@ -176,9 +176,6 @@ typedef struct ShaderPreview {
Main *bmain;
Main *pr_main;
-
- void *gl_context;
- bool gl_context_owner;
} ShaderPreview;
typedef struct IconPreviewSize {
@@ -194,8 +191,6 @@ typedef struct IconPreview {
void *owner;
ID *id;
ListBase sizes;
-
- void *gl_context;
} IconPreview;
/* *************************** Preview for buttons *********************** */
@@ -428,7 +423,7 @@ static Scene *preview_prepare_scene(Main *bmain, Scene *scene, ID *id, int id_ty
(*matar)[actcol] = mat;
}
else if (base->object->type == OB_LAMP) {
- base->flag |= BASE_VISIBLED;
+ base->flag |= BASE_VISIBLE;
}
}
}
@@ -746,10 +741,6 @@ static void shader_preview_render(ShaderPreview *sp, ID *id, int split, int firs
/* set this for all previews, default is react to G.is_break still */
RE_test_break_cb(re, sp, shader_preview_break);
- if (sp->gl_context) {
- RE_gl_context_set(re, sp->gl_context);
- }
-
/* lens adjust */
oldlens = ((Camera *)sce->camera->data)->lens;
if (sizex > sp->sizey)
@@ -869,10 +860,6 @@ static void shader_preview_free(void *customdata)
}
MEM_freeN(sp->lampcopy);
}
- if (sp->gl_context_owner && sp->gl_context) {
- WM_opengl_context_dispose(sp->gl_context);
- sp->gl_context = NULL;
- }
MEM_freeN(sp);
}
@@ -1088,8 +1075,6 @@ static void icon_preview_startjob_all_sizes(void *customdata, short *stop, short
sp->pr_rect = cur_size->rect;
sp->id = ip->id;
sp->bmain = ip->bmain;
- sp->gl_context = ip->gl_context;
- sp->gl_context_owner = false;
if (is_render) {
BLI_assert(ip->id);
@@ -1106,11 +1091,6 @@ static void icon_preview_startjob_all_sizes(void *customdata, short *stop, short
common_preview_startjob(sp, stop, do_update, progress);
shader_preview_free(sp);
}
-
- if (ip->gl_context) {
- WM_opengl_context_dispose(ip->gl_context);
- ip->gl_context = NULL;
- }
}
static void icon_preview_endjob(void *customdata)
@@ -1194,17 +1174,8 @@ void ED_preview_icon_job(const bContext *C, void *owner, ID *id, unsigned int *r
/* render all resolutions from suspended job too */
old_ip = WM_jobs_customdata_get(wm_job);
- if (old_ip) {
+ if (old_ip)
BLI_movelisttolist(&ip->sizes, &old_ip->sizes);
- /* NOTE: This assumes that it will be the same thread
- * that will be used when resuming the job. */
- ip->gl_context = old_ip->gl_context;
- }
-
- if (ip->gl_context == NULL) {
- /* Create context in the main thread. */
- ip->gl_context = WM_opengl_context_create();
- }
/* customdata for preview thread */
ip->bmain = CTX_data_main(C);
@@ -1235,7 +1206,7 @@ void ED_preview_shader_job(const bContext *C, void *owner, ID *id, ID *parent, M
{
Object *ob = CTX_data_active_object(C);
wmJob *wm_job;
- ShaderPreview *sp, *old_sp;
+ ShaderPreview *sp;
Scene *scene = CTX_data_scene(C);
short id_type = GS(id->name);
@@ -1252,21 +1223,6 @@ void ED_preview_shader_job(const bContext *C, void *owner, ID *id, ID *parent, M
WM_JOB_EXCL_RENDER, WM_JOB_TYPE_RENDER_PREVIEW);
sp = MEM_callocN(sizeof(ShaderPreview), "shader preview");
- /* Reuse previous gl context. */
- old_sp = WM_jobs_customdata_get(wm_job);
- if (old_sp) {
- /* NOTE: This assumes that it will be the same thread
- * that will be used when resuming the job. */
- old_sp->gl_context_owner = false; /* Don't free it */
- sp->gl_context = old_sp->gl_context;
- }
-
- if (sp->gl_context == NULL) {
- /* Create context in the main thread. */
- sp->gl_context = WM_opengl_context_create();
- }
- sp->gl_context_owner = true;
-
/* customdata for preview thread */
sp->scene = scene;
sp->depsgraph = CTX_data_depsgraph(C);
diff --git a/source/blender/editors/screen/CMakeLists.txt b/source/blender/editors/screen/CMakeLists.txt
index 29b9971eabb..ee114eba3c5 100644
--- a/source/blender/editors/screen/CMakeLists.txt
+++ b/source/blender/editors/screen/CMakeLists.txt
@@ -47,6 +47,7 @@ set(SRC
screen_draw.c
screen_edit.c
screen_ops.c
+ screen_user_menu.c
screendump.c
workspace_edit.c
workspace_layout_edit.c
diff --git a/source/blender/editors/screen/screen_context.c b/source/blender/editors/screen/screen_context.c
index 864150be9da..f56a27d1bb4 100644
--- a/source/blender/editors/screen/screen_context.c
+++ b/source/blender/editors/screen/screen_context.c
@@ -115,7 +115,7 @@ int ed_screen_context(const bContext *C, const char *member, bContextDataResult
}
else if (CTX_data_equals(member, "selectable_objects")) {
for (Base *base = view_layer->object_bases.first; base; base = base->next) {
- if (((base->flag & BASE_VISIBLED) != 0) && ((base->flag & BASE_SELECTABLED) != 0)) {
+ if (((base->flag & BASE_VISIBLE) != 0) && ((base->flag & BASE_SELECTABLE) != 0)) {
CTX_data_id_list_add(result, &base->object->id);
}
}
@@ -165,7 +165,7 @@ int ed_screen_context(const bContext *C, const char *member, bContextDataResult
}
else if (CTX_data_equals(member, "selectable_bases")) {
for (Base *base = view_layer->object_bases.first; base; base = base->next) {
- if ((base->flag & BASE_SELECTABLED) != 0) {
+ if ((base->flag & BASE_SELECTABLE) != 0) {
CTX_data_list_add(result, &scene->id, &RNA_ObjectBase, base);
}
}
@@ -195,7 +195,7 @@ int ed_screen_context(const bContext *C, const char *member, bContextDataResult
else if (CTX_data_equals(member, "editable_bases")) {
/* Visible + Editable, but not necessarily selected */
for (Base *base = view_layer->object_bases.first; base; base = base->next) {
- if ((base->flag & BASE_VISIBLED) != 0) {
+ if ((base->flag & BASE_VISIBLE) != 0) {
if (0 == BKE_object_is_libdata(base->object)) {
CTX_data_list_add(result, &scene->id, &RNA_ObjectBase, base);
}
diff --git a/source/blender/editors/screen/screen_edit.c b/source/blender/editors/screen/screen_edit.c
index 4d7533d575c..e4de3cdfa38 100644
--- a/source/blender/editors/screen/screen_edit.c
+++ b/source/blender/editors/screen/screen_edit.c
@@ -961,7 +961,7 @@ static void screen_cursor_set(wmWindow *win, const int xy[2])
ScrArea *sa;
for (sa = screen->areabase.first; sa; sa = sa->next)
- if ((az = is_in_area_actionzone(sa, xy)))
+ if ((az = ED_area_actionzone_find_xy(sa, xy)))
break;
if (sa) {
@@ -1003,7 +1003,7 @@ void ED_screen_set_active_region(bContext *C, wmWindow *win, const int xy[2])
ED_screen_areas_iter(win, scr, area_iter) {
if (xy[0] > area_iter->totrct.xmin && xy[0] < area_iter->totrct.xmax) {
if (xy[1] > area_iter->totrct.ymin && xy[1] < area_iter->totrct.ymax) {
- if (is_in_area_actionzone(area_iter, xy) == NULL) {
+ if (ED_area_actionzone_refresh_xy(area_iter, xy) == NULL) {
sa = area_iter;
break;
}
@@ -1073,7 +1073,7 @@ int ED_screen_area_active(const bContext *C)
ScrArea *sa = CTX_wm_area(C);
if (win && sc && sa) {
- AZone *az = is_in_area_actionzone(sa, &win->eventstate->x);
+ AZone *az = ED_area_actionzone_find_xy(sa, &win->eventstate->x);
ARegion *ar;
if (az && az->type == AZONE_REGION)
@@ -1680,6 +1680,7 @@ void ED_update_for_newframe(Main *bmain, Depsgraph *depsgraph)
for (sc = bmain->screen.first; sc; sc = sc->id.next) {
BKE_screen_view3d_scene_sync(sc, scene);
}
+ DEG_id_tag_update(&scene->id, DEG_TAG_COPY_ON_WRITE);
}
#endif
diff --git a/source/blender/editors/screen/screen_intern.h b/source/blender/editors/screen/screen_intern.h
index b02198764e0..2c343fb9d70 100644
--- a/source/blender/editors/screen/screen_intern.h
+++ b/source/blender/editors/screen/screen_intern.h
@@ -67,7 +67,8 @@ ScrEdge *screen_find_active_scredge(
const wmWindow *win, const bScreen *screen,
const int mx, const int my);
-struct AZone *is_in_area_actionzone(ScrArea *sa, const int xy[2]);
+struct AZone *ED_area_actionzone_find_xy(ScrArea *sa, const int xy[2]);
+struct AZone *ED_area_actionzone_refresh_xy(ScrArea *sa, const int xy[2]);
/* screen_context.c */
int ed_screen_context(
diff --git a/source/blender/editors/screen/screen_ops.c b/source/blender/editors/screen/screen_ops.c
index c2dab7e22dd..d74a9ed288c 100644
--- a/source/blender/editors/screen/screen_ops.c
+++ b/source/blender/editors/screen/screen_ops.c
@@ -669,7 +669,7 @@ static void fullscreen_click_rcti_init(rcti *rect, const short x1, const short y
BLI_rcti_init(rect, x, x + icon_size, y, y + icon_size);
}
-AZone *is_in_area_actionzone(ScrArea *sa, const int xy[2])
+static AZone *area_actionzone_refresh_xy(ScrArea *sa, const int xy[2], const bool test_only)
{
AZone *az = NULL;
@@ -677,102 +677,117 @@ AZone *is_in_area_actionzone(ScrArea *sa, const int xy[2])
if (BLI_rcti_isect_pt_v(&az->rect, xy)) {
if (az->type == AZONE_AREA) {
/* no triangle intersect but a hotspot circle based on corner */
- int radius = (xy[0] - az->x1) * (xy[0] - az->x1) + (xy[1] - az->y1) * (xy[1] - az->y1);
-
- if (radius <= AZONESPOT * AZONESPOT)
+ int radius_sq = SQUARE(xy[0] - az->x1) + SQUARE(xy[1] - az->y1);
+ if (radius_sq <= SQUARE(AZONESPOT)) {
break;
+ }
}
else if (az->type == AZONE_REGION) {
break;
}
else if (az->type == AZONE_FULLSCREEN) {
- int mouse_radius, spot_radius, fadein_radius, fadeout_radius;
rcti click_rect;
-
fullscreen_click_rcti_init(&click_rect, az->x1, az->y1, az->x2, az->y2);
+ const bool click_isect = BLI_rcti_isect_pt_v(&click_rect, xy);
- if (BLI_rcti_isect_pt_v(&click_rect, xy)) {
- az->alpha = 1.0f;
+ if (test_only) {
+ if (click_isect) {
+ break;
+ }
}
else {
- mouse_radius = (xy[0] - az->x2) * (xy[0] - az->x2) + (xy[1] - az->y2) * (xy[1] - az->y2);
- spot_radius = AZONESPOT * AZONESPOT;
- fadein_radius = AZONEFADEIN * AZONEFADEIN;
- fadeout_radius = AZONEFADEOUT * AZONEFADEOUT;
-
- if (mouse_radius < spot_radius) {
+ if (click_isect) {
az->alpha = 1.0f;
}
- else if (mouse_radius < fadein_radius) {
- az->alpha = 1.0f;
- }
- else if (mouse_radius < fadeout_radius) {
- az->alpha = 1.0f - ((float)(mouse_radius - fadein_radius)) / ((float)(fadeout_radius - fadein_radius));
- }
else {
- az->alpha = 0.0f;
+ const int mouse_sq = SQUARE(xy[0] - az->x2) + SQUARE(xy[1] - az->y2);
+ const int spot_sq = SQUARE(AZONESPOT);
+ const int fadein_sq = SQUARE(AZONEFADEIN);
+ const int fadeout_sq = SQUARE(AZONEFADEOUT);
+
+ if (mouse_sq < spot_sq) {
+ az->alpha = 1.0f;
+ }
+ else if (mouse_sq < fadein_sq) {
+ az->alpha = 1.0f;
+ }
+ else if (mouse_sq < fadeout_sq) {
+ az->alpha = 1.0f - ((float)(mouse_sq - fadein_sq)) / ((float)(fadeout_sq - fadein_sq));
+ }
+ else {
+ az->alpha = 0.0f;
+ }
+
+ /* fade in/out but no click */
+ az = NULL;
}
- /* fade in/out but no click */
- az = NULL;
+ /* XXX force redraw to show/hide the action zone */
+ ED_area_tag_redraw(sa);
+ break;
}
-
- /* XXX force redraw to show/hide the action zone */
- ED_area_tag_redraw_no_rebuild(sa);
- break;
}
else if (az->type == AZONE_REGION_SCROLL) {
ARegion *ar = az->ar;
View2D *v2d = &ar->v2d;
const short isect_value = UI_view2d_mouse_in_scrollers(ar, v2d, xy[0], xy[1]);
- bool redraw = false;
-
- if (isect_value == 'h') {
- if (az->direction == AZ_SCROLL_HOR) {
- az->alpha = 1.0f;
- v2d->alpha_hor = 255;
- v2d->size_hor = V2D_SCROLL_HEIGHT;
- redraw = true;
- }
- }
- else if (isect_value == 'v') {
- if (az->direction == AZ_SCROLL_VERT) {
- az->alpha = 1.0f;
- v2d->alpha_vert = 255;
- v2d->size_vert = V2D_SCROLL_WIDTH;
- redraw = true;
+ if (test_only) {
+ if (isect_value != 0) {
+ break;
}
}
else {
- const int local_xy[2] = {xy[0] - ar->winrct.xmin, xy[1] - ar->winrct.ymin};
- float dist_fac = 0.0f, alpha = 0.0f;
-
- if (az->direction == AZ_SCROLL_HOR) {
- dist_fac = BLI_rcti_length_y(&v2d->hor, local_xy[1]) / AZONEFADEIN;
- CLAMP(dist_fac, 0.0f, 1.0f);
- alpha = 1.0f - dist_fac;
+ bool redraw = false;
- v2d->alpha_hor = alpha * 255;
- v2d->size_hor = round_fl_to_int(V2D_SCROLL_HEIGHT -
- ((V2D_SCROLL_HEIGHT - V2D_SCROLL_HEIGHT_MIN) * dist_fac));
+ if (isect_value == 'h') {
+ if (az->direction == AZ_SCROLL_HOR) {
+ az->alpha = 1.0f;
+ v2d->alpha_hor = 255;
+ v2d->size_hor = V2D_SCROLL_HEIGHT;
+ redraw = true;
+ }
}
- else if (az->direction == AZ_SCROLL_VERT) {
- dist_fac = BLI_rcti_length_x(&v2d->vert, local_xy[0]) / AZONEFADEIN;
- CLAMP(dist_fac, 0.0f, 1.0f);
- alpha = 1.0f - dist_fac;
-
- v2d->alpha_vert = alpha * 255;
- v2d->size_vert = round_fl_to_int(V2D_SCROLL_WIDTH -
- ((V2D_SCROLL_WIDTH - V2D_SCROLL_WIDTH_MIN) * dist_fac));
+ else if (isect_value == 'v') {
+ if (az->direction == AZ_SCROLL_VERT) {
+ az->alpha = 1.0f;
+ v2d->alpha_vert = 255;
+ v2d->size_vert = V2D_SCROLL_WIDTH;
+ redraw = true;
+ }
+ }
+ else {
+ const int local_xy[2] = {xy[0] - ar->winrct.xmin, xy[1] - ar->winrct.ymin};
+ float dist_fac = 0.0f, alpha = 0.0f;
+
+ if (az->direction == AZ_SCROLL_HOR) {
+ dist_fac = BLI_rcti_length_y(&v2d->hor, local_xy[1]) / AZONEFADEIN;
+ CLAMP(dist_fac, 0.0f, 1.0f);
+ alpha = 1.0f - dist_fac;
+
+ v2d->alpha_hor = alpha * 255;
+ v2d->size_hor = round_fl_to_int(
+ V2D_SCROLL_HEIGHT -
+ ((V2D_SCROLL_HEIGHT - V2D_SCROLL_HEIGHT_MIN) * dist_fac));
+ }
+ else if (az->direction == AZ_SCROLL_VERT) {
+ dist_fac = BLI_rcti_length_x(&v2d->vert, local_xy[0]) / AZONEFADEIN;
+ CLAMP(dist_fac, 0.0f, 1.0f);
+ alpha = 1.0f - dist_fac;
+
+ v2d->alpha_vert = alpha * 255;
+ v2d->size_vert = round_fl_to_int(
+ V2D_SCROLL_WIDTH -
+ ((V2D_SCROLL_WIDTH - V2D_SCROLL_WIDTH_MIN) * dist_fac));
+ }
+ az->alpha = alpha;
+ redraw = true;
}
- az->alpha = alpha;
- redraw = true;
- }
- if (redraw) {
- ED_area_tag_redraw_no_rebuild(sa);
+ if (redraw) {
+ ED_area_tag_redraw_no_rebuild(sa);
+ }
+ /* Don't return! */
}
- /* Don't return! */
}
}
}
@@ -780,6 +795,15 @@ AZone *is_in_area_actionzone(ScrArea *sa, const int xy[2])
return az;
}
+AZone *ED_area_actionzone_find_xy(ScrArea *sa, const int xy[2])
+{
+ return area_actionzone_refresh_xy(sa, xy, true);
+}
+
+AZone *ED_area_actionzone_refresh_xy(ScrArea *sa, const int xy[2])
+{
+ return area_actionzone_refresh_xy(sa, xy, false);
+}
static void actionzone_exit(wmOperator *op)
{
@@ -817,7 +841,7 @@ static void actionzone_apply(bContext *C, wmOperator *op, int type)
static int actionzone_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
ScrArea *sa = CTX_wm_area(C);
- AZone *az = is_in_area_actionzone(sa, &event->x);
+ AZone *az = ED_area_actionzone_find_xy(sa, &event->x);
sActionzoneData *sad;
/* quick escape */
@@ -878,7 +902,7 @@ static int actionzone_modal(bContext *C, wmOperator *op, const wmEvent *event)
WM_window_screen_rect_calc(win, &screen_rect);
/* once we drag outside the actionzone, register a gesture
* check we're not on an edge so join finds the other area */
- is_gesture = ((is_in_area_actionzone(sad->sa1, &event->x) != sad->az) &&
+ is_gesture = ((ED_area_actionzone_find_xy(sad->sa1, &event->x) != sad->az) &&
(screen_area_map_find_active_scredge(
AREAMAP_FROM_SCREEN(sc), &screen_rect, event->x, event->y) == NULL));
}
@@ -4808,7 +4832,7 @@ void ED_keymap_screen(wmKeyConfig *keyconf)
/* tests */
WM_keymap_add_item(keymap, "SCREEN_OT_region_quadview", QKEY, KM_PRESS, KM_CTRL | KM_ALT, 0);
- WM_keymap_verify_item(keymap, "SCREEN_OT_repeat_history", F3KEY, KM_PRESS, 0, 0);
+ WM_keymap_verify_item(keymap, "SCREEN_OT_repeat_history", RKEY, KM_PRESS, KM_CTRL | KM_ALT, 0);
WM_keymap_add_item(keymap, "SCREEN_OT_repeat_last", RKEY, KM_PRESS, KM_SHIFT, 0);
WM_keymap_verify_item(keymap, "SCREEN_OT_region_flip", F5KEY, KM_PRESS, 0, 0);
WM_keymap_verify_item(keymap, "SCREEN_OT_redo_last", F6KEY, KM_PRESS, 0, 0);
diff --git a/source/blender/editors/screen/screen_user_menu.c b/source/blender/editors/screen/screen_user_menu.c
new file mode 100644
index 00000000000..d942602c896
--- /dev/null
+++ b/source/blender/editors/screen/screen_user_menu.c
@@ -0,0 +1,164 @@
+/*
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * The Original Code is Copyright (C) 2009 Blender Foundation.
+ * All rights reserved.
+ *
+ *
+ * Contributor(s): Blender Foundation
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+/** \file blender/editors/screen/screen_user_menu.c
+ * \ingroup spview3d
+ */
+
+#include <string.h>
+#include <stdio.h>
+#include <math.h>
+#include <float.h>
+
+#include "DNA_scene_types.h"
+
+#include "MEM_guardedalloc.h"
+
+#include "BLI_utildefines.h"
+#include "BLI_listbase.h"
+#include "BLI_string.h"
+
+#include "BLT_translation.h"
+
+#include "BKE_blender_user_menu.h"
+#include "BKE_context.h"
+#include "BKE_screen.h"
+#include "BKE_idprop.h"
+
+#include "WM_api.h"
+#include "WM_types.h"
+
+#include "ED_screen.h"
+
+#include "UI_interface.h"
+#include "UI_resources.h"
+
+/* -------------------------------------------------------------------- */
+/** \name Menu Type
+ * \{ */
+
+bUserMenu *ED_screen_user_menu_find(bContext *C)
+{
+ SpaceLink *sl = CTX_wm_space_data(C);
+ const char *context = CTX_data_mode_string(C);
+ return BKE_blender_user_menu_find(&U.user_menus, sl->spacetype, context);
+}
+
+bUserMenu *ED_screen_user_menu_ensure(bContext *C)
+{
+ SpaceLink *sl = CTX_wm_space_data(C);
+ const char *context = CTX_data_mode_string(C);
+ return BKE_blender_user_menu_ensure(&U.user_menus, sl->spacetype, context);
+}
+
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Menu Item
+ * \{ */
+
+bUserMenuItem_Op *ED_screen_user_menu_item_find_operator(
+ ListBase *lb,
+ wmOperatorType *ot, IDProperty *prop, short opcontext)
+{
+ for (bUserMenuItem *umi = lb->first; umi; umi = umi->next) {
+ if (umi->type == USER_MENU_TYPE_OPERATOR) {
+ bUserMenuItem_Op *umi_op = (bUserMenuItem_Op *)umi;
+ if (STREQ(ot->idname, umi_op->opname) &&
+ (opcontext == umi_op->opcontext) &&
+ (IDP_EqualsProperties(prop, umi_op->prop)))
+ {
+ return umi_op;
+ }
+ }
+ }
+ return NULL;
+}
+
+void ED_screen_user_menu_item_add_operator(
+ ListBase *lb, const char *ui_name,
+ wmOperatorType *ot, IDProperty *prop, short opcontext)
+{
+ bUserMenuItem_Op *umi_op = (bUserMenuItem_Op *)BKE_blender_user_menu_item_add(lb, USER_MENU_TYPE_OPERATOR);
+ umi_op->opcontext = opcontext;
+ if (!STREQ(ui_name, ot->name)) {
+ BLI_strncpy(umi_op->item.ui_name, ui_name, OP_MAX_TYPENAME);
+ }
+ BLI_strncpy(umi_op->opname, ot->idname, OP_MAX_TYPENAME);
+ umi_op->prop = prop ? IDP_CopyProperty(prop) : NULL;
+}
+
+void ED_screen_user_menu_item_remove(ListBase *lb, bUserMenuItem *umi)
+{
+ BLI_remlink(lb, umi);
+ BKE_blender_user_menu_item_free(umi);
+}
+
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Menu Definition
+ * \{ */
+
+static void screen_user_menu_draw(const bContext *C, Menu *menu)
+{
+ SpaceLink *sl = CTX_wm_space_data(C);
+ const char *context = CTX_data_mode_string(C);
+ bUserMenu *um_array[] = {
+ BKE_blender_user_menu_find(&U.user_menus, sl->spacetype, context),
+ (sl->spacetype != SPACE_TOPBAR) ? BKE_blender_user_menu_find(&U.user_menus, SPACE_TOPBAR, context) : NULL,
+ };
+ for (int um_index = 0; um_index < ARRAY_SIZE(um_array); um_index++) {
+ bUserMenu *um = um_array[um_index];
+ if (um == NULL) {
+ continue;
+ }
+ for (bUserMenuItem *umi = um->items.first; umi; umi = umi->next) {
+ if (umi->type == USER_MENU_TYPE_OPERATOR) {
+ bUserMenuItem_Op *umi_op = (bUserMenuItem_Op *)umi;
+ IDProperty *prop = umi_op->prop ? IDP_CopyProperty(umi_op->prop) : NULL;
+ uiItemFullO(
+ menu->layout, umi_op->opname, umi->ui_name[0] ? umi->ui_name : NULL,
+ ICON_NONE, prop, umi_op->opcontext, 0, NULL);
+ }
+ else if (umi->type == USER_MENU_TYPE_SEP) {
+ uiItemS(menu->layout);
+ }
+ }
+ }
+}
+
+void ED_screen_user_menu_register(void)
+{
+ MenuType *mt = MEM_callocN(sizeof(MenuType), __func__);
+ strcpy(mt->idname, "SCREEN_MT_user_menu");
+ strcpy(mt->label, "Quick Favorites");
+ strcpy(mt->translation_context, BLT_I18NCONTEXT_DEFAULT_BPYRNA);
+ mt->draw = screen_user_menu_draw;
+ WM_menutype_add(mt);
+}
+
+/** \} */
diff --git a/source/blender/editors/sculpt_paint/paint_curve.c b/source/blender/editors/sculpt_paint/paint_curve.c
index af0b828ae39..e2100ceb066 100644
--- a/source/blender/editors/sculpt_paint/paint_curve.c
+++ b/source/blender/editors/sculpt_paint/paint_curve.c
@@ -714,7 +714,7 @@ static int paintcurve_cursor_invoke(bContext *C, wmOperator *UNUSED(op), const w
break;
}
default:
- ED_view3d_cursor3d_update(C, event->mval);
+ ED_view3d_cursor3d_update(C, event->mval, true, V3D_CURSOR_ORIENT_VIEW);
break;
}
diff --git a/source/blender/editors/sculpt_paint/paint_hide.c b/source/blender/editors/sculpt_paint/paint_hide.c
index ac5b0624d56..4deec54a5b3 100644
--- a/source/blender/editors/sculpt_paint/paint_hide.c
+++ b/source/blender/editors/sculpt_paint/paint_hide.c
@@ -46,7 +46,6 @@
#include "BKE_pbvh.h"
#include "BKE_ccg.h"
#include "BKE_context.h"
-#include "BKE_DerivedMesh.h"
#include "BKE_mesh.h"
#include "BKE_mesh_runtime.h"
#include "BKE_multires.h"
diff --git a/source/blender/editors/sculpt_paint/paint_image.c b/source/blender/editors/sculpt_paint/paint_image.c
index 93fa3aac0d7..3c097095ddc 100644
--- a/source/blender/editors/sculpt_paint/paint_image.c
+++ b/source/blender/editors/sculpt_paint/paint_image.c
@@ -46,15 +46,16 @@
#include "IMB_imbuf_types.h"
#include "DNA_brush_types.h"
+#include "DNA_mesh_types.h"
#include "DNA_node_types.h"
#include "DNA_object_types.h"
#include "BKE_colorband.h"
#include "BKE_context.h"
-#include "BKE_DerivedMesh.h"
#include "BKE_brush.h"
#include "BKE_main.h"
#include "BKE_material.h"
+#include "BKE_mesh.h"
#include "BKE_node.h"
#include "BKE_paint.h"
#include "BKE_undo_system.h"
@@ -1055,6 +1056,7 @@ static int texture_paint_toggle_poll(bContext *C)
static int texture_paint_toggle_exec(bContext *C, wmOperator *op)
{
struct wmMsgBus *mbus = CTX_wm_message_bus(C);
+ Main *bmain = CTX_data_main(C);
Scene *scene = CTX_data_scene(C);
Object *ob = CTX_data_active_object(C);
const int mode_flag = OB_MODE_TEXTURE_PAINT;
@@ -1070,14 +1072,13 @@ static int texture_paint_toggle_exec(bContext *C, wmOperator *op)
ob->mode &= ~mode_flag;
if (U.glreslimit != 0)
- GPU_free_images();
- GPU_paint_set_mipmap(1);
+ GPU_free_images(bmain);
+ GPU_paint_set_mipmap(bmain, 1);
toggle_paint_cursor(C, 0);
}
else {
bScreen *sc;
- Main *bmain = CTX_data_main(C);
Image *ima = NULL;
ImagePaintSettings *imapaint = &scene->toolsettings->imapaint;
@@ -1122,12 +1123,16 @@ static int texture_paint_toggle_exec(bContext *C, wmOperator *op)
BKE_paint_init(bmain, scene, ePaintTextureProjective, PAINT_CURSOR_TEXTURE_PAINT);
if (U.glreslimit != 0)
- GPU_free_images();
- GPU_paint_set_mipmap(0);
+ GPU_free_images(bmain);
+ GPU_paint_set_mipmap(bmain, 0);
toggle_paint_cursor(C, 1);
}
+ Mesh *me = BKE_mesh_from_object(ob);
+ BLI_assert(me != NULL);
+ DEG_id_tag_update(&me->id, DEG_TAG_COPY_ON_WRITE);
+
WM_event_add_notifier(C, NC_SCENE | ND_MODE, scene);
WM_msg_publish_rna_prop(mbus, &ob->id, ob, Object, mode);
diff --git a/source/blender/editors/sculpt_paint/paint_image_proj.c b/source/blender/editors/sculpt_paint/paint_image_proj.c
index 62bc379241f..bbf1da2d584 100644
--- a/source/blender/editors/sculpt_paint/paint_image_proj.c
+++ b/source/blender/editors/sculpt_paint/paint_image_proj.c
@@ -58,6 +58,7 @@
#include "DNA_brush_types.h"
#include "DNA_material_types.h"
#include "DNA_mesh_types.h"
+#include "DNA_meshdata_types.h"
#include "DNA_node_types.h"
#include "DNA_object_types.h"
@@ -65,7 +66,6 @@
#include "BKE_colorband.h"
#include "BKE_context.h"
#include "BKE_colortools.h"
-#include "BKE_DerivedMesh.h"
#include "BKE_idprop.h"
#include "BKE_brush.h"
#include "BKE_image.h"
diff --git a/source/blender/editors/sculpt_paint/paint_mask.c b/source/blender/editors/sculpt_paint/paint_mask.c
index f22e6f514e6..4a338e65d79 100644
--- a/source/blender/editors/sculpt_paint/paint_mask.c
+++ b/source/blender/editors/sculpt_paint/paint_mask.c
@@ -45,7 +45,6 @@
#include "BKE_pbvh.h"
#include "BKE_ccg.h"
#include "BKE_context.h"
-#include "BKE_DerivedMesh.h"
#include "BKE_multires.h"
#include "BKE_paint.h"
#include "BKE_subsurf.h"
diff --git a/source/blender/editors/sculpt_paint/paint_vertex_proj.c b/source/blender/editors/sculpt_paint/paint_vertex_proj.c
index cacfdc2dbba..602bfe1ab8e 100644
--- a/source/blender/editors/sculpt_paint/paint_vertex_proj.c
+++ b/source/blender/editors/sculpt_paint/paint_vertex_proj.c
@@ -28,7 +28,7 @@
* \ingroup edsculpt
*
* Utility functions for getting vertex locations while painting
- * (since they may be instanced multiple times in a DerivedMesh)
+ * (since they may be instanced multiple times in an evaluated mesh)
*/
#include "MEM_guardedalloc.h"
@@ -39,8 +39,9 @@
#include "DNA_mesh_types.h"
#include "DNA_object_types.h"
-#include "BKE_DerivedMesh.h"
+#include "BKE_DerivedMesh.h" /* XXX To be removed, only used for DMCoNo struct */
#include "BKE_context.h"
+#include "BKE_mesh_iterators.h"
#include "BKE_mesh_runtime.h"
#include "DEG_depsgraph.h"
@@ -107,24 +108,10 @@ static void vpaint_proj_dm_map_cosnos_init(
struct VertProjHandle *vp_handle)
{
Mesh *me = ob->data;
- DerivedMesh *dm;
+ Mesh *me_eval = mesh_get_eval_final(depsgraph, scene, ob, CD_MASK_BAREMESH | CD_MASK_ORIGINDEX);
- dm = mesh_get_derived_final(depsgraph, scene, ob, CD_MASK_BAREMESH | CD_MASK_ORIGINDEX);
-
- if (dm->foreachMappedVert) {
- memset(vp_handle->vcosnos, 0, sizeof(DMCoNo) * me->totvert);
- dm->foreachMappedVert(dm, vpaint_proj_dm_map_cosnos_init__map_cb, vp_handle, DM_FOREACH_USE_NORMAL);
- }
- else {
- DMCoNo *v_co_no = vp_handle->vcosnos;
- int a;
- for (a = 0; a < me->totvert; a++, v_co_no++) {
- dm->getVertCo(dm, a, v_co_no->co);
- dm->getVertNo(dm, a, v_co_no->no);
- }
- }
-
- dm->release(dm);
+ memset(vp_handle->vcosnos, 0, sizeof(*vp_handle->vcosnos) * me->totvert);
+ BKE_mesh_foreach_mapped_vert(me_eval, vpaint_proj_dm_map_cosnos_init__map_cb, vp_handle, MESH_FOREACH_USE_NORMAL);
}
@@ -185,21 +172,13 @@ static void vpaint_proj_dm_map_cosnos_update(
Scene *scene = vp_handle->scene;
Object *ob = vp_handle->ob;
Mesh *me = ob->data;
- DerivedMesh *dm;
+ Mesh *me_eval = mesh_get_eval_final(depsgraph, scene, ob, CD_MASK_BAREMESH | CD_MASK_ORIGINDEX);
/* quick sanity check - we shouldn't have to run this if there are no modifiers */
BLI_assert(BLI_listbase_is_empty(&ob->modifiers) == false);
- dm = mesh_get_derived_final(depsgraph, scene, ob, CD_MASK_BAREMESH | CD_MASK_ORIGINDEX);
-
- /* highly unlikely this will become unavailable once painting starts (perhaps with animated modifiers) */
- if (LIKELY(dm->foreachMappedVert)) {
- copy_vn_fl(vp_handle->dists_sq, me->totvert, FLT_MAX);
-
- dm->foreachMappedVert(dm, vpaint_proj_dm_map_cosnos_update__map_cb, &vp_update, DM_FOREACH_USE_NORMAL);
- }
-
- dm->release(dm);
+ copy_vn_fl(vp_handle->dists_sq, me->totvert, FLT_MAX);
+ BKE_mesh_foreach_mapped_vert(me_eval, vpaint_proj_dm_map_cosnos_update__map_cb, &vp_update, MESH_FOREACH_USE_NORMAL);
}
diff --git a/source/blender/editors/sculpt_paint/paint_vertex_weight_ops.c b/source/blender/editors/sculpt_paint/paint_vertex_weight_ops.c
index 7d241835b62..126b3b42e8f 100644
--- a/source/blender/editors/sculpt_paint/paint_vertex_weight_ops.c
+++ b/source/blender/editors/sculpt_paint/paint_vertex_weight_ops.c
@@ -35,8 +35,8 @@
#include "IMB_imbuf_types.h"
#include "IMB_colormanagement.h"
-//#include "DNA_armature_types.h"
#include "DNA_mesh_types.h"
+#include "DNA_meshdata_types.h"
#include "DNA_particle_types.h"
#include "DNA_brush_types.h"
#include "DNA_object_types.h"
@@ -46,11 +46,11 @@
#include "RNA_define.h"
#include "RNA_enum_types.h"
-#include "BKE_DerivedMesh.h"
#include "BKE_brush.h"
#include "BKE_context.h"
#include "BKE_deform.h"
#include "BKE_mesh.h"
+#include "BKE_mesh_iterators.h"
#include "BKE_mesh_mapping.h"
#include "BKE_mesh_runtime.h"
#include "BKE_modifier.h"
@@ -785,31 +785,16 @@ static int paint_weight_gradient_exec(bContext *C, wmOperator *op)
ED_view3d_init_mats_rv3d(ob, ar->regiondata);
Mesh *me_eval = mesh_get_eval_final(depsgraph, scene, ob, scene->customdata_mask | CD_MASK_ORIGINDEX);
- int *mv_orig_indices = CustomData_get_layer(&me_eval->vdata, CD_ORIGINDEX);
- MVert *mv = me_eval->mvert;
- /* NULL origindex is valid when wehave no generative modifiers... */
- BLI_assert(mv_orig_indices != NULL || me_eval->totvert == me->totvert);
if (data.is_init) {
data.vert_visit = BLI_BITMAP_NEW(me->totvert, __func__);
- /* TODO add some similar helpers as DM's foreachMappedXXX callbacks, for evaluated mesh? */
- for (int mv_idx = 0; mv_idx < me_eval->totvert; mv_idx++, mv++) {
- const int mv_orig_idx = mv_orig_indices != NULL ? mv_orig_indices[mv_idx] : mv_idx;
- if (mv_orig_idx != ORIGINDEX_NONE) {
- gradientVertInit__mapFunc(&data, mv_orig_idx, mv->co, NULL, NULL);
- }
- }
+ BKE_mesh_foreach_mapped_vert(me_eval, gradientVertInit__mapFunc, &data, MESH_FOREACH_NOP);
MEM_freeN(data.vert_visit);
data.vert_visit = NULL;
}
else {
- for (int mv_idx = 0; mv_idx < me_eval->totvert; mv_idx++, mv++) {
- const int mv_orig_idx = mv_orig_indices != NULL ? mv_orig_indices[mv_idx] : mv_idx;
- if (mv_orig_idx != ORIGINDEX_NONE) {
- gradientVertUpdate__mapFunc(&data, mv_orig_idx, mv->co, NULL, NULL);
- }
- }
+ BKE_mesh_foreach_mapped_vert(me_eval, gradientVertUpdate__mapFunc, &data, MESH_FOREACH_NOP);
}
DEG_id_tag_update(&ob->id, OB_RECALC_DATA);
diff --git a/source/blender/editors/sculpt_paint/sculpt_undo.c b/source/blender/editors/sculpt_paint/sculpt_undo.c
index 2872ad4fb9c..bc22147b15d 100644
--- a/source/blender/editors/sculpt_paint/sculpt_undo.c
+++ b/source/blender/editors/sculpt_paint/sculpt_undo.c
@@ -561,7 +561,7 @@ static void sculpt_undo_restore_list(bContext *C, ListBase *lb)
else {
BKE_pbvh_search_callback(ss->pbvh, NULL, NULL, update_cb, &rebuild);
}
- BKE_pbvh_update(ss->pbvh, PBVH_UpdateBB | PBVH_UpdateOriginalBB | PBVH_UpdateRedraw, NULL);
+ BKE_pbvh_update(ss->pbvh, PBVH_UpdateBB | PBVH_UpdateOriginalBB | PBVH_UpdateRedraw | PBVH_UpdateNormals, NULL);
if (BKE_sculpt_multires_active(scene, ob)) {
if (rebuild)
diff --git a/source/blender/editors/space_action/space_action.c b/source/blender/editors/space_action/space_action.c
index 527e382ec1e..537f184c71c 100644
--- a/source/blender/editors/space_action/space_action.c
+++ b/source/blender/editors/space_action/space_action.c
@@ -47,6 +47,8 @@
#include "BKE_screen.h"
#include "RNA_access.h"
+#include "RNA_define.h"
+#include "RNA_enum_types.h"
#include "WM_api.h"
#include "WM_types.h"
@@ -102,6 +104,7 @@ static SpaceLink *action_new(const ScrArea *sa, const Scene *scene)
saction->autosnap = SACTSNAP_FRAME;
saction->mode = SACTCONT_DOPESHEET;
+ saction->mode_prev = SACTCONT_DOPESHEET;
saction->ads.filterflag |= ADS_FILTER_SUMMARY;
@@ -835,6 +838,37 @@ static void action_id_remap(ScrArea *UNUSED(sa), SpaceLink *slink, ID *old_id, I
}
+/**
+ * \note Used for splitting out a subset of modes is more involved,
+ * The previous non-timeline mode is stored so switching back to the
+ * dope-sheet doesn't always reset the sub-mode.
+ */
+static int action_space_subtype_get(ScrArea *sa)
+{
+ SpaceAction *sact = sa->spacedata.first;
+ return sact->mode == SACTCONT_TIMELINE ? SACTCONT_TIMELINE : SACTCONT_DOPESHEET;
+}
+
+static void action_space_subtype_set(ScrArea *sa, int value)
+{
+ SpaceAction *sact = sa->spacedata.first;
+ if (value == SACTCONT_TIMELINE) {
+ if (sact->mode != SACTCONT_TIMELINE) {
+ sact->mode_prev = sact->mode;
+ }
+ sact->mode = value;
+ }
+ else {
+ sact->mode = sact->mode_prev;
+ }
+}
+
+static void action_space_subtype_item_extend(
+ bContext *UNUSED(C), EnumPropertyItem **item, int *totitem)
+{
+ RNA_enum_items_add(item, totitem, rna_enum_space_action_mode_items);
+}
+
/* only called once, from space/spacetypes.c */
void ED_spacetype_action(void)
{
@@ -853,6 +887,9 @@ void ED_spacetype_action(void)
st->listener = action_listener;
st->refresh = action_refresh;
st->id_remap = action_id_remap;
+ st->space_subtype_item_extend = action_space_subtype_item_extend;
+ st->space_subtype_get = action_space_subtype_get;
+ st->space_subtype_set = action_space_subtype_set;
/* regions: main window */
art = MEM_callocN(sizeof(ARegionType), "spacetype action region");
diff --git a/source/blender/editors/space_api/spacetypes.c b/source/blender/editors/space_api/spacetypes.c
index 33ec7f771ba..2ee791e81d6 100644
--- a/source/blender/editors/space_api/spacetypes.c
+++ b/source/blender/editors/space_api/spacetypes.c
@@ -127,6 +127,8 @@ void ED_spacetypes_init(void)
ED_operatortypes_view2d();
ED_operatortypes_ui();
+ ED_screen_user_menu_register();
+
/* manipulator types */
ED_manipulatortypes_button_2d();
ED_manipulatortypes_dial_3d();
diff --git a/source/blender/editors/space_clip/clip_buttons.c b/source/blender/editors/space_clip/clip_buttons.c
index 469d94fed3a..f2fe06874d7 100644
--- a/source/blender/editors/space_clip/clip_buttons.c
+++ b/source/blender/editors/space_clip/clip_buttons.c
@@ -387,7 +387,7 @@ void uiTemplateMarker(uiLayout *layout, PointerRNA *ptr, const char *propname, P
else
tip = TIP_("Marker is enabled at current frame");
- bt = uiDefIconButBitI(block, UI_BTYPE_TOGGLE_N, MARKER_DISABLED, 0, ICON_RESTRICT_VIEW_OFF, 0, 0, UI_UNIT_X, UI_UNIT_Y,
+ bt = uiDefIconButBitI(block, UI_BTYPE_TOGGLE_N, MARKER_DISABLED, 0, ICON_HIDE_OFF, 0, 0, UI_UNIT_X, UI_UNIT_Y,
&cb->marker_flag, 0, 0, 1, 0, tip);
UI_but_funcN_set(bt, marker_update_cb, cb, NULL);
}
diff --git a/source/blender/editors/space_graph/graph_utils.c b/source/blender/editors/space_graph/graph_utils.c
index f55a5511e2d..e543111e662 100644
--- a/source/blender/editors/space_graph/graph_utils.c
+++ b/source/blender/editors/space_graph/graph_utils.c
@@ -44,17 +44,62 @@
#include "BKE_context.h"
#include "BKE_fcurve.h"
+#include "BKE_screen.h"
#include "WM_api.h"
#include "ED_anim_api.h"
+#include "ED_screen.h"
+#include "UI_interface.h"
#include "graph_intern.h" // own include
/* ************************************************************** */
+/* Set Up Drivers Editor */
+
+/* Set up UI configuration for Drivers Editor */
+/* NOTE: Currently called from windowmanager (new drivers editor window) and RNA (mode switching) */
+void ED_drivers_editor_init(bContext *C, ScrArea *sa)
+{
+ SpaceIpo *sipo = (SpaceIpo *)sa->spacedata.first;
+
+ /* Set mode */
+ sipo->mode = SIPO_MODE_DRIVERS;
+
+ /* Show Properties Region (or else the settings can't be edited) */
+ ARegion *ar_props = BKE_area_find_region_type(sa, RGN_TYPE_UI);
+ if (ar_props) {
+ UI_panel_category_active_set(ar_props, "Drivers");
+
+ ar_props->flag &= ~RGN_FLAG_HIDDEN;
+ /* XXX: Adjust width of this too? */
+
+ ED_region_visibility_change_update(C, ar_props);
+ }
+ else {
+ printf("%s: Couldn't find properties region for Drivers Editor - %p\n", __func__, sa);
+ }
+
+ /* Adjust framing in graph region */
+ /* TODO: Have a way of not resetting this every time?
+ * (e.g. So that switching back and forth between editors doesn't keep jumping?)
+ */
+ ARegion *ar_main = BKE_area_find_region_type(sa, RGN_TYPE_WINDOW);
+ if (ar_main) {
+ /* XXX: Ideally we recenter based on the range instead... */
+ ar_main->v2d.tot.xmin = -2.0f;
+ ar_main->v2d.tot.ymin = -2.0f;
+ ar_main->v2d.tot.xmax = 2.0f;
+ ar_main->v2d.tot.ymax = 2.0f;
+
+ ar_main->v2d.cur = ar_main->v2d.tot;
+ }
+}
+
+/* ************************************************************** */
/* Active F-Curve */
/* Find 'active' F-Curve. It must be editable, since that's the purpose of these buttons (subject to change).
diff --git a/source/blender/editors/space_graph/space_graph.c b/source/blender/editors/space_graph/space_graph.c
index 59d7d7500ae..7c3105843c5 100644
--- a/source/blender/editors/space_graph/space_graph.c
+++ b/source/blender/editors/space_graph/space_graph.c
@@ -60,6 +60,8 @@
#include "WM_message.h"
#include "RNA_access.h"
+#include "RNA_define.h"
+#include "RNA_enum_types.h"
#include "UI_resources.h"
#include "UI_view2d.h"
@@ -181,14 +183,14 @@ static void graph_free(SpaceLink *sl)
/* spacetype; init callback */
-static void graph_init(struct wmWindowManager *UNUSED(wm), ScrArea *sa)
+static void graph_init(struct wmWindowManager *wm, ScrArea *sa)
{
SpaceIpo *sipo = (SpaceIpo *)sa->spacedata.first;
/* init dopesheet data if non-existent (i.e. for old files) */
if (sipo->ads == NULL) {
sipo->ads = MEM_callocN(sizeof(bDopeSheet), "GraphEdit DopeSheet");
- sipo->ads->source = (ID *)(G.main->scene.first); // FIXME: this is a really nasty hack here for now...
+ sipo->ads->source = (ID *)WM_window_get_active_scene(wm->winactive);
}
/* force immediate init of any invalid F-Curve colors */
@@ -799,6 +801,24 @@ static void graph_id_remap(ScrArea *UNUSED(sa), SpaceLink *slink, ID *old_id, ID
}
}
+static int graph_space_subtype_get(ScrArea *sa)
+{
+ SpaceIpo *sgraph = sa->spacedata.first;
+ return sgraph->mode;
+}
+
+static void graph_space_subtype_set(ScrArea *sa, int value)
+{
+ SpaceIpo *sgraph = sa->spacedata.first;
+ sgraph->mode = value;
+}
+
+static void graph_space_subtype_item_extend(
+ bContext *UNUSED(C), EnumPropertyItem **item, int *totitem)
+{
+ RNA_enum_items_add(item, totitem, rna_enum_space_graph_mode_items);
+}
+
/* only called once, from space/spacetypes.c */
void ED_spacetype_ipo(void)
{
@@ -817,6 +837,9 @@ void ED_spacetype_ipo(void)
st->listener = graph_listener;
st->refresh = graph_refresh;
st->id_remap = graph_id_remap;
+ st->space_subtype_item_extend = graph_space_subtype_item_extend;
+ st->space_subtype_get = graph_space_subtype_get;
+ st->space_subtype_set = graph_space_subtype_set;
/* regions: main window */
art = MEM_callocN(sizeof(ARegionType), "spacetype graphedit region");
@@ -867,4 +890,3 @@ void ED_spacetype_ipo(void)
BKE_spacetype_register(st);
}
-
diff --git a/source/blender/editors/space_image/image_buttons.c b/source/blender/editors/space_image/image_buttons.c
index 7236a99ad80..9475c159653 100644
--- a/source/blender/editors/space_image/image_buttons.c
+++ b/source/blender/editors/space_image/image_buttons.c
@@ -710,7 +710,7 @@ static void uiblock_layer_pass_buttons(
if (render_slot) {
char str[64];
RenderSlot *slot = BKE_image_get_renderslot(image, *render_slot);
- if (slot->name[0] != '\0') {
+ if (slot && slot->name[0] != '\0') {
BLI_strncpy(str, slot->name, sizeof(str));
}
else {
diff --git a/source/blender/editors/space_image/space_image.c b/source/blender/editors/space_image/space_image.c
index e84b596530e..827c39b8033 100644
--- a/source/blender/editors/space_image/space_image.c
+++ b/source/blender/editors/space_image/space_image.c
@@ -301,7 +301,7 @@ static void image_keymap(struct wmKeyConfig *keyconf)
WM_keymap_add_item(keymap, "IMAGE_OT_reload", RKEY, KM_PRESS, KM_ALT, 0);
WM_keymap_add_item(keymap, "IMAGE_OT_read_viewlayers", RKEY, KM_PRESS, KM_CTRL, 0);
WM_keymap_add_item(keymap, "IMAGE_OT_save", SKEY, KM_PRESS, KM_ALT, 0);
- WM_keymap_add_item(keymap, "IMAGE_OT_save_as", F3KEY, KM_PRESS, 0, 0);
+ WM_keymap_add_item(keymap, "IMAGE_OT_save_as", SKEY, KM_PRESS, KM_SHIFT, 0);
WM_keymap_add_item(keymap, "IMAGE_OT_properties", NKEY, KM_PRESS, 0, 0);
WM_keymap_add_item(keymap, "IMAGE_OT_toolshelf", TKEY, KM_PRESS, 0, 0);
diff --git a/source/blender/editors/space_info/info_stats.c b/source/blender/editors/space_info/info_stats.c
index 481c9031a73..b0b0f6dee07 100644
--- a/source/blender/editors/space_info/info_stats.c
+++ b/source/blender/editors/space_info/info_stats.c
@@ -34,6 +34,7 @@
#include "DNA_curve_types.h"
#include "DNA_group_types.h"
#include "DNA_lattice_types.h"
+#include "DNA_mesh_types.h"
#include "DNA_meta_types.h"
#include "DNA_scene_types.h"
@@ -48,7 +49,6 @@
#include "BKE_blender_version.h"
#include "BKE_curve.h"
#include "BKE_displist.h"
-#include "BKE_DerivedMesh.h"
#include "BKE_key.h"
#include "BKE_layer.h"
#include "BKE_paint.h"
@@ -92,15 +92,15 @@ static void stats_object(Object *ob, int sel, int totob, SceneStats *stats)
switch (ob->type) {
case OB_MESH:
{
- /* we assume derivedmesh is already built, this strictly does stats now. */
- DerivedMesh *dm = ob->derivedFinal;
+ /* we assume evaluated mesh is already built, this strictly does stats now. */
+ Mesh *me_eval = ob->runtime.mesh_eval;
int totvert, totedge, totface, totloop;
- if (dm) {
- totvert = dm->getNumVerts(dm);
- totedge = dm->getNumEdges(dm);
- totface = dm->getNumPolys(dm);
- totloop = dm->getNumLoops(dm);
+ if (me_eval) {
+ totvert = me_eval->totvert;
+ totedge = me_eval->totedge;
+ totface = me_eval->totpoly;
+ totloop = me_eval->totloop;
stats->totvert += totvert * totob;
stats->totedge += totedge * totob;
@@ -387,7 +387,7 @@ static void stats_update(ViewLayer *view_layer)
else {
/* Objects */
for (base = view_layer->object_bases.first; base; base = base->next)
- if (base->flag & BASE_VISIBLED) {
+ if (base->flag & BASE_VISIBLE) {
stats_dupli_object(base, base->object, &stats);
}
}
diff --git a/source/blender/editors/space_nla/nla_channels.c b/source/blender/editors/space_nla/nla_channels.c
index d782fe4d7ef..d3725704636 100644
--- a/source/blender/editors/space_nla/nla_channels.c
+++ b/source/blender/editors/space_nla/nla_channels.c
@@ -129,7 +129,7 @@ static int mouse_nla_channels(bContext *C, bAnimContext *ac, float x, int channe
Object *ob = base->object;
AnimData *adt = ob->adt;
- if (nlaedit_is_tweakmode_on(ac) == 0 && (base->flag & BASE_SELECTABLED)) {
+ if (nlaedit_is_tweakmode_on(ac) == 0 && (base->flag & BASE_SELECTABLE)) {
/* set selection status */
if (selectmode == SELECT_INVERT) {
/* swap select */
diff --git a/source/blender/editors/space_nla/space_nla.c b/source/blender/editors/space_nla/space_nla.c
index 639195c16ac..745cea37ea3 100644
--- a/source/blender/editors/space_nla/space_nla.c
+++ b/source/blender/editors/space_nla/space_nla.c
@@ -178,14 +178,14 @@ static void nla_free(SpaceLink *sl)
/* spacetype; init callback */
-static void nla_init(struct wmWindowManager *UNUSED(wm), ScrArea *sa)
+static void nla_init(struct wmWindowManager *wm, ScrArea *sa)
{
SpaceNla *snla = (SpaceNla *)sa->spacedata.first;
/* init dopesheet data if non-existent (i.e. for old files) */
if (snla->ads == NULL) {
snla->ads = MEM_callocN(sizeof(bDopeSheet), "NlaEdit DopeSheet");
- snla->ads->source = (ID *)G.main->scene.first; // XXX this is bad, but we need this to be set correct
+ snla->ads->source = (ID *)WM_window_get_active_scene(wm->winactive);
}
ED_area_tag_refresh(sa);
diff --git a/source/blender/editors/space_node/space_node.c b/source/blender/editors/space_node/space_node.c
index 441ab03cb28..14ba9280a75 100644
--- a/source/blender/editors/space_node/space_node.c
+++ b/source/blender/editors/space_node/space_node.c
@@ -1045,4 +1045,3 @@ void ED_spacetype_node(void)
BKE_spacetype_register(st);
}
-
diff --git a/source/blender/editors/space_outliner/outliner_collections.c b/source/blender/editors/space_outliner/outliner_collections.c
index a700f8e20e0..b97cc13d713 100644
--- a/source/blender/editors/space_outliner/outliner_collections.c
+++ b/source/blender/editors/space_outliner/outliner_collections.c
@@ -164,8 +164,10 @@ static int collection_new_exec(bContext *C, wmOperator *op)
data.collection,
NULL);
- outliner_cleanup_tree(soops);
+ DEG_id_tag_update(&data.collection->id, DEG_TAG_COPY_ON_WRITE);
DEG_relations_tag_update(bmain);
+
+ outliner_cleanup_tree(soops);
WM_main_add_notifier(NC_SCENE | ND_LAYER, NULL);
return OPERATOR_FINISHED;
}
@@ -236,18 +238,19 @@ static int collection_delete_exec(bContext *C, wmOperator *op)
/* Effectively delete the collections. */
GSetIterator collections_to_edit_iter;
GSET_ITER(collections_to_edit_iter, data.collections_to_edit) {
- /* TODO: what if collection was child and got deleted in the meantime? */
Collection *collection = BLI_gsetIterator_getKey(&collections_to_edit_iter);
- BKE_collection_delete(bmain, collection, hierarchy);
+
+ /* Test in case collection got deleted as part of another one. */
+ if (BLI_findindex(&bmain->collection, collection) != -1) {
+ BKE_collection_delete(bmain, collection, hierarchy);
+ }
}
BLI_gset_free(data.collections_to_edit, NULL);
+ DEG_id_tag_update(&scene->id, DEG_TAG_COPY_ON_WRITE);
DEG_relations_tag_update(bmain);
- /* TODO(sergey): Use proper flag for tagging here. */
- DEG_id_tag_update(&scene->id, 0);
-
WM_main_add_notifier(NC_SCENE | ND_LAYER, NULL);
return OPERATOR_FINISHED;
@@ -462,11 +465,9 @@ static int collection_link_exec(bContext *C, wmOperator *UNUSED(op))
BLI_gset_free(data.collections_to_edit, NULL);
+ DEG_id_tag_update(&active_collection->id, DEG_TAG_COPY_ON_WRITE);
DEG_relations_tag_update(bmain);
- /* TODO(sergey): Use proper flag for tagging here. */
- DEG_id_tag_update(&scene->id, 0);
-
WM_main_add_notifier(NC_SCENE | ND_LAYER, NULL);
return OPERATOR_FINISHED;
@@ -527,9 +528,6 @@ static int collection_instance_exec(bContext *C, wmOperator *UNUSED(op))
DEG_relations_tag_update(bmain);
- /* TODO(sergey): Use proper flag for tagging here. */
- DEG_id_tag_update(&scene->id, 0);
-
WM_main_add_notifier(NC_SCENE | ND_LAYER, NULL);
return OPERATOR_FINISHED;
diff --git a/source/blender/editors/space_outliner/outliner_draw.c b/source/blender/editors/space_outliner/outliner_draw.c
index e4f551b0004..e617bb40837 100644
--- a/source/blender/editors/space_outliner/outliner_draw.c
+++ b/source/blender/editors/space_outliner/outliner_draw.c
@@ -51,6 +51,7 @@
#include "BKE_deform.h"
#include "BKE_fcurve.h"
#include "BKE_global.h"
+#include "BKE_idcode.h"
#include "BKE_layer.h"
#include "BKE_library.h"
#include "BKE_main.h"
@@ -278,6 +279,44 @@ static void restrictbutton_id_user_toggle(bContext *UNUSED(C), void *poin, void
}
}
+static void hidebutton_base_flag_cb(bContext *C, void *poin, void *poin2)
+{
+ Scene *scene = CTX_data_scene(C);
+ ViewLayer *view_layer = poin;
+ Base *base = poin2;
+ bool extend = (CTX_wm_window(C)->eventstate->ctrl == 0);
+
+ /* Undo button toggle, let function do it. */
+ base->flag ^= BASE_HIDDEN;
+
+ BKE_base_set_visible(scene, view_layer, base, extend);
+
+ if (!extend && (base->flag & BASE_VISIBLE)) {
+ /* Auto select solo-ed object. */
+ ED_object_base_select(base, BA_SELECT);
+ view_layer->basact = base;
+ }
+
+ DEG_id_tag_update(&scene->id, DEG_TAG_BASE_FLAGS_UPDATE);
+ WM_event_add_notifier(C, NC_SCENE | ND_OB_SELECT, scene);
+}
+
+static void hidebutton_layer_collection_flag_cb(bContext *C, void *poin, void *poin2)
+{
+ Scene *scene = CTX_data_scene(C);
+ ViewLayer *view_layer = poin;
+ LayerCollection *lc = poin2;
+ bool extend = (CTX_wm_window(C)->eventstate->ctrl == 0);
+
+ /* Undo button toggle, let function do it. */
+ lc->runtime_flag ^= LAYER_COLLECTION_HAS_VISIBLE_OBJECTS;
+
+ BKE_layer_collection_set_visible(scene, view_layer, lc, extend);
+
+ DEG_id_tag_update(&scene->id, DEG_TAG_BASE_FLAGS_UPDATE);
+ WM_event_add_notifier(C, NC_SCENE | ND_OB_SELECT, scene);
+}
+
static void namebutton_cb(bContext *C, void *tsep, char *oldname)
{
Main *bmain = CTX_data_main(C);
@@ -435,18 +474,25 @@ static void namebutton_cb(bContext *C, void *tsep, char *oldname)
}
static void outliner_draw_restrictbuts(
- uiBlock *block, Scene *scene, ARegion *ar, SpaceOops *soops, ListBase *lb)
+ uiBlock *block, Scene *scene, ViewLayer *view_layer, ARegion *ar, SpaceOops *soops, ListBase *lb)
{
uiBut *bt;
/* get RNA properties (once for speed) */
- PropertyRNA *collection_prop_hide_viewport;
- PropertyRNA *collection_prop_hide_select;
- PropertyRNA *collection_prop_hide_render;
+ PropertyRNA *object_prop_hide_viewport, *object_prop_hide_select, *object_prop_hide_render;
+ PropertyRNA *collection_prop_hide_viewport, *collection_prop_hide_select, *collection_prop_hide_render;
+
+ object_prop_hide_viewport = RNA_struct_type_find_property(&RNA_Object, "hide_viewport");
+ object_prop_hide_select = RNA_struct_type_find_property(&RNA_Object, "hide_select");
+ object_prop_hide_render = RNA_struct_type_find_property(&RNA_Object, "hide_render");
collection_prop_hide_select = RNA_struct_type_find_property(&RNA_Collection, "hide_select");
collection_prop_hide_viewport = RNA_struct_type_find_property(&RNA_Collection, "hide_viewport");
collection_prop_hide_render = RNA_struct_type_find_property(&RNA_Collection, "hide_render");
- BLI_assert(collection_prop_hide_viewport &&
+
+ BLI_assert(object_prop_hide_viewport &&
+ object_prop_hide_select &&
+ object_prop_hide_render &&
+ collection_prop_hide_viewport &&
collection_prop_hide_select &&
collection_prop_hide_render);
@@ -455,15 +501,51 @@ static void outliner_draw_restrictbuts(
if (te->ys + 2 * UI_UNIT_Y >= ar->v2d.cur.ymin && te->ys <= ar->v2d.cur.ymax) {
if (tselem->type == TSE_R_LAYER && (soops->outlinevis == SO_SCENES)) {
/* View layer render toggle. */
- ViewLayer *view_layer = te->directdata;
+ ViewLayer *layer = te->directdata;
bt = uiDefIconButBitS(
block, UI_BTYPE_ICON_TOGGLE_N, VIEW_LAYER_RENDER, 0, ICON_RESTRICT_RENDER_OFF,
(int)(ar->v2d.cur.xmax - OL_TOG_RESTRICT_RENDERX), te->ys, UI_UNIT_X,
- UI_UNIT_Y, &view_layer->flag, 0, 0, 0, 0, TIP_("Use view layer for rendering"));
+ UI_UNIT_Y, &layer->flag, 0, 0, 0, 0, TIP_("Use view layer for rendering"));
UI_but_func_set(bt, restrictbutton_r_lay_cb, tselem->id, NULL);
UI_but_flag_enable(bt, UI_BUT_DRAG_LOCK);
}
+ else if (tselem->type == 0 && te->idcode == ID_OB) {
+ Object *ob = (Object *)tselem->id;
+ Base *base = BKE_view_layer_base_find(view_layer, ob);
+
+ if (base) {
+ bt = uiDefIconButBitS(
+ block, UI_BTYPE_ICON_TOGGLE, BASE_HIDDEN, 0, ICON_HIDE_OFF,
+ (int)(ar->v2d.cur.xmax - OL_TOG_HIDEX), te->ys, UI_UNIT_X,
+ UI_UNIT_Y, &base->flag, 0, 0, 0, 0,
+ TIP_("Hide object in viewport (Ctrl to isolate)"));
+ UI_but_func_set(bt, hidebutton_base_flag_cb, view_layer, base);
+ UI_but_flag_enable(bt, UI_BUT_DRAG_LOCK);
+ }
+
+ PointerRNA ptr;
+ RNA_pointer_create((ID *)ob, &RNA_Object, ob, &ptr);
+
+ bt = uiDefIconButR_prop(block, UI_BTYPE_ICON_TOGGLE, 0, ICON_RESTRICT_VIEW_OFF,
+ (int)(ar->v2d.cur.xmax - OL_TOG_RESTRICT_VIEWX), te->ys, UI_UNIT_X, UI_UNIT_Y,
+ &ptr, object_prop_hide_viewport, -1, 0, 0, -1, -1,
+ TIP_("Restrict viewport visibility"));
+ UI_but_flag_enable(bt, UI_BUT_DRAG_LOCK);
+
+ bt = uiDefIconButR_prop(block, UI_BTYPE_ICON_TOGGLE, 0, ICON_RESTRICT_SELECT_OFF,
+ (int)(ar->v2d.cur.xmax - OL_TOG_RESTRICT_SELECTX), te->ys, UI_UNIT_X, UI_UNIT_Y,
+ &ptr, object_prop_hide_select, -1, 0, 0, -1, -1,
+ TIP_("Restrict viewport selection"));
+ UI_but_flag_enable(bt, UI_BUT_DRAG_LOCK);
+
+ bt = uiDefIconButR_prop(block, UI_BTYPE_ICON_TOGGLE, 0, ICON_RESTRICT_RENDER_OFF,
+ (int)(ar->v2d.cur.xmax - OL_TOG_RESTRICT_RENDERX), te->ys, UI_UNIT_X, UI_UNIT_Y,
+ &ptr, object_prop_hide_render, -1, 0, 0, -1, -1,
+ TIP_("Restrict render visibility"));
+ UI_but_flag_enable(bt, UI_BUT_DRAG_LOCK);
+
+ }
else if (tselem->type == TSE_MODIFIER) {
ModifierData *md = (ModifierData *)te->directdata;
Object *ob = (Object *)tselem->id;
@@ -489,7 +571,7 @@ static void outliner_draw_restrictbuts(
Object *ob = (Object *)tselem->id;
bt = uiDefIconButBitI(
- block, UI_BTYPE_ICON_TOGGLE, BONE_HIDDEN_P, 0, ICON_RESTRICT_VIEW_OFF,
+ block, UI_BTYPE_ICON_TOGGLE, BONE_HIDDEN_P, 0, ICON_HIDE_OFF,
(int)(ar->v2d.cur.xmax - OL_TOG_RESTRICT_VIEWX), te->ys, UI_UNIT_X,
UI_UNIT_Y, &(bone->flag), 0, 0, 0, 0,
TIP_("Restrict/Allow visibility in the 3D View"));
@@ -527,7 +609,7 @@ static void outliner_draw_restrictbuts(
bGPDlayer *gpl = (bGPDlayer *)te->directdata;
bt = uiDefIconButBitS(
- block, UI_BTYPE_ICON_TOGGLE, GP_LAYER_HIDE, 0, ICON_RESTRICT_VIEW_OFF,
+ block, UI_BTYPE_ICON_TOGGLE, GP_LAYER_HIDE, 0, ICON_HIDE_OFF,
(int)(ar->v2d.cur.xmax - OL_TOG_RESTRICT_VIEWX), te->ys, UI_UNIT_X,
UI_UNIT_Y, &gpl->flag, 0, 0, 0, 0,
TIP_("Restrict/Allow visibility in the 3D View"));
@@ -551,6 +633,16 @@ static void outliner_draw_restrictbuts(
if ((!lc || !(lc->flag & LAYER_COLLECTION_EXCLUDE)) &&
!(collection->flag & COLLECTION_IS_MASTER))
{
+ if (lc && (lc->runtime_flag & LAYER_COLLECTION_HAS_ENABLED_OBJECTS)) {
+ bt = uiDefIconButBitS(
+ block, UI_BTYPE_ICON_TOGGLE_N, LAYER_COLLECTION_HAS_VISIBLE_OBJECTS, 0, ICON_HIDE_OFF,
+ (int)(ar->v2d.cur.xmax - OL_TOG_HIDEX), te->ys, UI_UNIT_X,
+ UI_UNIT_Y, &lc->runtime_flag, 0, 0, 0, 0,
+ TIP_("Hide collection in viewport (Ctrl to isolate)"));
+ UI_but_func_set(bt, hidebutton_layer_collection_flag_cb, view_layer, lc);
+ UI_but_flag_enable(bt, UI_BUT_DRAG_LOCK);
+ }
+
PointerRNA collection_ptr;
RNA_id_pointer_create(&collection->id, &collection_ptr);
@@ -576,7 +668,7 @@ static void outliner_draw_restrictbuts(
}
if (TSELEM_OPEN(tselem, soops)) {
- outliner_draw_restrictbuts(block, scene, ar, soops, &te->subtree);
+ outliner_draw_restrictbuts(block, scene, view_layer, ar, soops, &te->subtree);
}
}
}
@@ -814,7 +906,7 @@ static void UNUSED_FUNCTION(tselem_draw_gp_icon_uibut)(struct DrawIconArg *arg,
static void tselem_draw_icon(
uiBlock *block, int xmax, float x, float y, TreeStoreElem *tselem, TreeElement *te,
- float alpha)
+ float alpha, const bool is_clickable)
{
struct DrawIconArg arg;
float aspect;
@@ -835,6 +927,7 @@ static void tselem_draw_icon(
arg.y = y;
#define ICON_DRAW(_icon) UI_icon_draw_alpha(x, y, _icon, alpha)
+#define ICON_CLICK_DRAW(_icon) if (!is_clickable) ICON_DRAW(_icon); else tselem_draw_icon_uibut(&arg, _icon)
if (tselem->type) {
switch (tselem->type) {
@@ -1106,33 +1199,33 @@ static void tselem_draw_icon(
Object *ob = (Object *)tselem->id;
switch (ob->type) {
case OB_LAMP:
- tselem_draw_icon_uibut(&arg, ICON_OUTLINER_OB_LAMP); break;
+ ICON_CLICK_DRAW(ICON_OUTLINER_OB_LAMP); break;
case OB_MESH:
- tselem_draw_icon_uibut(&arg, ICON_OUTLINER_OB_MESH); break;
+ ICON_CLICK_DRAW(ICON_OUTLINER_OB_MESH); break;
case OB_CAMERA:
- tselem_draw_icon_uibut(&arg, ICON_OUTLINER_OB_CAMERA); break;
+ ICON_CLICK_DRAW(ICON_OUTLINER_OB_CAMERA); break;
case OB_CURVE:
- tselem_draw_icon_uibut(&arg, ICON_OUTLINER_OB_CURVE); break;
+ ICON_CLICK_DRAW(ICON_OUTLINER_OB_CURVE); break;
case OB_MBALL:
- tselem_draw_icon_uibut(&arg, ICON_OUTLINER_OB_META); break;
+ ICON_CLICK_DRAW(ICON_OUTLINER_OB_META); break;
case OB_LATTICE:
- tselem_draw_icon_uibut(&arg, ICON_OUTLINER_OB_LATTICE); break;
+ ICON_CLICK_DRAW(ICON_OUTLINER_OB_LATTICE); break;
case OB_ARMATURE:
- tselem_draw_icon_uibut(&arg, ICON_OUTLINER_OB_ARMATURE); break;
+ ICON_CLICK_DRAW(ICON_OUTLINER_OB_ARMATURE); break;
case OB_FONT:
- tselem_draw_icon_uibut(&arg, ICON_OUTLINER_OB_FONT); break;
+ ICON_CLICK_DRAW(ICON_OUTLINER_OB_FONT); break;
case OB_SURF:
- tselem_draw_icon_uibut(&arg, ICON_OUTLINER_OB_SURFACE); break;
+ ICON_CLICK_DRAW(ICON_OUTLINER_OB_SURFACE); break;
case OB_SPEAKER:
- tselem_draw_icon_uibut(&arg, ICON_OUTLINER_OB_SPEAKER); break;
+ ICON_CLICK_DRAW(ICON_OUTLINER_OB_SPEAKER); break;
case OB_LIGHTPROBE:
- tselem_draw_icon_uibut(&arg, ICON_OUTLINER_OB_LIGHTPROBE); break;
+ ICON_CLICK_DRAW(ICON_OUTLINER_OB_LIGHTPROBE); break;
case OB_EMPTY:
if (ob->dup_group) {
- tselem_draw_icon_uibut(&arg, ICON_OUTLINER_OB_GROUP_INSTANCE);
+ ICON_CLICK_DRAW(ICON_OUTLINER_OB_GROUP_INSTANCE);
}
else {
- tselem_draw_icon_uibut(&arg, ICON_OUTLINER_OB_EMPTY);
+ ICON_CLICK_DRAW(ICON_OUTLINER_OB_EMPTY);
}
break;
}
@@ -1240,13 +1333,137 @@ static void tselem_draw_icon(
#undef ICON_DRAW
}
+/**
+ * For icon-only children of a collapsed tree,
+ * Draw small number over the icon to show how many items of this type are displayed.
+ */
+static void outliner_draw_iconrow_number(
+ const uiFontStyle *fstyle,
+ int offsx, int ys,
+ const eOLDrawState active,
+ const int num_elements)
+{
+ float color[4] = {0.4f, 0.4f, 0.4f, 0.9f};
+ copy_v3_fl(color, 0.2f);
+ if (active != OL_DRAWSEL_NONE) {
+ copy_v3_fl(color, 0.65f);
+ color[3] = 1.0f;
+ }
+
+ float ufac = 0.25f * UI_UNIT_X;
+ float offset_x = (float) offsx + UI_UNIT_X * 0.35f;
+
+ UI_draw_roundbox_corner_set(UI_CNR_ALL);
+ UI_draw_roundbox_aa(true,
+ offset_x + ufac,
+ (float)ys - UI_UNIT_Y * 0.2f + ufac,
+ offset_x + UI_UNIT_X - ufac,
+ (float)ys - UI_UNIT_Y * 0.2f + UI_UNIT_Y - ufac,
+ (float)UI_UNIT_Y / 2.0f - ufac,
+ color);
+
+ /* Now the numbers. */
+ unsigned char text_col[4];
+
+ UI_GetThemeColor4ubv(TH_TEXT_HI, text_col);
+ text_col[3] = 255;
+
+ uiFontStyle fstyle_small = *fstyle;
+ fstyle_small.points *= 0.8f;
+
+ /* We treat +99 as 4 digits to make sure the (eyeballed) alignment looks nice. */
+ int num_digits = 4;
+ char number_text[4] = "+99\0";
+ if (num_elements < 100) {
+ BLI_snprintf(number_text, sizeof(number_text), "%d", num_elements);
+ num_digits = num_elements < 10 ? 1 : 2;
+ }
+ UI_fontstyle_draw_simple(&fstyle_small,
+ (offset_x + ufac + UI_UNIT_X * (2 - num_digits) * 0.12f),
+ (float)ys - UI_UNIT_Y * 0.095f + ufac,
+ number_text, text_col);
+ UI_fontstyle_set(fstyle);
+ glEnable(GL_BLEND); /* Roundbox and text drawing disables. */
+}
+
+static void outliner_draw_iconrow_doit(
+ uiBlock *block, TreeElement *te,
+ const uiFontStyle *fstyle,
+ int xmax, int *offsx, int ys, float alpha_fac,
+ const eOLDrawState active,
+ const int num_elements)
+{
+ TreeStoreElem *tselem = TREESTORE(te);
+
+ if (active != OL_DRAWSEL_NONE) {
+ float ufac = UI_UNIT_X / 20.0f;
+ float color[4] = {1.0f, 1.0f, 1.0f, 0.4f};
+
+ UI_draw_roundbox_corner_set(UI_CNR_ALL);
+ color[3] *= alpha_fac;
+
+ UI_draw_roundbox_aa(true,
+ (float) *offsx + 1.0f * ufac,
+ (float)ys + 1.0f * ufac,
+ (float)*offsx + UI_UNIT_X - 1.0f * ufac,
+ (float)ys + UI_UNIT_Y - ufac,
+ (float)UI_UNIT_Y / 2.0f - ufac,
+ color);
+ glEnable(GL_BLEND); /* Roundbox disables. */
+ }
+
+ /* No inlined icon should be clickable. */
+ tselem_draw_icon(block, xmax, (float)*offsx, (float)ys, tselem, te, 0.5f * alpha_fac, false);
+ te->xs = *offsx;
+ te->ys = ys;
+ te->xend = (short)*offsx + UI_UNIT_X;
+
+ if (num_elements > 1) {
+ outliner_draw_iconrow_number(fstyle, *offsx, ys, active, num_elements);
+ }
+ (*offsx) += UI_UNIT_X;
+}
+
+/**
+ * Return the index to use based on the TreeElement ID and object type
+ *
+ * We use a continuum of indeces until we get to the object datablocks
+ * and we then make room for the object types.
+ */
+static int tree_element_id_type_to_index(TreeElement *te)
+{
+ TreeStoreElem *tselem = TREESTORE(te);
+
+ const int id_index = tselem->type == 0 ? BKE_idcode_to_index(te->idcode) : INDEX_ID_GR;
+ if (id_index < INDEX_ID_OB) {
+ return id_index;
+ }
+ else if (id_index == INDEX_ID_OB) {
+ const Object *ob = (Object *)tselem->id;
+ return INDEX_ID_OB + ob->type;
+ }
+ else {
+ return id_index + OB_TYPE_MAX;
+ }
+}
+
static void outliner_draw_iconrow(
- bContext *C, uiBlock *block, Scene *scene, ViewLayer *view_layer, SpaceOops *soops,
+ bContext *C, uiBlock *block, const uiFontStyle *fstyle, Scene *scene, ViewLayer *view_layer, SpaceOops *soops,
ListBase *lb, int level, int xmax, int *offsx, int ys, float alpha_fac)
{
eOLDrawState active;
const Object *obact = OBACT(view_layer);
+ struct {
+ eOLDrawState active[INDEX_ID_MAX + OB_TYPE_MAX];
+ int num_elements[INDEX_ID_MAX + OB_TYPE_MAX];
+ TreeElement *tree_element[INDEX_ID_MAX + OB_TYPE_MAX];
+ } data = {
+ .active = {0},
+ .num_elements = {0},
+ .tree_element = {NULL},
+ };
+
for (TreeElement *te = lb->first; te; te = te->next) {
/* exit drawing early */
if ((*offsx) - UI_UNIT_X > xmax)
@@ -1272,41 +1489,48 @@ static void outliner_draw_iconrow(
active = tree_element_type_active(C, scene, view_layer, soops, te, tselem, OL_SETSEL_NONE, false);
}
- if (active != OL_DRAWSEL_NONE) {
- float ufac = UI_UNIT_X / 20.0f;
- float color[4] = {1.0f, 1.0f, 1.0f, 0.4f};
-
- UI_draw_roundbox_corner_set(UI_CNR_ALL);
- color[3] *= alpha_fac;
-
- UI_draw_roundbox_aa(
- true,
- (float) *offsx + 1.0f * ufac,
- (float)ys + 1.0f * ufac,
- (float)*offsx + UI_UNIT_X - 1.0f * ufac,
- (float)ys + UI_UNIT_Y - ufac,
- (float)UI_UNIT_Y / 2.0f - ufac,
- color);
- glEnable(GL_BLEND); /* roundbox disables */
+ if (!ELEM(tselem->type, 0, TSE_LAYER_COLLECTION)) {
+ outliner_draw_iconrow_doit(block, te, fstyle, xmax, offsx, ys, alpha_fac, active, 1);
+ }
+ else {
+ const int index = tree_element_id_type_to_index(te);
+ data.num_elements[index]++;
+ if ((data.tree_element[index] == NULL) ||
+ (active > data.active[index]))
+ {
+ data.tree_element[index] = te;
+ }
+ data.active[index] = MAX2(active, data.active[index]);
}
-
- tselem_draw_icon(block, xmax, (float)*offsx, (float)ys, tselem, te, 0.5f * alpha_fac);
- te->xs = *offsx;
- te->ys = ys;
- te->xend = (short)*offsx + UI_UNIT_X;
- te->flag |= TE_ICONROW; // for click
-
- (*offsx) += UI_UNIT_X;
}
/* this tree element always has same amount of branches, so don't draw */
if (tselem->type != TSE_R_LAYER) {
outliner_draw_iconrow(
- C, block, scene, view_layer, soops,
+ C, block, fstyle, scene, view_layer, soops,
&te->subtree, level + 1, xmax, offsx, ys, alpha_fac);
}
}
+ for (int i = 0; i < INDEX_ID_MAX; i++) {
+ const int num_subtypes = (i == INDEX_ID_OB) ? OB_TYPE_MAX : 1;
+ /* See tree_element_id_type_to_index for the index logic. */
+ int index_base = i;
+ if (i > INDEX_ID_OB) {
+ index_base += OB_TYPE_MAX;
+ }
+ for (int j = 0; j < num_subtypes; j++) {
+ const int index = index_base + j;
+ if (data.num_elements[index] != 0) {
+ outliner_draw_iconrow_doit(block,
+ data.tree_element[index],
+ fstyle,
+ xmax, offsx, ys, alpha_fac,
+ data.active[index],
+ data.num_elements[index]);
+ }
+ }
+ }
}
/* closed tree element */
@@ -1447,7 +1671,7 @@ static void outliner_draw_tree_element(
/* datatype icon */
if (!(ELEM(tselem->type, TSE_RNA_PROPERTY, TSE_RNA_ARRAY_ELEM, TSE_ID_BASE))) {
- tselem_draw_icon(block, xmax, (float)startx + offsx, (float)*starty, tselem, te, alpha_fac);
+ tselem_draw_icon(block, xmax, (float)startx + offsx, (float)*starty, tselem, te, alpha_fac, true);
offsx += UI_UNIT_X + 2 * ufac;
}
else
@@ -1531,7 +1755,7 @@ static void outliner_draw_tree_element(
}
outliner_draw_iconrow(
- C, block, scene, view_layer, soops, &te->subtree, 0, xmax, &tempx,
+ C, block, fstyle, scene, view_layer, soops, &te->subtree, 0, xmax, &tempx,
*starty, alpha_fac);
glDisable(GL_BLEND);
@@ -1736,7 +1960,6 @@ static void outliner_draw_highlights_recursive(
const bool is_searching = (
SEARCHING_OUTLINER(soops) ||
(soops->outlinevis == SO_DATA_API &&
- (soops->filter & SO_FILTER_SEARCH) &&
soops->search_string[0] != 0));
for (TreeElement *te = lb->first; te; te = te->next) {
@@ -1893,7 +2116,10 @@ static void outliner_draw_restrictcols(ARegion *ar)
unsigned int pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_I32, 2, GWN_FETCH_INT_TO_FLOAT);
immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
immUniformThemeColorShadeAlpha(TH_BACK, -15, -200);
- immBegin(GWN_PRIM_LINES, 6);
+ immBegin(GWN_PRIM_LINES, 8);
+
+ immVertex2i(pos, (int)(ar->v2d.cur.xmax - OL_TOG_HIDEX), (int)ar->v2d.cur.ymax);
+ immVertex2i(pos, (int)(ar->v2d.cur.xmax - OL_TOG_HIDEX), (int)ar->v2d.cur.ymin);
immVertex2i(pos, (int)(ar->v2d.cur.xmax - OL_TOG_RESTRICT_VIEWX), (int)ar->v2d.cur.ymax);
immVertex2i(pos, (int)(ar->v2d.cur.xmax - OL_TOG_RESTRICT_VIEWX), (int)ar->v2d.cur.ymin);
@@ -1999,16 +2225,16 @@ void draw_outliner(const bContext *C)
/* draw restriction columns */
outliner_draw_restrictcols(ar);
- outliner_draw_restrictbuts(block, scene, ar, soops, &soops->tree);
+ outliner_draw_restrictbuts(block, scene, view_layer, ar, soops, &soops->tree);
}
+ UI_block_emboss_set(block, UI_EMBOSS);
+
/* draw edit buttons if nessecery */
if (te_edit) {
outliner_buttons(C, block, ar, te_edit);
}
- UI_block_emboss_set(block, UI_EMBOSS);
-
UI_block_end(C, block);
UI_block_draw(C, block);
}
diff --git a/source/blender/editors/space_outliner/outliner_edit.c b/source/blender/editors/space_outliner/outliner_edit.c
index c6288dc05ef..990d50ae42a 100644
--- a/source/blender/editors/space_outliner/outliner_edit.c
+++ b/source/blender/editors/space_outliner/outliner_edit.c
@@ -253,6 +253,55 @@ void OUTLINER_OT_item_openclose(wmOperatorType *ot)
RNA_def_boolean(ot->srna, "all", 1, "All", "Close or open all items");
}
+/* -------------------------------------------------------------------- */
+/** \name Object Mode Enter/Exit
+ * \{ */
+
+static void item_object_mode_enter_exit(
+ bContext *C, ReportList *reports, Object *ob,
+ bool enter)
+{
+ ViewLayer *view_layer = CTX_data_view_layer(C);
+ Object *obact = OBACT(view_layer);
+
+ if ((ob->type != obact->type) || ID_IS_LINKED(ob->data)) {
+ return;
+ }
+ if (((ob->mode & obact->mode) != 0) == enter) {
+ return;
+ }
+
+ if (ob == obact) {
+ BKE_report(reports, RPT_WARNING, "Active object mode not changed");
+ return;
+ }
+
+ Base *base = BKE_view_layer_base_find(view_layer, ob);
+ if (base == NULL) {
+ return;
+ }
+ Scene *scene = CTX_data_scene(C);
+ outliner_object_mode_toggle(C, scene, view_layer, base);
+}
+
+void item_object_mode_enter_cb(
+ bContext *C, ReportList *reports, Scene *UNUSED(scene), TreeElement *UNUSED(te),
+ TreeStoreElem *UNUSED(tsep), TreeStoreElem *tselem, void *UNUSED(user_data))
+{
+ Object *ob = (Object *)tselem->id;
+ item_object_mode_enter_exit(C, reports, ob, true);
+}
+
+void item_object_mode_exit_cb(
+ bContext *C, ReportList *reports, Scene *UNUSED(scene), TreeElement *UNUSED(te),
+ TreeStoreElem *UNUSED(tsep), TreeStoreElem *tselem, void *UNUSED(user_data))
+{
+ Object *ob = (Object *)tselem->id;
+ item_object_mode_enter_exit(C, reports, ob, false);
+}
+
+/** \} */
+
/* Rename --------------------------------------------------- */
static void do_item_rename(ARegion *ar, TreeElement *te, TreeStoreElem *tselem,
@@ -493,7 +542,7 @@ static int outliner_id_remap_exec(bContext *C, wmOperator *op)
DEG_relations_tag_update(bmain);
/* free gpu materials, some materials depend on existing objects, such as lamps so freeing correctly refreshes */
- GPU_materials_free();
+ GPU_materials_free(bmain);
WM_event_add_notifier(C, NC_WINDOW, NULL);
@@ -2317,6 +2366,7 @@ static int collection_drop_invoke(bContext *C, wmOperator *op, const wmEvent *ev
Object *ob = (Object *)BKE_libblock_find_name(bmain, ID_OB, childname);
BKE_collection_object_add(bmain, collection, ob);
+ DEG_id_tag_update(&collection->id, DEG_TAG_COPY_ON_WRITE);
DEG_relations_tag_update(bmain);
WM_event_add_notifier(C, NC_SCENE | ND_LAYER, scene);
diff --git a/source/blender/editors/space_outliner/outliner_intern.h b/source/blender/editors/space_outliner/outliner_intern.h
index 8ac09648d60..0ab22208841 100644
--- a/source/blender/editors/space_outliner/outliner_intern.h
+++ b/source/blender/editors/space_outliner/outliner_intern.h
@@ -151,11 +151,12 @@ typedef enum {
/* size constants */
#define OL_Y_OFFSET 2
+#define OL_TOG_HIDEX (UI_UNIT_X * 4.0f)
#define OL_TOG_RESTRICT_SELECTX (UI_UNIT_X * 3.0f)
#define OL_TOG_RESTRICT_VIEWX (UI_UNIT_X * 2.0f)
#define OL_TOG_RESTRICT_RENDERX UI_UNIT_X
-#define OL_TOGW OL_TOG_RESTRICT_SELECTX
+#define OL_TOGW OL_TOG_HIDEX
#define OL_RNA_COLX (UI_UNIT_X * 15)
#define OL_RNA_COL_SIZEX (UI_UNIT_X * 7.5f)
@@ -181,7 +182,7 @@ typedef enum {
* - not searching into RNA items helps but isn't the complete solution
*/
-#define SEARCHING_OUTLINER(sov) ((sov->search_flags & SO_SEARCH_RECURSIVE) && (sov->filter & SO_FILTER_SEARCH))
+#define SEARCHING_OUTLINER(sov) (sov->search_flags & SO_SEARCH_RECURSIVE)
/* is the currrent element open? if so we also show children */
#define TSELEM_OPEN(telm, sv) ( (telm->flag & TSE_CLOSED) == 0 || (SEARCHING_OUTLINER(sv) && (telm->flag & TSE_CHILDSEARCH)) )
@@ -226,6 +227,10 @@ void outliner_item_select(
struct SpaceOops *soops, const struct TreeElement *te,
const bool extend, const bool toggle);
+void outliner_object_mode_toggle(
+ struct bContext *C, Scene *scene, ViewLayer *view_layer,
+ Base *base);
+
/* outliner_edit.c ---------------------------------------------- */
typedef void (*outliner_operation_cb)(
struct bContext *C, struct ReportList *, struct Scene *scene,
@@ -271,6 +276,13 @@ void id_remap_cb(
struct bContext *C, struct ReportList *reports, struct Scene *scene, struct TreeElement *te,
struct TreeStoreElem *tsep, struct TreeStoreElem *tselem, void *user_data);
+void item_object_mode_enter_cb(
+ struct bContext *C, struct ReportList *reports, struct Scene *scene,
+ TreeElement *te, struct TreeStoreElem *tsep, struct TreeStoreElem *tselem, void *user_data);
+void item_object_mode_exit_cb(
+ struct bContext *C, struct ReportList *reports, struct Scene *scene,
+ TreeElement *te, struct TreeStoreElem *tsep, struct TreeStoreElem *tselem, void *user_data);
+
TreeElement *outliner_dropzone_find(const struct SpaceOops *soops, const float fmval[2], const bool children);
void outliner_set_coordinates(struct ARegion *ar, struct SpaceOops *soops);
diff --git a/source/blender/editors/space_outliner/outliner_ops.c b/source/blender/editors/space_outliner/outliner_ops.c
index ecfd12618e5..316caf0e239 100644
--- a/source/blender/editors/space_outliner/outliner_ops.c
+++ b/source/blender/editors/space_outliner/outliner_ops.c
@@ -560,6 +560,13 @@ void outliner_keymap(wmKeyConfig *keyconf)
WM_keymap_verify_item(keymap, "OBJECT_OT_move_to_collection", MKEY, KM_PRESS, 0, 0);
WM_keymap_verify_item(keymap, "OBJECT_OT_link_to_collection", MKEY, KM_PRESS, KM_SHIFT, 0);
+ kmi = WM_keymap_add_item(keymap, "OBJECT_OT_hide_view_clear", HKEY, KM_PRESS, KM_ALT, 0);
+ RNA_boolean_set(kmi->ptr, "select", false);
+ kmi = WM_keymap_add_item(keymap, "OBJECT_OT_hide_view_set", HKEY, KM_PRESS, 0, 0);
+ RNA_boolean_set(kmi->ptr, "unselected", false);
+ kmi = WM_keymap_add_item(keymap, "OBJECT_OT_hide_view_set", HKEY, KM_PRESS, KM_SHIFT, 0);
+ RNA_boolean_set(kmi->ptr, "unselected", true);
+
outliner_item_drag_drop_modal_keymap(keyconf);
}
diff --git a/source/blender/editors/space_outliner/outliner_select.c b/source/blender/editors/space_outliner/outliner_select.c
index 6a6a392e4a6..9b430b0af99 100644
--- a/source/blender/editors/space_outliner/outliner_select.c
+++ b/source/blender/editors/space_outliner/outliner_select.c
@@ -155,6 +155,20 @@ static void do_outliner_activate_pose(bContext *C, ViewLayer *view_layer, Base *
}
}
+/* For draw callback to run mode switching */
+void outliner_object_mode_toggle(
+ bContext *C, Scene *scene, ViewLayer *view_layer,
+ Base *base)
+{
+ Object *obact = OBACT(view_layer);
+ if (obact->mode & OB_MODE_EDIT) {
+ do_outliner_activate_obdata(C, scene, view_layer, base);
+ }
+ else if (obact->mode & OB_MODE_POSE) {
+ do_outliner_activate_pose(C, view_layer, base);
+ }
+}
+
/* ****************************************************** */
/* Outliner Element Selection/Activation on Click */
@@ -192,7 +206,7 @@ static void do_outliner_object_select_recursive(ViewLayer *view_layer, Object *o
for (base = FIRSTBASE(view_layer); base; base = base->next) {
Object *ob = base->object;
- if ((((base->flag & BASE_VISIBLED) == 0) && BKE_object_is_child_recursive(ob_parent, ob))) {
+ if ((((base->flag & BASE_VISIBLE) == 0) && BKE_object_is_child_recursive(ob_parent, ob))) {
ED_object_base_select(base, select ? BA_SELECT : BA_DESELECT);
}
}
@@ -986,7 +1000,7 @@ static void do_outliner_item_activate_tree_element(
Object *ob = (Object *)outliner_search_back(soops, te, ID_OB);
if ((ob != NULL) && (ob->data == tselem->id)) {
Base *base = BKE_view_layer_base_find(view_layer, ob);
- if ((base != NULL) && (base->flag & BASE_VISIBLED)) {
+ if ((base != NULL) && (base->flag & BASE_VISIBLE)) {
do_outliner_activate_obdata(C, scene, view_layer, base);
}
}
diff --git a/source/blender/editors/space_outliner/outliner_tools.c b/source/blender/editors/space_outliner/outliner_tools.c
index f8d9877be6e..e2eb617278b 100644
--- a/source/blender/editors/space_outliner/outliner_tools.c
+++ b/source/blender/editors/space_outliner/outliner_tools.c
@@ -229,18 +229,22 @@ static void unlink_collection_cb(
if (GS(tsep->id->name) == ID_OB) {
Object *ob = (Object *)tsep->id;
ob->dup_group = NULL;
+ DEG_id_tag_update(&ob->id, OB_RECALC_OB);
DEG_relations_tag_update(bmain);
}
else if (GS(tsep->id->name) == ID_GR) {
Collection *parent = (Collection *)tsep->id;
id_fake_user_set(&collection->id);
BKE_collection_child_remove(bmain, parent, collection);
+ DEG_id_tag_update(&parent->id, DEG_TAG_COPY_ON_WRITE);
DEG_relations_tag_update(bmain);
}
else if (GS(tsep->id->name) == ID_SCE) {
- Collection *parent = BKE_collection_master((Scene *)tsep->id);
+ Scene *scene = (Scene *)tsep->id;
+ Collection *parent = BKE_collection_master(scene);
id_fake_user_set(&collection->id);
BKE_collection_child_remove(bmain, parent, collection);
+ DEG_id_tag_update(&scene->id, DEG_TAG_COPY_ON_WRITE);
DEG_relations_tag_update(bmain);
}
}
@@ -257,11 +261,14 @@ static void unlink_object_cb(
if (GS(tsep->id->name) == ID_GR) {
Collection *parent = (Collection *)tsep->id;
BKE_collection_object_remove(bmain, parent, ob, true);
+ DEG_id_tag_update(&parent->id, DEG_TAG_COPY_ON_WRITE);
DEG_relations_tag_update(bmain);
}
else if (GS(tsep->id->name) == ID_SCE) {
- Collection *parent = BKE_collection_master((Scene *)tsep->id);
+ Scene *scene = (Scene *)tsep->id;
+ Collection *parent = BKE_collection_master(scene);
BKE_collection_object_remove(bmain, parent, ob, true);
+ DEG_id_tag_update(&scene->id, DEG_TAG_COPY_ON_WRITE);
DEG_relations_tag_update(bmain);
}
}
@@ -394,7 +401,7 @@ static void object_select_cb(
Object *ob = (Object *)tselem->id;
Base *base = BKE_view_layer_base_find(view_layer, ob);
- if (base && ((base->flag & BASE_VISIBLED) != 0)) {
+ if (base && ((base->flag & BASE_VISIBLE) != 0)) {
base->flag |= BASE_SELECTED;
}
}
@@ -911,6 +918,8 @@ enum {
OL_OP_TOGSEL,
OL_OP_TOGREN,
OL_OP_RENAME,
+ OL_OP_OBJECT_MODE_ENTER,
+ OL_OP_OBJECT_MODE_EXIT,
};
static const EnumPropertyItem prop_object_op_types[] = {
@@ -922,6 +931,8 @@ static const EnumPropertyItem prop_object_op_types[] = {
{OL_OP_REMAP, "REMAP", 0, "Remap Users",
"Make all users of selected data-blocks to use instead a new chosen one"},
{OL_OP_RENAME, "RENAME", 0, "Rename", ""},
+ {OL_OP_OBJECT_MODE_ENTER, "OBJECT_MODE_ENTER", 0, "Enter Mode", ""},
+ {OL_OP_OBJECT_MODE_EXIT, "OBJECT_MODE_EXIT", 0, "Exit Mode", ""},
{0, NULL, 0, NULL, NULL}
};
@@ -1005,6 +1016,14 @@ static int outliner_object_operation_exec(bContext *C, wmOperator *op)
outliner_do_object_operation(C, op->reports, scene, soops, &soops->tree, item_rename_cb);
str = "Rename Object";
}
+ else if (event == OL_OP_OBJECT_MODE_ENTER) {
+ outliner_do_object_operation(C, op->reports, scene, soops, &soops->tree, item_object_mode_enter_cb);
+ str = "Enter Current Mode";
+ }
+ else if (event == OL_OP_OBJECT_MODE_EXIT) {
+ outliner_do_object_operation(C, op->reports, scene, soops, &soops->tree, item_object_mode_exit_cb);
+ str = "Exit Current Mode";
+ }
else {
BLI_assert(0);
return OPERATOR_CANCELLED;
@@ -1574,8 +1593,8 @@ void OUTLINER_OT_animdata_operation(wmOperatorType *ot)
/* **************************************** */
static const EnumPropertyItem prop_constraint_op_types[] = {
- {OL_CONSTRAINTOP_ENABLE, "ENABLE", ICON_RESTRICT_VIEW_OFF, "Enable", ""},
- {OL_CONSTRAINTOP_DISABLE, "DISABLE", ICON_RESTRICT_VIEW_ON, "Disable", ""},
+ {OL_CONSTRAINTOP_ENABLE, "ENABLE", ICON_HIDE_OFF, "Enable", ""},
+ {OL_CONSTRAINTOP_DISABLE, "DISABLE", ICON_HIDE_ON, "Disable", ""},
{OL_CONSTRAINTOP_DELETE, "DELETE", ICON_X, "Delete", ""},
{0, NULL, 0, NULL, NULL}
};
diff --git a/source/blender/editors/space_outliner/outliner_tree.c b/source/blender/editors/space_outliner/outliner_tree.c
index d155457a208..9f6c944c914 100644
--- a/source/blender/editors/space_outliner/outliner_tree.c
+++ b/source/blender/editors/space_outliner/outliner_tree.c
@@ -1469,6 +1469,10 @@ static void outliner_add_layer_collection_objects(
Base *base = BKE_view_layer_base_find(layer, cob->ob);
TreeElement *te_object = outliner_add_element(soops, tree, base->object, ten, 0, 0);
te_object->directdata = base;
+
+ if (!(base->flag & BASE_VISIBLE)) {
+ te_object->flag |= TE_DISABLED;
+ }
}
}
@@ -1487,7 +1491,10 @@ static void outliner_add_layer_collections_recursive(
ten->reinsert_poll = outliner_collections_reorder_poll;
const bool exclude = (lc->flag & LAYER_COLLECTION_EXCLUDE) != 0;
- if (exclude) {
+ if (exclude ||
+ ((layer->runtime_flag & VIEW_LAYER_HAS_HIDE) &&
+ !(lc->runtime_flag & LAYER_COLLECTION_HAS_VISIBLE_OBJECTS)))
+ {
ten->flag |= TE_DISABLED;
}
@@ -1885,10 +1892,11 @@ static int outliner_exclude_filter_get(SpaceOops *soops)
{
int exclude_filter = soops->filter & ~SO_FILTER_OB_STATE;
- if (soops->filter & SO_FILTER_SEARCH) {
- if (soops->search_string[0] == 0) {
- exclude_filter &= ~SO_FILTER_SEARCH;
- }
+ if (soops->search_string[0] != 0) {
+ exclude_filter |= SO_FILTER_SEARCH;
+ }
+ else {
+ exclude_filter &= ~SO_FILTER_SEARCH;
}
/* Let's have this for the collection options at first. */
@@ -1976,7 +1984,7 @@ static bool outliner_element_visible_get(ViewLayer *view_layer, TreeElement *te,
}
if (exclude_filter & SO_FILTER_OB_STATE_VISIBLE) {
- if ((base->flag & BASE_VISIBLED) == 0) {
+ if ((base->flag & BASE_VISIBLE) == 0) {
return false;
}
}
@@ -2262,5 +2270,3 @@ void outliner_build_tree(Main *mainvar, Scene *scene, ViewLayer *view_layer, Spa
BKE_main_id_clear_newpoins(mainvar);
}
-
-
diff --git a/source/blender/editors/space_view3d/space_view3d.c b/source/blender/editors/space_view3d/space_view3d.c
index 2d51a4b4554..6b95df7c917 100644
--- a/source/blender/editors/space_view3d/space_view3d.c
+++ b/source/blender/editors/space_view3d/space_view3d.c
@@ -335,6 +335,9 @@ static SpaceLink *view3d_new(const ScrArea *UNUSED(sa), const Scene *scene)
v3d->overlay.flag = V3D_OVERLAY_LOOK_DEV;
v3d->overlay.wireframe_threshold = 0.5f;
v3d->overlay.bone_selection_alpha = 0.5f;
+ v3d->overlay.texture_paint_mode_opacity = 0.8;
+ v3d->overlay.weight_paint_mode_opacity = 0.8;
+ v3d->overlay.vertex_paint_mode_opacity = 0.8;
v3d->gridflag = V3D_SHOW_X | V3D_SHOW_Y | V3D_SHOW_FLOOR;
@@ -1410,7 +1413,7 @@ static int view3d_context(const bContext *C, const char *member, bContextDataRes
if (view_layer->basact) {
Object *ob = view_layer->basact->object;
/* if hidden but in edit mode, we still display, can happen with animation */
- if ((view_layer->basact->flag & BASE_VISIBLED) != 0 || (ob->mode & OB_MODE_EDIT)) {
+ if ((view_layer->basact->flag & BASE_VISIBLE) != 0 || (ob->mode & OB_MODE_EDIT)) {
CTX_data_pointer_set(result, &scene->id, &RNA_ObjectBase, view_layer->basact);
}
}
@@ -1422,7 +1425,7 @@ static int view3d_context(const bContext *C, const char *member, bContextDataRes
if (view_layer->basact) {
Object *ob = view_layer->basact->object;
/* if hidden but in edit mode, we still display, can happen with animation */
- if ((view_layer->basact->flag & BASE_VISIBLED) != 0 || (ob->mode & OB_MODE_EDIT) != 0) {
+ if ((view_layer->basact->flag & BASE_VISIBLE) != 0 || (ob->mode & OB_MODE_EDIT) != 0) {
CTX_data_id_pointer_set(result, &ob->id);
}
}
@@ -1541,11 +1544,6 @@ void ED_spacetype_view3d(void)
art->draw = view3d_tools_region_draw;
BLI_addhead(&st->regiontypes, art);
-#if 0
- /* unfinished still */
- view3d_toolshelf_register(art);
-#endif
-
/* regions: header */
art = MEM_callocN(sizeof(ARegionType), "spacetype view3d header region");
art->regionid = RGN_TYPE_HEADER;
diff --git a/source/blender/editors/space_view3d/view3d_buttons.c b/source/blender/editors/space_view3d/view3d_buttons.c
index 300b6fafd7a..6ebed88728e 100644
--- a/source/blender/editors/space_view3d/view3d_buttons.c
+++ b/source/blender/editors/space_view3d/view3d_buttons.c
@@ -69,6 +69,7 @@
#include "RNA_access.h"
#include "ED_armature.h"
+#include "ED_object.h"
#include "ED_mesh.h"
#include "ED_screen.h"
@@ -1163,6 +1164,11 @@ static void view3d_panel_transform(const bContext *C, Panel *pa)
}
}
+static void hide_collections_menu_draw(const bContext *C, Menu *menu)
+{
+ ED_hide_collections_menu_draw(C, menu->layout);
+}
+
void view3d_buttons_register(ARegionType *art)
{
PanelType *pt;
@@ -1182,6 +1188,15 @@ void view3d_buttons_register(ARegionType *art)
pt->draw = view3d_panel_vgroup;
pt->poll = view3d_panel_vgroup_poll;
BLI_addtail(&art->paneltypes, pt);
+
+ MenuType *mt;
+
+ mt = MEM_callocN(sizeof(MenuType), "spacetype view3d menu collections");
+ strcpy(mt->idname, "VIEW3D_MT_collection");
+ strcpy(mt->label, N_("Collection"));
+ strcpy(mt->translation_context, BLT_I18NCONTEXT_DEFAULT_BPYRNA);
+ mt->draw = hide_collections_menu_draw;
+ WM_menutype_add(mt);
}
static int view3d_properties_toggle_exec(bContext *C, wmOperator *UNUSED(op))
diff --git a/source/blender/editors/space_view3d/view3d_draw.c b/source/blender/editors/space_view3d/view3d_draw.c
index fd2f604651b..74554e8d62b 100644
--- a/source/blender/editors/space_view3d/view3d_draw.c
+++ b/source/blender/editors/space_view3d/view3d_draw.c
@@ -44,6 +44,7 @@
#include "BKE_context.h"
#include "BKE_global.h"
#include "BKE_key.h"
+#include "BKE_main.h"
#include "BKE_scene.h"
#include "BKE_object.h"
#include "BKE_paint.h"
@@ -1182,7 +1183,7 @@ static void draw_selected_name(Scene *scene, Object *ob, rcti *rect)
/**
* Information drawn on top of the solid plates and composed data
*/
-void view3d_draw_region_info(const bContext *C, ARegion *ar, const int offset)
+void view3d_draw_region_info(const bContext *C, ARegion *ar, const int UNUSED(offset))
{
RegionView3D *rv3d = ar->regiondata;
View3D *v3d = CTX_wm_view3d(C);
@@ -1196,8 +1197,6 @@ void view3d_draw_region_info(const bContext *C, ARegion *ar, const int offset)
rcti rect;
ED_region_visible_rect(ar, &rect);
- /* Leave room for previously drawn info. */
- rect.ymax -= offset;
view3d_draw_border(C, ar);
view3d_draw_grease_pencil(C);
@@ -1271,11 +1270,12 @@ RenderEngineType *ED_view3d_engine_type(Scene *scene, int drawtype)
void view3d_main_region_draw(const bContext *C, ARegion *ar)
{
+ Main *bmain = CTX_data_main(C);
View3D *v3d = CTX_wm_view3d(C);
view3d_draw_view(C, ar);
- GPU_free_images_old();
+ GPU_free_images_old(bmain);
GPU_pass_cache_garbage_collect();
/* XXX This is in order to draw UI batches with the DRW
@@ -1348,7 +1348,7 @@ void ED_view3d_draw_offscreen(
if ((v3d->flag2 & V3D_RENDER_SHADOW) == 0) {
/* free images which can have changed on frame-change
* warning! can be slow so only free animated images - campbell */
- GPU_free_images_anim();
+ GPU_free_images_anim(G.main); /* XXX :((( */
}
gpuPushProjectionMatrix();
diff --git a/source/blender/editors/space_view3d/view3d_draw_legacy.c b/source/blender/editors/space_view3d/view3d_draw_legacy.c
index 3a89c910ea8..b19001ab834 100644
--- a/source/blender/editors/space_view3d/view3d_draw_legacy.c
+++ b/source/blender/editors/space_view3d/view3d_draw_legacy.c
@@ -263,7 +263,7 @@ static void backdrawview3d(
G.f |= G_BACKBUFSEL;
- if (obact_eval && ((obact_eval->base_flag & BASE_VISIBLED) != 0)) {
+ if (obact_eval && ((obact_eval->base_flag & BASE_VISIBLE) != 0)) {
draw_object_backbufsel(depsgraph, scene_eval, v3d, rv3d, obact_eval, select_mode);
}
diff --git a/source/blender/editors/space_view3d/view3d_edit.c b/source/blender/editors/space_view3d/view3d_edit.c
index bae186097a8..88c7eabc62f 100644
--- a/source/blender/editors/space_view3d/view3d_edit.c
+++ b/source/blender/editors/space_view3d/view3d_edit.c
@@ -4553,7 +4553,7 @@ void VIEW3D_OT_clip_border(wmOperatorType *ot)
/* cursor position in vec, result in vec, mval in region coords */
/* note: cannot use event->mval here (called by object_add() */
-void ED_view3d_cursor3d_position(bContext *C, float fp[3], const int mval[2])
+void ED_view3d_cursor3d_position(bContext *C, const int mval[2], bool use_depth, float cursor_co[3])
{
ARegion *ar = CTX_wm_region(C);
View3D *v3d = CTX_wm_view3d(C);
@@ -4566,32 +4566,35 @@ void ED_view3d_cursor3d_position(bContext *C, float fp[3], const int mval[2])
if (rv3d == NULL)
return;
- ED_view3d_calc_zfac(rv3d, fp, &flip);
+ ED_view3d_calc_zfac(rv3d, cursor_co, &flip);
/* reset the depth based on the view offset (we _know_ the offset is infront of us) */
if (flip) {
- negate_v3_v3(fp, rv3d->ofs);
+ negate_v3_v3(cursor_co, rv3d->ofs);
/* re initialize, no need to check flip again */
- ED_view3d_calc_zfac(rv3d, fp, NULL /* &flip */ );
+ ED_view3d_calc_zfac(rv3d, cursor_co, NULL /* &flip */ );
}
- if (U.uiflag & USER_DEPTH_CURSOR) { /* maybe this should be accessed some other way */
+ if (use_depth) { /* maybe this should be accessed some other way */
struct Depsgraph *depsgraph = CTX_data_depsgraph(C);
view3d_operator_needs_opengl(C);
- if (ED_view3d_autodist(depsgraph, ar, v3d, mval, fp, true, NULL)) {
+ if (ED_view3d_autodist(depsgraph, ar, v3d, mval, cursor_co, true, NULL)) {
depth_used = true;
}
}
if (depth_used == false) {
float depth_pt[3];
- copy_v3_v3(depth_pt, fp);
- ED_view3d_win_to_3d_int(v3d, ar, depth_pt, mval, fp);
+ copy_v3_v3(depth_pt, cursor_co);
+ ED_view3d_win_to_3d_int(v3d, ar, depth_pt, mval, cursor_co);
}
}
-void ED_view3d_cursor3d_update(bContext *C, const int mval[2])
+void ED_view3d_cursor3d_position_rotation(
+ bContext *C, const int mval[2],
+ const bool use_depth, enum eV3DCursorOrient orientation,
+ float cursor_co[3], float cursor_quat[4])
{
Main *bmain = CTX_data_main(C);
Scene *scene = CTX_data_scene(C);
@@ -4599,16 +4602,26 @@ void ED_view3d_cursor3d_update(bContext *C, const int mval[2])
ARegion *ar = CTX_wm_region(C);
RegionView3D *rv3d = ar->regiondata;
- View3DCursor *cursor_curr = ED_view3d_cursor3d_get(scene, v3d);
- View3DCursor cursor_prev = *cursor_curr;
+ /* XXX, caller should check. */
+ if (rv3d == NULL)
+ return;
- ED_view3d_cursor3d_position(C, cursor_curr->location, mval);
- copy_qt_qt(cursor_curr->rotation, rv3d->viewquat);
- cursor_curr->rotation[0] *= -1.0f;
+ ED_view3d_cursor3d_position(C, mval, use_depth, cursor_co);
+
+ if (orientation == V3D_CURSOR_ORIENT_NONE) {
+ /* pass */
+ }
+ else if (orientation == V3D_CURSOR_ORIENT_VIEW) {
+ copy_qt_qt(cursor_quat, rv3d->viewquat);
+ cursor_quat[0] *= -1.0f;
+ }
+ else if (orientation == V3D_CURSOR_ORIENT_GEOM) {
+ copy_qt_qt(cursor_quat, rv3d->viewquat);
+ cursor_quat[0] *= -1.0f;
- {
const float mval_fl[2] = {UNPACK2(mval)};
float ray_no[3];
+ float ray_co[3];
struct SnapObjectContext *snap_context = ED_transform_snap_object_context_create_view3d(
bmain, scene, CTX_data_depsgraph(C), 0, ar, v3d);
@@ -4624,16 +4637,21 @@ void ED_view3d_cursor3d_update(bContext *C, const int mval[2])
.use_object_edit_cage = false,
},
mval_fl, &dist_px,
- cursor_curr->location, ray_no, NULL,
+ ray_co, ray_no, NULL,
&ob_dummy, obmat))
{
+ if (use_depth) {
+ copy_v3_v3(cursor_co, ray_co);
+ }
+
float tquat[4];
+
/* Math normal (Z). */
{
float z_src[3] = {0, 0, 1};
- mul_qt_v3(cursor_curr->rotation, z_src);
+ mul_qt_v3(cursor_quat, z_src);
rotation_between_vecs_to_quat(tquat, z_src, ray_no);
- mul_qt_qtqt(cursor_curr->rotation, tquat, cursor_curr->rotation);
+ mul_qt_qtqt(cursor_quat, tquat, cursor_quat);
}
/* Match object matrix (X). */
@@ -4646,27 +4664,47 @@ void ED_view3d_cursor3d_update(bContext *C, const int mval[2])
const int ortho_axis = axis_dominant_v3_ortho_single(ortho_axis_dot);
float x_src[3] = {1, 0, 0};
float x_dst[3];
- mul_qt_v3(cursor_curr->rotation, x_src);
+ mul_qt_v3(cursor_quat, x_src);
project_plane_v3_v3v3(x_dst, obmat[ortho_axis], ray_no);
normalize_v3(x_dst);
rotation_between_vecs_to_quat(tquat, x_src, x_dst);
- mul_qt_qtqt(cursor_curr->rotation, tquat, cursor_curr->rotation);
+ mul_qt_qtqt(cursor_quat, tquat, cursor_quat);
}
}
ED_transform_snap_object_context_destroy(snap_context);
}
+}
+
+void ED_view3d_cursor3d_update(
+ bContext *C, const int mval[2],
+ const bool use_depth, enum eV3DCursorOrient orientation)
+{
+ Scene *scene = CTX_data_scene(C);
+ View3D *v3d = CTX_wm_view3d(C);
+ ARegion *ar = CTX_wm_region(C);
+ RegionView3D *rv3d = ar->regiondata;
+
+ View3DCursor *cursor_curr = ED_view3d_cursor3d_get(scene, v3d);
+ View3DCursor cursor_prev = *cursor_curr;
+
+ ED_view3d_cursor3d_position_rotation(
+ C, mval,
+ use_depth, orientation,
+ cursor_curr->location, cursor_curr->rotation);
/* offset the cursor lock to avoid jumping to new offset */
if (v3d->ob_centre_cursor) {
if (U.uiflag & USER_LOCK_CURSOR_ADJUST) {
- float co_curr[2], co_prev[2];
+ float co_2d_curr[2], co_2d_prev[2];
- if ((ED_view3d_project_float_global(ar, cursor_prev.location, co_prev, V3D_PROJ_TEST_NOP) == V3D_PROJ_RET_OK) &&
- (ED_view3d_project_float_global(ar, cursor_curr->location, co_curr, V3D_PROJ_TEST_NOP) == V3D_PROJ_RET_OK))
+ if ((ED_view3d_project_float_global(
+ ar, cursor_prev.location, co_2d_prev, V3D_PROJ_TEST_NOP) == V3D_PROJ_RET_OK) &&
+ (ED_view3d_project_float_global(
+ ar, cursor_curr->location, co_2d_curr, V3D_PROJ_TEST_NOP) == V3D_PROJ_RET_OK))
{
- rv3d->ofs_lock[0] += (co_curr[0] - co_prev[0]) / (ar->winx * 0.5f);
- rv3d->ofs_lock[1] += (co_curr[1] - co_prev[1]) / (ar->winy * 0.5f);
+ rv3d->ofs_lock[0] += (co_2d_curr[0] - co_2d_prev[0]) / (ar->winx * 0.5f);
+ rv3d->ofs_lock[1] += (co_2d_curr[1] - co_2d_prev[1]) / (ar->winy * 0.5f);
}
}
else {
@@ -4689,9 +4727,20 @@ void ED_view3d_cursor3d_update(bContext *C, const int mval[2])
DEG_id_tag_update(&scene->id, DEG_TAG_COPY_ON_WRITE);
}
-static int view3d_cursor3d_invoke(bContext *C, wmOperator *UNUSED(op), const wmEvent *event)
+static int view3d_cursor3d_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
- ED_view3d_cursor3d_update(C, event->mval);
+ bool use_depth = (U.uiflag & USER_DEPTH_CURSOR);
+ {
+ PropertyRNA *prop = RNA_struct_find_property(op->ptr, "use_depth");
+ if (RNA_property_is_set(op->ptr, prop)) {
+ use_depth = RNA_property_boolean_get(op->ptr, prop);
+ }
+ else {
+ RNA_property_boolean_set(op->ptr, prop, use_depth);
+ }
+ }
+ const enum eV3DCursorOrient orientation = RNA_enum_get(op->ptr, "orientation");
+ ED_view3d_cursor3d_update(C, event->mval, use_depth, orientation);
return OPERATOR_FINISHED;
}
@@ -4711,6 +4760,24 @@ void VIEW3D_OT_cursor3d(wmOperatorType *ot)
/* flags */
// ot->flag = OPTYPE_REGISTER|OPTYPE_UNDO;
+
+ PropertyRNA *prop;
+ static const EnumPropertyItem orientation_items[] = {
+ {V3D_CURSOR_ORIENT_NONE, "NONE", 0, "None", "Leave orientation unchanged"},
+ {V3D_CURSOR_ORIENT_VIEW, "VIEW", 0, "View", "Orient to the viewport"},
+ {V3D_CURSOR_ORIENT_GEOM, "GEOM", 0, "Geometry", "Match the surface normal"},
+ {0, NULL, 0, NULL, NULL}
+ };
+
+ prop = RNA_def_boolean(
+ ot->srna, "use_depth", true, "Surface Project",
+ "Project onto the surface");
+ RNA_def_property_flag(prop, PROP_SKIP_SAVE);
+
+ prop = RNA_def_enum(
+ ot->srna, "orientation", orientation_items, V3D_CURSOR_ORIENT_VIEW,
+ "Orientation", "Preset viewpoint to use");
+ RNA_def_property_flag(prop, PROP_SKIP_SAVE);
}
/** \} */
diff --git a/source/blender/editors/space_view3d/view3d_intern.h b/source/blender/editors/space_view3d/view3d_intern.h
index 017b31a0bf2..4eb2a016b94 100644
--- a/source/blender/editors/space_view3d/view3d_intern.h
+++ b/source/blender/editors/space_view3d/view3d_intern.h
@@ -235,7 +235,6 @@ struct Object *ED_view3d_cameracontrol_object_get(
/* view3d_toolbar.c */
void VIEW3D_OT_toolshelf(struct wmOperatorType *ot);
-void view3d_toolshelf_register(struct ARegionType *art);
/* view3d_snap.c */
bool ED_view3d_minmax_verts(struct Object *obedit, float min[3], float max[3]);
diff --git a/source/blender/editors/space_view3d/view3d_ops.c b/source/blender/editors/space_view3d/view3d_ops.c
index b3211ed1108..267712b3339 100644
--- a/source/blender/editors/space_view3d/view3d_ops.c
+++ b/source/blender/editors/space_view3d/view3d_ops.c
@@ -302,7 +302,7 @@ void view3d_keymap(wmKeyConfig *keyconf)
kmi = WM_keymap_add_item(keymap, "VIEW3D_OT_view_all", CKEY, KM_PRESS, KM_SHIFT, 0);
RNA_boolean_set(kmi->ptr, "center", true);
- WM_keymap_add_menu_pie(keymap, "VIEW3D_PIE_view", ACCENTGRAVEKEY, KM_CLICK_DRAG, 0, 0);
+ WM_keymap_add_menu_pie(keymap, "VIEW3D_MT_view_pie", ACCENTGRAVEKEY, KM_CLICK_DRAG, 0, 0);
/* numpad view hotkeys*/
RNA_enum_set(WM_keymap_add_item(keymap, "VIEW3D_OT_viewnumpad", PAD0, KM_PRESS, 0, 0)->ptr, "type", RV3D_VIEW_CAMERA);
diff --git a/source/blender/editors/space_view3d/view3d_select.c b/source/blender/editors/space_view3d/view3d_select.c
index b4f3be178aa..c0a133032ea 100644
--- a/source/blender/editors/space_view3d/view3d_select.c
+++ b/source/blender/editors/space_view3d/view3d_select.c
@@ -1326,7 +1326,7 @@ static Base *mouse_select_eval_buffer(
while (base) {
/* skip objects with select restriction, to prevent prematurely ending this loop
* with an un-selectable choice */
- if ((base->flag & BASE_SELECTABLED) == 0) {
+ if ((base->flag & BASE_SELECTABLE) == 0) {
base = base->next;
if (base == NULL) base = FIRSTBASE(view_layer);
if (base == startbase) break;
diff --git a/source/blender/editors/space_view3d/view3d_toolbar.c b/source/blender/editors/space_view3d/view3d_toolbar.c
index acceb40beaa..707e0e7a394 100644
--- a/source/blender/editors/space_view3d/view3d_toolbar.c
+++ b/source/blender/editors/space_view3d/view3d_toolbar.c
@@ -28,153 +28,24 @@
* \ingroup spview3d
*/
-
#include <string.h>
#include <stdio.h>
#include <math.h>
#include <float.h>
-#include "DNA_object_types.h"
#include "DNA_scene_types.h"
-#include "MEM_guardedalloc.h"
-
-#include "BLI_blenlib.h"
#include "BLI_utildefines.h"
-#include "BLI_ghash.h"
-
-#include "BLT_translation.h"
#include "BKE_context.h"
-#include "BKE_screen.h"
-
#include "WM_api.h"
#include "WM_types.h"
-#include "RNA_access.h"
-
#include "ED_screen.h"
-#include "ED_undo.h"
-
-#include "UI_interface.h"
-#include "UI_resources.h"
#include "view3d_intern.h" /* own include */
-/* ******************* */
-
-typedef struct CustomTool {
- struct CustomTool *next, *prev;
- char opname[OP_MAX_TYPENAME];
- char context[OP_MAX_TYPENAME];
-} CustomTool;
-
-static void operator_call_cb(struct bContext *C, void *arg_listbase, void *arg2)
-{
- wmOperatorType *ot = arg2;
-
- if (ot) {
- CustomTool *ct = MEM_callocN(sizeof(CustomTool), "CustomTool");
-
- BLI_addtail(arg_listbase, ct);
- BLI_strncpy(ct->opname, ot->idname, OP_MAX_TYPENAME);
- BLI_strncpy(ct->context, CTX_data_mode_string(C), OP_MAX_TYPENAME);
- }
-
-}
-
-static void operator_search_cb(const struct bContext *C, void *UNUSED(arg), const char *str, uiSearchItems *items)
-{
- GHashIterator iter;
-
- for (WM_operatortype_iter(&iter); !BLI_ghashIterator_done(&iter); BLI_ghashIterator_step(&iter)) {
- wmOperatorType *ot = BLI_ghashIterator_getValue(&iter);
-
- if (BLI_strcasestr(ot->name, str)) {
- if (WM_operator_poll((bContext *)C, ot)) {
-
- if (false == UI_search_item_add(items, ot->name, ot, 0))
- break;
- }
- }
- }
-}
-
-
-/* ID Search browse menu, open */
-static uiBlock *tool_search_menu(bContext *C, ARegion *ar, void *arg_listbase)
-{
- static char search[OP_MAX_TYPENAME];
- wmEvent event;
- wmWindow *win = CTX_wm_window(C);
- uiBlock *block;
- uiBut *but;
-
- /* clear initial search string, then all items show */
- search[0] = 0;
-
- block = UI_block_begin(C, ar, "_popup", UI_EMBOSS);
- UI_block_flag_enable(block, UI_BLOCK_LOOP | UI_BLOCK_SEARCH_MENU);
-
- /* fake button, it holds space for search items */
- uiDefBut(block, UI_BTYPE_LABEL, 0, "", 10, 15, UI_searchbox_size_x(), UI_searchbox_size_y(), NULL, 0, 0, 0, 0, NULL);
-
- but = uiDefSearchBut(block, search, 0, ICON_VIEWZOOM, sizeof(search), 10, 0, 150, 19, 0, 0, "");
- UI_but_func_search_set(but, NULL, operator_search_cb, arg_listbase, operator_call_cb, NULL);
-
- UI_block_bounds_set_normal(block, 6);
- UI_block_direction_set(block, UI_DIR_DOWN);
- UI_block_end(C, block);
-
- wm_event_init_from_window(win, &event);
- event.type = EVT_BUT_OPEN;
- event.val = KM_PRESS;
- event.customdata = but;
- event.customdatafree = false;
- wm_event_add(win, &event);
-
- return block;
-}
-
-
-static void view3d_panel_tool_shelf(const bContext *C, Panel *pa)
-{
- SpaceLink *sl = CTX_wm_space_data(C);
- SpaceType *st = NULL;
- uiLayout *col;
- const char *context = CTX_data_mode_string(C);
-
- if (sl)
- st = BKE_spacetype_from_id(sl->spacetype);
-
- if (st && st->toolshelf.first) {
- CustomTool *ct;
-
- for (ct = st->toolshelf.first; ct; ct = ct->next) {
- if (STREQLEN(context, ct->context, OP_MAX_TYPENAME)) {
- col = uiLayoutColumn(pa->layout, true);
- uiItemFullO(col, ct->opname, NULL, ICON_NONE, NULL, WM_OP_INVOKE_REGION_WIN, 0, NULL);
- }
- }
- }
- col = uiLayoutColumn(pa->layout, true);
- uiDefBlockBut(uiLayoutGetBlock(pa->layout), tool_search_menu, &st->toolshelf, "Add Tool", 0, 0, UI_UNIT_X, UI_UNIT_Y, "Add Tool in shelf, gets saved in files");
-}
-
-
-void view3d_toolshelf_register(ARegionType *art)
-{
- PanelType *pt;
-
- pt = MEM_callocN(sizeof(PanelType), "spacetype view3d panel tools");
- strcpy(pt->idname, "VIEW3D_PT_tool_shelf");
- strcpy(pt->label, N_("Tool Shelf"));
- strcpy(pt->translation_context, BLT_I18NCONTEXT_DEFAULT_BPYRNA);
- pt->draw = view3d_panel_tool_shelf;
- BLI_addtail(&art->paneltypes, pt);
-}
-
/* ********** operator to open/close toolshelf region */
static int view3d_toolshelf_toggle_exec(bContext *C, wmOperator *UNUSED(op))
@@ -200,4 +71,3 @@ void VIEW3D_OT_toolshelf(wmOperatorType *ot)
/* flags */
ot->flag = 0;
}
-
diff --git a/source/blender/editors/space_view3d/view3d_view.c b/source/blender/editors/space_view3d/view3d_view.c
index abb8c688e05..8b9ad387065 100644
--- a/source/blender/editors/space_view3d/view3d_view.c
+++ b/source/blender/editors/space_view3d/view3d_view.c
@@ -509,7 +509,6 @@ static int view3d_camera_to_view_selected_exec(bContext *C, wmOperator *op)
{
Depsgraph *depsgraph = CTX_data_depsgraph(C);
Scene *scene = CTX_data_scene(C);
- ViewLayer *view_layer = CTX_data_view_layer(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);
@@ -523,7 +522,7 @@ static int view3d_camera_to_view_selected_exec(bContext *C, wmOperator *op)
}
/* this function does all the important stuff */
- if (BKE_camera_view_frame_fit_to_scene(depsgraph, scene, view_layer, camera_ob_eval, r_co, &r_scale)) {
+ if (BKE_camera_view_frame_fit_to_scene(depsgraph, scene, camera_ob_eval, r_co, &r_scale)) {
ObjectTfmProtectedChannels obtfm;
float obmat_new[4][4];
diff --git a/source/blender/editors/transform/transform_constraints.c b/source/blender/editors/transform/transform_constraints.c
index 3c70eaae2d3..93e644b9706 100644
--- a/source/blender/editors/transform/transform_constraints.c
+++ b/source/blender/editors/transform/transform_constraints.c
@@ -559,7 +559,7 @@ static void applyObjectConstraintRot(
/* on setup call, use first object */
if (td == NULL) {
- td = tc->data;
+ td = TRANS_DATA_CONTAINER_FIRST_OK(t)->data;
}
if (t->flag & T_EDIT) {
diff --git a/source/blender/editors/transform/transform_manipulator_3d.c b/source/blender/editors/transform/transform_manipulator_3d.c
index 75da0fc2d23..ccf6cc8c7ce 100644
--- a/source/blender/editors/transform/transform_manipulator_3d.c
+++ b/source/blender/editors/transform/transform_manipulator_3d.c
@@ -159,18 +159,15 @@ enum {
MAN_AXES_SCALE,
};
-/* naming from old blender we may combine. */
-enum {
- V3D_MANIP_TRANSLATE = 1,
- V3D_MANIP_ROTATE = 2,
- V3D_MANIP_SCALE = 4,
-};
-
-
typedef struct ManipulatorGroup {
bool all_hidden;
int twtype;
+ /* Users may change the twtype, detect changes to re-setup manipulator options. */
+ int twtype_init;
+ int twtype_prev;
+ int use_twtype_refresh;
+
struct wmManipulator *manipulators[MAN_AXIS_LAST];
} ManipulatorGroup;
@@ -269,9 +266,9 @@ static bool manipulator_is_axis_visible(
}
}
- if ((axis_type == MAN_AXES_TRANSLATE && !(twtype & V3D_MANIP_TRANSLATE)) ||
- (axis_type == MAN_AXES_ROTATE && !(twtype & V3D_MANIP_ROTATE)) ||
- (axis_type == MAN_AXES_SCALE && !(twtype & V3D_MANIP_SCALE)))
+ if ((axis_type == MAN_AXES_TRANSLATE && !(twtype & SCE_MANIP_TRANSLATE)) ||
+ (axis_type == MAN_AXES_ROTATE && !(twtype & SCE_MANIP_ROTATE)) ||
+ (axis_type == MAN_AXES_SCALE && !(twtype & SCE_MANIP_SCALE)))
{
return false;
}
@@ -301,34 +298,34 @@ static bool manipulator_is_axis_visible(
case MAN_AXIS_SCALE_Z:
return (rv3d->twdrawflag & MAN_SCALE_Z);
case MAN_AXIS_SCALE_C:
- return (rv3d->twdrawflag & MAN_SCALE_C && (twtype & V3D_MANIP_TRANSLATE) == 0);
+ return (rv3d->twdrawflag & MAN_SCALE_C && (twtype & SCE_MANIP_TRANSLATE) == 0);
case MAN_AXIS_TRANS_XY:
return (rv3d->twdrawflag & MAN_TRANS_X &&
rv3d->twdrawflag & MAN_TRANS_Y &&
- (twtype & V3D_MANIP_ROTATE) == 0);
+ (twtype & SCE_MANIP_ROTATE) == 0);
case MAN_AXIS_TRANS_YZ:
return (rv3d->twdrawflag & MAN_TRANS_Y &&
rv3d->twdrawflag & MAN_TRANS_Z &&
- (twtype & V3D_MANIP_ROTATE) == 0);
+ (twtype & SCE_MANIP_ROTATE) == 0);
case MAN_AXIS_TRANS_ZX:
return (rv3d->twdrawflag & MAN_TRANS_Z &&
rv3d->twdrawflag & MAN_TRANS_X &&
- (twtype & V3D_MANIP_ROTATE) == 0);
+ (twtype & SCE_MANIP_ROTATE) == 0);
case MAN_AXIS_SCALE_XY:
return (rv3d->twdrawflag & MAN_SCALE_X &&
rv3d->twdrawflag & MAN_SCALE_Y &&
- (twtype & V3D_MANIP_TRANSLATE) == 0 &&
- (twtype & V3D_MANIP_ROTATE) == 0);
+ (twtype & SCE_MANIP_TRANSLATE) == 0 &&
+ (twtype & SCE_MANIP_ROTATE) == 0);
case MAN_AXIS_SCALE_YZ:
return (rv3d->twdrawflag & MAN_SCALE_Y &&
rv3d->twdrawflag & MAN_SCALE_Z &&
- (twtype & V3D_MANIP_TRANSLATE) == 0 &&
- (twtype & V3D_MANIP_ROTATE) == 0);
+ (twtype & SCE_MANIP_TRANSLATE) == 0 &&
+ (twtype & SCE_MANIP_ROTATE) == 0);
case MAN_AXIS_SCALE_ZX:
return (rv3d->twdrawflag & MAN_SCALE_Z &&
rv3d->twdrawflag & MAN_SCALE_X &&
- (twtype & V3D_MANIP_TRANSLATE) == 0 &&
- (twtype & V3D_MANIP_ROTATE) == 0);
+ (twtype & SCE_MANIP_TRANSLATE) == 0 &&
+ (twtype & SCE_MANIP_ROTATE) == 0);
}
return false;
}
@@ -1122,15 +1119,15 @@ static void manipulator_line_range(const int twtype, const short axis_type, floa
switch (axis_type) {
case MAN_AXES_TRANSLATE:
- if (twtype & V3D_MANIP_SCALE) {
+ if (twtype & SCE_MANIP_SCALE) {
*r_start = *r_len - ofs + 0.075f;
}
- if (twtype & V3D_MANIP_ROTATE) {
+ if (twtype & SCE_MANIP_ROTATE) {
*r_len += ofs;
}
break;
case MAN_AXES_SCALE:
- if (twtype & (V3D_MANIP_TRANSLATE | V3D_MANIP_ROTATE)) {
+ if (twtype & (SCE_MANIP_TRANSLATE | SCE_MANIP_ROTATE)) {
*r_len -= ofs + 0.025f;
}
break;
@@ -1172,8 +1169,10 @@ static void manipulator_xform_message_subscribe(
if (type_fn == TRANSFORM_WGT_manipulator) {
extern PropertyRNA rna_ToolSettings_transform_pivot_point;
+ extern PropertyRNA rna_ToolSettings_use_manipulator_mode;
const PropertyRNA *props[] = {
- &rna_ToolSettings_transform_pivot_point
+ &rna_ToolSettings_transform_pivot_point,
+ &rna_ToolSettings_use_manipulator_mode,
};
for (int i = 0; i < ARRAY_SIZE(props); i++) {
WM_msg_subscribe_rna(mbus, &toolsettings_ptr, props[i], &msg_sub_value_mpr_tag_refresh, __func__);
@@ -1285,41 +1284,12 @@ static int manipulator_modal(
return OPERATOR_RUNNING_MODAL;
}
-static void WIDGETGROUP_manipulator_setup(const bContext *C, wmManipulatorGroup *mgroup)
+static void manipulatorgroup_init_properties_from_twtype(wmManipulatorGroup *mgroup)
{
- ManipulatorGroup *man = manipulatorgroup_init(mgroup);
struct {
wmOperatorType *translate, *rotate, *trackball, *resize;
} ot_store = {NULL};
-
- mgroup->customdata = man;
-
- {
- /* TODO: support mixing modes again? - it's supported but tool system makes it unobvious. */
- man->twtype = 0;
- ScrArea *sa = CTX_wm_area(C);
- bToolRef_Runtime *tref_rt = sa->runtime.tool ? sa->runtime.tool->runtime : NULL;
- wmKeyMap *km = tref_rt ? WM_keymap_find_all(C, tref_rt->keymap, sa->spacetype, RGN_TYPE_WINDOW) : NULL;
- /* Weak, check first event */
- wmKeyMapItem *kmi = km ? km->items.first : NULL;
-
- if (kmi == NULL) {
- man->twtype |= V3D_MANIP_TRANSLATE | V3D_MANIP_ROTATE | V3D_MANIP_SCALE;
- }
- else if (STREQ(kmi->idname, "TRANSFORM_OT_translate")) {
- man->twtype |= V3D_MANIP_TRANSLATE;
- }
- else if (STREQ(kmi->idname, "TRANSFORM_OT_rotate")) {
- man->twtype |= V3D_MANIP_ROTATE;
- }
- else if (STREQ(kmi->idname, "TRANSFORM_OT_resize")) {
- man->twtype |= V3D_MANIP_SCALE;
- }
- BLI_assert(man->twtype != 0);
- }
-
- /* *** set properties for axes *** */
-
+ ManipulatorGroup *man = mgroup->customdata;
MAN_ITER_AXES_BEGIN(axis, axis_idx)
{
const short axis_type = manipulator_get_axis_type(axis_idx);
@@ -1340,7 +1310,7 @@ static void WIDGETGROUP_manipulator_setup(const bContext *C, wmManipulatorGroup
case MAN_AXIS_SCALE_Z:
if (axis_idx >= MAN_AXIS_RANGE_TRANS_START && axis_idx < MAN_AXIS_RANGE_TRANS_END) {
int draw_options = 0;
- if ((man->twtype & (V3D_MANIP_ROTATE | V3D_MANIP_SCALE)) == 0) {
+ if ((man->twtype & (SCE_MANIP_ROTATE | SCE_MANIP_SCALE)) == 0) {
draw_options |= ED_MANIPULATOR_ARROW_DRAW_FLAG_STEM;
}
RNA_enum_set(axis->ptr, "draw_options", draw_options);
@@ -1434,6 +1404,42 @@ static void WIDGETGROUP_manipulator_setup(const bContext *C, wmManipulatorGroup
MAN_ITER_AXES_END;
}
+static void WIDGETGROUP_manipulator_setup(const bContext *C, wmManipulatorGroup *mgroup)
+{
+ ManipulatorGroup *man = manipulatorgroup_init(mgroup);
+
+ mgroup->customdata = man;
+
+ {
+ man->twtype = 0;
+ ScrArea *sa = CTX_wm_area(C);
+ bToolRef_Runtime *tref_rt = sa->runtime.tool ? sa->runtime.tool->runtime : NULL;
+ wmKeyMap *km = tref_rt ? WM_keymap_find_all(C, tref_rt->keymap, sa->spacetype, RGN_TYPE_WINDOW) : NULL;
+ /* Weak, check first event */
+ wmKeyMapItem *kmi = km ? km->items.first : NULL;
+
+ if (kmi == NULL) {
+ /* Setup all manipulators, they can be toggled via 'ToolSettings.manipulator_flag' */
+ man->twtype = SCE_MANIP_TRANSLATE | SCE_MANIP_ROTATE | SCE_MANIP_SCALE;
+ man->use_twtype_refresh = true;
+ }
+ else if (STREQ(kmi->idname, "TRANSFORM_OT_translate")) {
+ man->twtype |= SCE_MANIP_TRANSLATE;
+ }
+ else if (STREQ(kmi->idname, "TRANSFORM_OT_rotate")) {
+ man->twtype |= SCE_MANIP_ROTATE;
+ }
+ else if (STREQ(kmi->idname, "TRANSFORM_OT_resize")) {
+ man->twtype |= SCE_MANIP_SCALE;
+ }
+ BLI_assert(man->twtype != 0);
+ man->twtype_init = man->twtype;
+ }
+
+ /* *** set properties for axes *** */
+ manipulatorgroup_init_properties_from_twtype(mgroup);
+}
+
static void WIDGETGROUP_manipulator_refresh(const bContext *C, wmManipulatorGroup *mgroup)
{
ManipulatorGroup *man = mgroup->customdata;
@@ -1443,6 +1449,15 @@ static void WIDGETGROUP_manipulator_refresh(const bContext *C, wmManipulatorGrou
RegionView3D *rv3d = ar->regiondata;
struct TransformBounds tbounds;
+ if (man->use_twtype_refresh) {
+ Scene *scene = CTX_data_scene(C);
+ man->twtype = scene->toolsettings->manipulator_flag & man->twtype_init;
+ if (man->twtype != man->twtype_prev) {
+ man->twtype_prev = man->twtype;
+ manipulatorgroup_init_properties_from_twtype(mgroup);
+ }
+ }
+
/* skip, we don't draw anything anyway */
if ((man->all_hidden =
(ED_transform_calc_manipulator_stats(
@@ -1481,7 +1496,7 @@ static void WIDGETGROUP_manipulator_refresh(const bContext *C, wmManipulatorGrou
RNA_float_set(axis->ptr, "length", len);
if (axis_idx >= MAN_AXIS_RANGE_TRANS_START && axis_idx < MAN_AXIS_RANGE_TRANS_END) {
- if (man->twtype & V3D_MANIP_ROTATE) {
+ if (man->twtype & SCE_MANIP_ROTATE) {
/* Avoid rotate and translate arrows overlap. */
start_co[2] += 0.215f;
}
diff --git a/source/blender/editors/transform/transform_snap.c b/source/blender/editors/transform/transform_snap.c
index 704582deaca..02855e0a809 100644
--- a/source/blender/editors/transform/transform_snap.c
+++ b/source/blender/editors/transform/transform_snap.c
@@ -51,7 +51,6 @@
#include "GPU_immediate.h"
-#include "BKE_DerivedMesh.h"
#include "BKE_global.h"
#include "BKE_object.h"
#include "BKE_anim.h" /* for duplis */
diff --git a/source/blender/editors/undo/ed_undo.c b/source/blender/editors/undo/ed_undo.c
index c4bfe83ed4c..478e004743d 100644
--- a/source/blender/editors/undo/ed_undo.c
+++ b/source/blender/editors/undo/ed_undo.c
@@ -411,7 +411,7 @@ static const EnumPropertyItem *rna_undo_itemf(bContext *C, int *totitem)
item_tmp.identifier = us->name;
item_tmp.name = IFACE_(us->name);
if (us == wm->undo_stack->step_active) {
- item_tmp.icon = ICON_RESTRICT_VIEW_OFF;
+ item_tmp.icon = ICON_HIDE_OFF;
}
else {
item_tmp.icon = ICON_NONE;
diff --git a/source/blender/editors/uvedit/uvedit_draw.c b/source/blender/editors/uvedit/uvedit_draw.c
index 4473922841f..b3f3d188851 100644
--- a/source/blender/editors/uvedit/uvedit_draw.c
+++ b/source/blender/editors/uvedit/uvedit_draw.c
@@ -502,7 +502,7 @@ static void draw_uvs_other(ViewLayer *view_layer, Object *obedit, const Image *c
for (Base *base = view_layer->object_bases.first; base; base = base->next) {
if (((base->flag & BASE_SELECTED) != 0) &&
- ((base->flag & BASE_VISIBLED) != 0))
+ ((base->flag & BASE_VISIBLE) != 0))
{
Object *ob = base->object;
if ((ob->type == OB_MESH) && (ob != obedit) && ((Mesh *)ob->data)->mloopuv) {
diff --git a/source/blender/editors/uvedit/uvedit_unwrap_ops.c b/source/blender/editors/uvedit/uvedit_unwrap_ops.c
index 78b412579e6..5f60a5a714a 100644
--- a/source/blender/editors/uvedit/uvedit_unwrap_ops.c
+++ b/source/blender/editors/uvedit/uvedit_unwrap_ops.c
@@ -496,7 +496,7 @@ static ParamHandle *construct_param_handle_subsurfed(Scene *scene, Object *ob, B
smd.subdivType = smd_real->subdivType;
initialDerived = CDDM_from_editbmesh(em, false, false);
- derivedMesh = subsurf_make_derived_from_derived(initialDerived, &smd,
+ derivedMesh = subsurf_make_derived_from_derived(initialDerived, &smd, scene,
NULL, SUBSURF_IN_EDIT_MODE);
initialDerived->release(initialDerived);