diff --git a/CHANGELOG.md b/CHANGELOG.md index 776c2d3..b62ff8a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,17 @@ All notable changes to this project will be documented in this file. # Changelog +## [0.0.9] - 2019-08-21 +### Fixed +- Method how menu class is import +- Added proper Prefix & Suffix to menu classes +- Some keymaps not show in Preference panel +- Clearing keymaps + +## [0.0.8] - 2019-02-13 +### Fixed +- Issue with quick render menu. Now render window will show like as dropdown menu (mentioned by Jacques Lucke) + ## [0.0.7] - 2019-01-10 ### Changed - Fixed typo in workspace Texture Paint > was TEXTURE_PAINTING @@ -41,6 +52,8 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +[0.0.9]:https://github.com/schroef/QuickSwitch/releases/tag/v.0.0.9 +[0.0.8]:https://github.com/schroef/QuickSwitch/releases/tag/v.0.0.8 [0.0.7]:https://github.com/schroef/QuickSwitch/releases/tag/v.0.0.7 [0.0.6]:https://github.com/schroef/QuickSwitch/releases/tag/v.0.0.6 [0.0.5]:https://github.com/schroef/QuickSwitch/releases/tag/v.0.0.5 diff --git a/README.md b/README.md index 9d7a272..9a9e443 100644 --- a/README.md +++ b/README.md @@ -4,16 +4,15 @@ QuickSwitch a helper to quick switch workspaces and view render menu in viewport > Some limitations are currently present due to Beta containing some bugs -!['Look UI'](https://raw.githubusercontent.com/wiki/schroef/quickswitch/images/quickswitch_v007.jpg?v10-01-2019) +!['Look UI'](https://raw.githubusercontent.com/wiki/schroef/quickswitch/images/quickswitch_v009.jpg?v21-08-2019) > Choose either Pie menu or WM menu -!['Example Addon Prefs'](https://raw.githubusercontent.com/wiki/schroef/quickswitch/images/addon-preferences_v007.jpg) +!['Example Addon Prefs'](https://raw.githubusercontent.com/wiki/schroef/quickswitch/images/addon-preferences_v009.jpg) > Customise shortscuts from addon preferences - ### System Requirements | **OS** | **Blender** | diff --git a/__init__.py b/__init__.py index 2243ce5..0fd3527 100644 --- a/__init__.py +++ b/__init__.py @@ -71,16 +71,26 @@ ## Changed ## 10-01-19 - Fixed typo in workspace Texture Paint > was TEXTURE_PAINTING - +## v.0.0.8 +## Fixed +## 13-02-19 - Issue with quick render menu. Now render window will show like as dropdown menu (mentioned by Jacques Lucke) + +## v0.0.9 +## 2019-08-21 +### Fixed +## - Method how menu class is import +## - Added proper Prefix & Suffix to menu classes +## - Some keymaps not show in Preference panel +## - Clearing keymaps ####################################################### bl_info = { "name": "QuickSwitch", "description": "QuickSwitch is a little helper to make it easier to switch render engines & workspaces", - "location": "3D VIEW > Quick Switch", + "location": "3D VIEW > Quick Switch (see hotkeys)", "author": "Rombout Versluijs", - "version": (0, 0, 7), + "version": (0, 0, 9), "blender": (2, 80, 0), "wiki_url": "https://github.com/schroef/quickswitch", "tracker_url": "https://github.com/schroef/quickswitch/issues", @@ -89,7 +99,7 @@ import bpy import rna_keymap_ui -from bl_operators.presets import AddPresetBase, PresetMenu +#from bl_operators.presets import AddPresetBase, PresetMenu from bpy.app.handlers import persistent #from . import AddPresetBase @@ -117,9 +127,6 @@ def avail_workspaces(self,context): return screens -addon_keymaps = [] - - #def defaultWSSmodes(self, context): # ''' # Stores all default Object Modes when switching Workspaces @@ -199,10 +206,117 @@ def on_scene_update(scene): # return {'FINISHED'} # return {'CANCELLED'} + +viewLoc = (0.0, 0.0, 0.0) +distance = 0 +matrix = (0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0) +rotation = (0,0,0,0) #bpy.types.Scene.qsDefWSmodes = bpy.props.EnumProperty(name = "Def WorkSpace Modes", items=defaultWSSmodes) +bpy.types.Scene.qsStore3dView = bpy.props.BoolProperty(name = "Store View", default=False, description="This stores the view in 3D View and sets this view to the workspace you are moving to.") bpy.types.Scene.qsKeepMode = bpy.props.BoolProperty(name = "Keep Mode", default=False, description="This stores the current Object Interaction Mode, now when you switch workspaces you will return to prior mode and not the default one.") +class QS_StoreView(object): + #"""Get current view in the 3D View and store it for reuse""" + #bl_idname = "qs.store_view" + #bl_label = "Store View" + + def __init__(self, context): + self.context = context + #self.ViewPort = self.ViewPort() + + @property + def view(self): + """ Returns the set of 3D views. + """ + rtn = [] + for a in self.context.window.screen.areas: + if a.type == 'VIEW_3D': + rtn.append(a) + return rtn + + def ViewPort(self, context): + """ Return position, rotation data about a given view for the first space attached to it """ + global viewLoc, distance, rotation + + for area in bpy.context.screen.areas: + if area.type == 'VIEW_3D': + + rv3d = area.spaces[0].region_3d + view_Loc = rv3d.view_location + viewloc = rv3d.view_location + #viewloc = view_Loc[0],view_Loc[1],view_Loc[2] + distance = rv3d.view_distance + matrix = rv3d.view_matrix + print(distance) + #camera_pos = self.camera_position(matrix) + rotation = rv3d.view_rotation + #rotation = rotation[0],rotation[1],rotation[2],rotation[3] + #return view_Loc, rotation, distance #camera_pos, + return + +def ViewPort(wsn): + """ Return position, rotation data about a given view for the first space attached to it """ + global viewLoc, distance, matrix, rotation + + for i, area in enumerate(bpy.context.screen.areas): + # print(bpy.context.window.workspace.name) + #for area in bpy.context.window.workspace[bpy.data.workspaces[0]].screen.areas: + if area.type == 'VIEW_3D': + #print(bpy.context.window.workspace[bpy.data.workspaces[wsn]]) + #print(bpy.data.workspaces[wsn].screen.areas) + wsp = bpy.context.window.workspace + print(wsp.screen.areas) + rv3d = area.spaces[0].region_3d + #view_Loc = rv3d.view_location + viewLoc = rv3d.view_location + #viewloc = view_Loc[0],view_Loc[1],view_Loc[2] + distance = rv3d.view_distance + matrix = rv3d.view_matrix + print(distance) + #camera_pos = self.camera_position(matrix) + rotation = rv3d.view_rotation + #rotation = rotation[0],rotation[1],rotation[2],rotation[3] + #return view_Loc, rotation, distance #camera_pos, + +#class QS_Store3DView(PropertyGroup): +# viewLoc : StringProperty( +# name = "viewLoc", +# default="0,0,0") +# +# distance : StringProperty( +# name = "distance", +# default="0") +# +# rotation : StringProperty( +# name = "rotation", +# default="0,0,0,0") + +@persistent +def on_ws_switch(scene): + context = bpy.context + scene = context.scene + settings = scene.qsStoreView + + #viewport = QS_StoreView.ViewPort(context, context) + #settings.viewLoc =str(viewLoc) + #settings.distance =str(distance) + #settings.rotation =str(rotation) + global viewLoc, distance, matrix, rotation + wsn = context.workspace + #try: + ViewPort(wsn) + viewLoc = viewLoc + distance = distance + matrix = matrix + rotation = rotation + + print("## %s - %s -%s" % (viewLoc,distance, rotation)) + #except: + # pass + + +addon_keymaps = [] def add_hotkey(): preferences = bpy.context.preferences @@ -212,65 +326,64 @@ def add_hotkey(): kc = wm.keyconfigs.addon # for hotkeys within an addon km = kc.keymaps.new(name = "Screen", space_type = "EMPTY") - hKeys = [("NUMPAD_1"), ("NUMPAD_2"), ("NUMPAD_3"), ("NUMPAD_4"),("NUMPAD_5"),("NUMPAD_6"),("NUMPAD_7"),("NUMPAD_8"),("NUMPAD_9"),("NUMPAD_0")] - i=0 - for screen in hKeys: - kmi = km.keymap_items.new("workspace.set_layout", hKeys[i], "PRESS", oskey=True) # ...and if not found then add it - kmi.properties.layoutName = "WorkspaceSwitcher"+str(i) # also set proper name - kmi.active = True - addon_keymaps.append((km, kmi)) # also append to global (addon level) hotkey list for easy management - i+=1 #Add quick menu kmi = km.keymap_items.new("wm.call_menu", value='PRESS', type='W', ctrl=False, alt=True, shift=False, oskey=False) - kmi.properties.name = "workspace.switch_menu" + kmi.properties.name = "QS_MT_WorkspaceSwitchMenu" kmi.active = True addon_keymaps.append((km, kmi)) #Add quick pie menu kmi = km.keymap_items.new("wm.call_menu_pie", value='PRESS', type='W', ctrl=False, alt=True, shift=True, oskey=False) - kmi.properties.name = "workspace.switch_pie_menu" + kmi.properties.name = "QS_MT_WorkspaceSwitchPieMenu" kmi.active = True addon_keymaps.append((km, kmi)) - #Add QS Render Engine wm = bpy.context.window_manager kc = wm.keyconfigs.addon km = kc.keymaps.new(name = "Screen", space_type = "EMPTY") kmi = km.keymap_items.new("wm.call_menu", value='PRESS', type='E', alt=True, shift=True) - kmi.properties.name = "quick.switch_engine" + kmi.properties.name = "QS_MT_QuickSwitchEngine" kmi.active = True addon_keymaps.append((km, kmi)) + hKeys = [("NUMPAD_1"), ("NUMPAD_2"), ("NUMPAD_3"), ("NUMPAD_4"),("NUMPAD_5"),("NUMPAD_6"),("NUMPAD_7"),("NUMPAD_8"),("NUMPAD_9"),("NUMPAD_0")] + i=0 + for screen in hKeys: + kmi = km.keymap_items.new("qs.workspace_set_layout", hKeys[i], "PRESS", oskey=True) # ...and if not found then add it + kmi.properties.layoutName = "WorkspaceSwitcher"+str(i) # also set proper name + kmi.active = True + addon_keymaps.append((km, kmi)) # also append to global (addon level) hotkey list for easy management + i+=1 -class AddPresetQuickSwitch(AddPresetBase, Operator): - """Add or remove a QuickSwitch Preset""" - bl_idname = "qs.preset_add" - bl_label = "Add QuickSwitch Preset" - preset_menu = "QS_PT_presets" - - preset_defines = [ - "qs = bpy.context.cloth" - ] - - preset_values = [ - "qs.", - "qs.", - "qs.", - "qs.", - "qs.", - "qs.", - ] - - preset_subdir = "quickswitch" - - -class QS_PT_presets(PresetMenu): - bl_label = "QuickSwitch Presets" - preset_subdir = "quickswitch" - preset_operator = "script.execute_preset" - draw = Menu.draw_preset +#class AddPresetQuickSwitch(AddPresetBase, Operator): +# """Add or remove a QuickSwitch Preset""" +# bl_idname = "qs.preset_add" +# bl_label = "Add QuickSwitch Preset" +# preset_menu = "QS_PT_presets" +# +# preset_defines = [ +# "qs = bpy.context.cloth" +# ] +# +# preset_values = [ +# "qs.", +# "qs.", +# "qs.", +# "qs.", +# "qs.", +# "qs.", +# ] +# +# preset_subdir = "quickswitch" +# +# +#class QS_PT_presets(PresetMenu): +# bl_label = "QuickSwitch Presets" +# preset_subdir = "quickswitch" +# preset_operator = "script.execute_preset" +# draw = Menu.draw_preset #class RIGIFY_MT_SettingsPresetMenu(Menu): # bl_label = "Setting Presets" @@ -279,39 +392,40 @@ class QS_PT_presets(PresetMenu): # draw = Menu.draw_preset +## TEST GITHUB CALL +#import ssl +#import urllib.request +# +# +#class QS_OT_AddonUpdater(Operator): +# """Quick check addonupdater 2.80""" +# bl_idname="qs.addon_updater" +# bl_label="Addon Updater" +# +# def execute(self,context): +# print(ssl.OPENSSL_VERSION) +# api_url = 'https://api.github.com' +# user = "schroef" +# repo = "theaforblender" +# +# url = "{}{}{}{}{}{}".format(api_url,"/repos/",user,"/",repo,"/tags") +# +# request = urllib.request.Request(url) +# context = ssl._create_unverified_context() +# result = urllib.request.urlopen(request,context=context) # issue occurs here within blender +# result_string = result.read() +# result.close() +# get = result_string.decode() +# return {'FINISHED'} -import ssl -import urllib.request - - -class QS_OT_AddonUpdater(Operator): - """Quick check addonupdater 2.80""" - bl_idname="qs.addon_updater" - bl_label="Addon Updater" - - def execute(self,context): - print(ssl.OPENSSL_VERSION) - api_url = 'https://api.github.com' - user = "schroef" - repo = "theaforblender" - - url = "{}{}{}{}{}{}".format(api_url,"/repos/",user,"/",repo,"/tags") - - request = urllib.request.Request(url) - context = ssl._create_unverified_context() - result = urllib.request.urlopen(request,context=context) # issue occurs here within blender - result_string = result.read() - result.close() - get = result_string.decode() - print(get) - return {'FINISHED'} -class QS_OT_QuickSwitchEngine(Menu): - bl_idname = "quick.switch_engine" - bl_label = "Render" +class QS_MT_QuickSwitchEngine(Menu): + bl_idname = "QS_MT_QuickSwitchEngine" + bl_label = "Switch Engine & Render" def draw(self, context): layout = self.layout + layout.operator_context = "INVOKE_AREA" scene = context.scene rd = scene.render @@ -319,8 +433,9 @@ def draw(self, context): if rd.has_multiple_engines: layout.prop(rd, "engine", expand=True) - layout.separator() - layout.operator("qs.addon_updater", text="Addon Updater", icon='FILE_REFRESH') + # TEST GITHUB CALL + #layout.separator() + #layout.operator("qs.addon_updater", text="Addon Updater", icon='FILE_REFRESH') layout.separator() layout.operator("render.render", text="Render Image", icon='RENDER_STILL').use_viewport = True @@ -338,18 +453,16 @@ def draw(self, context): layout.separator() -def get_hotkey_entry_item(km, kmi_name, kmi_value): +def get_hotkey_entry_item(km, kmi_name, kmi_value, properties): ''' returns hotkey of specific type, with specific properties.name (keymap is not a dict, so referencing by keys is not enough if there are multiple hotkeys!) ''' for i, km_item in enumerate(km.keymap_items): if km.keymap_items.keys()[i] == kmi_name: - try: + if properties == 'name': if km.keymap_items[i].properties.name == kmi_value: return km_item - except: - pass try: if km.keymap_items[i].properties.layoutName == kmi_value: return km_item @@ -359,8 +472,8 @@ def get_hotkey_entry_item(km, kmi_name, kmi_value): class QS_MT_WorkspaceSwitchPieMenu(Menu): - bl_label = "Workspaces" - bl_idname = "workspace.switch_pie_menu" + bl_idname = "QS_MT_WorkspaceSwitchPieMenu" + bl_label = "Workspaces Pie Menu" def draw(self, context): layout = self.layout @@ -375,7 +488,7 @@ def draw(self, context): for i in range(0,8): - kmi = get_hotkey_entry_item(km, "workspace.set_layout", "WorkspaceSwitcher"+str(i)) + kmi = get_hotkey_entry_item(km, 'qs.workspace_set_layout', 'WorkspaceSwitcher'+str(i), 'layoutname') if not kmi == None: for k in range(0,len(icons)): if kmi.properties.wslayoutMenu in icons[k][0]: @@ -391,21 +504,23 @@ def draw(self, context): #row = col.row(align=True) col.scale_y=1.5 col.scale_x=1.5 + #col.prop(scene,"qsStore3dView") col.prop(scene,"qsKeepMode") - col.operator("workspace.set_layout", text='{}'.format(kmi.properties.wslayoutMenu),icon=icon).wslayoutMenu=kmi.properties.wslayoutMenu + col.operator("qs.workspace_set_layout", text='{}'.format(kmi.properties.wslayoutMenu),icon=icon).wslayoutMenu=kmi.properties.wslayoutMenu else: pie = layout.menu_pie() - pie.operator("workspace.set_layout", text='{}'.format(kmi.properties.wslayoutMenu),icon=icon).wslayoutMenu=kmi.properties.wslayoutMenu + pie.operator("qs.workspace_set_layout", text='{}'.format(kmi.properties.wslayoutMenu),icon=icon).wslayoutMenu=kmi.properties.wslayoutMenu class QS_MT_WorkspaceSwitchMenu(Menu): - bl_label = "Workspaces" - bl_idname = "workspace.switch_menu" + bl_idname = "QS_MT_WorkspaceSwitchMenu" + bl_label = "Workspaces Menu" def draw(self, context): layout = self.layout scene = context.scene + #layout.prop(scene,"qsStore3dView") layout.prop(scene,"qsKeepMode") layout.separator() @@ -415,13 +530,13 @@ def draw(self, context): ## Alphabetical order #for i in range(0,len(avail_workspaces(self, context))): - # layout.operator("workspace.set_layout", text='{}'.format(avail_workspaces(self, context)[i][1]), icon='SEQ_SPLITVIEW').wslayoutMenu=avail_workspaces(self, context)[i][1] + # layout.operator("qs.workspace_set_layout", text='{}'.format(avail_workspaces(self, context)[i][1]), icon='SEQ_SPLITVIEW').wslayoutMenu=avail_workspaces(self, context)[i][1] icons = [('Layout','VIEW3D'),('Modeling','VIEW3D'),('Sculpting','SCULPTMODE_HLT'),('UV Editing','GROUP_UVS'),('Texture Paint','IMAGE'),('Shading','SHADING_RENDERED'),('Animation','RENDER_ANIMATION'),('Rendering','RENDER_STILL'),('Compositing','NODE_COMPOSITING'),('Scripting','CONSOLE')] ## Custom order for i in range(0,len(avail_workspaces(self, context))): - kmi = get_hotkey_entry_item(km, "workspace.set_layout", "WorkspaceSwitcher"+str(i)) + kmi = get_hotkey_entry_item(km, 'qs.workspace_set_layout', 'WorkspaceSwitcher'+str(i), 'layoutname') if not kmi == None: for k in range(0,len(icons)): if kmi.properties.wslayoutMenu in icons[k][0]: @@ -430,13 +545,25 @@ def draw(self, context): else: icon = 'PREFERENCES' - layout.operator("workspace.set_layout", text='{}'.format(kmi.properties.wslayoutMenu),icon=icon).wslayoutMenu=kmi.properties.wslayoutMenu + layout.operator("qs.workspace_set_layout", text='{}'.format(kmi.properties.wslayoutMenu),icon=icon).wslayoutMenu=kmi.properties.wslayoutMenu layout.separator() +def getView(context): + for area in bpy.context.screen.areas: + if area.type == 'VIEW_3D': + qssw = context.scene.qsStoreView + rv3d = area.spaces[0].region_3d + rv3d.view_location = viewLoc#float(qssw.viewLoc[0]).strip(", ") #,float(qssw.viewLoc[1]),float(qssw.viewLoc[2])) + rv3d.view_distance = distance#float(qssw.distance) + rv3d.view_rotation = rotation#float(qssw.rotation) + rv3d.view_matrix = matrix#float(qssw.rotation) + + return + class QS_OT_SetWorkspace(Operator): """Switches to the Workspace of the given name.""" - bl_idname="workspace.set_layout" + bl_idname="qs.workspace_set_layout" bl_label="Switch to Workspace" wslayoutMenu: bpy.props.EnumProperty(name = "Workspace", items = avail_workspaces) @@ -460,19 +587,22 @@ def execute(self,context): break else: wsN = ws.name - print(ws.name) + #print(ws.name) if wsN == 'UV Editing': wsN = 'UV_Editing' if wsN == 'Texture Paint': wsN = 'Texture_Paint' ws.object_mode = scene.qsWSsmode[wsN] - try: - bpy.context.window.workspace = bpy.data.workspaces[self.wslayoutMenu] - return{'FINISHED'} - except: + #try: + if scene.qsStore3dView: + #items = scene.qsStoreView + getView(context) + bpy.context.window.workspace = bpy.data.workspaces[self.wslayoutMenu] + return{'FINISHED'} + #except: # except layout doesn't exists - self.report({'INFO'}, 'Workspace [{}] doesn\'t exist! Create it or pick another in addon settings.'.format(self.layoutName)) + #self.report({'INFO'}, 'Workspace [{}] doesn\'t exist! Create it or pick another in addon settings.'.format(self.layoutName)) return {'FINISHED'} @@ -509,7 +639,7 @@ def draw(self, context): split = box.split() col = split.column() col.label(text='Set Menus:') - kmi = get_hotkey_entry_item(km, "wm.call_menu", "workspace.switch_menu") + kmi = get_hotkey_entry_item(km, 'wm.call_menu', 'QS_MT_WorkspaceSwitchMenu', 'name') if kmi: col.label(text='Quick Switch Menu:') col.context_pointer_set("keymap", km) @@ -518,7 +648,7 @@ def draw(self, context): col.label(text="restore hotkeys from interface tab") - kmi = get_hotkey_entry_item(km, "wm.call_menu_pie", "workspace.switch_pie_menu") + kmi = get_hotkey_entry_item(km, 'wm.call_menu_pie', 'QS_MT_WorkspaceSwitchPieMenu', 'name') if kmi: col.label(text='Quick Switch Pie Menu:') col.context_pointer_set("keymap", km) @@ -532,7 +662,7 @@ def draw(self, context): col.label(text='Set Workspaces:') for i in range(0,len(avail_workspaces(self, context))): # if km.keymap_items.keys()[i] == 'Switch to Workspace': - kmi = get_hotkey_entry_item(km, "workspace.set_layout", "WorkspaceSwitcher"+str(i)) + kmi = get_hotkey_entry_item(km, 'qs.workspace_set_layout', 'WorkspaceSwitcher'+str(i), 'layoutname') if not kmi == None: if kmi: col.context_pointer_set("keymap", km) @@ -549,7 +679,7 @@ def draw(self, context): split = box.split() col = split.column() col.label(text='Set Render Menu:') - kmi = get_hotkey_entry_item(km, "wm.call_menu", "quick.switch_engine") + kmi = get_hotkey_entry_item(km, 'wm.call_menu', 'QS_MT_QuickSwitchEngine', 'name') if kmi: col.context_pointer_set("keymap", km) rna_keymap_ui.draw_kmi([], kc, km, kmi, col, 0) @@ -563,14 +693,15 @@ def draw(self, context): #Classes for register and unregister classes = ( QS_defaultWSSmodes, - AddPresetQuickSwitch, - QS_PT_presets, - QS_OT_AddonUpdater, - QS_OT_QuickSwitchEngine, + #QS_Store3DView, + #AddPresetQuickSwitch, + #QS_PT_presets, + #QS_OT_AddonUpdater, + QS_PT_AddonPreferences, + QS_MT_QuickSwitchEngine, QS_MT_WorkspaceSwitchPieMenu, QS_MT_WorkspaceSwitchMenu, QS_OT_SetWorkspace, - QS_PT_AddonPreferences, ) def register(): @@ -578,16 +709,19 @@ def register(): bpy.utils.register_class(cls) bpy.types.Scene.qsWSsmode = PointerProperty(type=QS_defaultWSSmodes) + #bpy.types.Scene.qsStoreView = PointerProperty(type=QS_Store3DView) # hotkey setup add_hotkey() bpy.app.handlers.depsgraph_update_pre.append(on_scene_update) + #bpy.app.handlers.depsgraph_update_pre.append(on_ws_switch) def unregister(): bpy.app.handlers.depsgraph_update_pre.remove(on_scene_update) + #bpy.app.handlers.depsgraph_update_pre.remove(on_ws_switch) # handle the keymap for km, kmi in addon_keymaps: @@ -598,7 +732,7 @@ def unregister(): bpy.utils.unregister_class(cls) del bpy.types.Scene.qsWSsmode - + #del bpy.types.Scene.qsStoreView if __name__ == "__main__": register()