[Bf-blender-cvs] [d937d06c02f] blender2.8: WorkSpace: UI filtering for add-ons

Campbell Barton noreply at git.blender.org
Wed Feb 28 15:26:54 CET 2018


Commit: d937d06c02f62c11385c1c1f58d963fec03365d9
Author: Campbell Barton
Date:   Thu Mar 1 01:26:02 2018 +1100
Branches: blender2.8
https://developer.blender.org/rBd937d06c02f62c11385c1c1f58d963fec03365d9

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

===================================================================

M	release/scripts/modules/addon_utils.py
M	release/scripts/modules/bpy_types.py
M	release/scripts/startup/bl_operators/wm.py
M	release/scripts/startup/bl_ui/properties_data_workspace.py
M	source/blender/blenkernel/BKE_screen.h
M	source/blender/blenkernel/BKE_workspace.h
M	source/blender/blenkernel/intern/workspace.c
M	source/blender/blenloader/intern/readfile.c
M	source/blender/blenloader/intern/writefile.c
M	source/blender/editors/screen/area.c
M	source/blender/makesdna/DNA_windowmanager_types.h
M	source/blender/makesdna/DNA_workspace_types.h
M	source/blender/makesrna/RNA_access.h
M	source/blender/makesrna/RNA_types.h
M	source/blender/makesrna/intern/rna_access.c
M	source/blender/makesrna/intern/rna_ui.c
M	source/blender/makesrna/intern/rna_wm.c
M	source/blender/makesrna/intern/rna_wm_manipulator.c
M	source/blender/makesrna/intern/rna_workspace.c
M	source/blender/python/intern/bpy.c
M	source/blender/python/intern/bpy_rna.c
M	source/blender/python/intern/bpy_rna.h
M	source/blender/windowmanager/intern/wm.c
M	source/blender/windowmanager/intern/wm_keymap.c
M	source/blender/windowmanager/manipulators/WM_manipulator_types.h
M	source/blender/windowmanager/manipulators/intern/wm_manipulator_group.c

===================================================================

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,
 )
 
diff --git a/source/blender/blenkernel/BKE_screen.h b/source/blender/blenkernel/BKE_screen.h
index 6669f3103da..3957641fe3f 100644
--- a/source/blender/blenkernel/BKE_screen.h
+++ b/source/blender/blenkernel/BKE_screen.h
@@ -194,6 +194,7 @@ typedef struct PanelType {
 	char translation_context[BKE_ST_MAXNAME];
 	char context[BKE_ST_MAXNAME];             /* for buttons window */
 	char category[BKE_ST_MAXNAME];            /* for category tabs */
+	char owner_id[BKE_ST_MAXNAME];              /* for work-spaces to selectively show. */
 	int space_type;
 	int region_type;
 
@@ -264,6 +265,7 @@ typedef struct MenuType {
 	char idname[BKE_ST_MAXNAME];        /* unique name */
 	char label[BKE_ST_MAXNAME];         /* for button text */
 	char translation_context[BKE_ST_MAXNAME];
+	char owner_id[BKE_ST_MAXNAME];  /* optional, see: #wmOwnerID */
 	const char *description;
 
 	/* verify if the menu should draw or not */
diff --git a/source/blender/blenkernel/BKE_workspace.h b/source/blender/blenkernel/BKE_workspace.h
index b309ae838d6..0aff79b7e30 100644
--- a/source/blender/blenkernel/BKE_workspace.h
+++ b/source/blender/blenkernel/BKE_workspace.h
@@ -136,6 +136,9 @@ void BKE_workspace_update_object_mode(
 struct Object *BKE_workspace_edit_object(
         struct WorkSpace *workspace, struct Scene *scene);
 
+bool BKE_workspace_owner_id_check(
+        const struct WorkSpace *workspace, const char *owner_id) ATTR_NONNULL();
+
 #undef GETTER_ATTRS
 #undef SETTER_ATTRS
 
diff --git a/source/blender/blenkernel/intern/workspace.c b/source/blender/blenkernel/intern/workspace.c
index 9251c6630a5..301084e22fc 100644
--- a/source/blender/blenkernel/intern/workspace.c
+++ b/source/blender/blenkernel/intern/workspace.c
@@ -169,6 +169,7 @@ void BKE_workspace_free(WorkSpace *workspace)
 	BKE_workspace_relations_free(&workspace->hook_layout_relations);
 	BKE_workspace_relations_free(&workspace->scene_viewlayer_relations);
 
+	BLI_freelistN(&workspace->owner_ids);
 	BLI_freelistN(&workspace->layouts);
 	BLI_freelistN(&workspace->transform_orientations);
 
@@ -535,3 +536,16 @@ Object *BKE_workspace_edit_object(WorkSpace *workspace, Scene *scene)
 	return NULL;
 }
 
+bool BKE_workspace_owner_id_check(
+        const WorkSpace *workspace, const char *owner_id)
+{
+	if ((*owner_id == '\0') ||
+	    ((workspace->flags & WORKSPACE_USE_FILTER_BY_ORIGIN) == 0))
+	{
+		return true;
+	}
+	else {
+		/* we could use hash lookup, for now this list is highly under < ~16 items. */
+		return BLI_findstring(&workspace->owner_ids, owner_id, offsetof(wmOwnerID, name)) != NULL;
+	}
+}
diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c
index d96be6a9f55..af97aeb8fc0 100644
--- a/source/blender/blenloader/intern/readfile.c
+++ b/source/blender/blenloader/intern/readfile.c
@@ -2904,6 +2904,7 @@ static void direct_link_workspace(FileData *fd, Wo

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list