diff options
author | Campbell Barton <ideasman42@gmail.com> | 2018-02-28 17:26:02 +0300 |
---|---|---|
committer | Campbell Barton <ideasman42@gmail.com> | 2018-02-28 17:31:07 +0300 |
commit | d937d06c02f62c11385c1c1f58d963fec03365d9 (patch) | |
tree | c9a7052205b4cbcc4c9219ed2e9838cc5414c56c /release | |
parent | 80d1d9629e1d4dd12aca580e3844a24f5d160356 (diff) |
WorkSpace: UI filtering for add-ons
Allows for each workspace to have it's own add-ons on display.
Filtering for: Panels, Menus, Keymaps & Manipulators.
Automatically applies to add-ons at the moment.
Access from workspace, toggled off by default
once enabled, add-ons can be white-listed.
See D3076
Diffstat (limited to 'release')
-rw-r--r-- | release/scripts/modules/addon_utils.py | 7 | ||||
-rw-r--r-- | release/scripts/modules/bpy_types.py | 25 | ||||
-rw-r--r-- | release/scripts/startup/bl_operators/wm.py | 33 | ||||
-rw-r--r-- | release/scripts/startup/bl_ui/properties_data_workspace.py | 57 |
4 files changed, 122 insertions, 0 deletions
diff --git a/release/scripts/modules/addon_utils.py b/release/scripts/modules/addon_utils.py index 97fc45189f2..23874abd8c9 100644 --- a/release/scripts/modules/addon_utils.py +++ b/release/scripts/modules/addon_utils.py @@ -352,6 +352,11 @@ def enable(module_name, *, default_set=False, persistent=False, handle_error=Non # 2) try register collected modules # removed, addons need to handle own registration now. + + from _bpy import _bl_owner_id_get, _bl_owner_id_set + owner_id_prev = _bl_owner_id_get() + _bl_owner_id_set(module_name) + # 3) try run the modules register function try: mod.register() @@ -363,6 +368,8 @@ def enable(module_name, *, default_set=False, persistent=False, handle_error=Non if default_set: _addon_remove(module_name) return None + finally: + _bl_owner_id_set(owner_id_prev) # * OK loaded successfully! * mod.__addon_enabled__ = True diff --git a/release/scripts/modules/bpy_types.py b/release/scripts/modules/bpy_types.py index 6b06ff77ecd..5387af46d9d 100644 --- a/release/scripts/modules/bpy_types.py +++ b/release/scripts/modules/bpy_types.py @@ -766,7 +766,23 @@ class _GenericUI: # ensure menus always get default context operator_context_default = self.layout.operator_context + # Support filtering out by owner + workspace = context.workspace + if workspace.use_filter_by_owner: + owner_names = {owner_id.name for owner_id in workspace.owner_ids} + else: + owner_names = None + for func in draw_ls._draw_funcs: + + # Begin 'owner_id' filter. + if owner_names is not None: + owner_id = getattr(func, "_owner", None) + if owner_id is not None: + if func._owner not in owner_names: + continue + # End 'owner_id' filter. + # so bad menu functions don't stop # the entire menu from drawing try: @@ -782,6 +798,13 @@ class _GenericUI: return draw_funcs + @staticmethod + def _dyn_owner_apply(draw_func): + from _bpy import _bl_owner_id_get + owner_id = _bl_owner_id_get() + if owner_id is not None: + draw_func._owner = owner_id + @classmethod def is_extended(cls): return bool(getattr(cls.draw, "_draw_funcs", None)) @@ -793,6 +816,7 @@ class _GenericUI: takes the same arguments as the menus draw function """ draw_funcs = cls._dyn_ui_initialize() + cls._dyn_owner_apply(draw_func) draw_funcs.append(draw_func) @classmethod @@ -802,6 +826,7 @@ class _GenericUI: the menus draw function """ draw_funcs = cls._dyn_ui_initialize() + cls._dyn_owner_apply(draw_func) draw_funcs.insert(0, draw_func) @classmethod diff --git a/release/scripts/startup/bl_operators/wm.py b/release/scripts/startup/bl_operators/wm.py index 022ee1576d8..1bbb3e9883e 100644 --- a/release/scripts/startup/bl_operators/wm.py +++ b/release/scripts/startup/bl_operators/wm.py @@ -1887,6 +1887,37 @@ class WM_OT_addon_disable(Operator): return {'FINISHED'} +class WM_OT_owner_enable(Operator): + """Enable workspace owner ID""" + bl_idname = "wm.owner_enable" + bl_label = "Enable Add-on" + + owner_id = StringProperty( + name="UI Tag", + ) + + def execute(self, context): + workspace = context.workspace + workspace.owner_ids.new(self.owner_id) + return {'FINISHED'} + + +class WM_OT_owner_disable(Operator): + """Enable workspace owner ID""" + bl_idname = "wm.owner_disable" + bl_label = "Disable UI Tag" + + owner_id = StringProperty( + name="UI Tag", + ) + + def execute(self, context): + workspace = context.workspace + owner_id = workspace.owner_ids[self.owner_id] + workspace.owner_ids.remove(owner_id) + return {'FINISHED'} + + class WM_OT_theme_install(Operator): """Load and apply a Blender XML theme file""" bl_idname = "wm.theme_install" @@ -2384,5 +2415,7 @@ classes = ( WM_OT_properties_remove, WM_OT_sysinfo, WM_OT_theme_install, + WM_OT_owner_disable, + WM_OT_owner_enable, WM_OT_url_open, ) diff --git a/release/scripts/startup/bl_ui/properties_data_workspace.py b/release/scripts/startup/bl_ui/properties_data_workspace.py index dae798bee95..1ece70f5e14 100644 --- a/release/scripts/startup/bl_ui/properties_data_workspace.py +++ b/release/scripts/startup/bl_ui/properties_data_workspace.py @@ -61,6 +61,62 @@ class WORKSPACE_PT_workspace(WorkSpaceButtonsPanel, Panel): layout.prop(view_render, "engine", text="") +class WORKSPACE_PT_owner_ids(WorkSpaceButtonsPanel, Panel): + bl_label = "Show/Hide Add-ons" + bl_options = {'DEFAULT_CLOSED'} + + def draw_header(self, context): + workspace = context.workspace + self.layout.prop(workspace, "use_filter_by_owner", text="") + + def draw(self, context): + layout = self.layout + # align just to pack more tightly + col = layout.box().column(align=True) + + workspace = context.workspace + userpref = context.user_preferences + + col.active = workspace.use_filter_by_owner + + import addon_utils + addon_map = { + mod.__name__: ("%s: %s" % (mod.bl_info["category"], mod.bl_info["name"])) + for mod in addon_utils.modules() + } + owner_ids = {owner_id.name for owner_id in workspace.owner_ids} + + for addon in userpref.addons: + module_name = addon.module + text = addon_map[module_name] + is_enabled = module_name in owner_ids + row = col.row() + row.operator( + "wm.owner_disable" if is_enabled else "wm.owner_enable", + icon='CHECKBOX_HLT' if is_enabled else 'CHECKBOX_DEHLT', + text="", + emboss=False, + ).owner_id = module_name + row.label(text) + if is_enabled: + owner_ids.remove(module_name) + + # Detect unused + if owner_ids: + layout.label(text="Unknown add-ons", icon='ERROR') + col = layout.box().column(align=True) + for module_name in sorted(owner_ids): + row = col.row() + row.operator( + "wm.owner_disable", + icon='CHECKBOX_HLT', + text="", + emboss=False, + ).owner_id = module_name + row.label(module_name) + + + class WORKSPACE_PT_custom_props(WorkSpaceButtonsPanel, PropertyPanel, Panel): _context_path = "workspace" _property_type = bpy.types.WorkSpace @@ -69,6 +125,7 @@ class WORKSPACE_PT_custom_props(WorkSpaceButtonsPanel, PropertyPanel, Panel): classes = ( WORKSPACE_PT_context, WORKSPACE_PT_workspace, + WORKSPACE_PT_owner_ids, WORKSPACE_PT_custom_props, ) |