diff options
Diffstat (limited to 'release')
73 files changed, 1312 insertions, 1040 deletions
diff --git a/release/datafiles/blender_icons16/icon16_force_smokeflow.dat b/release/datafiles/blender_icons16/icon16_force_fluidflow.dat Binary files differindex a5b978a80b1..a5b978a80b1 100644 --- a/release/datafiles/blender_icons16/icon16_force_smokeflow.dat +++ b/release/datafiles/blender_icons16/icon16_force_fluidflow.dat diff --git a/release/datafiles/blender_icons32/icon32_force_smokeflow.dat b/release/datafiles/blender_icons32/icon32_force_fluidflow.dat Binary files differindex 0553f2adac2..0553f2adac2 100644 --- a/release/datafiles/blender_icons32/icon32_force_smokeflow.dat +++ b/release/datafiles/blender_icons32/icon32_force_fluidflow.dat diff --git a/release/datafiles/fonts/bmonofont-i18n.ttf b/release/datafiles/fonts/bmonofont-i18n.ttf Binary files differindex 658ec68f36c..08b3f723d61 100644 --- a/release/datafiles/fonts/bmonofont-i18n.ttf +++ b/release/datafiles/fonts/bmonofont-i18n.ttf diff --git a/release/datafiles/fonts/droidsans.ttf b/release/datafiles/fonts/droidsans.ttf Binary files differindex 04b1ece64ee..eea72f53ccd 100644 --- a/release/datafiles/fonts/droidsans.ttf +++ b/release/datafiles/fonts/droidsans.ttf diff --git a/release/datafiles/splash.png b/release/datafiles/splash.png Binary files differindex 7f94a491469..babb3e30c6d 100644 --- a/release/datafiles/splash.png +++ b/release/datafiles/splash.png diff --git a/release/datafiles/userdef/userdef_default.c b/release/datafiles/userdef/userdef_default.c index d31c59f0d55..31d0eb8e923 100644 --- a/release/datafiles/userdef/userdef_default.c +++ b/release/datafiles/userdef/userdef_default.c @@ -227,6 +227,8 @@ const UserDef U_default = { .sequencer_disk_cache_size_limit = 100, .sequencer_disk_cache_flag = 0, + .collection_instance_empty_size = 1.0f, + .runtime = { .is_dirty = 0, diff --git a/release/datafiles/userdef/userdef_default_theme.c b/release/datafiles/userdef/userdef_default_theme.c index de3583db2bb..4d48bb8eaac 100644 --- a/release/datafiles/userdef/userdef_default_theme.c +++ b/release/datafiles/userdef/userdef_default_theme.c @@ -279,8 +279,8 @@ const bTheme U_theme_default = { .button_text_hi = RGBA(0xffffffff), .navigation_bar = RGBA(0x232323ff), .panelcolors = { - .header = RGBA(0x42424200), - .back = RGBA(0x00000028), + .header = RGBA(0x424242ff), + .back = RGBA(0x383838ff), .sub_back = RGBA(0x00000024), }, .vertex_size = 3, @@ -697,7 +697,7 @@ const bTheme U_theme_default = { .vertex_size = 3, .outline_width = 1, .facedot_size = 3, - .editmesh_active = RGBA(0xffffff80), + .editmesh_active = RGBA(0xffffff40), .handle_vertex_select = RGBA(0xffff00ff), .handle_vertex_size = 5, .gp_vertex_size = 3, diff --git a/release/scripts/modules/bl_i18n_utils/settings.py b/release/scripts/modules/bl_i18n_utils/settings.py index c233681dc41..e522ec3fcf9 100644 --- a/release/scripts/modules/bl_i18n_utils/settings.py +++ b/release/scripts/modules/bl_i18n_utils/settings.py @@ -28,6 +28,7 @@ import json import os import sys +import types import bpy @@ -556,6 +557,10 @@ def _gen_get_set_path(ref, name): return _get, _set +def _check_valid_data(uid, val): + return not uid.startswith("_") and type(val) not in tuple(types.__dict__.values()) + (type,) + + class I18nSettings: """ Class allowing persistence of our settings! @@ -567,20 +572,32 @@ class I18nSettings: # Addon preferences are singleton by definition, so is this class! if not I18nSettings._settings: cls._settings = super(I18nSettings, cls).__new__(cls) - cls._settings.__dict__ = {uid: data for uid, data in globals().items() if not uid.startswith("_")} + cls._settings.__dict__ = {uid: val for uid, val in globals().items() if _check_valid_data(uid, val)} return I18nSettings._settings - def from_json(self, string): - data = dict(json.loads(string)) + def __getstate__(self): + return self.to_dict() + + def __setstate__(self, mapping): + return self.from_dict(mapping) + + def from_dict(self, mapping): # Special case... :/ - if "INTERN_PY_SYS_PATHS" in data: - self.PY_SYS_PATHS = data["INTERN_PY_SYS_PATHS"] - self.__dict__.update(data) + if "INTERN_PY_SYS_PATHS" in mapping: + self.PY_SYS_PATHS = mapping["INTERN_PY_SYS_PATHS"] + self.__dict__.update(mapping) + + def to_dict(self): + glob = globals() + return {uid: val for uid, val in self.__dict__.items() if _check_valid_data(uid, val) and uid in glob} + + def from_json(self, string): + self.from_dict(dict(json.loads(string))) def to_json(self): # Only save the diff from default i18n_settings! glob = globals() - export_dict = {uid: val for uid, val in self.__dict__.items() if glob.get(uid) != val} + export_dict = {uid: val for uid, val in self.__dict__.items() if _check_valid_data(uid, val) and glob.get(uid) != val} return json.dumps(export_dict) def load(self, fname, reset=False): diff --git a/release/scripts/modules/bl_i18n_utils/utils.py b/release/scripts/modules/bl_i18n_utils/utils.py index 493afc53267..61837cc0956 100644 --- a/release/scripts/modules/bl_i18n_utils/utils.py +++ b/release/scripts/modules/bl_i18n_utils/utils.py @@ -21,7 +21,6 @@ # Some misc utilities... import collections -import concurrent.futures import copy import hashlib import os @@ -238,6 +237,12 @@ class I18nMessage: self.is_fuzzy = is_fuzzy self.is_commented = is_commented + # ~ def __getstate__(self): + # ~ return {key: getattr(self, key) for key in self.__slots__} + + # ~ def __getstate__(self): + # ~ return {key: getattr(self, key) for key in self.__slots__} + def _get_msgctxt(self): return "".join(self.msgctxt_lines) @@ -426,6 +431,14 @@ class I18nMessages: self._reverse_cache = None + def __getstate__(self): + return (self.settings, self.uid, self.msgs, self.parsing_errors) + + def __setstate__(self, data): + self.__init__() + self.settings, self.uid, self.msgs, self.parsing_errors = data + self.update_info() + @staticmethod def _new_messages(): return getattr(collections, 'OrderedDict', dict)() @@ -566,24 +579,23 @@ class I18nMessages: # Next process new keys. if use_similar > 0.0: - with concurrent.futures.ProcessPoolExecutor() as exctr: - for key, msgid in exctr.map(get_best_similar, - tuple((nk, use_similar, tuple(similar_pool.keys())) for nk in new_keys)): - if msgid: - # Try to get the same context, else just get one... - skey = (key[0], msgid) - if skey not in similar_pool[msgid]: - skey = tuple(similar_pool[msgid])[0] - # We keep org translation and comments, and mark message as fuzzy. - msg, refmsg = self.msgs[skey].copy(), ref.msgs[key] - msg.msgctxt = refmsg.msgctxt - msg.msgid = refmsg.msgid - msg.sources = refmsg.sources - msg.is_fuzzy = True - msg.is_commented = refmsg.is_commented - msgs[key] = msg - else: - msgs[key] = ref.msgs[key] + for key, msgid in map(get_best_similar, + tuple((nk, use_similar, tuple(similar_pool.keys())) for nk in new_keys)): + if msgid: + # Try to get the same context, else just get one... + skey = (key[0], msgid) + if skey not in similar_pool[msgid]: + skey = tuple(similar_pool[msgid])[0] + # We keep org translation and comments, and mark message as fuzzy. + msg, refmsg = self.msgs[skey].copy(), ref.msgs[key] + msg.msgctxt = refmsg.msgctxt + msg.msgid = refmsg.msgid + msg.sources = refmsg.sources + msg.is_fuzzy = True + msg.is_commented = refmsg.is_commented + msgs[key] = msg + else: + msgs[key] = ref.msgs[key] else: for key in new_keys: msgs[key] = ref.msgs[key] @@ -1075,9 +1087,7 @@ class I18nMessages: "-o", fname, ) - print("Running ", " ".join(cmd)) ret = subprocess.call(cmd) - print("Finished.") return # XXX Code below is currently broken (generates corrupted mo files it seems :( )! # Using http://www.gnu.org/software/gettext/manual/html_node/MO-Files.html notation. diff --git a/release/scripts/modules/bpy_types.py b/release/scripts/modules/bpy_types.py index a30f9d1dd1d..bf14d34ed20 100644 --- a/release/scripts/modules/bpy_types.py +++ b/release/scripts/modules/bpy_types.py @@ -25,12 +25,7 @@ StructRNA = bpy_types.bpy_struct StructMetaPropGroup = bpy_types.bpy_struct_meta_idprop # StructRNA = bpy_types.Struct -bpy_types.BlendDataLibraries.load = _bpy._library_load -bpy_types.BlendDataLibraries.write = _bpy._library_write -bpy_types.BlendData.user_map = _bpy._rna_id_collection_user_map -bpy_types.BlendData.batch_remove = _bpy._rna_id_collection_batch_remove -bpy_types.BlendData.orphans_purge = _bpy._rna_id_collection_orphans_purge - +# Note that methods extended in C are defined in: 'bpy_rna_types_capi.c' class Context(StructRNA): __slots__ = () @@ -118,14 +113,19 @@ class Object(bpy_types.ID): @property def children(self): - """All the children of this object. Warning: takes O(len(bpy.data.objects)) time.""" + """All the children of this object. + + .. note:: Takes ``O(len(bpy.data.objects))`` time.""" import bpy return tuple(child for child in bpy.data.objects if child.parent == self) @property def users_collection(self): - """The collections this object is in. Warning: takes O(len(bpy.data.collections) + len(bpy.data.scenes)) time.""" + """ + The collections this object is in. + + .. note:: Takes ``O(len(bpy.data.collections) + len(bpy.data.scenes))`` time.""" import bpy return ( tuple( @@ -139,7 +139,9 @@ class Object(bpy_types.ID): @property def users_scene(self): - """The scenes this object is in. Warning: takes O(len(bpy.data.scenes) * len(bpy.data.objects)) time.""" + """The scenes this object is in. + + .. note:: Takes ``O(len(bpy.data.scenes) * len(bpy.data.objects))`` time.""" import bpy return tuple(scene for scene in bpy.data.scenes if self in scene.objects[:]) @@ -292,12 +294,16 @@ class _GenericBone: @property def children(self): - """A list of all the bones children. Warning: takes O(len(bones)) time.""" + """A list of all the bones children. + + .. note:: Takes ``O(len(bones))`` time.""" return [child for child in self._other_bones if child.parent == self] @property def children_recursive(self): - """A list of all children from this bone. Warning: takes O(len(bones)**2) time.""" + """A list of all children from this bone. + + .. note:: Takes ``O(len(bones)**2)`` time.""" bones_children = [] for bone in self._other_bones: index = bone.parent_index(self) @@ -314,7 +320,9 @@ class _GenericBone: Returns a chain of children with the same base name as this bone. Only direct chains are supported, forks caused by multiple children with matching base names will terminate the function - and not be returned. Warning: takes O(len(bones)**2) time. + and not be returned. + + .. note:: Takes ``O(len(bones)**2)`` time. """ basename = self.basename chain = [] @@ -1008,7 +1016,10 @@ class NodeSocket(StructRNA, metaclass=RNAMetaPropGroup): @property def links(self): - """List of node links from or to this socket. Warning: takes O(len(nodetree.links)) time.""" + """ + List of node links from or to this socket. + + .. note:: Takes ``O(len(nodetree.links))`` time.""" return tuple( link for link in self.id_data.links if (link.from_socket == self or diff --git a/release/scripts/modules/rna_info.py b/release/scripts/modules/rna_info.py index 71d7ee5a7bc..964eff0e572 100644 --- a/release/scripts/modules/rna_info.py +++ b/release/scripts/modules/rna_info.py @@ -303,7 +303,9 @@ class InfoPropertyRNA: for dim in self.array_dimensions[::-1]: if dim != 0: self.default = tuple(zip(*((iter(self.default),) * dim))) - self.default_str = tuple("(%s)" % ", ".join(s for s in b) for b in zip(*((iter(self.default_str),) * dim))) + self.default_str = tuple( + "(%s)" % ", ".join(s for s in b) for b in zip(*((iter(self.default_str),) * dim)) + ) self.default_str = self.default_str[0] elif self.type == "enum" and self.is_enum_flag: self.default = getattr(rna_prop, "default_flag", set()) @@ -349,7 +351,9 @@ class InfoPropertyRNA: type_str += self.type if self.array_length: if self.array_dimensions[1] != 0: - type_str += " multi-dimensional array of %s items" % (" * ".join(str(d) for d in self.array_dimensions if d != 0)) + type_str += " multi-dimensional array of %s items" % ( + " * ".join(str(d) for d in self.array_dimensions if d != 0) + ) else: type_str += " array of %d items" % (self.array_length) diff --git a/release/scripts/modules/rna_keymap_ui.py b/release/scripts/modules/rna_keymap_ui.py index 22be5186186..844daded570 100644 --- a/release/scripts/modules/rna_keymap_ui.py +++ b/release/scripts/modules/rna_keymap_ui.py @@ -161,7 +161,12 @@ def draw_kmi(display_keymaps, kc, km, kmi, layout, level): if (not kmi.is_user_defined) and kmi.is_user_modified: row.operator("preferences.keyitem_restore", text="", icon='BACK').item_id = kmi.id else: - row.operator("preferences.keyitem_remove", text="", icon='X').item_id = kmi.id + row.operator( + "preferences.keyitem_remove", + text="", + # Abusing the tracking icon, but it works pretty well here. + icon=('TRACKING_CLEAR_BACKWARDS' if kmi.is_user_defined else 'X') + ).item_id = kmi.id # Expanded, additional event settings if kmi.show_expanded: diff --git a/release/scripts/presets/interface_theme/blender_light.xml b/release/scripts/presets/interface_theme/blender_light.xml index f4ec8233df3..48ad0a8367e 100644 --- a/release/scripts/presets/interface_theme/blender_light.xml +++ b/release/scripts/presets/interface_theme/blender_light.xml @@ -724,7 +724,7 @@ freestyle_face_mark="#7fff7f33" face_back="#00000000" face_front="#00000000" - editmesh_active="#ffffff80" + editmesh_active="#ffffff40" wire_edit="#c0c0c0" edge_select="#ff8500" scope_back="#727272ff" diff --git a/release/scripts/presets/keyconfig/keymap_data/blender_default.py b/release/scripts/presets/keyconfig/keymap_data/blender_default.py index f2c3a9f1ee5..2559a2f1df5 100644 --- a/release/scripts/presets/keyconfig/keymap_data/blender_default.py +++ b/release/scripts/presets/keyconfig/keymap_data/blender_default.py @@ -798,8 +798,8 @@ def km_outliner(params): ("outliner.drivers_add_selected", {"type": 'D', "value": 'PRESS', "ctrl": True}, None), ("outliner.drivers_delete_selected", {"type": 'D', "value": 'PRESS', "ctrl": True, "alt": True}, None), ("outliner.collection_new", {"type": 'C', "value": 'PRESS'}, None), - ("outliner.collection_delete", {"type": 'X', "value": 'PRESS'}, None), - ("outliner.collection_delete", {"type": 'DEL', "value": 'PRESS'}, None), + ("outliner.delete", {"type": 'X', "value": 'PRESS'}, None), + ("outliner.delete", {"type": 'DEL', "value": 'PRESS'}, None), ("object.move_to_collection", {"type": 'M', "value": 'PRESS'}, None), ("object.link_to_collection", {"type": 'M', "value": 'PRESS', "shift": True}, None), ("outliner.collection_exclude_set", {"type": 'E', "value": 'PRESS'}, None), @@ -1391,7 +1391,6 @@ def km_time_scrub(_params): items.extend([ ("anim.change_frame", {"type": "LEFTMOUSE", "value": 'PRESS'}, None), - ("graph.cursor_set", {"type": "LEFTMOUSE", "value": 'PRESS'}, None), ]) return keymap @@ -3028,6 +3027,8 @@ def km_grease_pencil(_params): # Draw ("gpencil.annotate", {"type": 'LEFTMOUSE', "value": 'PRESS', "key_modifier": 'D'}, {"properties": [("mode", 'DRAW'), ("wait_for_input", False)]}), + ("gpencil.annotate", {"type": 'LEFTMOUSE', "value": 'PRESS', "key_modifier": 'D', "shift": True}, + {"properties": [("mode", 'DRAW'), ("wait_for_input", False)]}), # Draw - straight lines ("gpencil.annotate", {"type": 'LEFTMOUSE', "value": 'PRESS', "alt": True, "key_modifier": 'D'}, {"properties": [("mode", 'DRAW_STRAIGHT'), ("wait_for_input", False)]}), @@ -3226,6 +3227,8 @@ def km_grease_pencil_stroke_paint_mode(params): {"properties": [("unselected", True)]}), # Active layer op_menu("GPENCIL_MT_layer_active", {"type": 'Y', "value": 'PRESS'}), + # Active material + op_menu("GPENCIL_MT_material_active", {"type": 'U', "value": 'PRESS'}), # Keyframe menu op_menu("VIEW3D_MT_gpencil_animation", {"type": 'I', "value": 'PRESS'}), # Draw context menu @@ -4942,6 +4945,32 @@ def km_transform_modal_map(_params): return keymap +def km_view3d_interactive_add_tool_modal_map(_params): + items = [] + keymap = ( + "View3D Placement Modal Map", + {"space_type": 'EMPTY', "region_type": 'WINDOW', "modal": True}, + {"items": items}, + ) + + items.extend([ + ("PIVOT_CENTER_ON", {"type": 'LEFT_ALT', "value": 'PRESS', "any": True}, None), + ("PIVOT_CENTER_OFF", {"type": 'LEFT_ALT', "value": 'RELEASE', "any": True}, None), + ("PIVOT_CENTER_ON", {"type": 'RIGHT_ALT', "value": 'PRESS', "any": True}, None), + ("PIVOT_CENTER_OFF", {"type": 'RIGHT_ALT', "value": 'RELEASE', "any": True}, None), + ("FIXED_ASPECT_ON", {"type": 'LEFT_SHIFT', "value": 'PRESS', "any": True}, None), + ("FIXED_ASPECT_OFF", {"type": 'LEFT_SHIFT', "value": 'RELEASE', "any": True}, None), + ("FIXED_ASPECT_ON", {"type": 'RIGHT_SHIFT', "value": 'PRESS', "any": True}, None), + ("FIXED_ASPECT_OFF", {"type": 'RIGHT_SHIFT', "value": 'RELEASE', "any": True}, None), + ("SNAP_ON", {"type": 'LEFT_CTRL', "value": 'PRESS', "any": True}, None), + ("SNAP_OFF", {"type": 'LEFT_CTRL', "value": 'RELEASE', "any": True}, None), + ("SNAP_ON", {"type": 'RIGHT_CTRL', "value": 'PRESS', "any": True}, None), + ("SNAP_OFF", {"type": 'RIGHT_CTRL', "value": 'RELEASE', "any": True}, None), + ]) + + return keymap + + def km_view3d_gesture_circle(_params): items = [] keymap = ( @@ -5852,13 +5881,13 @@ def km_3d_view_tool_edit_armature_extrude_to_cursor(params): ) -def km_3d_view_tool_edit_mesh_add_cube(params): +def km_3d_view_tool_interactive_add(params): return ( - "3D View Tool: Edit Mesh, Add Cube", + "3D View Tool: Object, Add Primitive", {"space_type": 'VIEW_3D', "region_type": 'WINDOW'}, {"items": [ - ("view3d.cursor3d", {"type": params.tool_mouse, "value": 'CLICK'}, None), - ("mesh.primitive_cube_add_gizmo", {"type": params.tool_tweak, "value": 'ANY'}, None), + ("view3d.interactive_add", {"type": params.tool_tweak, "value": 'ANY', "any": True}, + {"properties": [("wait_for_input", False)]}), ]}, ) @@ -5873,6 +5902,23 @@ def km_3d_view_tool_edit_mesh_extrude_region(params): ]}, ) +def km_3d_view_tool_edit_mesh_extrude_dissolve_and_intersect(params): + return ( + "3D View Tool: Edit Mesh, Extrude Dissolve and Intersect", + {"space_type": 'VIEW_3D', "region_type": 'WINDOW'}, + {"items": [ + ("mesh.extrude_region_dissolve_move_intersect", {"type": params.tool_tweak, "value": 'ANY'}, + {"properties": [ + ("MESH_OT_extrude_region", [("use_dissolve_ortho_edges", True)]), + ("TRANSFORM_OT_translate", [ + ("release_confirm", True), + ("use_automerge_and_split", True), + ("constraint_axis", (False, False, True)), + ("orient_type", 'NORMAL'), + ]), + ]}), + ]}, + ) def km_3d_view_tool_edit_mesh_extrude_along_normals(params): return ( @@ -6654,6 +6700,7 @@ def generate_keymaps(params=None): km_eyedropper_modal_map(params), km_eyedropper_colorramp_pointsampling_map(params), km_transform_modal_map(params), + km_view3d_interactive_add_tool_modal_map(params), km_view3d_gesture_circle(params), km_gesture_border(params), km_gesture_zoom_border(params), @@ -6713,6 +6760,7 @@ def generate_keymaps(params=None): km_3d_view_tool_scale(params), km_3d_view_tool_shear(params), km_3d_view_tool_measure(params), + km_3d_view_tool_interactive_add(params), km_3d_view_tool_pose_breakdowner(params), km_3d_view_tool_pose_push(params), km_3d_view_tool_pose_relax(params), @@ -6721,8 +6769,8 @@ def generate_keymaps(params=None): km_3d_view_tool_edit_armature_bone_envelope(params), km_3d_view_tool_edit_armature_extrude(params), km_3d_view_tool_edit_armature_extrude_to_cursor(params), - km_3d_view_tool_edit_mesh_add_cube(params), km_3d_view_tool_edit_mesh_extrude_region(params), + km_3d_view_tool_edit_mesh_extrude_dissolve_and_intersect(params), km_3d_view_tool_edit_mesh_extrude_along_normals(params), km_3d_view_tool_edit_mesh_extrude_individual(params), km_3d_view_tool_edit_mesh_extrude_to_cursor(params), diff --git a/release/scripts/presets/keyconfig/keymap_data/industry_compatible_data.py b/release/scripts/presets/keyconfig/keymap_data/industry_compatible_data.py index 0005e7dd3d2..3698db4cf94 100644 --- a/release/scripts/presets/keyconfig/keymap_data/industry_compatible_data.py +++ b/release/scripts/presets/keyconfig/keymap_data/industry_compatible_data.py @@ -520,10 +520,8 @@ def km_outliner(params): ("anim.keyframe_delete", {"type": 'S', "value": 'PRESS', "alt": True}, None), ("outliner.drivers_add_selected", {"type": 'D', "value": 'PRESS', "ctrl": True}, None), ("outliner.drivers_delete_selected", {"type": 'D', "value": 'PRESS', "ctrl": True, "alt": True}, None), - ("outliner.collection_delete", {"type": 'BACK_SPACE', "value": 'PRESS'}, None), - ("outliner.collection_delete", {"type": 'DEL', "value": 'PRESS'}, None), - ("outliner.object_operation", {"type": 'BACK_SPACE', "value": 'PRESS'}, {"properties": [("type", 'DELETE')]}), - ("outliner.object_operation", {"type": 'DEL', "value": 'PRESS'}, {"properties": [("type", 'DELETE')]}), + ("outliner.delete", {"type": 'BACK_SPACE', "value": 'PRESS'}, None), + ("outliner.delete", {"type": 'DEL', "value": 'PRESS'}, None), ("object.move_to_collection", {"type": 'G', "value": 'PRESS', "ctrl": True}, None), ("object.link_to_collection", {"type": 'M', "value": 'PRESS', "shift": True, "ctrl": True}, None), ("outliner.collection_exclude_set", {"type": 'E', "value": 'PRESS'}, None), @@ -2376,7 +2374,7 @@ def km_grease_pencil_stroke_paint_mode(params): op_tool_cycle("builtin.cutter", {"type": 'K', "value": 'PRESS'}), op_tool_cycle("builtin.cursor", {"type": 'C', "value": 'PRESS'}), # Active layer - op_menu("GPENCIL_MT_layer_active", {"type": 'M', "value": 'PRESS'}), + op_menu("GPENCIL_MT_layer_active", {"type": 'Y', "value": 'PRESS'}), # Keyframe menu op_menu("VIEW3D_MT_gpencil_animation", {"type": 'I', "value": 'PRESS'}), ]) @@ -3377,6 +3375,10 @@ def km_sculpt(params): # Remesh ("object.voxel_remesh", {"type": 'R', "value": 'PRESS', "ctrl": True}, None), ("object.quadriflow_remesh", {"type": 'R', "value": 'PRESS', "ctrl": True, "alt": True}, None), + # Remesh + ("object.voxel_remesh", {"type": 'R', "value": 'PRESS', "ctrl": True}, None), + ("object.voxel_size_edit", {"type": 'R', "value": 'PRESS', "shift": True}, None), + ("object.quadriflow_remesh", {"type": 'R', "value": 'PRESS', "ctrl": True, "alt": True}, None), # Brush properties ("brush.scale_size", {"type": 'LEFT_BRACKET', "value": 'PRESS'}, {"properties": [("scalar", 0.9)]}), @@ -3766,6 +3768,8 @@ def km_object_non_modal(params): ) items.extend([ + ("object.mode_set",{"type": 'ONE', "value": 'PRESS'}, + {"properties": [("mode", 'PAINT_GPENCIL')]}), ("object.mode_set",{"type": 'THREE', "value": 'PRESS'}, {"properties": [("mode", 'POSE')]}), ("object.mode_set_with_submode",{"type": 'ONE', "value": 'PRESS'}, @@ -3788,11 +3792,11 @@ def km_object_non_modal(params): {"properties": [("mode", 'TEXTURE_PAINT')]}), ("object.mode_set",{"type": 'TWO', "value": 'PRESS'}, {"properties": [("mode", 'EDIT_GPENCIL')]}), - ("object.mode_set",{"type": 'THREE', "value": 'PRESS'}, - {"properties": [("mode", 'SCULPT_GPENCIL')]}), - ("object.mode_set",{"type": 'FOUR', "value": 'PRESS'}, - {"properties": [("mode", 'PAINT_GPENCIL')]}), ("object.mode_set",{"type": 'FIVE', "value": 'PRESS'}, + {"properties": [("mode", 'SCULPT_GPENCIL')]}), + ("object.mode_set",{"type": 'SIX', "value": 'PRESS'}, + {"properties": [("mode", 'VERTEX_GPENCIL')]}), + ("object.mode_set",{"type": 'SEVEN', "value": 'PRESS'}, {"properties": [("mode", 'WEIGHT_GPENCIL')]}), ]) diff --git a/release/scripts/presets/tracking_camera/1__colon__2.3_inch.py b/release/scripts/presets/tracking_camera/1__colon__2.3_inch.py index 218e51a53a6..9fcd40fbb65 100644 --- a/release/scripts/presets/tracking_camera/1__colon__2.3_inch.py +++ b/release/scripts/presets/tracking_camera/1__colon__2.3_inch.py @@ -7,4 +7,3 @@ camera.pixel_aspect = 1 camera.k1 = 0.0 camera.k2 = 0.0 camera.k3 = 0.0 - diff --git a/release/scripts/presets/tracking_camera/1__colon__2.5_inch.py b/release/scripts/presets/tracking_camera/1__colon__2.5_inch.py index 0f16dc9b503..2f064e59838 100644 --- a/release/scripts/presets/tracking_camera/1__colon__2.5_inch.py +++ b/release/scripts/presets/tracking_camera/1__colon__2.5_inch.py @@ -7,4 +7,3 @@ camera.pixel_aspect = 1 camera.k1 = 0.0 camera.k2 = 0.0 camera.k3 = 0.0 - diff --git a/release/scripts/presets/tracking_camera/2__colon__3_inch.py b/release/scripts/presets/tracking_camera/2__colon__3_inch.py index 079d0c6308f..8936e627d77 100644 --- a/release/scripts/presets/tracking_camera/2__colon__3_inch.py +++ b/release/scripts/presets/tracking_camera/2__colon__3_inch.py @@ -7,4 +7,3 @@ camera.pixel_aspect = 1 camera.k1 = 0.0 camera.k2 = 0.0 camera.k3 = 0.0 - diff --git a/release/scripts/presets/tracking_camera/4__colon__3_inch.py b/release/scripts/presets/tracking_camera/4__colon__3_inch.py index 0d3313ab755..2317715e1b4 100644 --- a/release/scripts/presets/tracking_camera/4__colon__3_inch.py +++ b/release/scripts/presets/tracking_camera/4__colon__3_inch.py @@ -7,4 +7,3 @@ camera.pixel_aspect = 1 camera.k1 = 0.0 camera.k2 = 0.0 camera.k3 = 0.0 - diff --git a/release/scripts/presets/tracking_camera/Arri_Alexa.py b/release/scripts/presets/tracking_camera/Arri_Alexa.py index 7144f9a03aa..ded361ec965 100644 --- a/release/scripts/presets/tracking_camera/Arri_Alexa.py +++ b/release/scripts/presets/tracking_camera/Arri_Alexa.py @@ -7,4 +7,3 @@ camera.pixel_aspect = 1 camera.k1 = 0.0 camera.k2 = 0.0 camera.k3 = 0.0 - diff --git a/release/scripts/presets/tracking_camera/Canon_1100D.py b/release/scripts/presets/tracking_camera/Canon_1100D.py index dc09e3d0896..96d6d456337 100644 --- a/release/scripts/presets/tracking_camera/Canon_1100D.py +++ b/release/scripts/presets/tracking_camera/Canon_1100D.py @@ -7,4 +7,3 @@ camera.pixel_aspect = 1 camera.k1 = 0.0 camera.k2 = 0.0 camera.k3 = 0.0 - diff --git a/release/scripts/presets/tracking_camera/Canon_APS-C.py b/release/scripts/presets/tracking_camera/Canon_APS-C.py index c55716a06a8..cc4da545272 100644 --- a/release/scripts/presets/tracking_camera/Canon_APS-C.py +++ b/release/scripts/presets/tracking_camera/Canon_APS-C.py @@ -7,4 +7,3 @@ camera.pixel_aspect = 1 camera.k1 = 0.0 camera.k2 = 0.0 camera.k3 = 0.0 - diff --git a/release/scripts/presets/tracking_camera/Canon_APS-H.py b/release/scripts/presets/tracking_camera/Canon_APS-H.py index 0b757edef20..853edd5dcba 100644 --- a/release/scripts/presets/tracking_camera/Canon_APS-H.py +++ b/release/scripts/presets/tracking_camera/Canon_APS-H.py @@ -7,4 +7,3 @@ camera.pixel_aspect = 1 camera.k1 = 0.0 camera.k2 = 0.0 camera.k3 = 0.0 - diff --git a/release/scripts/presets/tracking_camera/Canon_C300.py b/release/scripts/presets/tracking_camera/Canon_C300.py index 24fbbc78ff7..809f8f432f8 100644 --- a/release/scripts/presets/tracking_camera/Canon_C300.py +++ b/release/scripts/presets/tracking_camera/Canon_C300.py @@ -7,4 +7,3 @@ camera.pixel_aspect = 1 camera.k1 = 0.0 camera.k2 = 0.0 camera.k3 = 0.0 - diff --git a/release/scripts/presets/tracking_camera/Full_Frame_35mm_Camera.py b/release/scripts/presets/tracking_camera/Full_Frame_35mm_Camera.py index 478e53584fb..0f3da0b4d72 100644 --- a/release/scripts/presets/tracking_camera/Full_Frame_35mm_Camera.py +++ b/release/scripts/presets/tracking_camera/Full_Frame_35mm_Camera.py @@ -7,4 +7,3 @@ camera.pixel_aspect = 1 camera.k1 = 0.0 camera.k2 = 0.0 camera.k3 = 0.0 - diff --git a/release/scripts/presets/tracking_camera/GoPro_Hero3_Black.py b/release/scripts/presets/tracking_camera/GoPro_Hero3_Black.py index 47e026e9d00..29851352284 100644 --- a/release/scripts/presets/tracking_camera/GoPro_Hero3_Black.py +++ b/release/scripts/presets/tracking_camera/GoPro_Hero3_Black.py @@ -8,4 +8,3 @@ camera.pixel_aspect = 1 camera.k1 = 0.0 camera.k2 = 0.0 camera.k3 = 0.0 - diff --git a/release/scripts/presets/tracking_camera/GoPro_Hero3_Silver.py b/release/scripts/presets/tracking_camera/GoPro_Hero3_Silver.py index 10ca885769a..9e08cf283a7 100644 --- a/release/scripts/presets/tracking_camera/GoPro_Hero3_Silver.py +++ b/release/scripts/presets/tracking_camera/GoPro_Hero3_Silver.py @@ -8,4 +8,3 @@ camera.pixel_aspect = 1 camera.k1 = 0.0 camera.k2 = 0.0 camera.k3 = 0.0 - diff --git a/release/scripts/presets/tracking_camera/GoPro_Hero3_White.py b/release/scripts/presets/tracking_camera/GoPro_Hero3_White.py index c9bda2258c8..6b1f9d97e81 100644 --- a/release/scripts/presets/tracking_camera/GoPro_Hero3_White.py +++ b/release/scripts/presets/tracking_camera/GoPro_Hero3_White.py @@ -8,4 +8,3 @@ camera.pixel_aspect = 1 camera.k1 = 0.0 camera.k2 = 0.0 camera.k3 = 0.0 - diff --git a/release/scripts/presets/tracking_camera/Nexus_5.py b/release/scripts/presets/tracking_camera/Nexus_5.py index 68ec347d3e1..172c8e93bfd 100644 --- a/release/scripts/presets/tracking_camera/Nexus_5.py +++ b/release/scripts/presets/tracking_camera/Nexus_5.py @@ -8,4 +8,3 @@ camera.pixel_aspect = 1 camera.k1 = 0.0 camera.k2 = 0.0 camera.k3 = 0.0 - diff --git a/release/scripts/presets/tracking_camera/Samsung_Galaxy_S3.py b/release/scripts/presets/tracking_camera/Samsung_Galaxy_S3.py index 6dbdaefbd2f..d10994e45f5 100644 --- a/release/scripts/presets/tracking_camera/Samsung_Galaxy_S3.py +++ b/release/scripts/presets/tracking_camera/Samsung_Galaxy_S3.py @@ -8,4 +8,3 @@ camera.pixel_aspect = 1 camera.k1 = 0.0 camera.k2 = 0.0 camera.k3 = 0.0 - diff --git a/release/scripts/presets/tracking_camera/Samsung_Galaxy_S4.py b/release/scripts/presets/tracking_camera/Samsung_Galaxy_S4.py index 051cdf64402..c5fef80b3de 100644 --- a/release/scripts/presets/tracking_camera/Samsung_Galaxy_S4.py +++ b/release/scripts/presets/tracking_camera/Samsung_Galaxy_S4.py @@ -8,4 +8,3 @@ camera.pixel_aspect = 1 camera.k1 = 0.0 camera.k2 = 0.0 camera.k3 = 0.0 - diff --git a/release/scripts/presets/tracking_camera/Super_16.py b/release/scripts/presets/tracking_camera/Super_16.py index f1a8bb37328..e94da9a99ba 100644 --- a/release/scripts/presets/tracking_camera/Super_16.py +++ b/release/scripts/presets/tracking_camera/Super_16.py @@ -7,4 +7,3 @@ camera.pixel_aspect = 1 camera.k1 = 0.0 camera.k2 = 0.0 camera.k3 = 0.0 - diff --git a/release/scripts/presets/tracking_camera/Super_35.py b/release/scripts/presets/tracking_camera/Super_35.py index f533d3e4bcf..e07edc3a22c 100644 --- a/release/scripts/presets/tracking_camera/Super_35.py +++ b/release/scripts/presets/tracking_camera/Super_35.py @@ -7,4 +7,3 @@ camera.pixel_aspect = 1 camera.k1 = 0.0 camera.k2 = 0.0 camera.k3 = 0.0 - diff --git a/release/scripts/presets/tracking_camera/iPhone_4.py b/release/scripts/presets/tracking_camera/iPhone_4.py index b0ac49706b3..220e5e08147 100644 --- a/release/scripts/presets/tracking_camera/iPhone_4.py +++ b/release/scripts/presets/tracking_camera/iPhone_4.py @@ -8,4 +8,3 @@ camera.pixel_aspect = 1 camera.k1 = 0.0 camera.k2 = 0.0 camera.k3 = 0.0 - diff --git a/release/scripts/presets/tracking_camera/iPhone_4S.py b/release/scripts/presets/tracking_camera/iPhone_4S.py index 2569f9b412b..686cffc8f99 100644 --- a/release/scripts/presets/tracking_camera/iPhone_4S.py +++ b/release/scripts/presets/tracking_camera/iPhone_4S.py @@ -8,4 +8,3 @@ camera.pixel_aspect = 1 camera.k1 = 0.0 camera.k2 = 0.0 camera.k3 = 0.0 - diff --git a/release/scripts/presets/tracking_camera/iPhone_5.py b/release/scripts/presets/tracking_camera/iPhone_5.py index f7944e3fa63..d8e05da8425 100644 --- a/release/scripts/presets/tracking_camera/iPhone_5.py +++ b/release/scripts/presets/tracking_camera/iPhone_5.py @@ -8,4 +8,3 @@ camera.pixel_aspect = 1 camera.k1 = 0.0 camera.k2 = 0.0 camera.k3 = 0.0 - diff --git a/release/scripts/startup/bl_operators/__init__.py b/release/scripts/startup/bl_operators/__init__.py index 5af2bd22222..d7df29f1769 100644 --- a/release/scripts/startup/bl_operators/__init__.py +++ b/release/scripts/startup/bl_operators/__init__.py @@ -42,6 +42,7 @@ _modules = [ "rigidbody", "screen_play_rendered_anim", "sequencer", + "simulation", "userpref", "uvcalc_follow_active", "uvcalc_lightmap", diff --git a/release/scripts/startup/bl_operators/simulation.py b/release/scripts/startup/bl_operators/simulation.py new file mode 100644 index 00000000000..5d9c9476318 --- /dev/null +++ b/release/scripts/startup/bl_operators/simulation.py @@ -0,0 +1,39 @@ +# ##### BEGIN GPL LICENSE BLOCK ##### +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software Foundation, +# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +# +# ##### END GPL LICENSE BLOCK ##### + +import bpy + +class NewSimulation(bpy.types.Operator): + """Create a new simulation data block and edit it in the opened simulation editor""" + + bl_idname = "simulation.new" + bl_label = "New Simulation" + bl_options = {'REGISTER', 'UNDO'} + + @classmethod + def poll(cls, context): + return context.area.type == 'NODE_EDITOR' and context.space_data.tree_type == 'SimulationNodeTree' + + def execute(self, context): + simulation = bpy.data.simulations.new("Simulation") + context.space_data.simulation = simulation + return {'FINISHED'} + +classes = ( + NewSimulation, +) diff --git a/release/scripts/startup/bl_operators/userpref.py b/release/scripts/startup/bl_operators/userpref.py index f78ee026927..2e14df1920f 100644 --- a/release/scripts/startup/bl_operators/userpref.py +++ b/release/scripts/startup/bl_operators/userpref.py @@ -110,20 +110,30 @@ class PREFERENCES_OT_copy_prev(Operator): bl_idname = "preferences.copy_prev" bl_label = "Copy Previous Settings" - @staticmethod - def previous_version(): - ver = bpy.app.version - ver_old = ((ver[0] * 100) + ver[1]) - 1 - return ver_old // 100, ver_old % 100 + @classmethod + def _old_version_path(cls, version): + return bpy.utils.resource_path('USER', version[0], version[1]) - @staticmethod - def _old_path(): - ver = bpy.app.version - ver_old = ((ver[0] * 100) + ver[1]) - 1 - return bpy.utils.resource_path('USER', ver_old // 100, ver_old % 100) + @classmethod + def previous_version(cls): + # Find config folder from previous version. + import os + version = bpy.app.version + version_old = ((version[0] * 100) + version[1]) - 1 + while version_old % 10 > 0: + version_split = version_old // 100, version_old % 100 + if os.path.isdir(cls._old_version_path(version_split)): + return version_split + version_old = version_old - 1 + return None - @staticmethod - def _new_path(): + @classmethod + def _old_path(cls): + version_old = cls.previous_version() + return cls._old_version_path(version_old) if version_old else None + + @classmethod + def _new_path(cls): return bpy.utils.resource_path('USER') @classmethod @@ -132,6 +142,8 @@ class PREFERENCES_OT_copy_prev(Operator): old = cls._old_path() new = cls._new_path() + if not old: + return False # Disable operator in case config path is overridden with environment # variable. That case has no automatic per-version configuration. @@ -972,6 +984,7 @@ class PREFERENCES_OT_studiolight_install(Operator): options={'HIDDEN'}, ) type: EnumProperty( + name="Type", items=( ('MATCAP', "MatCap", ""), ('WORLD', "World", ""), diff --git a/release/scripts/startup/bl_operators/uvcalc_follow_active.py b/release/scripts/startup/bl_operators/uvcalc_follow_active.py index 83d451fbc89..6f441238606 100644 --- a/release/scripts/startup/bl_operators/uvcalc_follow_active.py +++ b/release/scripts/startup/bl_operators/uvcalc_follow_active.py @@ -18,9 +18,6 @@ # <pep8 compliant> -# for full docs see... -# https://docs.blender.org/manual/en/latest/editors/uv_image/uv/editing/unwrapping/mapping_types.html#follow-active-quads - import bpy from bpy.types import Operator diff --git a/release/scripts/startup/bl_operators/view3d.py b/release/scripts/startup/bl_operators/view3d.py index fcabee94a89..88fa06a913f 100644 --- a/release/scripts/startup/bl_operators/view3d.py +++ b/release/scripts/startup/bl_operators/view3d.py @@ -72,13 +72,19 @@ class VIEW3D_OT_edit_mesh_extrude_move(Operator): bl_label = "Extrude and Move on Normals" bl_idname = "view3d.edit_mesh_extrude_move_normal" + dissolve_and_intersect: BoolProperty( + name="dissolve_and_intersect", + default=False, + description="Dissolves adjacent faces and intersects new geometry" + ) + @classmethod def poll(cls, context): obj = context.active_object return (obj is not None and obj.mode == 'EDIT') @staticmethod - def extrude_region(context, use_vert_normals): + def extrude_region(context, use_vert_normals, dissolve_and_intersect): mesh = context.object.data totface = mesh.total_face_sel @@ -91,6 +97,17 @@ class VIEW3D_OT_edit_mesh_extrude_move(Operator): 'INVOKE_REGION_WIN', TRANSFORM_OT_shrink_fatten={}, ) + elif dissolve_and_intersect: + bpy.ops.mesh.extrude_region_dissolve_move_intersect( + 'INVOKE_REGION_WIN', + MESH_OT_extrude_region={ + "use_dissolve_ortho_edges": True, + }, + TRANSFORM_OT_translate={ + "orient_type": 'NORMAL', + "constraint_axis": (False, False, True), + }, + ) else: bpy.ops.mesh.extrude_region_move( 'INVOKE_REGION_WIN', @@ -119,7 +136,7 @@ class VIEW3D_OT_edit_mesh_extrude_move(Operator): return {'FINISHED'} def execute(self, context): - return VIEW3D_OT_edit_mesh_extrude_move.extrude_region(context, False) + return VIEW3D_OT_edit_mesh_extrude_move.extrude_region(context, False, self.dissolve_and_intersect) def invoke(self, context, _event): return self.execute(context) @@ -136,7 +153,7 @@ class VIEW3D_OT_edit_mesh_extrude_shrink_fatten(Operator): return (obj is not None and obj.mode == 'EDIT') def execute(self, context): - return VIEW3D_OT_edit_mesh_extrude_move.extrude_region(context, True) + return VIEW3D_OT_edit_mesh_extrude_move.extrude_region(context, True, False) def invoke(self, context, _event): return self.execute(context) diff --git a/release/scripts/startup/bl_operators/wm.py b/release/scripts/startup/bl_operators/wm.py index 319fe364ca3..633118c3b2e 100644 --- a/release/scripts/startup/bl_operators/wm.py +++ b/release/scripts/startup/bl_operators/wm.py @@ -2485,8 +2485,8 @@ class WM_MT_splash(Menu): row = layout.row() sub = row.row() - if bpy.types.PREFERENCES_OT_copy_prev.poll(context): - old_version = bpy.types.PREFERENCES_OT_copy_prev.previous_version() + old_version = bpy.types.PREFERENCES_OT_copy_prev.previous_version() + if bpy.types.PREFERENCES_OT_copy_prev.poll(context) and old_version: sub.operator("preferences.copy_prev", text="Load %d.%d Settings" % old_version) sub.operator("wm.save_userpref", text="Save New Settings") else: @@ -2557,6 +2557,36 @@ class WM_MT_splash(Menu): layout.separator() +class WM_MT_splash_about(Menu): + bl_label = "About" + + def draw(self, context): + + layout = self.layout + layout.operator_context = 'EXEC_DEFAULT' + + layout.label(text="Blender is free software") + layout.label(text="Licensed under the GNU General Public License") + layout.separator() + layout.separator() + + split = layout.split() + split.emboss = 'PULLDOWN_MENU' + split.scale_y = 1.3 + + col1 = split.column() + + col1.operator("wm.url_open_preset", text="Release Notes", icon='URL').type = 'RELEASE_NOTES' + col1.operator("wm.url_open_preset", text="Credits", icon='URL').type = 'CREDITS' + col1.operator("wm.url_open", text="License", icon='URL').url = "https://www.blender.org/about/license/" + + col2 = split.column() + + col2.operator("wm.url_open_preset", text="Blender Website", icon='URL').type = 'BLENDER' + col2.operator("wm.url_open", text="Blender Store", icon='URL').url = "https://store.blender.org" + col2.operator("wm.url_open_preset", text="Development Fund", icon='FUND').type = 'FUND' + + class WM_OT_drop_blend_file(Operator): bl_idname = "wm.drop_blend_file" bl_label = "Handle dropped .blend file" @@ -2626,4 +2656,5 @@ classes = ( BatchRenameAction, WM_OT_batch_rename, WM_MT_splash, + WM_MT_splash_about, ) diff --git a/release/scripts/startup/bl_ui/properties_data_armature.py b/release/scripts/startup/bl_ui/properties_data_armature.py index d44af702d46..05abfa02500 100644 --- a/release/scripts/startup/bl_ui/properties_data_armature.py +++ b/release/scripts/startup/bl_ui/properties_data_armature.py @@ -84,17 +84,12 @@ class DATA_PT_display(ArmatureButtonsPanel, Panel): layout.prop(arm, "display_type", text="Display As") - flow = layout.grid_flow(row_major=False, columns=0, even_columns=False, even_rows=False, align=True) - col = flow.column() + col = layout.column(heading="Show") col.prop(arm, "show_names", text="Names") - col = flow.column() col.prop(arm, "show_axes", text="Axes") - col = flow.column() col.prop(arm, "show_bone_custom_shapes", text="Shapes") - col = flow.column() col.prop(arm, "show_group_colors", text="Group Colors") if ob: - col = flow.column() col.prop(ob, "show_in_front", text="In Front") diff --git a/release/scripts/startup/bl_ui/properties_data_camera.py b/release/scripts/startup/bl_ui/properties_data_camera.py index aee909e3a6c..62dffa3b6ba 100644 --- a/release/scripts/startup/bl_ui/properties_data_camera.py +++ b/release/scripts/startup/bl_ui/properties_data_camera.py @@ -360,8 +360,9 @@ class DATA_PT_camera_background_image(CameraButtonsPanel, Panel): col.prop(bg, "rotation") col.prop(bg, "scale") - col.prop(bg, "use_flip_x") - col.prop(bg, "use_flip_y") + col = box.column(heading="Flip") + col.prop(bg, "use_flip_x", text="X") + col.prop(bg, "use_flip_y", text="Y") class DATA_PT_camera_display(CameraButtonsPanel, Panel): @@ -377,21 +378,12 @@ class DATA_PT_camera_display(CameraButtonsPanel, Panel): col = layout.column(align=True) - col.separator() - col.prop(cam, "display_size", text="Size") - col.separator() - - flow = layout.grid_flow(row_major=False, columns=0, even_columns=False, even_rows=False, align=False) - - col = flow.column() + col = layout.column(heading="Show") col.prop(cam, "show_limits", text="Limits") - col = flow.column() col.prop(cam, "show_mist", text="Mist") - col = flow.column() col.prop(cam, "show_sensor", text="Sensor") - col = flow.column() col.prop(cam, "show_name", text="Name") @@ -407,24 +399,20 @@ class DATA_PT_camera_display_composition_guides(CameraButtonsPanel, Panel): cam = context.camera - flow = layout.grid_flow(row_major=False, columns=0, even_columns=False, even_rows=False, align=False) + layout.prop(cam, "show_composition_thirds") - col = flow.column() + col = layout.column(heading="Center", align=True) col.prop(cam, "show_composition_center") - col = flow.column() - col.prop(cam, "show_composition_center_diagonal") - col = flow.column() - col.prop(cam, "show_composition_thirds") - col = flow.column() - col.prop(cam, "show_composition_golden") - col = flow.column() - col.prop(cam, "show_composition_golden_tria_a") - col = flow.column() - col.prop(cam, "show_composition_golden_tria_b") - col = flow.column() - col.prop(cam, "show_composition_harmony_tri_a") - col = flow.column() - col.prop(cam, "show_composition_harmony_tri_b") + col.prop(cam, "show_composition_center_diagonal", text="Diagonal") + + col = layout.column(heading="Golden", align=True) + col.prop(cam, "show_composition_golden", text="Ratio") + col.prop(cam, "show_composition_golden_tria_a", text="Triangle A") + col.prop(cam, "show_composition_golden_tria_b", text="Triangle B") + + col = layout.column(heading="Harmony", align=True) + col.prop(cam, "show_composition_harmony_tri_a", text="Triangle A") + col.prop(cam, "show_composition_harmony_tri_b", text="Triangle B") class DATA_PT_camera_display_passepartout(CameraButtonsPanel, Panel): diff --git a/release/scripts/startup/bl_ui/properties_data_curve.py b/release/scripts/startup/bl_ui/properties_data_curve.py index b694062dfc5..7e7488f4cf1 100644 --- a/release/scripts/startup/bl_ui/properties_data_curve.py +++ b/release/scripts/startup/bl_ui/properties_data_curve.py @@ -276,23 +276,23 @@ class DATA_PT_active_spline(CurveButtonsPanelActive, Panel): col.prop(act_spline, "use_smooth") else: - sub = col.column(align=True) - sub.prop(act_spline, "use_cyclic_u") + sub = col.column(heading="Cyclic", align=True) + sub.prop(act_spline, "use_cyclic_u", text="U") if is_surf: sub.prop(act_spline, "use_cyclic_v", text="V") if act_spline.type == 'NURBS': - sub = col.column(align=True) + sub = col.column(heading="Bezier", align=True) # sub.active = (not act_spline.use_cyclic_u) - sub.prop(act_spline, "use_bezier_u", text="Bezier U") + sub.prop(act_spline, "use_bezier_u", text="U") if is_surf: subsub = sub.column() subsub.active = (not act_spline.use_cyclic_v) subsub.prop(act_spline, "use_bezier_v", text="V") - sub = col.column(align=True) - sub.prop(act_spline, "use_endpoint_u", text="Endpoint U") + sub = col.column(heading="Endpoint", align=True) + sub.prop(act_spline, "use_endpoint_u", text="U") if is_surf: subsub = sub.column() diff --git a/release/scripts/startup/bl_ui/properties_data_empty.py b/release/scripts/startup/bl_ui/properties_data_empty.py index 898ab2e4359..1523f69536f 100644 --- a/release/scripts/startup/bl_ui/properties_data_empty.py +++ b/release/scripts/startup/bl_ui/properties_data_empty.py @@ -53,9 +53,11 @@ class DATA_PT_empty(DataButtonsPanel, Panel): depth_row.enabled = not ob.show_in_front depth_row.prop(ob, "empty_image_depth", text="Depth", expand=True) col.row().prop(ob, "empty_image_side", text="Side", expand=True) - col.prop(ob, "show_empty_image_orthographic", text="Display Orthographic") - col.prop(ob, "show_empty_image_perspective", text="Display Perspective") - col.prop(ob, "show_empty_image_only_axis_aligned") + + col = layout.column(heading="Show in", align=True) + col.prop(ob, "show_empty_image_orthographic", text="Orthographic") + col.prop(ob, "show_empty_image_perspective", text="Perspective") + col.prop(ob, "show_empty_image_only_axis_aligned", text="Only Axis Aligned") class DATA_PT_empty_alpha(DataButtonsPanel, Panel): diff --git a/release/scripts/startup/bl_ui/properties_data_mesh.py b/release/scripts/startup/bl_ui/properties_data_mesh.py index d91b2ceb7f7..425c94dfdcd 100644 --- a/release/scripts/startup/bl_ui/properties_data_mesh.py +++ b/release/scripts/startup/bl_ui/properties_data_mesh.py @@ -190,27 +190,20 @@ class DATA_PT_normals(MeshButtonsPanel, Panel): COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_WORKBENCH'} def draw(self, context): - pass - - -class DATA_PT_normals_auto_smooth(MeshButtonsPanel, Panel): - bl_label = "Auto Smooth" - bl_parent_id = "DATA_PT_normals" - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_WORKBENCH'} - - def draw_header(self, context): - mesh = context.mesh - - self.layout.prop(mesh, "use_auto_smooth", text="") - - def draw(self, context): layout = self.layout layout.use_property_split = True mesh = context.mesh - layout.active = mesh.use_auto_smooth and not mesh.has_custom_normals - layout.prop(mesh, "auto_smooth_angle", text="Angle") + col = layout.column(align=False, heading="Auto Smooth") + col.use_property_decorate = False + row = col.row(align=True) + sub = row.row(align=True) + sub.prop(mesh, "use_auto_smooth", text="") + sub = sub.row(align=True) + sub.active = mesh.use_auto_smooth and not mesh.has_custom_normals + sub.prop(mesh, "auto_smooth_angle", text="") + row.prop_decorator(mesh, "auto_smooth_angle") class DATA_PT_texture_space(MeshButtonsPanel, Panel): @@ -485,9 +478,11 @@ class DATA_PT_remesh(MeshButtonsPanel, Panel): col.prop(mesh, "remesh_voxel_adaptivity") col.prop(mesh, "use_remesh_fix_poles") col.prop(mesh, "use_remesh_smooth_normals") - col.prop(mesh, "use_remesh_preserve_volume") - col.prop(mesh, "use_remesh_preserve_paint_mask") - col.prop(mesh, "use_remesh_preserve_sculpt_face_sets") + + col = layout.column(heading="Preserve") + col.prop(mesh, "use_remesh_preserve_volume", text="Volume") + col.prop(mesh, "use_remesh_preserve_paint_mask", text="Paint Mask") + col.prop(mesh, "use_remesh_preserve_sculpt_face_sets", text="Face Sets") col.operator("object.voxel_remesh", text="Voxel Remesh") else: col.operator("object.quadriflow_remesh", text="QuadriFlow Remesh") @@ -515,12 +510,12 @@ class DATA_PT_customdata(MeshButtonsPanel, Panel): else: col.operator("mesh.customdata_custom_splitnormals_add", icon='ADD') - col = layout.column() + col = layout.column(heading="Store") col.enabled = obj is not None and obj.mode != 'EDIT' - col.prop(me, "use_customdata_vertex_bevel") - col.prop(me, "use_customdata_edge_bevel") - col.prop(me, "use_customdata_edge_crease") + col.prop(me, "use_customdata_vertex_bevel", text="Vertex Bevel Weight") + col.prop(me, "use_customdata_edge_bevel", text="Edge Bevel Weight") + col.prop(me, "use_customdata_edge_crease", text="Edge Crease") class DATA_PT_custom_props_mesh(MeshButtonsPanel, PropertyPanel, Panel): @@ -544,7 +539,6 @@ classes = ( DATA_PT_vertex_colors, DATA_PT_face_maps, DATA_PT_normals, - DATA_PT_normals_auto_smooth, DATA_PT_texture_space, DATA_PT_remesh, DATA_PT_customdata, diff --git a/release/scripts/startup/bl_ui/properties_data_modifier.py b/release/scripts/startup/bl_ui/properties_data_modifier.py index 7e6ae62f763..71c6817abe9 100644 --- a/release/scripts/startup/bl_ui/properties_data_modifier.py +++ b/release/scripts/startup/bl_ui/properties_data_modifier.py @@ -688,8 +688,7 @@ class DATA_PT_modifiers(ModifierButtonsPanel, Panel): split = layout.split() col = split.column() col.prop(md, "levels", text="Preview") - # TODO(sergey): Expose it again after T58473 is solved. - # col.prop(md, "sculpt_levels", text="Sculpt") + col.prop(md, "sculpt_levels", text="Sculpt") col.prop(md, "render_levels", text="Render") row = col.row() @@ -699,10 +698,20 @@ class DATA_PT_modifiers(ModifierButtonsPanel, Panel): col = split.column() col.enabled = ob.mode != 'EDIT' - col.operator("object.multires_subdivide", text="Subdivide") + op = col.operator("object.multires_subdivide", text="Subdivide") + op.mode = 'CATMULL_CLARK' + + op = col.operator("object.multires_subdivide", text="Subdivide Simple") + op.mode = 'SIMPLE' + + op = col.operator("object.multires_subdivide", text="Subdivide Linear") + op.mode = 'LINEAR' + col.operator("object.multires_higher_levels_delete", text="Delete Higher") + col.operator("object.multires_unsubdivide", text="Unsubdivide") col.operator("object.multires_reshape", text="Reshape") col.operator("object.multires_base_apply", text="Apply Base") + col.operator("object.multires_rebuild_subdiv", text="Rebuild Subdivisions") col.prop(md, "uv_smooth", text="") col.prop(md, "show_only_control_edges") @@ -1428,6 +1437,9 @@ class DATA_PT_modifiers(ModifierButtonsPanel, Panel): if md.falloff_type == 'CURVE': layout.template_curve_mapping(md, "map_curve") + row = layout.row(align=True) + row.prop(md, "normalize") + # Common mask options layout.separator() self.vertex_weight_mask(layout, ob, md) @@ -1453,6 +1465,9 @@ class DATA_PT_modifiers(ModifierButtonsPanel, Panel): col.label(text="Mix Set:") col.prop(md, "mix_set", text="") + row = layout.row(align=True) + row.prop(md, "normalize") + # Common mask options layout.separator() self.vertex_weight_mask(layout, ob, md) @@ -1486,6 +1501,9 @@ class DATA_PT_modifiers(ModifierButtonsPanel, Panel): row.prop(md, "falloff_type") row.prop(md, "invert_falloff", text="", icon='ARROW_LEFTRIGHT') + row = layout.row(align=True) + row.prop(md, "normalize") + # Common mask options layout.separator() self.vertex_weight_mask(layout, ob, md) @@ -1817,6 +1835,10 @@ class DATA_PT_modifiers(ModifierButtonsPanel, Panel): col.prop(md, "thresh", text="Threshold") col.prop(md, "face_influence") + def SIMULATION(self, layout, ob, md): + layout.prop(md, "simulation") + layout.prop(md, "data_path") + class DATA_PT_gpencil_modifiers(ModifierButtonsPanel, Panel): bl_label = "Modifiers" @@ -1878,7 +1900,15 @@ class DATA_PT_gpencil_modifiers(ModifierButtonsPanel, Panel): split = col2.split(factor=0.6) row = split.row(align=True) - row.prop_search(md, "material", gpd, "materials", text="", icon='SHADING_TEXTURE') + + valid = md.material in (slot.material for slot in ob.material_slots) or md.material is None + if valid: + icon = 'SHADING_TEXTURE' + else: + icon = 'ERROR' + + row.alert = not valid + row.prop_search(md, "material", gpd, "materials", text="", icon=icon) row.prop(md, "invert_materials", text="", icon='ARROW_LEFTRIGHT') row = split.row(align=True) @@ -1981,6 +2011,27 @@ class DATA_PT_gpencil_modifiers(ModifierButtonsPanel, Panel): self.gpencil_masking(layout, ob, md, True, True) + def GP_TEXTURE(self, layout, ob, md): + col = layout.column() + + col.prop(md, "mode") + if md.mode in {'STROKE', 'STROKE_AND_FILL'}: + col.label(text="Stroke Texture:") + col.prop(md, "fit_method") + col.prop(md, "uv_offset") + col.prop(md, "uv_scale") + + if md.mode == 'STROKE_AND_FILL': + col.separator() + + if md.mode in {'FILL', 'STROKE_AND_FILL'}: + col.label(text="Fill Texture:") + col.prop(md, "fill_rotation", text="Rotation") + col.prop(md, "fill_offset", text="Location") + col.prop(md, "fill_scale", text="Scale") + + self.gpencil_masking(layout, ob, md, True) + def GP_TINT(self, layout, ob, md): layout.row().prop(md, "tint_type", expand=True) @@ -2155,6 +2206,11 @@ class DATA_PT_gpencil_modifiers(ModifierButtonsPanel, Panel): sub.prop(md, "frame_start", text="Start") sub.prop(md, "frame_end", text="End") + col.prop(md, "use_percentage") + sub = col.column(align=True) + sub.active = md.use_percentage + sub.prop(md, "percentage_factor") + layout.label(text="Influence Filters:") split = layout.split(factor=0.25) diff --git a/release/scripts/startup/bl_ui/properties_grease_pencil_common.py b/release/scripts/startup/bl_ui/properties_grease_pencil_common.py index 6a94212fb81..07c9fc363b5 100644 --- a/release/scripts/startup/bl_ui/properties_grease_pencil_common.py +++ b/release/scripts/startup/bl_ui/properties_grease_pencil_common.py @@ -44,38 +44,6 @@ def gpencil_stroke_placement_settings(context, layout): row.prop_enum(tool_settings, propname, 'CURSOR', text="Cursor") -def gpencil_active_brush_settings_simple(context, layout): - tool_settings = context.tool_settings - brush = tool_settings.gpencil_paint.brush - if brush is None: - layout.label(text="No Active Brush") - return - - col = layout.column() - col.label(text="Active Brush: ") - - row = col.row(align=True) - row.operator_context = 'EXEC_REGION_WIN' - row.operator_menu_enum("gpencil.brush_change", "brush", text="", icon='BRUSH_DATA') - row.prop(brush, "name", text="") - - col.prop(brush, "size", slider=True) - row = col.row(align=True) - row.prop(brush, "use_random_pressure", text="", icon='RNDCURVE') - row.prop(brush, "pen_sensitivity_factor", slider=True) - row.prop(brush, "use_pressure", text="", icon='STYLUS_PRESSURE') - row = col.row(align=True) - row.prop(brush, "use_random_strength", text="", icon='RNDCURVE') - row.prop(brush, "strength", slider=True) - row.prop(brush, "use_strength_pressure", text="", icon='STYLUS_PRESSURE') - row = col.row(align=True) - row.prop(brush, "jitter", slider=True) - row.prop(brush, "use_jitter_pressure", text="", icon='STYLUS_PRESSURE') - row = col.row() - row.prop(brush, "angle", slider=True) - row.prop(brush, "angle_factor", text="Factor", slider=True) - - # XXX: To be replaced with active tools class AnnotationDrawingToolsPanel: # subclass must set @@ -361,6 +329,35 @@ class GPENCIL_MT_layer_active(Menu): layout.operator("gpencil.layer_add", text="New Layer", icon='ADD') +class GPENCIL_MT_material_active(Menu): + bl_label = "Change Active Material" + + @classmethod + def poll(cls, context): + ob = context.active_object + tool_settings = context.scene.tool_settings + mode = tool_settings.gpencil_paint.color_mode + if mode != 'MATERIAL': + return False + + if ob is None or len(ob.material_slots) == 0: + return False + + return True + + def draw(self, context): + layout = self.layout + layout.operator_context = 'INVOKE_REGION_WIN' + ob = context.active_object + mat_active = ob.active_material + + for slot in ob.material_slots: + mat = slot.material + if mat: + icon = mat.id_data.preview.icon_id + layout.operator("gpencil.material_set", text=mat.name, icon_value=icon).slot = mat.name + + class GPENCIL_MT_gpencil_draw_delete(Menu): bl_label = "Delete" @@ -520,7 +517,7 @@ class AnnotationOnionSkin: if gpl is None: return False - return True + return True def draw_header(self, context): gpl = context.active_annotation_layer @@ -548,30 +545,6 @@ class AnnotationOnionSkin: sub.prop(gpl, "annotation_onion_after_range", text="After") -class GreasePencilToolsPanel: - # For use in "2D" Editors without their own toolbar - # subclass must set - # bl_space_type = 'IMAGE_EDITOR' - bl_label = "Grease Pencil Settings" - bl_region_type = 'UI' - bl_options = {'DEFAULT_CLOSED'} - - @classmethod - def poll(cls, _context): - # XXX - disabled in 2.8 branch. - # return (context.gpencil_data is not None) - return False - - def draw(self, context): - layout = self.layout - - gpencil_active_brush_settings_simple(context, layout) - - layout.separator() - - gpencil_stroke_placement_settings(context, layout) - - class GreasePencilMaterialsPanel: # Mix-in, use for properties editor and top-bar. def draw(self, context): @@ -632,8 +605,8 @@ class GreasePencilMaterialsPanel: if ob.data.use_stroke_edit_mode: row = layout.row(align=True) row.operator("gpencil.stroke_change_color", text="Assign") - row.operator("gpencil.select_material", text="Select").deselect = False - row.operator("gpencil.select_material", text="Deselect").deselect = True + row.operator("gpencil.material_select", text="Select").deselect = False + row.operator("gpencil.material_select", text="Deselect").deselect = True # stroke color ma = None if is_view3d and brush is not None: @@ -931,6 +904,7 @@ classes = ( GPENCIL_MT_cleanup, GPENCIL_MT_move_to_layer, GPENCIL_MT_layer_active, + GPENCIL_MT_material_active, GPENCIL_MT_gpencil_draw_delete, GPENCIL_MT_layer_mask_menu, diff --git a/release/scripts/startup/bl_ui/properties_material.py b/release/scripts/startup/bl_ui/properties_material.py index ab70c4c25c0..6aaec9940e8 100644 --- a/release/scripts/startup/bl_ui/properties_material.py +++ b/release/scripts/startup/bl_ui/properties_material.py @@ -172,10 +172,11 @@ class EEVEE_MATERIAL_PT_surface(MaterialButtonsPanel, Panel): layout.prop(mat, "use_nodes", icon='NODETREE') layout.separator() + layout.use_property_split = True + if mat.use_nodes: panel_node_draw(layout, mat.node_tree, 'OUTPUT_MATERIAL', "Surface") else: - layout.use_property_split = True layout.prop(mat, "diffuse_color", text="Base Color") layout.prop(mat, "metallic") layout.prop(mat, "specular_intensity", text="Specular") @@ -197,6 +198,8 @@ class EEVEE_MATERIAL_PT_volume(MaterialButtonsPanel, Panel): def draw(self, context): layout = self.layout + layout.use_property_split = True + mat = context.material panel_node_draw(layout, mat.node_tree, 'OUTPUT_MATERIAL', "Volume") diff --git a/release/scripts/startup/bl_ui/properties_object.py b/release/scripts/startup/bl_ui/properties_object.py index a805b965af2..8ce53ed30eb 100644 --- a/release/scripts/startup/bl_ui/properties_object.py +++ b/release/scripts/startup/bl_ui/properties_object.py @@ -212,7 +212,6 @@ class OBJECT_PT_display(ObjectButtonsPanel, Panel): layout = self.layout layout.use_property_split = True - flow = layout.grid_flow(row_major=True, columns=0, even_columns=True, even_rows=False, align=False) obj = context.object obj_type = obj.type @@ -222,35 +221,22 @@ class OBJECT_PT_display(ObjectButtonsPanel, Panel): is_dupli = (obj.instance_type != 'NONE') is_gpencil = (obj_type == 'GPENCIL') - col = flow.column() + col = layout.column(heading="Show") col.prop(obj, "show_name", text="Name") - - col = flow.column() col.prop(obj, "show_axis", text="Axis") # Makes no sense for cameras, armatures, etc.! # but these settings do apply to dupli instances if is_geometry or is_dupli: - col = flow.column() col.prop(obj, "show_wire", text="Wireframe") if obj_type == 'MESH' or is_dupli: - col = flow.column() col.prop(obj, "show_all_edges", text="All Edges") - - col = flow.column() if is_geometry: col.prop(obj, "show_texture_space", text="Texture Space") - col = flow.column() col.prop(obj.display, "show_shadows", text="Shadow") - - col = flow.column() col.prop(obj, "show_in_front", text="In Front") # if obj_type == 'MESH' or is_empty_image: # col.prop(obj, "show_transparent", text="Transparency") - - flow = layout.grid_flow(row_major=True, columns=0, even_columns=True, even_rows=False, align=False) - - col = flow.column() if is_wire: # wire objects only use the max. display type for duplis col.active = is_dupli @@ -258,28 +244,17 @@ class OBJECT_PT_display(ObjectButtonsPanel, Panel): if is_geometry or is_dupli or is_empty_image or is_gpencil: # Only useful with object having faces/materials... - col = flow.column() col.prop(obj, "color") - -class OBJECT_PT_display_bounds(ObjectButtonsPanel, Panel): - bl_label = "Bounds" - bl_parent_id = "OBJECT_PT_display" - bl_options = {'DEFAULT_CLOSED'} - - def draw_header(self, context): - - obj = context.object - - self.layout.prop(obj, "show_bounds", text="") - - def draw(self, context): - layout = self.layout - obj = context.object - layout.use_property_split = True - - layout.active = obj.show_bounds or (obj.display_type == 'BOUNDS') - layout.prop(obj, "display_bounds_type", text="Shape") + col = layout.column(align=False, heading="Bounds") + col.use_property_decorate = False + row = col.row(align=True) + sub = row.row(align=True) + sub.prop(obj, "show_bounds", text="") + sub = sub.row(align=True) + sub.active = obj.show_bounds or (obj.display_type == 'BOUNDS') + sub.prop(obj, "display_bounds_type", text="") + row.prop_decorator(obj, "display_bounds_type") class OBJECT_PT_instancing(ObjectButtonsPanel, Panel): @@ -295,7 +270,6 @@ class OBJECT_PT_instancing(ObjectButtonsPanel, Panel): row.prop(ob, "instance_type", expand=True) layout.use_property_split = True - flow = layout.grid_flow(row_major=True, columns=0, even_columns=True, even_rows=False, align=False) if ob.instance_type == 'VERTS': layout.prop(ob, "use_instance_vertices_rotation", text="Align to Vertex Normal") @@ -305,9 +279,9 @@ class OBJECT_PT_instancing(ObjectButtonsPanel, Panel): col.prop(ob, "instance_collection", text="Collection") if ob.instance_type != 'NONE' or ob.particle_systems: - col = flow.column(align=True) - col.prop(ob, "show_instancer_for_viewport") - col.prop(ob, "show_instancer_for_render") + col = layout.column(heading="Show Instancer", align=True) + col.prop(ob, "show_instancer_for_viewport", text="Viewport") + col.prop(ob, "show_instancer_for_render", text="Render") class OBJECT_PT_instancing_size(ObjectButtonsPanel, Panel): @@ -385,19 +359,17 @@ class OBJECT_PT_visibility(ObjectButtonsPanel, Panel): layout = self.layout layout.use_property_split = True - flow = layout.grid_flow(row_major=False, columns=0, even_columns=True, even_rows=False, align=False) layout = self.layout ob = context.object - col = flow.column() - col.prop(ob, "hide_viewport", text="Show in Viewports", toggle=False, invert_checkbox=True) - col = flow.column() - col.prop(ob, "hide_render", text="Show in Renders", toggle=False, invert_checkbox=True) - col = flow.column() - col.prop(ob, "hide_select", text="Selectable", toggle=False, invert_checkbox=True) + layout.prop(ob, "hide_select", text="Selectable", toggle=False, invert_checkbox=True) + + col = layout.column(heading="Show in") + col.prop(ob, "hide_viewport", text="Viewports", toggle=False, invert_checkbox=True) + col.prop(ob, "hide_render", text="Renders", toggle=False, invert_checkbox=True) if context.object.type == 'GPENCIL': - col = flow.column() + col = layout.column(heading="Grease Pencil") col.prop(ob, "use_grease_pencil_lights", toggle=False) @@ -419,7 +391,6 @@ classes = ( OBJECT_PT_motion_paths, OBJECT_PT_motion_paths_display, OBJECT_PT_display, - OBJECT_PT_display_bounds, OBJECT_PT_visibility, OBJECT_PT_custom_props, ) diff --git a/release/scripts/startup/bl_ui/properties_output.py b/release/scripts/startup/bl_ui/properties_output.py index 748961bb40f..e859798c085 100644 --- a/release/scripts/startup/bl_ui/properties_output.py +++ b/release/scripts/startup/bl_ui/properties_output.py @@ -94,14 +94,14 @@ class RENDER_PT_dimensions(RenderOutputButtonsPanel, Panel): return args @staticmethod - def draw_framerate(layout, sub, rd): + def draw_framerate(layout, rd): if RENDER_PT_dimensions._preset_class is None: RENDER_PT_dimensions._preset_class = bpy.types.RENDER_MT_framerate_presets args = rd.fps, rd.fps_base, RENDER_PT_dimensions._preset_class.bl_label fps_label_text, show_framerate = RENDER_PT_dimensions._draw_framerate_label(*args) - sub.menu("RENDER_MT_framerate_presets", text=fps_label_text) + layout.menu("RENDER_MT_framerate_presets", text=fps_label_text) if show_framerate: col = layout.column(align=True) @@ -136,10 +136,8 @@ class RENDER_PT_dimensions(RenderOutputButtonsPanel, Panel): col.prop(scene, "frame_end", text="End") col.prop(scene, "frame_step", text="Step") - col = layout.split() - col.alignment = 'RIGHT' - col.label(text="Frame Rate") - self.draw_framerate(layout, col, rd) + col = layout.column(heading="Frame Rate") + self.draw_framerate(col, rd) class RENDER_PT_frame_remapping(RenderOutputButtonsPanel, Panel): @@ -171,10 +169,8 @@ class RENDER_PT_post_processing(RenderOutputButtonsPanel, Panel): rd = context.scene.render - flow = layout.grid_flow(row_major=True, columns=0, even_columns=True, even_rows=False, align=False) - col = flow.column() + col = layout.column(heading="Pipeline") col.prop(rd, "use_compositing") - col = flow.column() col.prop(rd, "use_sequencer") layout.prop(rd, "dither_intensity", text="Dither", slider=True) @@ -192,44 +188,23 @@ class RENDER_PT_stamp(RenderOutputButtonsPanel, Panel): rd = context.scene.render - flow = layout.grid_flow(row_major=True, columns=0, even_columns=True, even_rows=False, align=False) + if rd.use_sequencer: + layout.prop(rd, "metadata_input") - col = flow.column() + col = layout.column(heading="Include") col.prop(rd, "use_stamp_date", text="Date") - col = flow.column() col.prop(rd, "use_stamp_time", text="Time") - - col = flow.column() col.prop(rd, "use_stamp_render_time", text="Render Time") - col = flow.column() col.prop(rd, "use_stamp_frame", text="Frame") - col = flow.column() col.prop(rd, "use_stamp_frame_range", text="Frame Range") - col = flow.column() col.prop(rd, "use_stamp_memory", text="Memory") - col = flow.column() col.prop(rd, "use_stamp_hostname", text="Hostname") - - col = flow.column() col.prop(rd, "use_stamp_camera", text="Camera") - col = flow.column() col.prop(rd, "use_stamp_lens", text="Lens") - - col = flow.column() col.prop(rd, "use_stamp_scene", text="Scene") - col = flow.column() col.prop(rd, "use_stamp_marker", text="Marker") - - col = flow.column() col.prop(rd, "use_stamp_filename", text="Filename") - col = flow.column() - col.prop(rd, "use_stamp_sequencer_strip", text="Strip Name") - - if rd.use_sequencer: - col = flow.column() - col.prop(rd, "use_stamp_strip_meta", text="Use Strip Metadata") - class RENDER_PT_stamp_note(RenderOutputButtonsPanel, Panel): bl_label = "Note" @@ -293,21 +268,17 @@ class RENDER_PT_output(RenderOutputButtonsPanel, Panel): layout.use_property_split = True - flow = layout.grid_flow(row_major=True, columns=0, even_columns=True, even_rows=False, align=False) - - col = flow.column() - col.active = not rd.is_movie_format - col.prop(rd, "use_overwrite") - col = flow.column() - col.active = not rd.is_movie_format - col.prop(rd, "use_placeholder") - col = flow.column() + col = layout.column(heading="Saving") col.prop(rd, "use_file_extension") - col = flow.column() col.prop(rd, "use_render_cache") layout.template_image_settings(image_settings, color_management=False) + if not rd.is_movie_format: + col = layout.column(heading="Image Sequence") + col.prop(rd, "use_overwrite") + col.prop(rd, "use_placeholder") + class RENDER_PT_output_views(RenderOutputButtonsPanel, Panel): bl_label = "Views" diff --git a/release/scripts/startup/bl_ui/properties_paint_common.py b/release/scripts/startup/bl_ui/properties_paint_common.py index 50cbaaccc28..5fadb31c83f 100644 --- a/release/scripts/startup/bl_ui/properties_paint_common.py +++ b/release/scripts/startup/bl_ui/properties_paint_common.py @@ -125,7 +125,7 @@ class UnifiedPaintPanel: if unified_name and not header: # NOTE: We don't draw UnifiedPaintSettings in the header to reduce clutter. D5928#136281 - row.prop(ups, unified_name, text="", icon="BRUSHES_ALL") + row.prop(ups, unified_name, text="", icon='BRUSHES_ALL') return row @@ -587,10 +587,12 @@ def brush_settings(layout, context, brush, popover=False): slider=True, ) - layout.prop(brush, "use_plane_trim", text="Plane Trim") - row = layout.row() - row.active = brush.use_plane_trim - row.prop(brush, "plane_trim", slider=True, text="Distance") + row = layout.row(heading="Plane Trim") + row.prop(brush, "use_plane_trim", text="") + sub = row.row() + sub.active = brush.use_plane_trim + sub.prop(brush, "plane_trim", slider=True, text="") + layout.separator() # height @@ -617,10 +619,12 @@ def brush_settings(layout, context, brush, popover=False): if brush.sculpt_tool == 'POSE': layout.separator() + layout.prop(brush, "pose_deform_type") layout.prop(brush, "pose_origin_type") layout.prop(brush, "pose_offset") layout.prop(brush, "pose_smooth_iterations") - layout.prop(brush, "pose_ik_segments") + if brush.pose_deform_type == 'ROTATE_TWIST': + layout.prop(brush, "pose_ik_segments") layout.prop(brush, "use_pose_ik_anchored") layout.separator() @@ -808,23 +812,27 @@ def brush_settings_advanced(layout, context, brush, popover=False): use_accumulate = capabilities.has_accumulate use_frontface = True + col = layout.column(heading="Auto-Masking", align=True) + # topology automasking - layout.prop(brush, "use_automasking_topology") + col.prop(brush, "use_automasking_topology", text="Topology") # face masks automasking - layout.prop(brush, "use_automasking_face_sets") + col.prop(brush, "use_automasking_face_sets", text="Face Sets") # boundary edges/face sets automasking - layout.prop(brush, "use_automasking_boundary_edges") - layout.prop(brush, "use_automasking_boundary_face_sets") - layout.prop(brush, "automasking_boundary_edges_propagation_steps") + col.prop(brush, "use_automasking_boundary_edges", text="Mesh Boundary") + col.prop(brush, "use_automasking_boundary_face_sets", text="Face Sets Boundary") + col.prop(brush, "automasking_boundary_edges_propagation_steps") + layout.separator() # sculpt plane settings if capabilities.has_sculpt_plane: layout.prop(brush, "sculpt_plane") - layout.prop(brush, "use_original_normal") - layout.prop(brush, "use_original_plane") + col = layout.column(heading="Use Original", align=True) + col.prop(brush, "use_original_normal", text="Normal") + col.prop(brush, "use_original_plane", text="Plane") layout.separator() # 3D and 2D Texture Paint. @@ -1070,9 +1078,21 @@ def brush_basic_gpencil_paint_settings(layout, context, brush, *, compact=False) row = layout.row(align=True) row.prop(brush, "size", text="Radius") row.prop(gp_settings, "use_pressure", text="", icon='STYLUS_PRESSURE') + + if gp_settings.use_pressure and context.area.type == 'PROPERTIES': + col = layout.column() + col.template_curve_mapping(gp_settings, "curve_sensitivity", brush=True, + use_negative_slope=True) + row = layout.row(align=True) row.prop(gp_settings, "pen_strength", slider=True) row.prop(gp_settings, "use_strength_pressure", text="", icon='STYLUS_PRESSURE') + + if gp_settings.use_strength_pressure and context.area.type == 'PROPERTIES': + col = layout.column() + col.template_curve_mapping(gp_settings, "curve_strength", brush=True, + use_negative_slope=True) + if brush.gpencil_tool == 'TINT': row = layout.row(align=True) row.prop(gp_settings, "vertex_mode", text="Mode") diff --git a/release/scripts/startup/bl_ui/properties_physics_common.py b/release/scripts/startup/bl_ui/properties_physics_common.py index 479782f1e3b..0cd99efcca9 100644 --- a/release/scripts/startup/bl_ui/properties_physics_common.py +++ b/release/scripts/startup/bl_ui/properties_physics_common.py @@ -310,8 +310,10 @@ def basic_force_field_settings_ui(self, field): else: col.prop(field, "flow") - col.prop(field, "apply_to_location", text="Affect Location") - col.prop(field, "apply_to_rotation", text="Affect Rotation") + sub = col.column(heading="Affect") + + sub.prop(field, "apply_to_location", text="Location") + sub.prop(field, "apply_to_rotation", text="Rotation") col = flow.column() sub = col.column(align=True) @@ -336,26 +338,29 @@ def basic_force_field_falloff_ui(self, field): if not field or field.type == 'NONE': return - flow = layout.grid_flow(row_major=True, columns=0, even_columns=True, even_rows=False, align=True) - - col = flow.column() + col = layout.column() col.prop(field, "z_direction") col.prop(field, "falloff_power", text="Power") - col = flow.column() - col.prop(field, "use_min_distance", text="Use Minimum") - - sub = col.column(align=True) + col = layout.column(align=False, heading="Min Distance") + col.use_property_decorate = False + row = col.row(align=True) + sub = row.row(align=True) + sub.prop(field, "use_min_distance", text="") + sub = sub.row(align=True) sub.active = field.use_min_distance - sub.prop(field, "distance_min", text="Min Distance") - - col = flow.column() - col.prop(field, "use_max_distance", text="Use Maximum") - - sub = col.column(align=True) + sub.prop(field, "distance_min", text="") + row.prop_decorator(field, "distance_min") + + col = layout.column(align=False, heading="Max Distance") + col.use_property_decorate = False + row = col.row(align=True) + sub = row.row(align=True) + sub.prop(field, "use_max_distance", text="") + sub = sub.row(align=True) sub.active = field.use_max_distance - sub.prop(field, "distance_max", text="Max Distance") - + sub.prop(field, "distance_max", text="") + row.prop_decorator(field, "distance_max") classes = ( PHYSICS_PT_add, diff --git a/release/scripts/startup/bl_ui/properties_physics_field.py b/release/scripts/startup/bl_ui/properties_physics_field.py index 00dc068a51a..d1ff1dc9f5e 100644 --- a/release/scripts/startup/bl_ui/properties_physics_field.py +++ b/release/scripts/startup/bl_ui/properties_physics_field.py @@ -123,7 +123,7 @@ class PHYSICS_PT_field_settings(PhysicButtonsPanel, Panel): col.prop(field, "use_object_coords") col.prop(field, "use_2d_force") - elif field.type == 'SMOKE_FLOW': + elif field.type == 'FLUID_FLOW': col = flow.column() col.prop(field, "strength") col.prop(field, "flow") diff --git a/release/scripts/startup/bl_ui/properties_physics_rigidbody.py b/release/scripts/startup/bl_ui/properties_physics_rigidbody.py index dd7bf54dc68..b03f80bd600 100644 --- a/release/scripts/startup/bl_ui/properties_physics_rigidbody.py +++ b/release/scripts/startup/bl_ui/properties_physics_rigidbody.py @@ -79,14 +79,12 @@ class PHYSICS_PT_rigid_body_settings(PHYSICS_PT_rigidbody_panel, Panel): rigid_body_warning(layout) return - flow = layout.grid_flow(row_major=True, columns=0, even_columns=True, even_rows=False, align=True) - col = flow.column() + col = layout.column() if rbo.type == 'ACTIVE': col.prop(rbo, "mass") col.prop(rbo, "enabled", text="Dynamic") - col = flow.column() col.prop(rbo, "kinematic", text="Animated") diff --git a/release/scripts/startup/bl_ui/properties_render.py b/release/scripts/startup/bl_ui/properties_render.py index a207fb4c79e..155bbb523c7 100644 --- a/release/scripts/startup/bl_ui/properties_render.py +++ b/release/scripts/startup/bl_ui/properties_render.py @@ -475,33 +475,21 @@ class RENDER_PT_eevee_film(RenderButtonsPanel, Panel): scene = context.scene rd = scene.render + props = scene.eevee col = layout.column() col.prop(rd, "filter_size") col.prop(rd, "film_transparent", text="Transparent") - -class RENDER_PT_eevee_film_overscan(RenderButtonsPanel, Panel): - bl_label = "Overscan" - bl_parent_id = "RENDER_PT_eevee_film" - bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_EEVEE'} - - def draw_header(self, context): - - scene = context.scene - props = scene.eevee - - self.layout.prop(props, "use_overscan", text="") - - def draw(self, context): - layout = self.layout - layout.use_property_split = True - scene = context.scene - props = scene.eevee - - layout.active = props.use_overscan - layout.prop(props, "overscan_size", text="Size") + col = layout.column(align=False, heading="Overscan") + col.use_property_decorate = False + row = col.row(align=True) + sub = row.row(align=True) + sub.prop(props, "use_overscan", text="") + sub = sub.row(align=True) + sub.active = props.use_overscan + sub.prop(props, "overscan_size", text="") + row.prop_decorator(props, "overscan_size") class RENDER_PT_eevee_hair(RenderButtonsPanel, Panel): @@ -716,7 +704,7 @@ classes = ( RENDER_PT_eevee_indirect_lighting, RENDER_PT_eevee_indirect_lighting_display, RENDER_PT_eevee_film, - RENDER_PT_eevee_film_overscan, + RENDER_PT_gpencil, RENDER_PT_opengl_sampling, RENDER_PT_opengl_lighting, diff --git a/release/scripts/startup/bl_ui/properties_texture.py b/release/scripts/startup/bl_ui/properties_texture.py index 40a630ff834..5af8bc2aaa7 100644 --- a/release/scripts/startup/bl_ui/properties_texture.py +++ b/release/scripts/startup/bl_ui/properties_texture.py @@ -163,6 +163,8 @@ class TEXTURE_PT_node(TextureButtonsPanel, Panel): def draw(self, context): layout = self.layout + layout.use_property_split = True + node = context.texture_node ntree = node.id_data layout.template_node_view(ntree, node, None) diff --git a/release/scripts/startup/bl_ui/properties_view_layer.py b/release/scripts/startup/bl_ui/properties_view_layer.py index 5fe06ebbb6e..3645f0dc2f2 100644 --- a/release/scripts/startup/bl_ui/properties_view_layer.py +++ b/release/scripts/startup/bl_ui/properties_view_layer.py @@ -40,17 +40,12 @@ class VIEWLAYER_PT_layer(ViewLayerButtonsPanel, Panel): layout.use_property_split = True - flow = layout.grid_flow(row_major=True, columns=0, even_columns=True, even_rows=False, align=False) - - layout.use_property_split = True - scene = context.scene rd = scene.render layer = context.view_layer - col = flow.column() + col = layout.column() col.prop(layer, "use", text="Use for Rendering") - col = flow.column() col.prop(rd, "use_single_layer", text="Render Single Layer") @@ -77,14 +72,10 @@ class VIEWLAYER_PT_eevee_layer_passes_data(ViewLayerButtonsPanel, Panel): rd = scene.render view_layer = context.view_layer - flow = layout.grid_flow(row_major=True, columns=0, even_columns=True, even_rows=False, align=False) - col = flow.column() + col = layout.column() col.prop(view_layer, "use_pass_combined") - col = flow.column() col.prop(view_layer, "use_pass_z") - col = flow.column() col.prop(view_layer, "use_pass_mist") - col = flow.column() col.prop(view_layer, "use_pass_normal") @@ -104,29 +95,19 @@ class VIEWLAYER_PT_eevee_layer_passes_light(ViewLayerButtonsPanel, Panel): scene = context.scene scene_eevee = scene.eevee - split = layout.split(factor=0.35) - split.use_property_split = False - split.label(text="Diffuse") - row = split.row(align=True) - row.prop(view_layer, "use_pass_diffuse_direct", text="Light", toggle=True) - row.prop(view_layer, "use_pass_diffuse_color", text="Color", toggle=True) - - split = layout.split(factor=0.35) - split.use_property_split = False - split.label(text="Specular") - row = split.row(align=True) - row.prop(view_layer, "use_pass_glossy_direct", text="Light", toggle=True) - row.prop(view_layer, "use_pass_glossy_color", text="Color", toggle=True) - - split = layout.split(factor=0.35) - split.use_property_split = False - split.label(text="Volume") - row = split.row(align=True) - row.prop(view_layer_eevee, "use_pass_volume_transmittance", text="Transmittance", toggle=True) - row.prop(view_layer_eevee, "use_pass_volume_scatter", text="Scatter", toggle=True) - flow = layout.grid_flow(row_major=True, columns=0, even_columns=True, even_rows=False, align=False) - - col = layout.column(align=True) + col = layout.column(heading="Diffuse", align=True) + col.prop(view_layer, "use_pass_diffuse_direct", text="Light") + col.prop(view_layer, "use_pass_diffuse_color", text="Color") + + col = layout.column(heading="Specular", align=True) + col.prop(view_layer, "use_pass_glossy_direct", text="Light") + col.prop(view_layer, "use_pass_glossy_color", text="Color") + + col = layout.column(heading="Volume", align=True) + col.prop(view_layer_eevee, "use_pass_volume_transmittance", text="Transmittance") + col.prop(view_layer_eevee, "use_pass_volume_scatter", text="Scatter") + + col = layout.column(heading="Other", align=True) col.prop(view_layer, "use_pass_emit", text="Emission") col.prop(view_layer, "use_pass_environment") col.prop(view_layer, "use_pass_shadow") @@ -146,14 +127,12 @@ class VIEWLAYER_PT_eevee_layer_passes_effects(ViewLayerButtonsPanel, Panel): layout.use_property_split = True layout.use_property_decorate = False - flow = layout.grid_flow(row_major=True, columns=0, even_columns=True, even_rows=False, align=False) - view_layer = context.view_layer view_layer_eevee = view_layer.eevee scene = context.scene scene_eevee = scene.eevee - col = flow.column() + col = layout.column() col.prop(view_layer_eevee, "use_pass_bloom", text="Bloom") col.active = scene_eevee.use_bloom diff --git a/release/scripts/startup/bl_ui/properties_world.py b/release/scripts/startup/bl_ui/properties_world.py index 705be66ecc1..6f00e521e58 100644 --- a/release/scripts/startup/bl_ui/properties_world.py +++ b/release/scripts/startup/bl_ui/properties_world.py @@ -105,6 +105,8 @@ class EEVEE_WORLD_PT_surface(WorldButtonsPanel, Panel): layout.prop(world, "use_nodes", icon='NODETREE') layout.separator() + layout.use_property_split = True + if world.use_nodes: ntree = world.node_tree node = ntree.get_output_node('EEVEE') @@ -139,6 +141,8 @@ class EEVEE_WORLD_PT_volume(WorldButtonsPanel, Panel): ntree = world.node_tree node = ntree.get_output_node('EEVEE') + layout.use_property_split = True + if node: input = find_node_input(node, 'Volume') if input: diff --git a/release/scripts/startup/bl_ui/space_clip.py b/release/scripts/startup/bl_ui/space_clip.py index f93629a4f03..5b6cc6609e0 100644 --- a/release/scripts/startup/bl_ui/space_clip.py +++ b/release/scripts/startup/bl_ui/space_clip.py @@ -918,6 +918,10 @@ class CLIP_PT_tracking_lens(Panel): col = layout.column(align=True) col.prop(camera, "division_k1") col.prop(camera, "division_k2") + elif camera.distortion_model == 'NUKE': + col = layout.column(align=True) + col.prop(camera, "nuke_k1") + col.prop(camera, "nuke_k2") class CLIP_PT_marker(CLIP_PT_tracking_panel, Panel): diff --git a/release/scripts/startup/bl_ui/space_filebrowser.py b/release/scripts/startup/bl_ui/space_filebrowser.py index 3bf5bbf7b46..9a39d840149 100644 --- a/release/scripts/startup/bl_ui/space_filebrowser.py +++ b/release/scripts/startup/bl_ui/space_filebrowser.py @@ -20,6 +20,7 @@ from bpy.types import Header, Panel, Menu, UIList + class FILEBROWSER_HT_header(Header): bl_space_type = 'FILE_BROWSER' @@ -31,8 +32,7 @@ class FILEBROWSER_HT_header(Header): if st.active_operator is None: layout.template_header() - layout.menu("FILEBROWSER_MT_view") - layout.menu("FILEBROWSER_MT_select") + FILEBROWSER_MT_editor_menus.draw_collapsible(context, layout) # can be None when save/reload with a file selector open @@ -66,8 +66,9 @@ class FILEBROWSER_PT_display(Panel): if params.display_type == 'THUMBNAIL': layout.prop(params, "display_size", text="Size") else: - layout.prop(params, "show_details_size", text="Size") - layout.prop(params, "show_details_datetime", text="Date") + col = layout.column(heading="Columns", align=True) + col.prop(params, "show_details_size", text="Size") + col.prop(params, "show_details_datetime", text="Date") layout.prop(params, "recursion_level", text="Recursions") @@ -410,6 +411,17 @@ class FILEBROWSER_PT_directory_path(Panel): ).region_type = 'TOOL_PROPS' +class FILEBROWSER_MT_editor_menus(Menu): + bl_idname = "FILEBROWSER_MT_editor_menus" + bl_label = "" + + def draw(self, _context): + layout = self.layout + + layout.menu("FILEBROWSER_MT_view") + layout.menu("FILEBROWSER_MT_select") + + class FILEBROWSER_MT_view(Menu): bl_label = "View" @@ -501,6 +513,7 @@ classes = ( FILEBROWSER_PT_bookmarks_recents, FILEBROWSER_PT_advanced_filter, FILEBROWSER_PT_directory_path, + FILEBROWSER_MT_editor_menus, FILEBROWSER_MT_view, FILEBROWSER_MT_select, FILEBROWSER_MT_context_menu, diff --git a/release/scripts/startup/bl_ui/space_image.py b/release/scripts/startup/bl_ui/space_image.py index 3aac56d9f0e..76b7fc7f156 100644 --- a/release/scripts/startup/bl_ui/space_image.py +++ b/release/scripts/startup/bl_ui/space_image.py @@ -113,7 +113,7 @@ class IMAGE_MT_view(Menu): if show_uvedit: layout.operator("image.view_selected", text="Frame Selected") - layout.operator("image.view_all", text="Frame All") + layout.operator("image.view_all") layout.operator("image.view_all", text="Frame All Fit").fit_view = True layout.operator("image.view_center_cursor", text="Center View to Cursor") @@ -381,6 +381,10 @@ class IMAGE_MT_uvs(Menu): layout.separator() + layout.operator("uv.reset") + + layout.separator() + class IMAGE_MT_uvs_select_mode(Menu): bl_label = "UV Select Mode" @@ -952,6 +956,7 @@ class IMAGE_PT_view_display_uv_edit_overlays(Panel): col = layout.column() col.prop(uvedit, "show_smooth_edges", text="Smooth") col.prop(uvedit, "show_modified_edges", text="Modified") + col.prop(uvedit, "uv_opacity") class IMAGE_PT_view_display_uv_edit_overlays_stretch(Panel): diff --git a/release/scripts/startup/bl_ui/space_node.py b/release/scripts/startup/bl_ui/space_node.py index bdda0ebbe9a..b5926692324 100644 --- a/release/scripts/startup/bl_ui/space_node.py +++ b/release/scripts/startup/bl_ui/space_node.py @@ -151,6 +151,14 @@ class NODE_HT_header(Header): if snode_id: layout.prop(snode_id, "use_nodes") + elif snode.tree_type == 'SimulationNodeTree': + row = layout.row(align=True) + row.prop(snode, "simulation", text="") + row.operator("simulation.new", text="", icon='ADD') + simulation = snode.simulation + if simulation: + row.prop(snode.simulation, "use_fake_user", text="") + else: # Custom node tree is edited as independent ID block NODE_MT_editor_menus.draw_collapsible(context, layout) diff --git a/release/scripts/startup/bl_ui/space_outliner.py b/release/scripts/startup/bl_ui/space_outliner.py index a74d9cc9547..ee8015df273 100644 --- a/release/scripts/startup/bl_ui/space_outliner.py +++ b/release/scripts/startup/bl_ui/space_outliner.py @@ -212,8 +212,8 @@ class OUTLINER_MT_collection(Menu): layout.separator() - layout.operator("outliner.collection_delete", text="Delete", icon='X').hierarchy = False - layout.operator("outliner.collection_delete", text="Delete Hierarchy").hierarchy = True + layout.operator("outliner.delete", text="Delete", icon='X') + layout.operator("outliner.collection_hierarchy_delete") layout.separator() @@ -278,7 +278,7 @@ class OUTLINER_MT_object(Menu): layout.separator() - layout.operator("outliner.object_operation", text="Delete", icon='X').type = 'DELETE' + layout.operator("outliner.delete", text="Delete", icon='X') if space.display_mode == 'VIEW_LAYER' and not space.use_filter_collection: layout.operator("outliner.object_operation", text="Delete Hierarchy").type = 'DELETE_HIERARCHY' diff --git a/release/scripts/startup/bl_ui/space_sequencer.py b/release/scripts/startup/bl_ui/space_sequencer.py index 4784d0cb08b..41c220f7ee4 100644 --- a/release/scripts/startup/bl_ui/space_sequencer.py +++ b/release/scripts/startup/bl_ui/space_sequencer.py @@ -29,6 +29,7 @@ from bpy.app.translations import ( ) from bl_ui.properties_grease_pencil_common import ( AnnotationDataPanel, + AnnotationOnionSkin, ) from bl_ui.space_toolsystem_common import ( ToolActivePanelHelper, @@ -275,7 +276,7 @@ class SEQUENCER_MT_view(Menu): if is_sequencer_view: layout.operator_context = 'INVOKE_REGION_WIN' layout.operator("sequencer.view_selected", text="Frame Selected") - layout.operator("sequencer.view_all", text="Frame All") + layout.operator("sequencer.view_all") layout.operator("view2d.zoom_border", text="Zoom") if is_preview: @@ -306,12 +307,15 @@ class SEQUENCER_MT_view(Menu): layout.separator() layout.operator_context = 'INVOKE_DEFAULT' - layout.prop(st, "show_seconds") layout.prop(st, "show_locked_time") + + layout.separator() + layout.prop(st, "show_seconds") layout.prop(st, "show_strip_offset") layout.prop(st, "show_fcurves") - layout.separator() layout.prop(st, "show_markers") + layout.menu("SEQUENCER_MT_view_cache", text="Show Cache") + layout.prop_menu_enum(st, "waveform_display_type", text="Show Waveforms") if is_preview: layout.separator() @@ -323,12 +327,6 @@ class SEQUENCER_MT_view(Menu): elif st.display_mode == 'WAVEFORM': layout.prop(st, "show_separate_color", text="Show Separate Color Channels") - if is_sequencer_view: - layout.separator() - - layout.menu("SEQUENCER_MT_view_cache") - layout.prop_menu_enum(st, "waveform_display_type") - layout.separator() layout.operator("render.opengl", text="Sequence Render Image", icon='RENDER_STILL').sequencer = True @@ -337,7 +335,7 @@ class SEQUENCER_MT_view(Menu): props.sequencer = True layout.separator() - layout.operator("sequencer.export_subtitles", text="Export Subtitles", icon="EXPORT") + layout.operator("sequencer.export_subtitles", text="Export Subtitles", icon='EXPORT') layout.separator() @@ -1032,10 +1030,14 @@ class SEQUENCER_PT_effect(SequencerButtonsPanel, Panel): if strip.input_count > 0: col = layout.column() - col.enabled = False - col.prop(strip, "input_1") + row = col.row() + row.prop(strip, "input_1") + if strip.input_count > 1: - col.prop(strip, "input_2") + row.operator("sequencer.swap_inputs", text="", icon='SORT_ASC') + row = col.row() + row.prop(strip, "input_2") + row.operator("sequencer.swap_inputs", text="", icon='SORT_DESC') strip_type = strip.type @@ -1138,6 +1140,8 @@ class SEQUENCER_PT_effect(SequencerButtonsPanel, Panel): col = layout.column(align=True) if strip_type == 'SPEED': col.prop(strip, "multiply_speed") + col.prop(strip, "frame_interpolation_mode") + elif strip_type in {'CROSS', 'GAMMA_CROSS', 'WIPE', 'ALPHA_OVER', 'ALPHA_UNDER', 'OVER_DROP'}: col.prop(strip, "use_default_fade", text="Default fade") if not strip.use_default_fade: @@ -1192,31 +1196,14 @@ class SEQUENCER_PT_effect_text_style(SequencerButtonsPanel, Panel): col.prop(strip, "font_size") col.prop(strip, "color") - -class SEQUENCER_PT_effect_text_style_shadow(SequencerButtonsPanel, Panel): - bl_label = "Shadow" - bl_parent_id = "SEQUENCER_PT_effect_text_style" - bl_options = {'DEFAULT_CLOSED'} - bl_category = "Strip" - - @classmethod - def poll(cls, context): - strip = act_strip(context) - return strip.type != 'SOUND' - - def draw_header(self, context): - strip = act_strip(context) - self.layout.prop(strip, "use_shadow", text="") - - def draw(self, context): - strip = act_strip(context) - layout = self.layout - layout.use_property_split = True - - layout.active = strip.use_shadow and (not strip.mute) - - col = layout.column(align=True) - col.prop(strip, "shadow_color", text="Color") + row = layout.row(align=True, heading="Shadow") + row.use_property_decorate = False + sub = row.row(align=True) + sub.prop(strip, "use_shadow", text="") + subsub = sub.row(align=True) + subsub.active = strip.use_shadow and (not strip.mute) + subsub.prop(strip, "shadow_color", text="") + row.prop_decorator(strip, "shadow_color") class SEQUENCER_PT_source(SequencerButtonsPanel, Panel): @@ -1687,18 +1674,15 @@ class SEQUENCER_PT_adjust_transform(SequencerButtonsPanel, Panel): layout = self.layout strip = act_strip(context) - layout.active = not strip.mute - - split = layout.split() + layout.use_property_split = True + layout.use_property_decorate = False - col = split.column() - col.alignment = 'RIGHT' - col.label(text="Mirror") + layout.active = not strip.mute - col = split.column() - row = col.row(align=True) - row.prop(strip, "use_flip_x", text="X", toggle=True) - row.prop(strip, "use_flip_y", text="Y", toggle=True) + row = layout.row(heading="Mirror") + sub = row.row(align=True) + sub.prop(strip, "use_flip_x", text="X", toggle=True) + sub.prop(strip, "use_flip_y", text="Y", toggle=True) class SEQUENCER_PT_adjust_video(SequencerButtonsPanel, Panel): @@ -1802,12 +1786,12 @@ class SEQUENCER_PT_cache_settings(SequencerButtonsPanel, Panel): ed = context.scene.sequence_editor - col = layout.column() + col = layout.column(heading="Cache", align=True) - col.prop(ed, "use_cache_raw") - col.prop(ed, "use_cache_preprocessed") - col.prop(ed, "use_cache_composite") - col.prop(ed, "use_cache_final") + col.prop(ed, "use_cache_raw", text="Raw") + col.prop(ed, "use_cache_preprocessed", text="Pre-Processed") + col.prop(ed, "use_cache_composite", text="Composite") + col.prop(ed, "use_cache_final", text="Final") col.separator() col.prop(ed, "recycle_max_cost") @@ -1871,21 +1855,19 @@ class SEQUENCER_PT_strip_proxy(SequencerButtonsPanel, Panel): flow = layout.column_flow() if ed.proxy_storage == 'PER_STRIP': - flow.prop(proxy, "use_proxy_custom_directory") - flow.prop(proxy, "use_proxy_custom_file") - + col = layout.column(heading="Custom Proxy") + col.prop(proxy, "use_proxy_custom_directory", text="Directory") if proxy.use_proxy_custom_directory and not proxy.use_proxy_custom_file: - flow.prop(proxy, "directory") + col.prop(proxy, "directory") + col.prop(proxy, "use_proxy_custom_file", text="File") if proxy.use_proxy_custom_file: - flow.prop(proxy, "filepath") + col.prop(proxy, "filepath") - box = layout.box() - row = box.row(align=True) - row.prop(strip.proxy, "build_25") - row.prop(strip.proxy, "build_75") - row = box.row(align=True) - row.prop(strip.proxy, "build_50") - row.prop(strip.proxy, "build_100") + row = layout.row(heading="Resolutions", align=True) + row.prop(strip.proxy, "build_25", toggle=True) + row.prop(strip.proxy, "build_50", toggle=True) + row.prop(strip.proxy, "build_75", toggle=True) + row.prop(strip.proxy, "build_100", toggle=True) layout.use_property_split = True layout.use_property_decorate = False @@ -1926,14 +1908,14 @@ class SEQUENCER_PT_strip_cache(SequencerButtonsPanel, Panel): strip = act_strip(context) layout.active = strip.override_cache_settings - col = layout.column() - col.prop(strip, "use_cache_raw") - col.prop(strip, "use_cache_preprocessed") - col.prop(strip, "use_cache_composite") + col = layout.column(heading="Cache") + col.prop(strip, "use_cache_raw", text="Raw") + col.prop(strip, "use_cache_preprocessed", text="Pre-Processed") + col.prop(strip, "use_cache_composite", text="Composite") class SEQUENCER_PT_preview(SequencerButtonsPanel_Output, Panel): - bl_label = "Scene Preview/Render" + bl_label = "Scene Strip Display" bl_space_type = 'SEQUENCE_EDITOR' bl_region_type = 'UI' bl_options = {'DEFAULT_CLOSED'} @@ -1947,7 +1929,7 @@ class SEQUENCER_PT_preview(SequencerButtonsPanel_Output, Panel): render = context.scene.render col = layout.column() - col.prop(render, "sequencer_gl_preview", text="Preview Shading") + col.prop(render, "sequencer_gl_preview", text="Shading") if render.sequencer_gl_preview in {'SOLID', 'WIREFRAME'}: col.prop(render, "use_sequencer_override_scene_strip") @@ -2095,10 +2077,12 @@ class SEQUENCER_PT_modifiers(SequencerButtonsPanel, Panel): box = layout.box() row = box.row() + row.use_property_decorate = False row.prop(mod, "show_expanded", text="", emboss=False) row.prop(mod, "name", text="") row.prop(mod, "mute", text="") + row.use_property_decorate = True sub = row.row(align=True) props = sub.operator("sequencer.strip_modifier_move", text="", icon='TRIA_UP') @@ -2170,6 +2154,33 @@ class SEQUENCER_PT_annotation(AnnotationDataPanel, SequencerButtonsPanel_Output, # But, it should only show up when there are images in the preview region +class SEQUENCER_PT_annotation_onion(AnnotationOnionSkin, SequencerButtonsPanel_Output, Panel): + bl_space_type = 'SEQUENCE_EDITOR' + bl_region_type = 'UI' + bl_category = "View" + + @staticmethod + def has_preview(context): + st = context.space_data + return st.view_type in {'PREVIEW', 'SEQUENCER_PREVIEW'} + + @classmethod + def poll(cls, context): + if context.annotation_data_owner is None: + return False + elif type(context.annotation_data_owner) is bpy.types.Object: + return False + else: + gpl = context.active_annotation_layer + if gpl is None: + return False + + return cls.has_preview(context) + + # NOTE: this is just a wrapper around the generic GP Panel + # But, it should only show up when there are images in the preview region + + class SEQUENCER_PT_custom_props(SequencerButtonsPanel, PropertyPanel, Panel): COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_WORKBENCH'} _context_path = "scene.sequence_editor.active_strip" @@ -2205,10 +2216,16 @@ classes = ( SEQUENCER_MT_strip_input, SEQUENCER_MT_strip_lock_mute, SEQUENCER_MT_context_menu, + SEQUENCER_PT_active_tool, SEQUENCER_PT_strip, SEQUENCER_PT_effect, + SEQUENCER_PT_scene, + SEQUENCER_PT_mask, + SEQUENCER_PT_effect_text_style, + SEQUENCER_PT_effect_text_layout, + SEQUENCER_PT_adjust, SEQUENCER_PT_adjust_comp, SEQUENCER_PT_adjust_transform, @@ -2218,12 +2235,6 @@ classes = ( SEQUENCER_PT_adjust_color, SEQUENCER_PT_adjust_sound, - SEQUENCER_PT_scene, - SEQUENCER_PT_mask, - SEQUENCER_PT_effect_text_style, - SEQUENCER_PT_effect_text_layout, - SEQUENCER_PT_effect_text_style_shadow, - SEQUENCER_PT_time, SEQUENCER_PT_source, @@ -2236,13 +2247,14 @@ classes = ( SEQUENCER_PT_custom_props, - SEQUENCER_PT_preview, SEQUENCER_PT_view, SEQUENCER_PT_frame_overlay, SEQUENCER_PT_view_safe_areas, SEQUENCER_PT_view_safe_areas_center_cut, + SEQUENCER_PT_preview, SEQUENCER_PT_annotation, + SEQUENCER_PT_annotation_onion, ) if __name__ == "__main__": # only for live edit. diff --git a/release/scripts/startup/bl_ui/space_text.py b/release/scripts/startup/bl_ui/space_text.py index b7c5dcd5437..f6f22ad464f 100644 --- a/release/scripts/startup/bl_ui/space_text.py +++ b/release/scripts/startup/bl_ui/space_text.py @@ -129,18 +129,21 @@ class TEXT_PT_properties(Panel): layout.use_property_decorate = False st = context.space_data - flow = layout.column_flow() if not st.text: - flow.active = False - row = flow.row(align=True) + layout.active = False + st = context.space_data - row.prop(st, "show_margin", text="Margin") - rowsub = row.row() - rowsub.active = st.show_margin - rowsub.prop(st, "margin_column", text="") - flow.prop(st, "font_size") - flow.prop(st, "tab_width") + col = layout.column(align=False, heading="Margin") + row = col.row(align=True) + sub = row.row(align=True) + sub.prop(st, "show_margin", text="") + sub = sub.row(align=True) + sub.active = st.show_margin + sub.prop(st, "margin_column", text="") + + layout.prop(st, "font_size") + layout.prop(st, "tab_width") text = st.text if text: diff --git a/release/scripts/startup/bl_ui/space_toolsystem_toolbar.py b/release/scripts/startup/bl_ui/space_toolsystem_toolbar.py index 8d1f23e5df0..1aa5dde168b 100644 --- a/release/scripts/startup/bl_ui/space_toolsystem_toolbar.py +++ b/release/scripts/startup/bl_ui/space_toolsystem_toolbar.py @@ -147,6 +147,8 @@ class _defs_annotate: def draw_settings_common(context, layout, tool): gpd = context.annotation_data + region_type = context.region.type + if gpd is not None: if gpd.layers.active_note is not None: text = gpd.layers.active_note @@ -159,17 +161,24 @@ class _defs_annotate: gpl = context.active_annotation_layer if gpl is not None: layout.label(text="Annotation:") - sub = layout.row(align=True) - sub.ui_units_x = 8 - - sub.prop(gpl, "color", text="") - sub.popover( - panel="TOPBAR_PT_annotation_layers", - text=text, - ) + if context.space_data.type == 'VIEW_3D': + if region_type == 'TOOL_HEADER': + sub = layout.split(align=True, factor=0.5) + sub.ui_units_x = 6.5 + sub.prop(gpl, "color", text="") + else: + sub = layout.row(align=True) + sub.prop(gpl, "color", text="") + sub.popover( + panel="TOPBAR_PT_annotation_layers", + text=text, + ) + else: + layout.prop(gpl, "color", text="") - tool_settings = context.tool_settings space_type = tool.space_type + tool_settings = context.tool_settings + if space_type == 'VIEW_3D': layout.separator() @@ -180,6 +189,29 @@ class _defs_annotate: elif tool_settings.gpencil_stroke_placement_view3d in {'SURFACE', 'STROKE'}: row.prop(tool_settings, "use_gpencil_stroke_endpoints") + if tool.idname == "builtin.annotate_line": + layout.separator() + + props = tool.operator_properties("gpencil.annotate") + if region_type == 'TOOL_HEADER': + row = layout.row() + row.ui_units_x = 15 + row.prop(props, "arrowstyle_start", text="Start") + row.separator() + row.prop(props, "arrowstyle_end", text="End") + else: + col = layout.row().column(align=True) + col.prop(props, "arrowstyle_start", text="Style Start") + col.prop(props, "arrowstyle_end", text="End") + elif tool.idname == "builtin.annotate" and region_type != 'TOOL_HEADER': + layout.separator() + props = tool.operator_properties("gpencil.annotate") + layout.prop(props, "use_stabilizer", text="Stabilize Stroke") + col = layout.column(align=False) + col.active = props.use_stabilizer + col.prop(props, "stabilizer_radius", text="Radius", slider=True) + col.prop(props, "stabilizer_factor", text="Factor", slider=True) + @ToolDef.from_fn.with_args(draw_settings=draw_settings_common) def scribble(*, draw_settings): return dict( @@ -404,10 +436,124 @@ class _defs_view3d_select: ) +class _defs_view3d_add: + + # Layout tweaks here would be good to avoid, + # this shows limits in layout engine, as buttons are using a lot of space. + @staticmethod + def draw_settings_interactive_add(layout, tool): + props = tool.operator_properties("view3d.interactive_add") + row = layout.row() + row.scale_x = 0.8 + row.label(text="Depth:") + row = layout.row() + row.scale_x = 0.9 + row.prop(props, "plane_depth", text="") + row = layout.row() + row.prop(props, "plane_axis", text="") + row = layout.row() + row.scale_x = 0.7 + row.prop(props, "plane_origin") + + @ToolDef.from_fn + def cube_add(): + def draw_settings(_context, layout, tool): + _defs_view3d_add.draw_settings_interactive_add(layout, tool) + return dict( + idname="builtin.primitive_cube_add", + label="Add Cube", + icon="ops.mesh.primitive_cube_add_gizmo", + description=( + "Add cube to mesh interactively" + ), + widget="VIEW3D_GGT_placement", + keymap="3D View Tool: Object, Add Primitive", + draw_settings=draw_settings, + ) + + @ToolDef.from_fn + def cone_add(): + def draw_settings(_context, layout, tool): + _defs_view3d_add.draw_settings_interactive_add(layout, tool) + + props = tool.operator_properties("mesh.primitive_cone_add") + layout.prop(props, "vertices") + layout.prop(props, "end_fill_type") + return dict( + idname="builtin.primitive_cone_add", + label="Add Cone", + icon="ops.mesh.primitive_cube_add_gizmo", + description=( + "Add cone to mesh interactively" + ), + widget="VIEW3D_GGT_placement", + keymap="3D View Tool: Object, Add Primitive", + draw_settings=draw_settings, + ) + + @ToolDef.from_fn + def cylinder_add(): + def draw_settings(_context, layout, tool): + _defs_view3d_add.draw_settings_interactive_add(layout, tool) + + props = tool.operator_properties("mesh.primitive_cylinder_add") + layout.prop(props, "vertices") + layout.prop(props, "end_fill_type") + return dict( + idname="builtin.primitive_cylinder_add", + label="Add Cylinder", + icon="ops.mesh.primitive_cylinder_add_gizmo", + description=( + "Add cylinder to mesh interactively" + ), + widget="VIEW3D_GGT_placement", + keymap="3D View Tool: Object, Add Primitive", + draw_settings=draw_settings, + ) + + @ToolDef.from_fn + def uv_sphere_add(): + def draw_settings(_context, layout, tool): + _defs_view3d_add.draw_settings_interactive_add(layout, tool) + + props = tool.operator_properties("mesh.primitive_uv_sphere_add") + layout.prop(props, "segments") + layout.prop(props, "ring_count") + return dict( + idname="builtin.primitive_uv_sphere_add", + label="Add UV Sphere", + icon="ops.mesh.primitive_sphere_add_gizmo", + description=( + "Add cylinder to mesh interactively" + ), + widget="VIEW3D_GGT_placement", + keymap="3D View Tool: Object, Add Primitive", + draw_settings=draw_settings, + ) + + @ToolDef.from_fn + def ico_sphere_add(): + def draw_settings(_context, layout, tool): + _defs_view3d_add.draw_settings_interactive_add(layout, tool) + + props = tool.operator_properties("mesh.primitive_ico_sphere_add") + layout.prop(props, "subdivisions") + return dict( + idname="builtin.primitive_ico_sphere_add", + label="Add Ico Sphere", + icon="ops.mesh.primitive_sphere_add_gizmo", + description=( + "Add cylinder to mesh interactively" + ), + widget="VIEW3D_GGT_placement", + keymap="3D View Tool: Object, Add Primitive", + draw_settings=draw_settings, + ) + + # ----------------------------------------------------------------------------- # Object Modes (named based on context.mode) - class _defs_edit_armature: @ToolDef.from_fn @@ -466,19 +612,6 @@ class _defs_edit_armature: class _defs_edit_mesh: @ToolDef.from_fn - def cube_add(): - return dict( - idname="builtin.add_cube", - label="Add Cube", - icon="ops.mesh.primitive_cube_add_gizmo", - description=( - "Add cube to mesh interactively" - ), - widget=None, - keymap=(), - ) - - @ToolDef.from_fn def rip_region(): def draw_settings(_context, layout, tool): props = tool.operator_properties("mesh.rip_move") @@ -625,9 +758,10 @@ class _defs_edit_mesh: layout.prop(props, "vertex_only") layout.prop(props, "clamp_overlap") layout.prop(props, "loop_slide") - layout.prop(props, "mark_seam") - layout.prop(props, "mark_sharp") layout.prop(props, "harden_normals") + col = layout.column(heading="Mark") + col.prop(props, "mark_seam", text="Seam") + col.prop(props, "mark_sharp", text="Sharp") layout.prop(props, "material") @@ -668,6 +802,19 @@ class _defs_edit_mesh: ) @ToolDef.from_fn + def extrude_dissolve_and_intersect(): + return dict( + idname="builtin.extrude_dissolve_and_intersect", + label="Extrude Dissolve and Intersect", + description=( + "Extrude, dissolves edges whose faces form a flat surface and intersect new edges" + ), + icon="none", + widget="VIEW3D_GGT_tool_generic_handle_normal", + keymap=(), + ) + + @ToolDef.from_fn def extrude_normals(): def draw_settings(_context, layout, tool): props = tool.operator_properties("mesh.extrude_region_shrink_fatten") @@ -842,23 +989,61 @@ class _defs_edit_curve: @ToolDef.from_fn def draw(): - def draw_settings(context, layout, _tool): + def draw_settings(context, layout, tool, *, extra=False): # Tool settings initialize operator options. tool_settings = context.tool_settings cps = tool_settings.curve_paint_settings + region_type = context.region.type - col = layout.column() + if region_type == 'TOOL_HEADER': + if not extra: + layout.prop(cps, "curve_type", text="") + layout.prop(cps, "depth_mode", expand=True) + layout.popover("TOPBAR_PT_tool_settings_extra", text="...") + return - col.prop(cps, "curve_type") + layout.use_property_split = True + layout.use_property_decorate = False + if region_type != 'TOOL_HEADER': + layout.prop(cps, "curve_type") + layout.separator() if cps.curve_type == 'BEZIER': - col.prop(cps, "error_threshold") - col.prop(cps, "fit_method") - col.prop(cps, "use_corners_detect") + layout.prop(cps, "fit_method") + layout.prop(cps, "error_threshold") + if region_type != 'TOOL_HEADER': + row = layout.row(heading="Detect Corners", align=True) + else: + row = layout.row(heading="Corners", align=True) + row.prop(cps, "use_corners_detect", text="") + sub = row.row(align=True) + sub.active = cps.use_corners_detect + sub.prop(cps, "corner_angle", text="") + layout.separator() + + + col = layout.column(align=True) + col.prop(cps, "radius_taper_start", text="Taper Start", slider=True) + col.prop(cps, "radius_taper_end", text="End", slider=True) + col = layout.column(align=True) + col.prop(cps, "radius_min", text="Radius Min") + col.prop(cps, "radius_max", text="Max") + col.prop(cps, "use_pressure_radius") + + layout.separator() + + if region_type != 'TOOL_HEADER': + row = layout.row() + row.prop(cps, "depth_mode", expand=True) + if cps.depth_mode == 'SURFACE': + col = layout.column() + col.prop(cps, "surface_offset") + col.prop(cps, "use_offset_absolute") + col.prop(cps, "use_stroke_endpoints") + if cps.use_stroke_endpoints: + colsub = layout.column(align=True) + colsub.prop(cps, "surface_plane") - col = layout.row() - col.active = cps.use_corners_detect - col.prop(cps, "corner_angle") return dict( idname="builtin.draw", @@ -2063,6 +2248,14 @@ class VIEW3D_PT_tools_active(ToolSelectPanelHelper, Panel): ), ) + _tools_view3d_add = ( + _defs_view3d_add.cube_add, + _defs_view3d_add.cone_add, + _defs_view3d_add.cylinder_add, + _defs_view3d_add.uv_sphere_add, + _defs_view3d_add.ico_sphere_add, + ) + _tools_default = ( *_tools_select, _defs_view3d_generic.cursor, @@ -2081,6 +2274,9 @@ class VIEW3D_PT_tools_active(ToolSelectPanelHelper, Panel): ], 'OBJECT': [ *_tools_default, + + None, + _tools_view3d_add, ], 'POSE': [ *_tools_default, @@ -2109,8 +2305,11 @@ class VIEW3D_PT_tools_active(ToolSelectPanelHelper, Panel): 'EDIT_MESH': [ *_tools_default, None, + _tools_view3d_add, + None, ( _defs_edit_mesh.extrude, + _defs_edit_mesh.extrude_dissolve_and_intersect, _defs_edit_mesh.extrude_normals, _defs_edit_mesh.extrude_individual, _defs_edit_mesh.extrude_cursor, diff --git a/release/scripts/startup/bl_ui/space_topbar.py b/release/scripts/startup/bl_ui/space_topbar.py index 9cc979f7546..6fc29119cdc 100644 --- a/release/scripts/startup/bl_ui/space_topbar.py +++ b/release/scripts/startup/bl_ui/space_topbar.py @@ -229,14 +229,7 @@ class TOPBAR_MT_app(Menu): layout = self.layout layout.operator("wm.splash") - - layout.separator() - - layout.menu("TOPBAR_MT_app_support") - - layout.separator() - - layout.menu("TOPBAR_MT_app_about") + layout.operator("wm.splash_about") layout.separator() @@ -409,45 +402,6 @@ class TOPBAR_MT_file_defaults(Menu): props.app_template = app_template -class TOPBAR_MT_app_about(Menu): - bl_label = "About" - - def draw(self, _context): - layout = self.layout - - layout.operator("wm.url_open_preset", text="Release Notes", - icon='URL').type = 'RELEASE_NOTES' - - layout.separator() - - layout.operator("wm.url_open_preset", - text="Blender Website", icon='URL').type = 'BLENDER' - layout.operator("wm.url_open_preset", text="Credits", - icon='URL').type = 'CREDITS' - - layout.separator() - - layout.operator( - "wm.url_open", text="License", icon='URL', - ).url = "https://www.blender.org/about/license/" - - -class TOPBAR_MT_app_support(Menu): - bl_label = "Support Blender" - - def draw(self, _context): - layout = self.layout - - layout.operator("wm.url_open_preset", - text="Development Fund", icon='FUND').type = 'FUND' - - layout.separator() - - layout.operator( - "wm.url_open", text="Blender Store", icon='URL', - ).url = "https://store.blender.org" - - # Include technical operators here which would otherwise have no way for users to access. class TOPBAR_MT_app_system(Menu): bl_label = "System" @@ -582,6 +536,8 @@ class TOPBAR_MT_edit(Menu): def draw(self, context): layout = self.layout + show_developer = context.preferences.view.show_developer_ui + layout.operator("ed.undo") layout.operator("ed.redo") @@ -600,8 +556,9 @@ class TOPBAR_MT_edit(Menu): layout.separator() - layout.operator("wm.search_menu", - text="Operator Search...", icon='VIEWZOOM') + layout.operator("wm.search_menu", text="Menu Search...", icon='VIEWZOOM') + if show_developer: + layout.operator("wm.search_operator", text="Operator Search...", icon='VIEWZOOM') layout.separator() @@ -853,9 +810,7 @@ classes = ( TOPBAR_MT_workspace_menu, TOPBAR_MT_editor_menus, TOPBAR_MT_app, - TOPBAR_MT_app_about, TOPBAR_MT_app_system, - TOPBAR_MT_app_support, TOPBAR_MT_file, TOPBAR_MT_file_new, TOPBAR_MT_file_recover, diff --git a/release/scripts/startup/bl_ui/space_userpref.py b/release/scripts/startup/bl_ui/space_userpref.py index 8686c6a2327..5a36f6bb081 100644 --- a/release/scripts/startup/bl_ui/space_userpref.py +++ b/release/scripts/startup/bl_ui/space_userpref.py @@ -200,19 +200,16 @@ class USERPREF_PT_interface_display(InterfacePanel, CenterAlignMixIn, Panel): prefs = context.preferences view = prefs.view - flow = layout.grid_flow(row_major=False, columns=0, even_columns=True, even_rows=False, align=False) - - flow.prop(view, "ui_scale", text="Resolution Scale") - flow.prop(view, "ui_line_width", text="Line Width") - - layout.separator() + col = layout.column() - flow = layout.grid_flow(row_major=False, columns=0, even_columns=True, even_rows=False, align=False) + col.prop(view, "ui_scale", text="Resolution Scale") + col.prop(view, "ui_line_width", text="Line Width") + col.prop(view, "show_splash", text="Splash Screen") + col.prop(view, "show_developer_ui") - flow.prop(view, "show_splash", text="Splash Screen") - flow.prop(view, "show_tooltips") - flow.prop(view, "show_tooltips_python") - flow.prop(view, "show_developer_ui") + col = layout.column(heading="Tooltips") + col.prop(view, "show_tooltips") + col.prop(view, "show_tooltips_python") class USERPREF_PT_interface_text(InterfacePanel, CenterAlignMixIn, Panel): @@ -248,12 +245,11 @@ class USERPREF_PT_interface_translation(InterfacePanel, CenterAlignMixIn, Panel) layout.prop(view, "language") - flow = layout.grid_flow(row_major=False, columns=0, even_columns=True, even_rows=False, align=False) - flow.active = (bpy.app.translations.locale != 'en_US') - - flow.prop(view, "use_translate_tooltips", text="Tooltips") - flow.prop(view, "use_translate_interface", text="Interface") - flow.prop(view, "use_translate_new_dataname", text="New Data") + col = layout.column(heading="Affect") + col.active = (bpy.app.translations.locale != 'en_US') + col.prop(view, "use_translate_tooltips", text="Tooltips") + col.prop(view, "use_translate_interface", text="Interface") + col.prop(view, "use_translate_new_dataname", text="New Data") class USERPREF_PT_interface_editors(InterfacePanel, CenterAlignMixIn, Panel): @@ -264,14 +260,13 @@ class USERPREF_PT_interface_editors(InterfacePanel, CenterAlignMixIn, Panel): view = prefs.view system = prefs.system - flow = layout.grid_flow(row_major=False, columns=0, even_columns=True, even_rows=False, align=False) - - flow.prop(system, "use_region_overlap") - flow.prop(view, "show_layout_ui", text="Corner Splitting") - flow.prop(view, "show_navigate_ui") - flow.prop(view, "color_picker_type") - flow.row().prop(view, "header_align") - flow.prop(view, "factor_display_type") + col = layout.column() + col.prop(system, "use_region_overlap") + col.prop(view, "show_layout_ui", text="Corner Splitting") + col.prop(view, "show_navigate_ui") + col.prop(view, "color_picker_type") + col.row().prop(view, "header_align") + col.prop(view, "factor_display_type") class USERPREF_PT_interface_temporary_windows(InterfacePanel, CenterAlignMixIn, Panel): @@ -283,10 +278,9 @@ class USERPREF_PT_interface_temporary_windows(InterfacePanel, CenterAlignMixIn, prefs = context.preferences view = prefs.view - flow = layout.grid_flow(row_major=False, columns=0, even_columns=True, even_rows=False, align=False) - - flow.prop(view, "render_display_type", text="Render in") - flow.prop(view, "filebrowser_display_type", text="File Browser") + col = layout.column() + col.prop(view, "render_display_type", text="Render in") + col.prop(view, "filebrowser_display_type", text="File Browser") class USERPREF_PT_interface_menus(InterfacePanel, Panel): @@ -366,6 +360,7 @@ class USERPREF_PT_edit_objects_new(EditingPanel, CenterAlignMixIn, Panel): flow.prop(edit, "material_link", text="Link Materials to") flow.prop(edit, "object_align", text="Align to") flow.prop(edit, "use_enter_edit_mode", text="Enter Edit Mode") + flow.prop(edit, "collection_instance_empty_size", text="Instance Empty Size") class USERPREF_PT_edit_objects_duplicate_data(EditingPanel, CenterAlignMixIn, Panel): @@ -376,6 +371,8 @@ class USERPREF_PT_edit_objects_duplicate_data(EditingPanel, CenterAlignMixIn, Pa prefs = context.preferences edit = prefs.edit + layout.use_property_split = False + flow = layout.grid_flow(row_major=False, columns=0, even_columns=True, even_rows=False, align=True) col = flow.column() @@ -409,10 +406,9 @@ class USERPREF_PT_edit_cursor(EditingPanel, CenterAlignMixIn, Panel): prefs = context.preferences edit = prefs.edit - flow = layout.grid_flow(row_major=False, columns=0, even_columns=True, even_rows=False, align=False) - - flow.prop(edit, "use_mouse_depth_cursor") - flow.prop(edit, "use_cursor_lock_adjust") + col = layout.column() + col.prop(edit, "use_mouse_depth_cursor") + col.prop(edit, "use_cursor_lock_adjust") class USERPREF_PT_edit_gpencil(EditingPanel, CenterAlignMixIn, Panel): @@ -423,10 +419,9 @@ class USERPREF_PT_edit_gpencil(EditingPanel, CenterAlignMixIn, Panel): prefs = context.preferences edit = prefs.edit - flow = layout.grid_flow(row_major=False, columns=0, even_columns=True, even_rows=False, align=False) - - flow.prop(edit, "grease_pencil_manhattan_distance", text="Manhattan Distance") - flow.prop(edit, "grease_pencil_euclidean_distance", text="Euclidean Distance") + col = layout.column(heading="Distance") + col.prop(edit, "grease_pencil_manhattan_distance", text="Manhattan") + col.prop(edit, "grease_pencil_euclidean_distance", text="Euclidean") class USERPREF_PT_edit_annotations(EditingPanel, CenterAlignMixIn, Panel): @@ -436,10 +431,9 @@ class USERPREF_PT_edit_annotations(EditingPanel, CenterAlignMixIn, Panel): prefs = context.preferences edit = prefs.edit - flow = layout.grid_flow(row_major=False, columns=0, even_columns=True, even_rows=False, align=False) - - flow.prop(edit, "grease_pencil_default_color", text="Default Color") - flow.prop(edit, "grease_pencil_eraser_radius", text="Eraser Radius") + col = layout.column() + col.prop(edit, "grease_pencil_default_color", text="Default Color") + col.prop(edit, "grease_pencil_eraser_radius", text="Eraser Radius") class USERPREF_PT_edit_weight_paint(EditingPanel, CenterAlignMixIn, Panel): @@ -450,6 +444,8 @@ class USERPREF_PT_edit_weight_paint(EditingPanel, CenterAlignMixIn, Panel): prefs = context.preferences view = prefs.view + layout.use_property_split = False + layout.prop(view, "use_weight_color_range", text="Use Custom Colors") col = layout.column() @@ -465,10 +461,9 @@ class USERPREF_PT_edit_misc(EditingPanel, CenterAlignMixIn, Panel): prefs = context.preferences edit = prefs.edit - flow = layout.grid_flow(row_major=False, columns=0, even_columns=True, even_rows=False, align=False) - - flow.prop(edit, "sculpt_paint_overlay_color", text="Sculpt Overlay Color") - flow.prop(edit, "node_margin", text="Node Auto-offset Margin") + col = layout.column() + col.prop(edit, "sculpt_paint_overlay_color", text="Sculpt Overlay Color") + col.prop(edit, "node_margin", text="Node Auto-offset Margin") # ----------------------------------------------------------------------------- @@ -488,20 +483,16 @@ class USERPREF_PT_animation_timeline(AnimationPanel, CenterAlignMixIn, Panel): view = prefs.view edit = prefs.edit - flow = layout.grid_flow(row_major=False, columns=0, even_columns=True, even_rows=False, align=False) - flow.prop(edit, "use_negative_frames") - - layout.separator() - - flow = layout.grid_flow(row_major=False, columns=0, even_columns=True, even_rows=False, align=False) + col = layout.column() + col.prop(edit, "use_negative_frames") - flow.prop(view, "view2d_grid_spacing_min", text="Minimum Grid Spacing") - flow.prop(view, "timecode_style") - flow.prop(view, "view_frame_type") + col.prop(view, "view2d_grid_spacing_min", text="Minimum Grid Spacing") + col.prop(view, "timecode_style") + col.prop(view, "view_frame_type") if view.view_frame_type == 'SECONDS': - flow.prop(view, "view_frame_seconds") + col.prop(view, "view_frame_seconds") elif view.view_frame_type == 'KEYFRAMES': - flow.prop(view, "view_frame_keyframes") + col.prop(view, "view_frame_keyframes") class USERPREF_PT_animation_keyframes(AnimationPanel, CenterAlignMixIn, Panel): @@ -511,25 +502,14 @@ class USERPREF_PT_animation_keyframes(AnimationPanel, CenterAlignMixIn, Panel): prefs = context.preferences edit = prefs.edit - flow = layout.grid_flow(row_major=False, columns=0, even_columns=True, even_rows=False, align=False) - - flow.prop(edit, "use_visual_keying") - flow.prop(edit, "use_keyframe_insert_needed", text="Only Insert Needed") - - -class USERPREF_PT_animation_autokey(AnimationPanel, CenterAlignMixIn, Panel): - bl_label = "Auto-Keyframing" - bl_parent_id = "USERPREF_PT_animation_keyframes" - - def draw_centered(self, context, layout): - prefs = context.preferences - edit = prefs.edit - - flow = layout.grid_flow(row_major=False, columns=0, even_columns=True, even_rows=False, align=False) + col = layout.column() + col.prop(edit, "use_visual_keying") + col.prop(edit, "use_keyframe_insert_needed", text="Only Insert Needed") - flow.prop(edit, "use_auto_keying_warning", text="Show Warning") - flow.prop(edit, "use_keyframe_insert_available", text="Only Insert Available") - flow.prop(edit, "use_auto_keying", text="Enable in New Scenes") + col = layout.column(heading="Auto-Keyframing") + col.prop(edit, "use_auto_keying_warning", text="Show Warning") + col.prop(edit, "use_keyframe_insert_available", text="Only Insert Available") + col.prop(edit, "use_auto_keying", text="Enable in New Scenes") class USERPREF_PT_animation_fcurves(AnimationPanel, CenterAlignMixIn, Panel): @@ -605,23 +585,27 @@ class USERPREF_PT_system_memory(SystemPanel, CenterAlignMixIn, Panel): system = prefs.system edit = prefs.edit - layout.prop(edit, "undo_steps", text="Undo Steps") - layout.prop(edit, "undo_memory_limit", text="Undo Memory Limit") - layout.prop(edit, "use_global_undo") + col = layout.column() + col.prop(edit, "undo_steps", text="Undo Steps") + col.prop(edit, "undo_memory_limit", text="Undo Memory Limit") + col.prop(edit, "use_global_undo") layout.separator() - layout.prop(system, "texture_time_out", text="Texture Time Out") - layout.prop(system, "texture_collection_rate", text="Garbage Collection Rate") + col = layout.column() + col.prop(system, "scrollback", text="Console Scrollback Lines") layout.separator() - layout.prop(system, "vbo_time_out", text="Vbo Time Out") - layout.prop(system, "vbo_collection_rate", text="Garbage Collection Rate") + col = layout.column() + col.prop(system, "texture_time_out", text="Texture Time Out") + col.prop(system, "texture_collection_rate", text="Garbage Collection Rate") layout.separator() - layout.prop(system, "scrollback", text="Console Scrollback Lines") + col = layout.column() + col.prop(system, "vbo_time_out", text="Vbo Time Out") + col.prop(system, "vbo_collection_rate", text="Garbage Collection Rate") class USERPREF_PT_system_video_sequencer(SystemPanel, CenterAlignMixIn, Panel): @@ -660,23 +644,19 @@ class USERPREF_PT_viewport_display(ViewportPanel, CenterAlignMixIn, Panel): prefs = context.preferences view = prefs.view - flow = layout.grid_flow(row_major=False, columns=0, even_columns=True, even_rows=False, align=False) - - flow.prop(view, "show_object_info", text="Object Info") - flow.prop(view, "show_view_name", text="View Name") - flow.prop(view, "show_playback_fps", text="Playback FPS") + col = layout.column(heading="Show") + col.prop(view, "show_object_info", text="Object Info") + col.prop(view, "show_view_name", text="View Name") + col.prop(view, "show_playback_fps", text="Playback FPS") layout.separator() - flow = layout.grid_flow(row_major=False, columns=0, even_columns=True, even_rows=False, align=False) - - col = flow.column() + col = layout.column() col.prop(view, "gizmo_size") col.prop(view, "lookdev_sphere_size") - flow.separator() + col.separator() - col = flow.column() col.prop(view, "mini_axis_type", text="3D Viewport Axis") if view.mini_axis_type == 'MINIMAL': @@ -691,11 +671,12 @@ class USERPREF_PT_viewport_quality(ViewportPanel, CenterAlignMixIn, Panel): prefs = context.preferences system = prefs.system - flow = layout.grid_flow(row_major=False, columns=0, even_columns=True, even_rows=False, align=False) + col = layout.column() + col.prop(system, "viewport_aa") - flow.prop(system, "viewport_aa") - flow.prop(system, "use_overlay_smooth_wire") - flow.prop(system, "use_edit_mode_smooth_wire") + col = layout.column(heading="Smooth Wires") + col.prop(system, "use_overlay_smooth_wire", text="Overlay") + col.prop(system, "use_edit_mode_smooth_wire", text="Edit Mode") class USERPREF_PT_viewport_textures(ViewportPanel, CenterAlignMixIn, Panel): @@ -705,12 +686,11 @@ class USERPREF_PT_viewport_textures(ViewportPanel, CenterAlignMixIn, Panel): prefs = context.preferences system = prefs.system - flow = layout.grid_flow(row_major=False, columns=0, even_columns=True, even_rows=False, align=False) - - flow.prop(system, "gl_texture_limit", text="Limit Size") - flow.prop(system, "anisotropic_filter") - flow.prop(system, "gl_clip_alpha", slider=True) - flow.prop(system, "image_draw_method", text="Image Display Method") + col = layout.column() + col.prop(system, "gl_texture_limit", text="Limit Size") + col.prop(system, "anisotropic_filter") + col.prop(system, "gl_clip_alpha", slider=True) + col.prop(system, "image_draw_method", text="Image Display Method") class USERPREF_PT_viewport_selection(ViewportPanel, CenterAlignMixIn, Panel): @@ -721,9 +701,7 @@ class USERPREF_PT_viewport_selection(ViewportPanel, CenterAlignMixIn, Panel): prefs = context.preferences system = prefs.system - flow = layout.grid_flow(row_major=False, columns=0, even_columns=True, even_rows=False, align=False) - - flow.prop(system, "use_select_pick_depth") + layout.prop(system, "use_select_pick_depth") # ----------------------------------------------------------------------------- @@ -1331,37 +1309,40 @@ class USERPREF_PT_saveload_blend(SaveLoadPanel, CenterAlignMixIn, Panel): paths = prefs.filepaths view = prefs.view - flow = layout.grid_flow(row_major=False, columns=0, even_columns=True, even_rows=False, align=False) + col = layout.column(heading="Save") + col.prop(view, "use_save_prompt") + col.prop(paths, "use_save_preview_images") - flow.prop(paths, "use_relative_paths") - flow.prop(paths, "use_file_compression") - flow.prop(paths, "use_load_ui") - flow.prop(paths, "use_save_preview_images") - flow.prop(paths, "use_tabs_as_spaces") - flow.prop(view, "use_save_prompt") + col = layout.column(heading="Default to") + col.prop(paths, "use_relative_paths") + col.prop(paths, "use_file_compression") + col.prop(paths, "use_load_ui") - layout.separator() + col = layout.column(heading="Text Files") + col.prop(paths, "use_tabs_as_spaces") - flow = layout.grid_flow(row_major=False, columns=0, even_columns=True, even_rows=False, align=False) - - flow.prop(paths, "save_version") - flow.prop(paths, "recent_files") + col = layout.column() + col.prop(paths, "save_version") + col.prop(paths, "recent_files") class USERPREF_PT_saveload_blend_autosave(SaveLoadPanel, CenterAlignMixIn, Panel): bl_label = "Auto Save" bl_parent_id = "USERPREF_PT_saveload_blend" - def draw_centered(self, context, layout): + def draw_header(self, context): prefs = context.preferences paths = prefs.filepaths - flow = layout.grid_flow(row_major=False, columns=0, even_columns=True, even_rows=False, align=False) + self.layout.prop(paths, "use_auto_save_temporary_files", text="") - flow.prop(paths, "use_auto_save_temporary_files") - sub = flow.column() - sub.active = paths.use_auto_save_temporary_files - sub.prop(paths, "auto_save_time", text="Timer (mins)") + def draw_centered(self, context, layout): + prefs = context.preferences + paths = prefs.filepaths + + col = layout.column() + col.active = paths.use_auto_save_temporary_files + col.prop(paths, "auto_save_time", text="Timer (mins)") class USERPREF_PT_saveload_file_browser(SaveLoadPanel, CenterAlignMixIn, Panel): @@ -1371,12 +1352,13 @@ class USERPREF_PT_saveload_file_browser(SaveLoadPanel, CenterAlignMixIn, Panel): prefs = context.preferences paths = prefs.filepaths - flow = layout.grid_flow(row_major=False, columns=0, even_columns=True, even_rows=False, align=False) + col = layout.column() + col.prop(paths, "use_filter_files") - flow.prop(paths, "use_filter_files") - flow.prop(paths, "show_hidden_files_datablocks") - flow.prop(paths, "hide_recent_locations") - flow.prop(paths, "hide_system_bookmarks") + col = layout.column(heading="Hide") + col.prop(paths, "show_hidden_files_datablocks", text="Dot File & Datablocks") + col.prop(paths, "hide_recent_locations", text="Recent Locations") + col.prop(paths, "hide_system_bookmarks", text="System Bookmarks") # ----------------------------------------------------------------------------- @@ -1435,10 +1417,9 @@ class USERPREF_PT_input_tablet(InputPanel, CenterAlignMixIn, Panel): layout.prop(inputs, "tablet_api") layout.separator() - flow = layout.grid_flow(row_major=False, columns=0, even_columns=True, even_rows=False, align=False) - - flow.prop(inputs, "pressure_threshold_max") - flow.prop(inputs, "pressure_softness") + col = layout.column() + col.prop(inputs, "pressure_threshold_max") + col.prop(inputs, "pressure_softness") class USERPREF_PT_input_ndof(InputPanel, CenterAlignMixIn, Panel): @@ -1476,24 +1457,27 @@ class USERPREF_PT_navigation_orbit(NavigationPanel, CenterAlignMixIn, Panel): inputs = prefs.inputs view = prefs.view - flow = layout.grid_flow(row_major=False, columns=0, even_columns=True, even_rows=False, align=False) + col = layout.column() - flow.row().prop(inputs, "view_rotate_method", expand=True) + col.row().prop(inputs, "view_rotate_method", expand=True) if inputs.view_rotate_method == 'TURNTABLE': - flow.prop(inputs, "view_rotate_sensitivity_turntable") + col.prop(inputs, "view_rotate_sensitivity_turntable") else: - flow.prop(inputs, "view_rotate_sensitivity_trackball") + col.prop(inputs, "view_rotate_sensitivity_trackball") + col.prop(inputs, "use_rotate_around_active") + + col.separator() - flow.prop(inputs, "use_rotate_around_active") - flow.prop(inputs, "use_auto_perspective") - flow.prop(inputs, "use_mouse_depth_navigate") if sys.platform == "darwin": - flow.prop(inputs, "use_trackpad_natural", text="Natural Trackpad Direction") + col.prop(inputs, "use_trackpad_natural", text="Natural Trackpad Direction") - flow.separator() + col = layout.column(heading="Auto") + col.prop(inputs, "use_auto_perspective", text="Perspective") + col.prop(inputs, "use_mouse_depth_navigate", text="Depth") - flow.prop(view, "smooth_view") - flow.prop(view, "rotation_angle") + col = layout.column() + col.prop(view, "smooth_view") + col.prop(view, "rotation_angle") class USERPREF_PT_navigation_zoom(NavigationPanel, CenterAlignMixIn, Panel): @@ -1503,16 +1487,20 @@ class USERPREF_PT_navigation_zoom(NavigationPanel, CenterAlignMixIn, Panel): prefs = context.preferences inputs = prefs.inputs - flow = layout.grid_flow(row_major=False, columns=0, even_columns=True, even_rows=False, align=False) + col = layout.column() - flow.row().prop(inputs, "view_zoom_method", text="Zoom Method") + col.row().prop(inputs, "view_zoom_method", text="Zoom Method") if inputs.view_zoom_method in {'DOLLY', 'CONTINUE'}: - flow.row().prop(inputs, "view_zoom_axis") - flow.prop(inputs, "invert_mouse_zoom", text="Invert Mouse Zoom Direction") + col.row().prop(inputs, "view_zoom_axis") + col.prop(inputs, "use_zoom_to_mouse") + col = layout.column(heading="Invert Zoom Direction", align=True) + col.prop(inputs, "invert_mouse_zoom", text="Mouse") + col.prop(inputs, "invert_zoom_wheel", text="Wheel") + else: + col.prop(inputs, "use_zoom_to_mouse") + col.prop(inputs, "invert_zoom_wheel", text="Invert Wheel Zoom Direction") - flow.prop(inputs, "invert_zoom_wheel", text="Invert Wheel Zoom Direction") # sub.prop(view, "wheel_scroll_lines", text="Scroll Lines") - flow.prop(inputs, "use_zoom_to_mouse") class USERPREF_PT_navigation_fly_walk(NavigationPanel, CenterAlignMixIn, Panel): @@ -1543,15 +1531,14 @@ class USERPREF_PT_navigation_fly_walk_navigation(NavigationPanel, CenterAlignMix inputs = prefs.inputs walk = inputs.walk_navigation - flow = layout.grid_flow(row_major=False, columns=0, even_columns=True, even_rows=False, align=False) - - flow.prop(walk, "use_mouse_reverse") - flow.prop(walk, "mouse_speed") - flow.prop(walk, "teleport_time") + col = layout.column() + col.prop(walk, "use_mouse_reverse") + col.prop(walk, "mouse_speed") + col.prop(walk, "teleport_time") - sub = flow.column(align=True) - sub.prop(walk, "walk_speed") - sub.prop(walk, "walk_speed_factor") + col = layout.column(align=True) + col.prop(walk, "walk_speed") + col.prop(walk, "walk_speed_factor") class USERPREF_PT_navigation_fly_walk_gravity(NavigationPanel, CenterAlignMixIn, Panel): @@ -1578,10 +1565,9 @@ class USERPREF_PT_navigation_fly_walk_gravity(NavigationPanel, CenterAlignMixIn, layout.active = walk.use_gravity - flow = layout.grid_flow(row_major=False, columns=0, even_columns=True, even_rows=False, align=False) - - flow.prop(walk, "view_height") - flow.prop(walk, "jump_height") + col = layout.column() + col.prop(walk, "view_height") + col.prop(walk, "jump_height") # Special case, this is only exposed as a popover. @@ -1589,7 +1575,7 @@ class USERPREF_PT_ndof_settings(Panel): bl_label = "3D Mouse Settings" bl_space_type = 'TOPBAR' # dummy. bl_region_type = 'HEADER' - bl_ui_units_x = 10 + bl_ui_units_x = 12 @staticmethod def draw_settings(layout, props, show_3dview_settings=True): @@ -1611,16 +1597,12 @@ class USERPREF_PT_ndof_settings(Panel): if show_3dview_settings: col.prop(props, "ndof_show_guide") col.prop(props, "ndof_zoom_invert") - col.prop(props, "ndof_pan_yz_swap_axis", text="Swap Y and Z Pan Axes") + row = col.row(heading="Pan") + row.prop(props, "ndof_pan_yz_swap_axis", text="Swap Y and Z Axes") layout.separator() - split = layout.split() - col = split.column() - col.alignment = 'RIGHT' - col.label(text="Invert Axis Pan" if show_3dview_settings else "Invert Pan Axis") - col = split.column() - row = col.row(align=True) + row = layout.row(heading=("Invert Axis Pan" if show_3dview_settings else "Invert Pan Axis")) for text, attr in ( ("X", "ndof_panx_invert_axis"), ("Y", "ndof_pany_invert_axis"), @@ -1629,12 +1611,7 @@ class USERPREF_PT_ndof_settings(Panel): row.prop(props, attr, text=text, toggle=True) if show_3dview_settings: - split = layout.split() - col = split.column() - col.alignment = 'RIGHT' - col.label(text="Invert Axis Orbit") - col = split.column() - row = col.row(align=True) + row = layout.row(heading="Orbit") for text, attr in ( ("X", "ndof_rotx_invert_axis"), ("Y", "ndof_roty_invert_axis"), @@ -1644,8 +1621,8 @@ class USERPREF_PT_ndof_settings(Panel): layout.separator() - col = layout.column() - col.prop(props, "ndof_lock_horizon", text="Fly/Walk Lock Horizon") + col = layout.column(heading="Fly/Walk") + col.prop(props, "ndof_lock_horizon") col.prop(props, "ndof_fly_helicopter") def draw(self, context): @@ -1654,7 +1631,6 @@ class USERPREF_PT_ndof_settings(Panel): layout.use_property_decorate = False # No animation. input_prefs = context.preferences.inputs - is_view3d = context.space_data.type == 'VIEW_3D' self.draw_settings(layout, input_prefs, is_view3d) @@ -2129,7 +2105,7 @@ class ExperimentalPanel: experimental = prefs.experimental layout = self.layout - layout.use_property_split = True + layout.use_property_split = False layout.use_property_decorate = False for prop_keywords, task in items: @@ -2155,16 +2131,6 @@ class USERPREF_PT_experimental_virtual_reality(ExperimentalPanel, Panel): ) """ -class USERPREF_PT_experimental_ui(ExperimentalPanel, Panel): - bl_label = "UI" - - def draw(self, context): - self._draw_items( - context, ( - ({"property": "use_menu_search"}, "T74157"), - ), - ) - class USERPREF_PT_experimental_system(ExperimentalPanel, Panel): bl_label = "System" @@ -2217,7 +2183,6 @@ classes = ( USERPREF_PT_animation_timeline, USERPREF_PT_animation_keyframes, - USERPREF_PT_animation_autokey, USERPREF_PT_animation_fcurves, USERPREF_PT_system_cycles_devices, @@ -2268,7 +2233,6 @@ classes = ( # Popovers. USERPREF_PT_ndof_settings, - USERPREF_PT_experimental_ui, USERPREF_PT_experimental_system, # Add dynamically generated editor theme panels last, diff --git a/release/scripts/startup/bl_ui/space_view3d.py b/release/scripts/startup/bl_ui/space_view3d.py index bb67dc085b1..ed9a27aeae6 100644 --- a/release/scripts/startup/bl_ui/space_view3d.py +++ b/release/scripts/startup/bl_ui/space_view3d.py @@ -125,7 +125,6 @@ class VIEW3D_HT_tool_header(Header): if brush.gpencil_tool not in {'FILL', 'TINT'}: layout.popover("VIEW3D_PT_tools_grease_pencil_brush_stroke") - layout.popover("VIEW3D_PT_tools_grease_pencil_brushcurves") layout.popover("VIEW3D_PT_tools_grease_pencil_paint_appearance") elif tool_mode == 'SCULPT_GPENCIL': @@ -737,7 +736,12 @@ class VIEW3D_HT_header(Header): row.prop(tool_settings, "use_gpencil_vertex_select_mask_stroke", text="") row.prop(tool_settings, "use_gpencil_vertex_select_mask_segment", text="") - if gpd.use_stroke_edit_mode or gpd.is_stroke_sculpt_mode or gpd.is_stroke_weight_mode or gpd.is_stroke_vertex_mode: + if ( + gpd.use_stroke_edit_mode or + gpd.is_stroke_sculpt_mode or + gpd.is_stroke_weight_mode or + gpd.is_stroke_vertex_mode + ): row = layout.row(align=True) row.prop(gpd, "use_multiedit", text="", icon='GP_MULTIFRAME_EDITING') @@ -830,18 +834,17 @@ class VIEW3D_HT_header(Header): # While exposing 'shading.show_xray(_wireframe)' is correct. # this hides the key shortcut from users: T70433. + if has_pose_mode: + draw_depressed = overlay.show_xray_bone + elif shading.type == 'WIREFRAME': + draw_depressed = shading.show_xray_wireframe + else: + draw_depressed = shading.show_xray row.operator( "view3d.toggle_xray", text="", icon='XRAY', - depress=( - overlay.show_xray_bone if has_pose_mode else - getattr( - shading, - "show_xray_wireframe" if shading.type == 'WIREFRAME' else - "show_xray" - ) - ), + depress=draw_depressed, ) row = layout.row(align=True) @@ -1165,7 +1168,7 @@ class VIEW3D_MT_view(Menu): if view.region_quadviews: layout.operator("view3d.view_selected", text="Frame Selected (Quad View)").use_all_regions = True - layout.operator("view3d.view_all", text="Frame All").center = False + layout.operator("view3d.view_all").center = False layout.operator("view3d.view_persportho", text="Perspective/Orthographic") layout.menu("VIEW3D_MT_view_local") @@ -1296,7 +1299,7 @@ class VIEW3D_MT_view_align(Menu): layout.separator() - layout.operator("view3d.view_all", text="Center Cursor and View All").center = True + layout.operator("view3d.view_all", text="Center Cursor and Frame All").center = True layout.operator("view3d.view_center_cursor") layout.separator() @@ -5302,6 +5305,7 @@ class VIEW3D_MT_sculpt_mask_edit_pie(Menu): op.auto_iteration_count = False class VIEW3D_MT_sculpt_face_sets_edit_pie(Menu): + bl_label = "Face Sets Edit" def draw(self, _context): @@ -5397,8 +5401,8 @@ class VIEW3D_PT_view3d_properties(Panel): layout.use_property_split = True layout.use_property_decorate = False # No animation. - flow = layout.grid_flow(row_major=True, columns=0, even_columns=False, even_rows=False, align=True) - col = flow.column() + + col = layout.column() subcol = col.column() subcol.active = bool(view.region_3d.view_perspective != 'CAMERA' or view.region_quadviews) @@ -5408,20 +5412,22 @@ class VIEW3D_PT_view3d_properties(Panel): subcol.prop(view, "clip_start", text="Clip Start") subcol.prop(view, "clip_end", text="End") - subcol.separator() - - col = flow.column() + layout.separator() - subcol = col.column() - subcol.prop(view, "use_local_camera") + col = layout.column(align=False, heading="Local Camera") + col.use_property_decorate = False + row = col.row(align=True) + sub = row.row(align=True) + sub.prop(view, "use_local_camera", text="") + sub = sub.row(align=True) + sub.enabled = view.use_local_camera + sub.prop(view, "camera", text="") - subcol = col.column() - subcol.enabled = view.use_local_camera - subcol.prop(view, "camera", text="Local Camera") + layout.separator() - subcol = col.column(align=True) - subcol.prop(view, "use_render_border") - subcol.active = view.region_3d.view_perspective != 'CAMERA' + col = layout.column(align=True) + col.prop(view, "use_render_border") + col.active = view.region_3d.view_perspective != 'CAMERA' class VIEW3D_PT_view3d_lock(Panel): @@ -5440,23 +5446,24 @@ class VIEW3D_PT_view3d_lock(Panel): view = context.space_data col = layout.column(align=True) - subcol = col.column() - subcol.active = bool(view.region_3d.view_perspective != 'CAMERA' or view.region_quadviews) + sub = col.column() + sub.active = bool(view.region_3d.view_perspective != 'CAMERA' or view.region_quadviews) - subcol.prop(view, "lock_object") + sub.prop(view, "lock_object") lock_object = view.lock_object if lock_object: if lock_object.type == 'ARMATURE': - subcol.prop_search( + sub.prop_search( view, "lock_bone", lock_object.data, "edit_bones" if lock_object.mode == 'EDIT' else "bones", text="", ) else: - subcol.prop(view, "lock_cursor", text="Lock to 3D Cursor") + subcol = sub.column(heading="Lock") + subcol.prop(view, "lock_cursor", text="To 3D Cursor") - col.prop(view, "lock_camera") + col.prop(view, "lock_camera", text="Camera to View") class VIEW3D_PT_view3d_cursor(Panel): @@ -6046,16 +6053,17 @@ class VIEW3D_PT_overlay_guides(Panel): split = col.split() sub = split.column() sub.prop(overlay, "show_text", text="Text Info") + sub.prop(overlay, "show_stats", text="Statistics") + sub = split.column() sub.prop(overlay, "show_cursor", text="3D Cursor") + sub.prop(overlay, "show_annotation", text="Annotations") if shading.type == 'MATERIAL': row = col.row() row.active = shading.render_pass == 'COMBINED' row.prop(overlay, "show_look_dev") - col.prop(overlay, "show_annotation", text="Annotations") - class VIEW3D_PT_overlay_object(Panel): bl_space_type = 'VIEW_3D' @@ -6376,7 +6384,7 @@ class VIEW3D_PT_overlay_edit_curve(Panel): col.active = display_all row = col.row() - row.prop(overlay, "show_curve_handles", text="Handles") + row.prop(overlay, "display_handle", text="Handles") row = col.row() row.prop(overlay, "show_curve_normals", text="") @@ -6733,9 +6741,10 @@ class VIEW3D_PT_overlay_gpencil_options(Panel): col = layout.column() row = col.row() row.prop(overlay, "use_gpencil_grid", text="") - sub = row.row() + sub = row.row(align=True) sub.active = overlay.use_gpencil_grid sub.prop(overlay, "gpencil_grid_opacity", text="Canvas", slider=True) + sub.prop(overlay, "use_gpencil_canvas_xray", text="", icon='XRAY') row = col.row() row.prop(overlay, "use_gpencil_fade_layers", text="") @@ -7056,6 +7065,18 @@ def draw_gpencil_layer_active(context, layout): row.operator("gpencil.layer_remove", text="", icon='X') +def draw_gpencil_material_active(context, layout): + ob = context.active_object + if ob and len(ob.material_slots) > 0 and ob.active_material_index >= 0: + ma = ob.material_slots[ob.active_material_index].material + if ma: + layout.label(text="Active Material") + row = layout.row(align=True) + row.operator_context = 'EXEC_REGION_WIN' + row.operator_menu_enum("gpencil.material_set", "slot", text="", icon='MATERIAL') + row.prop(ma, "name", text="") + + class VIEW3D_PT_gpencil_sculpt_context_menu(Panel): bl_space_type = 'VIEW_3D' bl_region_type = 'WINDOW' @@ -7129,6 +7150,9 @@ class VIEW3D_PT_gpencil_draw_context_menu(Panel): # Layers draw_gpencil_layer_active(context, layout) + # Material + if not is_vertex: + draw_gpencil_material_active(context, layout) class VIEW3D_PT_gpencil_vertex_context_menu(Panel): diff --git a/release/scripts/startup/bl_ui/space_view3d_toolbar.py b/release/scripts/startup/bl_ui/space_view3d_toolbar.py index 553726503d9..3d72a2a588c 100644 --- a/release/scripts/startup/bl_ui/space_view3d_toolbar.py +++ b/release/scripts/startup/bl_ui/space_view3d_toolbar.py @@ -125,21 +125,15 @@ class View3DPanel: # Used by vertex & weight paint def draw_vpaint_symmetry(layout, vpaint): - split = layout.split() - - col = split.column() - col.alignment = 'RIGHT' - col.label(text="Mirror") + col = layout.column() + col.use_property_split = True + col.use_property_decorate = False - col = split.column() - row = col.row(align=True) + row = col.row(heading="Mirror", align=True) row.prop(vpaint, "use_symmetry_x", text="X", toggle=True) row.prop(vpaint, "use_symmetry_y", text="Y", toggle=True) row.prop(vpaint, "use_symmetry_z", text="Z", toggle=True) - col = layout.column() - col.use_property_split = True - col.use_property_decorate = False col.prop(vpaint, "radial_symmetry", text="Radial") @@ -179,10 +173,10 @@ class VIEW3D_PT_tools_object_options_transform(View3DPanel, Panel): tool_settings = context.tool_settings - layout.label(text="Affect Only") - layout.prop(tool_settings, "use_transform_data_origin", text="Origins") - layout.prop(tool_settings, "use_transform_pivot_point_align", text="Locations") - layout.prop(tool_settings, "use_transform_skip_children", text="Parents") + col = layout.column(heading="Affect Only", align=True) + col.prop(tool_settings, "use_transform_data_origin", text="Origins") + col.prop(tool_settings, "use_transform_pivot_point_align", text="Locations") + col.prop(tool_settings, "use_transform_skip_children", text="Parents") # ********** default tools for editmode_mesh **************** @@ -209,16 +203,11 @@ class VIEW3D_PT_tools_meshedit_options(View3DPanel, Panel): split = layout.split() - col = split.column() - col.alignment = 'RIGHT' - col.label(text="Mirror") - - col = split.column() - - row = col.row(align=True) - row.prop(mesh, "use_mirror_x", text="X", toggle=True) - row.prop(mesh, "use_mirror_y", text="Y", toggle=True) - row.prop(mesh, "use_mirror_z", text="Z", toggle=True) + row = layout.row(heading="Mirror") + sub = row.row(align=True) + sub.prop(mesh, "use_mirror_x", text="X", toggle=True) + sub.prop(mesh, "use_mirror_y", text="Y", toggle=True) + sub.prop(mesh, "use_mirror_z", text="Z", toggle=True) row = layout.row(align=True) row.active = ob.data.use_mirror_x or ob.data.use_mirror_y or ob.data.use_mirror_z @@ -254,62 +243,6 @@ class VIEW3D_PT_tools_meshedit_options_automerge(View3DPanel, Panel): col.prop(tool_settings, "use_mesh_automerge_and_split", toggle=False) col.prop(tool_settings, "double_threshold", text="Threshold") -# ********** default tools for editmode_curve **************** - - -class VIEW3D_PT_tools_curveedit_options_stroke(View3DPanel, Panel): - bl_category = "Tool" - bl_context = ".curve_edit" # dot on purpose (access from topbar) - bl_label = "Curve Stroke" - - def draw(self, context): - layout = self.layout - - tool_settings = context.tool_settings - cps = tool_settings.curve_paint_settings - - col = layout.column() - - col.prop(cps, "curve_type") - - if cps.curve_type == 'BEZIER': - col.label(text="Bezier Options:") - col.prop(cps, "error_threshold") - col.prop(cps, "fit_method") - col.prop(cps, "use_corners_detect") - - col = layout.column() - col.active = cps.use_corners_detect - col.prop(cps, "corner_angle") - - col.label(text="Pressure Radius:") - row = layout.row(align=True) - rowsub = row.row(align=True) - rowsub.prop(cps, "radius_min", text="Min") - rowsub.prop(cps, "radius_max", text="Max") - - row.prop(cps, "use_pressure_radius", text="", icon_only=True) - - col = layout.column() - col.label(text="Taper Radius:") - row = layout.row(align=True) - row.prop(cps, "radius_taper_start", text="Start") - row.prop(cps, "radius_taper_end", text="End") - - col = layout.column() - col.label(text="Projection Depth:") - row = layout.row(align=True) - row.prop(cps, "depth_mode", expand=True) - - col = layout.column() - if cps.depth_mode == 'SURFACE': - col.prop(cps, "surface_offset") - col.prop(cps, "use_offset_absolute") - col.prop(cps, "use_stroke_endpoints") - if cps.use_stroke_endpoints: - colsub = layout.column(align=True) - colsub.prop(cps, "surface_plane", expand=True) - # ********** default tools for editmode_armature **************** @@ -868,10 +801,13 @@ class VIEW3D_PT_sculpt_voxel_remesh(Panel, View3DPaintPanel): col.prop(mesh, "remesh_voxel_adaptivity") col.prop(mesh, "use_remesh_fix_poles") col.prop(mesh, "use_remesh_smooth_normals") - col.prop(mesh, "use_remesh_preserve_volume") - col.prop(mesh, "use_remesh_preserve_paint_mask") - col.prop(mesh, "use_remesh_preserve_sculpt_face_sets") - col.operator("object.voxel_remesh", text="Remesh") + + col = layout.column(heading="Preserve", align=True) + col.prop(mesh, "use_remesh_preserve_volume", text="Volume") + col.prop(mesh, "use_remesh_preserve_paint_mask", text="Paint Mask") + col.prop(mesh, "use_remesh_preserve_sculpt_face_sets", text="Face Sets") + + layout.operator("object.voxel_remesh", text="Remesh") # TODO, move to space_view3d.py @@ -892,23 +828,19 @@ class VIEW3D_PT_sculpt_options(Panel, View3DPaintPanel): tool_settings = context.tool_settings sculpt = tool_settings.sculpt - flow = layout.grid_flow(row_major=True, columns=0, even_columns=True, even_rows=False, align=False) - - col = flow.column() + col = layout.column(heading="Display", align=True) col.prop(sculpt, "use_threaded", text="Threaded Sculpt") - col = flow.column() col.prop(sculpt, "show_low_resolution") - col = flow.column() col.prop(sculpt, "use_sculpt_delay_updates") - col = flow.column() col.prop(sculpt, "use_deform_only") - col = flow.column() col.separator() - col.prop(sculpt, "use_automasking_topology") - col.prop(sculpt, "use_automasking_face_sets") - col.prop(sculpt, "use_automasking_boundary_edges") - col.prop(sculpt, "use_automasking_boundary_face_sets") + + col = layout.column(heading="Auto-Masking", align=True) + col.prop(sculpt, "use_automasking_topology", text="Topology") + col.prop(sculpt, "use_automasking_face_sets", text="Face Sets") + col.prop(sculpt, "use_automasking_boundary_edges", text="Mesh Boundary") + col.prop(sculpt, "use_automasking_boundary_face_sets", text="Face Sets Boundary") class VIEW3D_PT_sculpt_options_gravity(Panel, View3DPaintPanel): @@ -951,61 +883,34 @@ class VIEW3D_PT_sculpt_symmetry(Panel, View3DPaintPanel): def draw(self, context): layout = self.layout + layout.use_property_split = True + layout.use_property_decorate = False sculpt = context.tool_settings.sculpt - split = layout.split() - - col = split.column() - col.alignment = 'RIGHT' - col.label(text="Mirror") - - col = split.column() - - row = col.row(align=True) + row = layout.row(align=True, heading="Mirror") row.prop(sculpt, "use_symmetry_x", text="X", toggle=True) row.prop(sculpt, "use_symmetry_y", text="Y", toggle=True) row.prop(sculpt, "use_symmetry_z", text="Z", toggle=True) - split = layout.split() - - col = split.column() - col.alignment = 'RIGHT' - col.label(text="Lock") - - col = split.column() - - row = col.row(align=True) + row = layout.row(align=True, heading="Lock") row.prop(sculpt, "lock_x", text="X", toggle=True) row.prop(sculpt, "lock_y", text="Y", toggle=True) row.prop(sculpt, "lock_z", text="Z", toggle=True) - split = layout.split() - - col = split.column() - col.alignment = 'RIGHT' - col.label(text="Tiling") - - col = split.column() - - row = col.row(align=True) + row = layout.row(align=True, heading="Tiling") row.prop(sculpt, "tile_x", text="X", toggle=True) row.prop(sculpt, "tile_y", text="Y", toggle=True) row.prop(sculpt, "tile_z", text="Z", toggle=True) - layout.use_property_split = True - layout.use_property_decorate = False - layout.prop(sculpt, "use_symmetry_feather", text="Feather") - layout.column().prop(sculpt, "radial_symmetry", text="Radial") - layout.column().prop(sculpt, "tile_offset", text="Tile Offset") + layout.prop(sculpt, "radial_symmetry", text="Radial") + layout.prop(sculpt, "tile_offset", text="Tile Offset") layout.separator() - col = layout.column() - - col.prop(sculpt, "symmetrize_direction") - col.operator("sculpt.symmetrize") + layout.prop(sculpt, "symmetrize_direction") + layout.operator("sculpt.symmetrize") class VIEW3D_PT_sculpt_symmetry_for_topbar(Panel): @@ -1208,12 +1113,8 @@ class VIEW3D_PT_tools_imagepaint_options(View3DPaintPanel, Panel): layout.prop(ipaint, "seam_bleed") layout.prop(ipaint, "dither", slider=True) - flow = layout.grid_flow(row_major=True, columns=0, even_columns=True, even_rows=False, align=False) - - col = flow.column() + col = layout.column() col.prop(ipaint, "use_occlude") - - col = flow.column() col.prop(ipaint, "use_backface_culling", text="Backface Culling") @@ -1646,7 +1547,9 @@ class VIEW3D_PT_tools_grease_pencil_brush_random(View3DPanel, Panel): layout.use_property_split = True layout.use_property_decorate = False - brush = context.tool_settings.gpencil_paint.brush + tool_settings = context.tool_settings + brush = tool_settings.gpencil_paint.brush + mode = tool_settings.gpencil_paint.color_mode gp_settings = brush.gpencil_settings if self.is_popover: @@ -1655,83 +1558,68 @@ class VIEW3D_PT_tools_grease_pencil_brush_random(View3DPanel, Panel): row.label(text=self.bl_label) col = layout.column() - col.active = gp_settings.use_settings_random - - col.prop(gp_settings, "random_pressure", text="Pressure", slider=True) - col.prop(gp_settings, "random_strength", text="Strength", slider=True) - col.prop(gp_settings, "uv_random", text="UV", slider=True) + col.enabled = gp_settings.use_settings_random row = col.row(align=True) - row.prop(gp_settings, "pen_jitter", slider=True) - row.prop(gp_settings, "use_jitter_pressure", text="", icon='STYLUS_PRESSURE') - - -# Grease Pencil drawingcurves -class VIEW3D_PT_tools_grease_pencil_brushcurves(View3DPanel, Panel): - bl_context = ".greasepencil_paint" - bl_parent_id = 'VIEW3D_PT_tools_grease_pencil_brush_settings' - bl_label = "Curves" - bl_category = "Tool" - bl_options = {'DEFAULT_CLOSED'} - - @classmethod - def poll(cls, context): - brush = context.tool_settings.gpencil_paint.brush - return brush is not None and brush.gpencil_tool not in {'ERASE', 'FILL', 'TINT'} - - def draw(self, context): - pass - - -class VIEW3D_PT_tools_grease_pencil_brushcurves_sensitivity(View3DPanel, Panel): - bl_context = ".greasepencil_paint" - bl_label = "Sensitivity" - bl_category = "Tool" - bl_parent_id = "VIEW3D_PT_tools_grease_pencil_brushcurves" - - def draw(self, context): - layout = self.layout - layout.use_property_split = True - - brush = context.tool_settings.gpencil_paint.brush - gp_settings = brush.gpencil_settings - - layout.template_curve_mapping(gp_settings, "curve_sensitivity", brush=True, - use_negative_slope=True) - - -class VIEW3D_PT_tools_grease_pencil_brushcurves_strength(View3DPanel, Panel): - bl_context = ".greasepencil_paint" - bl_label = "Strength" - bl_category = "Tool" - bl_parent_id = "VIEW3D_PT_tools_grease_pencil_brushcurves" - - def draw(self, context): - layout = self.layout - layout.use_property_split = True - - brush = context.tool_settings.gpencil_paint.brush - gp_settings = brush.gpencil_settings + row.prop(gp_settings, "random_pressure", text="Radius", slider=True) + row.prop(gp_settings, "use_stroke_random_radius", text="", icon='GP_SELECT_STROKES') + row.prop(gp_settings, "use_random_press_radius", text="", icon='STYLUS_PRESSURE') + if gp_settings.use_random_press_radius and self.is_popover is False: + col.template_curve_mapping(gp_settings, "curve_random_pressure", brush=True, + use_negative_slope=True) - layout.template_curve_mapping(gp_settings, "curve_strength", brush=True, - use_negative_slope=True) + row = col.row(align=True) + row.prop(gp_settings, "random_strength", text="Strength", slider=True) + row.prop(gp_settings, "use_stroke_random_strength", text="", icon='GP_SELECT_STROKES') + row.prop(gp_settings, "use_random_press_strength", text="", icon='STYLUS_PRESSURE') + if gp_settings.use_random_press_strength and self.is_popover is False: + col.template_curve_mapping(gp_settings, "curve_random_strength", brush=True, + use_negative_slope=True) + row = col.row(align=True) + row.prop(gp_settings, "uv_random", text="UV", slider=True) + row.prop(gp_settings, "use_stroke_random_uv", text="", icon='GP_SELECT_STROKES') + row.prop(gp_settings, "use_random_press_uv", text="", icon='STYLUS_PRESSURE') + if gp_settings.use_random_press_uv and self.is_popover is False: + col.template_curve_mapping(gp_settings, "curve_random_uv", brush=True, + use_negative_slope=True) -class VIEW3D_PT_tools_grease_pencil_brushcurves_jitter(View3DPanel, Panel): - bl_context = ".greasepencil_paint" - bl_label = "Jitter" - bl_category = "Tool" - bl_parent_id = "VIEW3D_PT_tools_grease_pencil_brushcurves" + col.separator() - def draw(self, context): - layout = self.layout - layout.use_property_split = True + col1 = col.column(align=True) + col1.enabled = mode == 'VERTEXCOLOR' and gp_settings.use_settings_random + row = col1.row(align=True) + row.prop(gp_settings, "random_hue_factor", slider=True) + row.prop(gp_settings, "use_stroke_random_hue", text="", icon='GP_SELECT_STROKES') + row.prop(gp_settings, "use_random_press_hue", text="", icon='STYLUS_PRESSURE') + if gp_settings.use_random_press_hue and self.is_popover is False: + col1.template_curve_mapping(gp_settings, "curve_random_hue", brush=True, + use_negative_slope=True) + + row = col1.row(align=True) + row.prop(gp_settings, "random_saturation_factor", slider=True) + row.prop(gp_settings, "use_stroke_random_sat", text="", icon='GP_SELECT_STROKES') + row.prop(gp_settings, "use_random_press_sat", text="", icon='STYLUS_PRESSURE') + if gp_settings.use_random_press_sat and self.is_popover is False: + col1.template_curve_mapping(gp_settings, "curve_random_saturation", brush=True, + use_negative_slope=True) + + row = col1.row(align=True) + row.prop(gp_settings, "random_value_factor", slider=True) + row.prop(gp_settings, "use_stroke_random_val", text="", icon='GP_SELECT_STROKES') + row.prop(gp_settings, "use_random_press_val", text="", icon='STYLUS_PRESSURE') + if gp_settings.use_random_press_val and self.is_popover is False: + col1.template_curve_mapping(gp_settings, "curve_random_value", brush=True, + use_negative_slope=True) - brush = context.tool_settings.gpencil_paint.brush - gp_settings = brush.gpencil_settings + col.separator() - layout.template_curve_mapping(gp_settings, "curve_jitter", brush=True, - use_negative_slope=True) + row = col.row(align=True) + row.prop(gp_settings, "pen_jitter", slider=True) + row.prop(gp_settings, "use_jitter_pressure", text="", icon='STYLUS_PRESSURE') + if gp_settings.use_jitter_pressure and self.is_popover is False: + col.template_curve_mapping(gp_settings, "curve_jitter", brush=True, + use_negative_slope=True) class VIEW3D_PT_tools_grease_pencil_brush_paint_falloff(GreasePencilBrushFalloff, Panel, View3DPaintPanel): @@ -2225,12 +2113,14 @@ class VIEW3D_PT_tools_grease_pencil_weight_appearance(GreasePencilDisplayPanel, bl_category = "Tool" bl_label = "Cursor" + class VIEW3D_PT_tools_grease_pencil_vertex_appearance(GreasePencilDisplayPanel, Panel, View3DPanel): bl_context = ".greasepencil_vertex" bl_parent_id = 'VIEW3D_PT_tools_grease_pencil_vertex_paint_settings' bl_category = "Tool" bl_label = "Cursor" + class VIEW3D_PT_gpencil_brush_presets(Panel, PresetPanel): """Brush settings""" bl_label = "Brush Presets" @@ -2247,7 +2137,6 @@ classes = ( VIEW3D_PT_tools_object_options_transform, VIEW3D_PT_tools_meshedit_options, VIEW3D_PT_tools_meshedit_options_automerge, - VIEW3D_PT_tools_curveedit_options_stroke, VIEW3D_PT_tools_armatureedit_options, VIEW3D_PT_tools_posemode_options, @@ -2307,10 +2196,6 @@ classes = ( VIEW3D_PT_tools_grease_pencil_brush_post_processing, VIEW3D_PT_tools_grease_pencil_brush_random, VIEW3D_PT_tools_grease_pencil_brush_stabilizer, - VIEW3D_PT_tools_grease_pencil_brushcurves, - VIEW3D_PT_tools_grease_pencil_brushcurves_sensitivity, - VIEW3D_PT_tools_grease_pencil_brushcurves_strength, - VIEW3D_PT_tools_grease_pencil_brushcurves_jitter, VIEW3D_PT_tools_grease_pencil_paint_appearance, VIEW3D_PT_tools_grease_pencil_sculpt_select, VIEW3D_PT_tools_grease_pencil_sculpt_settings, diff --git a/release/scripts/startup/nodeitems_builtins.py b/release/scripts/startup/nodeitems_builtins.py index 969a1ca1bd7..2dc6c6cd409 100644 --- a/release/scripts/startup/nodeitems_builtins.py +++ b/release/scripts/startup/nodeitems_builtins.py @@ -58,6 +58,13 @@ class TextureNodeCategory(SortedNodeCategory): context.space_data.tree_type == 'TextureNodeTree') +class SimulationNodeCategory(SortedNodeCategory): + @classmethod + def poll(cls, context): + return (context.space_data.type == 'NODE_EDITOR' and + context.space_data.tree_type == 'SimulationNodeTree') + + # menu entry for node group tools def group_tools_draw(self, layout, context): layout.operator("node.group_make") @@ -70,10 +77,11 @@ node_tree_group_type = { 'CompositorNodeTree': 'CompositorNodeGroup', 'ShaderNodeTree': 'ShaderNodeGroup', 'TextureNodeTree': 'TextureNodeGroup', + 'SimulationNodeTree': 'SimulationNodeGroup', } -# generic node group items generator for shader, compositor and texture node groups +# generic node group items generator for shader, compositor, simulation and texture node groups def node_group_items(context): if context is None: return @@ -467,17 +475,81 @@ texture_node_categories = [ ]), ] +simulation_node_categories = [ + # Simulation Nodes + SimulationNodeCategory("SIM_OUTPUT", "Output", items=[ + NodeItem("SimulationNodeParticleSimulation"), + ]), + SimulationNodeCategory("SIM_INPUTS", "Input", items=[ + NodeItem("SimulationNodeTime"), + NodeItem("SimulationNodeParticleAttribute"), + NodeItem("FunctionNodeGroupInstanceID"), + ]), + SimulationNodeCategory("SIM_EMITTERS", "Emitters", items=[ + NodeItem("SimulationNodeParticleMeshEmitter"), + NodeItem("SimulationNodeEmitParticles"), + ]), + SimulationNodeCategory("SIM_EVENTS", "Events", items=[ + NodeItem("SimulationNodeParticleBirthEvent"), + NodeItem("SimulationNodeParticleTimeStepEvent"), + NodeItem("SimulationNodeParticleMeshCollisionEvent"), + ]), + SimulationNodeCategory("SIM_FORCES", "Forces", items=[ + NodeItem("SimulationNodeForce"), + ]), + SimulationNodeCategory("SIM_EXECUTE", "Execute", items=[ + NodeItem("SimulationNodeSetParticleAttribute"), + NodeItem("SimulationNodeExecuteCondition"), + NodeItem("SimulationNodeMultiExecute"), + ]), + SimulationNodeCategory("SIM_NOISE", "Noise", items=[ + NodeItem("ShaderNodeTexNoise"), + NodeItem("ShaderNodeTexWhiteNoise"), + ]), + SimulationNodeCategory("SIM_COLOR", "Color", items=[ + NodeItem("ShaderNodeMixRGB"), + NodeItem("ShaderNodeInvert"), + NodeItem("ShaderNodeHueSaturation"), + NodeItem("ShaderNodeGamma"), + NodeItem("ShaderNodeBrightContrast"), + ]), + SimulationNodeCategory("SIM_CONVERTER", "Converter", items=[ + NodeItem("ShaderNodeMapRange"), + NodeItem("ShaderNodeClamp"), + NodeItem("ShaderNodeMath"), + NodeItem("ShaderNodeValToRGB"), + NodeItem("ShaderNodeVectorMath"), + NodeItem("ShaderNodeSeparateRGB"), + NodeItem("ShaderNodeCombineRGB"), + NodeItem("ShaderNodeSeparateXYZ"), + NodeItem("ShaderNodeCombineXYZ"), + NodeItem("ShaderNodeSeparateHSV"), + NodeItem("ShaderNodeCombineHSV"), + NodeItem("FunctionNodeBooleanMath"), + NodeItem("FunctionNodeFloatCompare"), + NodeItem("FunctionNodeSwitch"), + NodeItem("FunctionNodeCombineStrings"), + ]), + SimulationNodeCategory("SIM_GROUP", "Group", items=node_group_items), + SimulationNodeCategory("SIM_LAYOUT", "Layout", items=[ + NodeItem("NodeFrame"), + NodeItem("NodeReroute"), + ]), +] + def register(): nodeitems_utils.register_node_categories('SHADER', shader_node_categories) nodeitems_utils.register_node_categories('COMPOSITING', compositor_node_categories) nodeitems_utils.register_node_categories('TEXTURE', texture_node_categories) + nodeitems_utils.register_node_categories('SIMULATION', simulation_node_categories) def unregister(): nodeitems_utils.unregister_node_categories('SHADER') nodeitems_utils.unregister_node_categories('COMPOSITING') nodeitems_utils.unregister_node_categories('TEXTURE') + nodeitems_utils.unregister_node_categories('SIMULATION') if __name__ == "__main__": |