Refactor, Add UI preferences, UI updates

This commit is contained in:
Francesco Bellini 2024-09-07 18:34:41 +02:00
parent 782e507709
commit 41960910ee
7 changed files with 59 additions and 20 deletions

View File

@ -26,7 +26,7 @@ bl_info = {
"name": "Scene Workspaces",
"tagline": "Filter and reorder workspaces independently for each scene",
"blender": (4, 2, 0),
"location": "Workspaces",
"location": "Workspaces topbar, Properties > Scene",
"category": ["System", "User Interface", "Scene"],
"support": "COMMUNITY",
"blender_manifest": "blender_manifest.toml"

View File

@ -10,8 +10,20 @@ def get_scene_workspaces(scene = None):
else:
return []
def prefs():
return bpy.context.preferences.addons[base_package].preferences
def get_use_global():
return bpy.context.preferences.addons[base_package].preferences.use_global
return prefs().use_global
def get_show_switch():
return prefs().show_switch
def get_active_spacing():
return prefs().active_spacing
def get_quick_unlink():
return prefs().quick_unlink
def set_scene_workspaces(workspaces):
bpy.data.scenes[bpy.context.scene.name]['scene_workspaces'] = workspaces

View File

@ -9,7 +9,7 @@ class SW_MT_copy_from(Menu):
layout = self.layout
for s in bpy.data.scenes:
if s.name != bpy.context.scene.name:
layout.operator("sw.copy_from_scene", text=s.name, icon="SCENE").scene = s.name
layout.operator("sw.copy_from_scene", text=s.name, icon="SCENE_DATA").scene = s.name
class SW_MT_missing_workspaces(Menu):
bl_label = "Link other workspaces to this scene"

View File

@ -3,15 +3,15 @@ import time
import bpy
from bpy.types import Operator
from bpy.props import StringProperty, BoolProperty, IntProperty
from .funcs import select_all, get_scene_workspaces, set_scene_workspaces, get_use_global, has_data
from .funcs import select_all, get_scene_workspaces, set_scene_workspaces, get_use_global, has_data, prefs
class SW_OT_switch(Operator):
bl_idname = "sw.switch"
bl_label = "Scene Workspaces On/Off"
bl_label = "Show/Hide Scene Workspaces"
bl_description = "Switch workspaces topbar between Scene Workspaces and default"
def execute(self, context):
context.preferences.addons[base_package].preferences.use_global = not get_use_global()
prefs().use_global = not get_use_global()
context.preferences.is_dirty = True
return {'FINISHED'}
@ -113,10 +113,13 @@ class SW_OT_copy_from_scene(Operator):
class SW_OT_link_workspace(Operator):
bl_idname = "sw.link_workspace"
bl_label = "Link Workspace"
bl_description = "Link this workspace to this Scene"
workspace: StringProperty(name="workspace")
@classmethod
def description(cls, context, props):
return "This is the active workspace, but it's not linked to this scene. Click to link" if props.workspace == bpy.context.window.workspace.name else "Link this workspace to this Scene"
def execute(self, context):
if not has_data():
set_scene_workspaces([])

View File

@ -8,6 +8,7 @@ class SW_PT_select_scene_workspaces(Panel):
bl_space_type = 'PROPERTIES'
bl_region_type = 'WINDOW'
bl_context = "scene"
bl_options = {'DEFAULT_CLOSED'}
def draw(self, context):
layout = self.layout
@ -17,6 +18,7 @@ class SW_PT_select_scene_workspaces(Panel):
box = layout.box()
if not sw:
box.label(text="There are no workspaces linked right now...")
box.operator("sw.link_all")
else:
i = 0
for w in sw:

View File

@ -7,8 +7,17 @@ class SWPreferences(AddonPreferences):
bl_idname = base_package
use_global: BoolProperty(name="Use default workspaces", description="Switch the workspace topbar between Scene Workspaces and the default one", default=False)
show_switch: BoolProperty(name="Show Switch", description="Show/Hide the switch button next to the workspaces topbar. Useful for quickly lookup the original workspaces topbar", default=True)
active_spacing: BoolProperty(name="Active workspace spacing", description="Add space around the active workspace", default=True)
quick_unlink: BoolProperty(name="Show Quick Unlink", description="Show/Hide the unlink button at left of the active workspace", default=True)
def draw(self, context):
layout = self.layout
layout.prop(self, "use_global")
layout.prop(self, "show_switch")
box = layout.box()
box.label("UI Options")
box.prop(self, "quick_unlink")
box.prop(self, "active_spacing")

View File

@ -1,7 +1,7 @@
from .. import __package__ as base_package
import bpy
from bpy.types import Header, Panel
from .funcs import get_scene_workspaces, get_use_global
from .funcs import get_scene_workspaces, get_use_global, get_show_switch, get_quick_unlink, get_active_spacing
# Ref TOPBAR_HT_upper_bar https://projects.blender.org/blender/blender/src/commit/2204157a2c9fc926643b0e39968602c750d9b5e6/scripts/startup/bl_ui/space_topbar.py#L14
class TOPBAR_HT_upper_bar(Header):
@ -29,6 +29,8 @@ class TOPBAR_HT_upper_bar(Header):
# Edited
use_global = get_use_global()
quick_unlink = get_quick_unlink()
active_spacing = get_active_spacing()
if not screen.show_fullscreen:
main_col = layout.column()
@ -36,10 +38,11 @@ class TOPBAR_HT_upper_bar(Header):
spacer_row.scale_y = .33
main_row = main_col.row()
sy = 1.18
sx = 1.1
sx = 1.12
if get_show_switch():
col = main_row.column()
col.scale_y = sy
col.operator("sw.switch", text="", emboss=False, icon="RADIOBUT_OFF" if use_global else "RADIOBUT_ON")
# Show/Hide Custom Topbar
col.operator("sw.switch", text="", emboss=False, icon="CHECKBOX_DEHLT" if use_global else "CHECKBOX_HLT")
if use_global:
# Original
layout.template_ID_tabs(window, "workspace", new="workspace.add", menu="TOPBAR_MT_workspace_menu")
@ -48,6 +51,7 @@ class TOPBAR_HT_upper_bar(Header):
r.scale_x = 0.87
r.scale_y = sy
ws = get_scene_workspaces()
# Link all (with no linked workspaces)
if not ws and bpy.data.workspaces:
c = r.column()
c.scale_x = 1.4
@ -56,42 +60,51 @@ class TOPBAR_HT_upper_bar(Header):
for w in ws:
i = ws.index(w)
active = bpy.context.window.workspace.name == w
if active and i > 0:
if active and i > 0 and active_spacing:
r.separator()
ab = r.box()
ab = ab.row(align=True)
if active:
# Workspace unlink
if active and quick_unlink:
col = ab.column()
col.scale_x = sx
col.operator("sw.remove", text="", icon="X", emboss=False).index = i
exist = w in [x.name for x in bpy.data.workspaces]
# Workspace
ab.operator("sw.workspace", text=w, icon="NONE" if exist else "ERROR", emboss=active, depress=active).workspace = w
# Active workspace options
if active:
col = ab.column()
col.scale_x = sx
col.menu("TOPBAR_MT_workspace_menu", text="", icon="OPTIONS")
active_not_here = False
if active_spacing:
r.separator()
# Link other workspaces
if [x for x in bpy.data.workspaces if x.name not in get_scene_workspaces()]:
c = r.column()
c.scale_x = sx
c.menu("SW_MT_missing_workspaces", text="", icon="THREE_DOTS")
c = r.column()
c.scale_x = sx
c.operator("workspace.add", text="", icon="ADD")
c.menu("SW_MT_missing_workspaces", text="", icon="WORKSPACE")
# Duplicate linked workspaces from other scenes
if len(bpy.data.scenes) > 1:
c = r.column()
c.scale_x = sx
c.menu("SW_MT_copy_from", text="", icon="DUPLICATE")
# Original Add Workspace menu
c = r.column()
c.scale_x = sx
c.operator("workspace.add", text="", icon="ADD")
# Active (but not linked) workspace
if active_not_here:
r.separator()
r = r.box()
r = r.row(align=True)
b = r.box()
b.scale_x = sx
b.operator("sw.link_workspace", text=f"{bpy.context.window.workspace.name} (not linked)", icon="ADD", emboss=True, depress=True).workspace = bpy.context.window.workspace.name
b.operator("sw.link_workspace", text=f"{bpy.context.window.workspace.name} (link)", icon="LINKED", emboss=True, depress=True).workspace = bpy.context.window.workspace.name
# Active workspace options
col = r.box()
col.scale_x = sx
col.menu("TOPBAR_MT_workspace_menu", text="", icon="OPTIONS")