From 3a1b03b5a615614c63ead5a484ae33ce4a92f065 Mon Sep 17 00:00:00 2001 From: lijenstina Date: Thu, 30 Mar 2017 11:45:23 +0200 Subject: API Navigator: Cleanup, UI fixes Bumped version to 1.0.3 Pep8 cleanup imports as tuples Removed an empty operator FakeButton too much fuss for a tooltip UI uses embossed buttons set to True Moved the list size filter to the top Moved the PropertyGroup out of register --- development_api_navigator.py | 340 +++++++++++++++++++++---------------------- 1 file changed, 170 insertions(+), 170 deletions(-) (limited to 'development_api_navigator.py') diff --git a/development_api_navigator.py b/development_api_navigator.py index e7db1cf9..7be8a73e 100644 --- a/development_api_navigator.py +++ b/development_api_navigator.py @@ -2,7 +2,6 @@ # # ***** 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 @@ -22,12 +21,12 @@ bl_info = { "name": "API Navigator", "author": "Dany Lebel (Axon_D)", - "version": (1, 0, 2), + "version": (1, 0, 3), "blender": (2, 57, 0), "location": "Text Editor > Properties > API Navigator Panel", "description": "Allows exploration of the python api via the user interface", "warning": "", - "wiki_url": "http://wiki.blender.org/index.php/Extensions:2.6/Py/" + "wiki_url": "https://wiki.blender.org/index.php/Extensions:2.6/Py/" "Scripts/Text_Editor/API_Navigator", "category": "Development", } @@ -58,77 +57,73 @@ with the Escape key. (but a bug prevent the keymap to register correctly at star """ import bpy +from bpy.types import ( + Operator, + Panel, + PropertyGroup, + ) +from bpy.props import ( + StringProperty, + IntProperty, + PointerProperty + ) from console.complete_import import get_root_modules -############ Global Variables ############ - -last_text = None # last text data block - -root_module = None # root module of the tree - -root_m_path = '' # root_module + path as a string +# ########## Global Variables ########## +last_text = None # last text data block +root_module = None # root module of the tree +root_m_path = '' # root_module + path as a string current_module = None # the object itself in the tree structure +tree_level = None # the list of objects from the current_module -tree_level = None # the list of objects from the current_module - def init_tree_level(): global tree_level - tree_level = [[],[],[],[],[],[],[], [], []] - -init_tree_level() + tree_level = [[], [], [], [], [], [], [], [], []] -api_doc_ = '' # the documentation formated for the API Navigator +init_tree_level() +api_doc_ = '' # the documentation formated for the API Navigator module_type = None # the type of current_module - return_report = '' # what current_module returns +filter_mem = {} # remember last filters entered for each path +too_long = False # is tree_level list too long to display in a panel? -filter_mem = {} # remember last filters entered for each path - -too_long = False # is tree_level list too long to display in a panel? - - -############ Functions ############ +# ########## Functions ############ def get_root_module(path): - #print('get_root_module') global root_module if '.' in path: root = path[:path.find('.')] - else : + else: root = path - try : + try: root_module = __import__(root) - except : + except: root_module = None def evaluate(module): - #print('evaluate') global root_module, tree_level, root_m_path - # path = bpy.context.window_manager.api_nav_props.path - try : + try: len_name = root_module.__name__.__len__() root_m_path = 'root_module' + module[len_name:] current_module = eval(root_m_path) return current_module - except : + except: init_tree_level return None def get_tree_level(): - #print('get_tree_level') path = bpy.context.window_manager.api_nav_props.path def object_list(): - #print('object_list') global current_module, root_m_path itm, val, mod, typ, props, struct, met, att, bug = [], [], [], [], [], [], [], [], [] @@ -138,22 +133,19 @@ def get_tree_level(): current_type = str(module_type) if current_type != "": if iterable == 'a': - #if iterable == 'a': - #current_type.__iter__() itm = list(current_module.keys()) if not itm: val = list(current_module) - else : + else: val = list(current_module) for i in dir(current_module): - try : + try: t = str(type(eval(root_m_path + '.' + i))) except (AttributeError, SyntaxError): bug += [i] continue - if t == "": mod += [i] elif t[0:16] == "": typ += [i] - else : + else: att += [i] return [itm, val, mod, typ, props, struct, met, att, bug] @@ -176,8 +168,6 @@ def get_tree_level(): def parent(path): """Returns the parent path""" - #print('parent') - parent = path if parent[-1] == ']' and '[' in parent: while parent[-1] != '[': @@ -185,7 +175,7 @@ def parent(path): elif '.' in parent: while parent[-1] != '.': parent = parent[:-1] - else : + else: return '' parent = parent[:-1] return parent @@ -195,19 +185,18 @@ def update_filter(): """Update the filter according to the current path""" global filter_mem - try : + try: bpy.context.window_manager.api_nav_props.filter = filter_mem[bpy.context.window_manager.api_nav_props.path] - except : + except: bpy.context.window_manager.api_nav_props.filter = '' def isiterable(mod): - - try : + try: iter(mod) - except : + except: return False - try : + try: mod[''] return 'a' except KeyError: @@ -221,13 +210,13 @@ def fill_filter_mem(): filter = bpy.context.window_manager.api_nav_props.filter if filter: - filter_mem[bpy.context.window_manager.api_nav_props.old_path] = bpy.context.window_manager.api_nav_props.filter - else : + filter_mem[bpy.context.window_manager.api_nav_props.old_path] = \ + bpy.context.window_manager.api_nav_props.filter + else: filter_mem.pop(bpy.context.window_manager.api_nav_props.old_path, None) -###### API Navigator parent class ####### - +# #### API Navigator parent class ###### class ApiNavigator(): """Parent class for API Navigator""" @@ -242,7 +231,7 @@ class ApiNavigator(): last_text = bpy.context.space_data.text.name elif bpy.data.texts.__len__() < 2: last_text = None - else : + else: last_text = None bpy.context.window_manager.api_nav_props.pages = 0 get_root_module(bpy.context.window_manager.api_nav_props.path) @@ -254,7 +243,7 @@ class ApiNavigator(): if tree_level.__len__() > 30: global too_long too_long = True - else : + else: too_long = False ApiNavigator.generate_api_doc() @@ -266,7 +255,7 @@ class ApiNavigator(): global current_module, api_doc_, return_report, module_type path = bpy.context.window_manager.api_nav_props.path - line = "-" * (path.__len__()+2) + line = "-" * (path.__len__() + 2) header = """\n\n\n\t\t%s\n\t %s\n\ _____________________________________________\n\ \n\ @@ -300,11 +289,11 @@ _____________________________________________\n\ space_data = bpy.context.space_data - try : + try: doc_text = bpy.data.texts['api_doc_'] space_data.text = doc_text doc_text.clear() - except : + except: bpy.data.texts.new(name='api_doc_') doc_text = bpy.data.texts['api_doc_'] space_data.text = doc_text @@ -313,8 +302,7 @@ _____________________________________________\n\ return {'FINISHED'} - -############ Operators ############ +# ######### Operators ########### def api_update(context): if bpy.context.window_manager.api_nav_props.path != bpy.context.window_manager.api_nav_props.old_path: fill_filter_mem() @@ -324,7 +312,7 @@ def api_update(context): ApiNavigator.doc_text_datablock() -class Update(ApiNavigator, bpy.types.Operator): +class Update(ApiNavigator, Operator): """Update the tree structure""" bl_idname = "api_navigator.update" bl_label = "API Navigator Update" @@ -334,8 +322,8 @@ class Update(ApiNavigator, bpy.types.Operator): return {'FINISHED'} -class BackToBpy(ApiNavigator, bpy.types.Operator): - """go back to module bpy""" +class BackToBpy(ApiNavigator, Operator): + """Go back to module bpy""" bl_idname = "api_navigator.back_to_bpy" bl_label = "Back to bpy" @@ -343,7 +331,7 @@ class BackToBpy(ApiNavigator, bpy.types.Operator): fill_filter_mem() if not bpy.context.window_manager.api_nav_props.path: bpy.context.window_manager.api_nav_props.old_path = bpy.context.window_manager.api_nav_props.path = 'bpy' - else : + else: bpy.context.window_manager.api_nav_props.old_path = bpy.context.window_manager.api_nav_props.path = 'bpy' update_filter() self.generate_global_values() @@ -351,20 +339,27 @@ class BackToBpy(ApiNavigator, bpy.types.Operator): return {'FINISHED'} -class Down(ApiNavigator, bpy.types.Operator): - """go to this Module""" +class Down(ApiNavigator, Operator): + """Go to this Module""" bl_idname = "api_navigator.down" bl_label = "API Navigator Down" - pointed_module = bpy.props.StringProperty(name='Current Module', default='') + pointed_module = StringProperty( + name="Current Module", + default="" + ) def execute(self, context): fill_filter_mem() if not bpy.context.window_manager.api_nav_props.path: - bpy.context.window_manager.api_nav_props.old_path = bpy.context.window_manager.api_nav_props.path = bpy.context.window_manager.api_nav_props.path + self.pointed_module - else : - bpy.context.window_manager.api_nav_props.old_path = bpy.context.window_manager.api_nav_props.path = bpy.context.window_manager.api_nav_props.path + '.' + self.pointed_module + bpy.context.window_manager.api_nav_props.old_path = \ + bpy.context.window_manager.api_nav_props.path = \ + bpy.context.window_manager.api_nav_props.path + self.pointed_module + else: + bpy.context.window_manager.api_nav_props.old_path = \ + bpy.context.window_manager.api_nav_props.path = \ + bpy.context.window_manager.api_nav_props.path + '.' + self.pointed_module update_filter() self.generate_global_values() @@ -372,18 +367,19 @@ class Down(ApiNavigator, bpy.types.Operator): return {'FINISHED'} -class Parent(ApiNavigator, bpy.types.Operator): - """go to Parent Module""" +class Parent(ApiNavigator, Operator): + """Go to Parent Module""" bl_idname = "api_navigator.parent" bl_label = "API Navigator Parent" - def execute(self, context): path = bpy.context.window_manager.api_nav_props.path if path: fill_filter_mem() - bpy.context.window_manager.api_nav_props.old_path = bpy.context.window_manager.api_nav_props.path = parent(bpy.context.window_manager.api_nav_props.path) + bpy.context.window_manager.api_nav_props.old_path = \ + bpy.context.window_manager.api_nav_props.path = \ + parent(bpy.context.window_manager.api_nav_props.path) update_filter() self.generate_global_values() self.doc_text_datablock() @@ -391,52 +387,52 @@ class Parent(ApiNavigator, bpy.types.Operator): return {'FINISHED'} -class ClearFilter(ApiNavigator, bpy.types.Operator): +class ClearFilter(ApiNavigator, Operator): """Clear the filter""" - bl_idname = 'api_navigator.clear_filter' - bl_label = 'API Nav clear filter' + bl_idname = "api_navigator.clear_filter" + bl_label = "API Nav clear filter" def execute(self, context): bpy.context.window_manager.api_nav_props.filter = '' return {'FINISHED'} -class FakeButton(ApiNavigator, bpy.types.Operator): - """The list is not displayed completely""" # only serve as an indicator - bl_idname = 'api_navigator.fake_button' - bl_label = '' - - -class Subscript(ApiNavigator, bpy.types.Operator): +class Subscript(ApiNavigator, Operator): """Subscript to this Item""" bl_idname = "api_navigator.subscript" bl_label = "API Navigator Subscript" - subscription = bpy.props.StringProperty(name='', default='') + + subscription = StringProperty( + name="", + default="" + ) def execute(self, context): fill_filter_mem() - bpy.context.window_manager.api_nav_props.old_path = bpy.context.window_manager.api_nav_props.path = bpy.context.window_manager.api_nav_props.path + '[' + self.subscription + ']' + bpy.context.window_manager.api_nav_props.old_path = \ + bpy.context.window_manager.api_nav_props.path = \ + bpy.context.window_manager.api_nav_props.path + '[' + self.subscription + ']' update_filter() self.generate_global_values() self.doc_text_datablock() return {'FINISHED'} -class Toggle_doc(ApiNavigator, bpy.types.Operator): +class Toggle_doc(ApiNavigator, Operator): """Toggle on or off api_doc_ Text""" - bl_idname = 'api_navigator.toggle_doc' - bl_label = 'Toggle api_doc_' - + bl_idname = "api_navigator.toggle_doc" + bl_label = "Toggle api_doc_" def execute(self, context): global last_text - try : + try: if bpy.context.space_data.text.name != "api_doc_": last_text = bpy.context.space_data.text.name - except : pass + except: + pass - try : + try: text = bpy.data.texts["api_doc_"] bpy.data.texts["api_doc_"].clear() bpy.data.texts.remove(text) @@ -444,31 +440,30 @@ class Toggle_doc(ApiNavigator, bpy.types.Operator): self.doc_text_datablock() return {'FINISHED'} - try : + try: text = bpy.data.texts[last_text] bpy.context.space_data.text = text - #line = bpy.ops.text.line_number() # operator doesn't seems to work ??? - #bpy.ops.text.jump(line=line) return {'FINISHED'} - except : pass + except: + pass bpy.context.space_data.text = None + return {'FINISHED'} -############ UI Panels ############ -class OBJECT_PT_api_navigator(ApiNavigator, bpy.types.Panel): +# ######### UI Panels ############ +class OBJECT_PT_api_navigator(ApiNavigator, Panel): bl_idname = 'api_navigator' bl_space_type = "TEXT_EDITOR" bl_region_type = "UI" bl_label = "API Navigator" bl_options = {'DEFAULT_CLOSED'} - columns = 3 - def iterable_draw(self): + # Note: Currently unused method global tree_level, current_module iterable = isiterable(current_module) @@ -481,11 +476,9 @@ class OBJECT_PT_api_navigator(ApiNavigator, bpy.types.Panel): return {'FINISHED'} col = self.layout - # filter = bpy.context.window_manager.api_nav_props.filter # UNUSED reduce_to = bpy.context.window_manager.api_nav_props.reduce_to * self.columns pages = bpy.context.window_manager.api_nav_props.pages - page_index = reduce_to*pages - # rank = 0 # UNUSED + page_index = reduce_to * pages count = 0 i = 0 filtered = 0 @@ -509,7 +502,8 @@ class OBJECT_PT_api_navigator(ApiNavigator, bpy.types.Panel): if not (i % self.columns): row = col.row() - row.operator('api_navigator.subscript', text=mod, emboss=False).subscription = '"' + mod + '"' + row.operator("api_navigator.subscript", + text=mod, emboss=True).subscription = '"' + mod + '"' filtered += 1 i += 1 count += 1 @@ -532,7 +526,8 @@ class OBJECT_PT_api_navigator(ApiNavigator, bpy.types.Panel): if not (i % self.columns): row = col.row() - row.operator('api_navigator.subscript', text=mod, emboss=False).subscription = str(i) + row.operator("api_navigator.subscript", + text=mod, emboss=True).subscription = str(i) filtered += 1 i += 1 count += 1 @@ -541,34 +536,25 @@ class OBJECT_PT_api_navigator(ApiNavigator, bpy.types.Panel): if too_long: row = col.row() - row.prop(bpy.context.window_manager.api_nav_props, 'reduce_to') - row.operator('api_navigator.fake_button', text='', emboss=False, icon="DOTSDOWN") - row.prop(bpy.context.window_manager.api_nav_props, 'pages', text='Pages') + row.prop(bpy.context.window_manager.api_nav_props, "reduce_to") + row.label(text="", icon="DOTSDOWN") + row.prop(bpy.context.window_manager.api_nav_props, "pages", text="Pages") return {'FINISHED'} - - - - def list_draw(self, t, pages, icon, label=None, emboss=False): + def list_draw(self, t, pages, icon, label=None, emboss=True): global tree_level, current_module - def reduced(too_long): - - if too_long: - row = col.row() - row.prop(bpy.context.window_manager.api_nav_props, 'reduce_to') - row.operator('api_navigator.fake_button', text='', emboss=False, icon="DOTSDOWN") - row.prop(bpy.context.window_manager.api_nav_props, 'pages', text='Pages') + def reduced(row, too_long): + if row and too_long: + sub_row = row.row(align=True) + sub_row.prop(bpy.context.window_manager.api_nav_props, "reduce_to") + sub_row.prop(bpy.context.window_manager.api_nav_props, "pages", text="Pages") layout = self.layout - filter = bpy.context.window_manager.api_nav_props.filter - reduce_to = bpy.context.window_manager.api_nav_props.reduce_to * self.columns - - page_index = reduce_to*pages - + page_index = reduce_to * pages len = tree_level[t].__len__() too_long = len > reduce_to @@ -577,8 +563,11 @@ class OBJECT_PT_api_navigator(ApiNavigator, bpy.types.Panel): col = layout.column() box = col.box() - row = box.row() - row.label(text=label, icon=icon) + row = box.row(align=True) + title_box = row.box() + title_box.label(text=label, icon=icon) + + reduced(title_box, too_long) if t < 2: box = box.box() @@ -601,43 +590,42 @@ class OBJECT_PT_api_navigator(ApiNavigator, bpy.types.Panel): continue if not (objects % self.columns): - row = col.row() + row = col.row(align=True) if t > 1: - row.operator("api_navigator.down", text=obj, emboss=emboss).pointed_module = obj + row.operator("api_navigator.down", + text=obj, emboss=emboss).pointed_module = obj elif t == 0: - row.operator('api_navigator.subscript', text=str(obj), emboss=False).subscription = '"' + obj + '"' - else : - row.operator('api_navigator.subscript', text=str(obj), emboss=False).subscription = str(i) + row.operator("api_navigator.subscript", + text=str(obj), emboss=emboss).subscription = '"' + obj + '"' + else: + row.operator("api_navigator.subscript", + text=str(obj), emboss=emboss).subscription = str(i) filtered += 1 i += 1 objects += 1 count += 1 - reduced(too_long) - return {'FINISHED'} - def draw(self, context): global tree_level, current_module, module_type, return_report api_update(context) - ###### layout ###### layout = self.layout - layout.label(text="Tree Structure:") - col = layout.column(align=True) + col = layout.column(align=True) col.prop(bpy.context.window_manager.api_nav_props, 'path', text='') - row = col.row() + + row = col.row(align=True) row.operator("api_navigator.parent", text="Parent", icon="BACK") row.operator("api_navigator.back_to_bpy", text='', emboss=True, icon="FILE_PARENT") col = layout.column() row = col.row(align=True) - row.prop(bpy.context.window_manager.api_nav_props, 'filter') - row.operator('api_navigator.clear_filter', text='', icon='PANEL_CLOSE') + row.prop(bpy.context.window_manager.api_nav_props, "filter", text="Filter") + row.operator("api_navigator.clear_filter", text="", icon="PANEL_CLOSE") col = layout.column() @@ -645,17 +633,50 @@ class OBJECT_PT_api_navigator(ApiNavigator, bpy.types.Panel): self.list_draw(0, pages, "DOTSDOWN", label="Items") self.list_draw(1, pages, "DOTSDOWN", label="Item Values") self.list_draw(2, pages, "PACKAGE", label="Modules", emboss=True) - self.list_draw(3, pages, "WORDWRAP_ON", label="Types", emboss=False) - self.list_draw(4, pages, "BUTS", label="Properties", emboss=False) + self.list_draw(3, pages, "WORDWRAP_ON", label="Types", emboss=True) + self.list_draw(4, pages, "BUTS", label="Properties", emboss=True) self.list_draw(5, pages, "OOPS", label="Structs and Functions") self.list_draw(6, pages, "SCRIPTWIN", label="Methods and Functions") self.list_draw(7, pages, "INFO", label="Attributes") self.list_draw(8, pages, "ERROR", label="Inaccessible") -########### Menu functions ############### - - +# ###### Properties ####### +class ApiNavProps(PropertyGroup): + """ + Fake module like class. + + bpy.context.window_manager.api_nav_props + """ + path = StringProperty( + name="path", + description="Enter bpy.ops.api_navigator to see the documentation", + default="bpy" + ) + old_path = StringProperty( + name="old_path", + default="" + ) + filter = StringProperty( + name="filter", + description="Filter the resulting modules", + default="" + ) + reduce_to = IntProperty( + name="Reduce to", + description="Display a maximum number of x entries by pages", + default=10, + min=1 + ) + pages = IntProperty( + name="Pages", + description="Display a Page", + default=0, + min=0 + ) + + +# ######## Register ######### def register_keymaps(): kc = bpy.context.window_manager.keyconfigs.addon if kc: @@ -672,34 +693,13 @@ def unregister_keymaps(): def register(): - from bpy.props import StringProperty, IntProperty, PointerProperty - - class ApiNavProps(bpy.types.PropertyGroup): - """ - Fake module like class. - - bpy.context.window_manager.api_nav_props - - """ - path = StringProperty(name='path', - description='Enter bpy.ops.api_navigator to see the documentation', - default='bpy') - old_path = StringProperty(name='old_path', default='') - filter = StringProperty(name='filter', - description='Filter the resulting modules', default='') - reduce_to = IntProperty(name='Reduce to ', - description='Display a maximum number of x entries by pages', - default=10, min=1) - pages = IntProperty(name='Pages', - description='Display a Page', default=0, min=0) - bpy.utils.register_module(__name__) - bpy.types.WindowManager.api_nav_props = PointerProperty( - type=ApiNavProps, name='API Nav Props', description='') - + type=ApiNavProps, + name="API Nav Props", + description="" + ) register_keymaps() - #print(get_tree_level()) def unregister(): -- cgit v1.2.3