forked from bartvdbraak/blender
cb8f7fd385
Auto save is now working again in 2.5. It will also remember now what the location of the original file was when recovering it, so that library links still work and saving the restored file does not save to the temp directory. There is also a new Recover Auto Save operator which will open the filebrowser in the temp directory and show the auto saved .blends. Implemenation Notes: * Timer storage was moved from window to windowmanager, so we can have windowmanager level timers too now, doesn't make sense to have autosave timer attached to a particular window. * FileGlobal now has a filename field storing where the file was saved. Note that this is only used when loading a file through the recover operators, regular file read doesn't use it, so copying the quit.blend manually over the original file will still work as expected. * Jobs timer no longer uses operator now, this seems more like an internal thing, changing keymaps should not make it possible to break the jobs manager. * Autosave is postponed by 10 seconds when a modal operator is running, e.g. transform or file browsing. * Moved setting G.sce in setup_app_data before depsgraph updates, these can use the filename for pointcaches.
322 lines
9.7 KiB
Python
322 lines
9.7 KiB
Python
|
|
import bpy
|
|
|
|
import dynamic_menu
|
|
# reload(dynamic_menu)
|
|
|
|
class INFO_HT_header(bpy.types.Header):
|
|
__space_type__ = 'INFO'
|
|
|
|
def draw(self, context):
|
|
layout = self.layout
|
|
|
|
st = context.space_data
|
|
scene = context.scene
|
|
rd = scene.render_data
|
|
|
|
row = layout.row(align=True)
|
|
row.template_header()
|
|
|
|
if context.area.show_menus:
|
|
sub = row.row(align=True)
|
|
sub.itemM("INFO_MT_file")
|
|
sub.itemM("INFO_MT_add")
|
|
if rd.use_game_engine:
|
|
sub.itemM("INFO_MT_game")
|
|
else:
|
|
sub.itemM("INFO_MT_render")
|
|
sub.itemM("INFO_MT_help")
|
|
|
|
layout.template_ID(context.window, "screen", new="screen.new", unlink="screen.delete")
|
|
layout.template_ID(context.screen, "scene", new="scene.new", unlink="scene.delete")
|
|
|
|
if rd.multiple_engines:
|
|
layout.itemR(rd, "engine", text="")
|
|
|
|
layout.itemS()
|
|
|
|
layout.template_operator_search()
|
|
layout.template_running_jobs()
|
|
|
|
layout.itemL(text=scene.statistics())
|
|
|
|
layout.itemO("wm.window_fullscreen_toggle", icon='ICON_ARROW_LEFTRIGHT', text="")
|
|
|
|
class INFO_MT_file(bpy.types.Menu):
|
|
__label__ = "File"
|
|
|
|
def draw(self, context):
|
|
layout = self.layout
|
|
|
|
layout.operator_context = "EXEC_AREA"
|
|
layout.itemO("wm.read_homefile", text="New", icon='ICON_NEW')
|
|
layout.operator_context = "INVOKE_AREA"
|
|
layout.itemO("wm.open_mainfile", text="Open...", icon='ICON_FILE_FOLDER')
|
|
layout.item_menu_enumO("wm.open_recentfile", "file", text="Open Recent")
|
|
layout.itemO("wm.recover_last_session")
|
|
layout.itemO("wm.recover_auto_save", text="Recover Auto Save...")
|
|
|
|
layout.itemS()
|
|
|
|
layout.operator_context = "EXEC_AREA"
|
|
layout.itemO("wm.save_mainfile", text="Save", icon='ICON_FILE_TICK')
|
|
layout.operator_context = "INVOKE_AREA"
|
|
layout.itemO("wm.save_as_mainfile", text="Save As...")
|
|
layout.itemO("screen.userpref_show", text="User Preferences...", icon='ICON_PREFERENCES')
|
|
|
|
layout.itemS()
|
|
layout.operator_context = "INVOKE_AREA"
|
|
layout.itemO("wm.link_append", text="Link")
|
|
layout.item_booleanO("wm.link_append", "link", False, text="Append")
|
|
layout.itemS()
|
|
|
|
layout.itemM("INFO_MT_file_import")
|
|
layout.itemM("INFO_MT_file_export")
|
|
|
|
layout.itemS()
|
|
|
|
layout.itemM("INFO_MT_file_external_data")
|
|
|
|
layout.itemS()
|
|
|
|
layout.operator_context = "EXEC_AREA"
|
|
layout.itemO("wm.exit_blender", text="Quit", icon='ICON_QUIT')
|
|
|
|
|
|
# test for expanding menus
|
|
'''
|
|
class INFO_MT_file_more(INFO_MT_file):
|
|
__label__ = "File"
|
|
|
|
def draw(self, context):
|
|
layout = self.layout
|
|
|
|
layout.itemO("wm.read_homefile", text="TESTING ")
|
|
|
|
dynamic_menu.setup(INFO_MT_file_more)
|
|
'''
|
|
|
|
class INFO_MT_file_import(dynamic_menu.DynMenu):
|
|
__label__ = "Import"
|
|
|
|
def draw(self, context):
|
|
pass # dynamic menu
|
|
|
|
class INFO_MT_file_export(dynamic_menu.DynMenu):
|
|
__label__ = "Export"
|
|
|
|
def draw(self, context):
|
|
pass # dynamic menu
|
|
|
|
class INFO_MT_file_external_data(bpy.types.Menu):
|
|
__label__ = "External Data"
|
|
|
|
def draw(self, context):
|
|
layout = self.layout
|
|
|
|
layout.itemO("file.pack_all", text="Pack into .blend file")
|
|
layout.itemO("file.unpack_all", text="Unpack into Files...")
|
|
|
|
layout.itemS()
|
|
|
|
layout.itemO("file.make_paths_relative")
|
|
layout.itemO("file.make_paths_absolute")
|
|
layout.itemO("file.report_missing_files")
|
|
layout.itemO("file.find_missing_files")
|
|
|
|
|
|
class INFO_MT_mesh_add(dynamic_menu.DynMenu):
|
|
__label__ = "Mesh"
|
|
def draw(self, context):
|
|
layout = self.layout
|
|
layout.operator_context = 'INVOKE_REGION_WIN'
|
|
layout.itemO("mesh.primitive_plane_add", icon='ICON_MESH_PLANE', text="Plane")
|
|
layout.itemO("mesh.primitive_cube_add", icon='ICON_MESH_CUBE', text="Cube")
|
|
layout.itemO("mesh.primitive_circle_add", icon='ICON_MESH_CIRCLE', text="Circle")
|
|
layout.itemO("mesh.primitive_uv_sphere_add", icon='ICON_MESH_UVSPHERE', text="UV Sphere")
|
|
layout.itemO("mesh.primitive_ico_sphere_add", icon='ICON_MESH_ICOSPHERE', text="Icosphere")
|
|
layout.itemO("mesh.primitive_tube_add", icon='ICON_MESH_TUBE', text="Tube")
|
|
layout.itemO("mesh.primitive_cone_add", icon='ICON_MESH_CONE', text="Cone")
|
|
layout.itemS()
|
|
layout.itemO("mesh.primitive_grid_add", icon='ICON_MESH_GRID', text="Grid")
|
|
layout.itemO("mesh.primitive_monkey_add", icon='ICON_MESH_MONKEY', text="Monkey")
|
|
|
|
class INFO_MT_add(bpy.types.Menu):
|
|
__label__ = "Add"
|
|
|
|
def draw(self, context):
|
|
layout = self.layout
|
|
|
|
layout.operator_context = "EXEC_SCREEN"
|
|
|
|
# layout.item_menu_enumO("object.mesh_add", "type", text="Mesh", icon='ICON_OUTLINER_OB_MESH')
|
|
layout.itemM("INFO_MT_mesh_add", icon='ICON_OUTLINER_OB_MESH')
|
|
|
|
layout.item_menu_enumO("object.curve_add", "type", text="Curve", icon='ICON_OUTLINER_OB_CURVE')
|
|
layout.item_menu_enumO("object.surface_add", "type", text="Surface", icon='ICON_OUTLINER_OB_SURFACE')
|
|
layout.item_menu_enumO("object.metaball_add", "type", 'META', text="Metaball", icon='ICON_OUTLINER_OB_META')
|
|
layout.itemO("object.text_add", text="Text", icon='ICON_OUTLINER_OB_FONT')
|
|
|
|
layout.itemS()
|
|
|
|
layout.itemO("object.armature_add", text="Armature", icon='ICON_OUTLINER_OB_ARMATURE')
|
|
layout.item_enumO("object.add", "type", 'LATTICE', icon='ICON_OUTLINER_OB_LATTICE')
|
|
layout.item_enumO("object.add", "type", 'EMPTY', icon='ICON_OUTLINER_OB_EMPTY')
|
|
|
|
layout.itemS()
|
|
|
|
layout.item_enumO("object.add", "type", 'CAMERA', icon='ICON_OUTLINER_OB_CAMERA')
|
|
layout.item_menu_enumO("object.lamp_add", "type", 'LAMP', text="Lamp", icon='ICON_OUTLINER_OB_LAMP')
|
|
|
|
layout.itemS()
|
|
|
|
layout.item_menu_enumO("object.effector_add", "type", 'EMPTY', text="Force Field", icon='ICON_OUTLINER_OB_EMPTY')
|
|
|
|
layout.itemS()
|
|
|
|
layout.item_menu_enumO("object.group_instance_add", "type", text="Group Instance", icon='ICON_OUTLINER_OB_EMPTY')
|
|
|
|
class INFO_MT_game(bpy.types.Menu):
|
|
__label__ = "Game"
|
|
|
|
def draw(self, context):
|
|
layout = self.layout
|
|
|
|
gs = context.scene.game_data
|
|
|
|
layout.itemO("view3d.game_start")
|
|
|
|
layout.itemS()
|
|
|
|
layout.itemR(gs, "show_debug_properties")
|
|
layout.itemR(gs, "show_framerate_profile")
|
|
layout.itemR(gs, "show_physics_visualization")
|
|
layout.itemR(gs, "deprecation_warnings")
|
|
|
|
class INFO_MT_render(bpy.types.Menu):
|
|
__label__ = "Render"
|
|
|
|
def draw(self, context):
|
|
layout = self.layout
|
|
|
|
rd = context.scene.render_data
|
|
|
|
layout.itemO("screen.render", text="Render Image", icon='ICON_RENDER_STILL')
|
|
layout.item_booleanO("screen.render", "animation", True, text="Render Animation", icon='ICON_RENDER_ANIMATION')
|
|
|
|
layout.itemS()
|
|
|
|
layout.itemO("screen.render_view_show")
|
|
|
|
class INFO_MT_help(bpy.types.Menu):
|
|
__label__ = "Help"
|
|
|
|
def draw(self, context):
|
|
layout = self.layout
|
|
|
|
layout.itemO("help.manual", icon='ICON_HELP')
|
|
layout.itemO("help.release_logs", icon='ICON_URL')
|
|
|
|
layout.itemS()
|
|
|
|
layout.itemO("help.blender_website", icon='ICON_URL')
|
|
layout.itemO("help.blender_eshop", icon='ICON_URL')
|
|
layout.itemO("help.developer_community", icon='ICON_URL')
|
|
layout.itemO("help.user_community", icon='ICON_URL')
|
|
layout.itemS()
|
|
layout.itemO("help.operator_cheat_sheet")
|
|
|
|
bpy.types.register(INFO_HT_header)
|
|
bpy.types.register(INFO_MT_file)
|
|
bpy.types.register(INFO_MT_file_import)
|
|
bpy.types.register(INFO_MT_file_export)
|
|
bpy.types.register(INFO_MT_file_external_data)
|
|
bpy.types.register(INFO_MT_add)
|
|
bpy.types.register(INFO_MT_mesh_add)
|
|
bpy.types.register(INFO_MT_game)
|
|
bpy.types.register(INFO_MT_render)
|
|
bpy.types.register(INFO_MT_help)
|
|
|
|
# Help operators
|
|
|
|
class HelpOperator(bpy.types.Operator):
|
|
def execute(self, context):
|
|
try: import webbrowser
|
|
except: webbrowser = None
|
|
|
|
if webbrowser:
|
|
webbrowser.open(self.__URL__)
|
|
else:
|
|
raise Exception("Operator requires a full Python installation")
|
|
|
|
return ('FINISHED',)
|
|
|
|
class HELP_OT_manual(HelpOperator):
|
|
'''The Blender Wiki manual'''
|
|
__idname__ = "help.manual"
|
|
__label__ = "Manual"
|
|
__URL__ = 'http://wiki.blender.org/index.php/Manual'
|
|
|
|
class HELP_OT_release_logs(HelpOperator):
|
|
'''Information about the changes in this version of Blender'''
|
|
__idname__ = "help.release_logs"
|
|
__label__ = "Release Logs"
|
|
__URL__ = 'http://www.blender.org/development/release-logs/'
|
|
|
|
class HELP_OT_blender_website(HelpOperator):
|
|
'''The official Blender website'''
|
|
__idname__ = "help.blender_website"
|
|
__label__ = "Blender Website"
|
|
__URL__ = 'http://www.blender.org/'
|
|
|
|
class HELP_OT_blender_eshop(HelpOperator):
|
|
'''Buy official Blender resources and merchandise online'''
|
|
__idname__ = "help.blender_eshop"
|
|
__label__ = "Blender e-Shop"
|
|
__URL__ = 'http://www.blender3d.org/e-shop'
|
|
|
|
class HELP_OT_developer_community(HelpOperator):
|
|
'''Get involved with Blender development'''
|
|
__idname__ = "help.developer_community"
|
|
__label__ = "Developer Community"
|
|
__URL__ = 'http://www.blender.org/community/get-involved/'
|
|
|
|
class HELP_OT_user_community(HelpOperator):
|
|
'''Get involved with other Blender users'''
|
|
__idname__ = "help.user_community"
|
|
__label__ = "User Community"
|
|
__URL__ = 'http://www.blender.org/community/user-community/'
|
|
|
|
class HELP_OT_operator_cheat_sheet(bpy.types.Operator):
|
|
__idname__ = "help.operator_cheat_sheet"
|
|
__label__ = "Operator Cheat Sheet (new textblock)"
|
|
def execute(self, context):
|
|
op_strings = []
|
|
tot = 0
|
|
for op_module_name in dir(bpy.ops):
|
|
op_module = getattr(bpy.ops, op_module_name)
|
|
for op_submodule_name in dir(op_module):
|
|
op = getattr(op_module, op_submodule_name)
|
|
text = repr(op)
|
|
if text.startswith('bpy.ops.'):
|
|
op_strings.append(text)
|
|
tot += 1
|
|
|
|
op_strings.append('')
|
|
|
|
bpy.ops.text.new() # XXX - assumes new text is always at the end!
|
|
textblock = bpy.data.texts[-1]
|
|
textblock.write('# %d Operators\n\n' % tot)
|
|
textblock.write('\n'.join(op_strings))
|
|
textblock.name = "OperatorList.txt"
|
|
print("See OperatorList.txt textblock")
|
|
return ('FINISHED',)
|
|
|
|
bpy.ops.add(HELP_OT_manual)
|
|
bpy.ops.add(HELP_OT_release_logs)
|
|
bpy.ops.add(HELP_OT_blender_website)
|
|
bpy.ops.add(HELP_OT_blender_eshop)
|
|
bpy.ops.add(HELP_OT_developer_community)
|
|
bpy.ops.add(HELP_OT_user_community)
|
|
bpy.ops.add(HELP_OT_operator_cheat_sheet)
|