1 # SPDX-FileCopyrightText: 2020-2022 Blender Foundation
3 # SPDX-License-Identifier: GPL-2.0-or-later
8 "name": "UI Animation Render",
10 "description": "Render animations of the Blender UI.",
11 "blender": (2, 80, 0),
13 "location": "View3D > Sidebar > View Tab and Ctrl+Shift+F12",
21 def draw_ui(prefs
, layout
):
22 layout
.prop(prefs
, "delay")
24 col
= layout
.column(align
=True)
25 col
.label(text
="Animation Highlight:")
28 row
.prop(prefs
, "anim_highlight", expand
=True)
30 if prefs
.anim_highlight
== "replace":
31 split
= col
.split(factor
=0.2)
32 split
.label(text
="Color")
33 row
= split
.row(align
=True)
34 row
.prop(prefs
, "highlight_color", text
="")
35 row
.prop(prefs
, "highlight_blend", text
="Blend")
38 class UIAnimationRenderPreferences(bpy
.types
.AddonPreferences
):
41 delay
: bpy
.props
.FloatProperty(
43 description
="How much time to wait (seconds) before capturing each frame, to allow the viewport to clean up",
47 anim_highlight
: bpy
.props
.EnumProperty(
48 name
="Animation Highlight",
49 description
="What to do with the animated field highlight color",
50 items
=[("keep", "Keep", "Keep the animated field highlight", 0),
51 ("hide", "Hide", "Hide the animated field highlight", 1),
52 ("replace", "Replace", "Replace the animated field highlight", 2)],
56 highlight_color
: bpy
.props
.FloatVectorProperty(
57 name
="Highlight Color",
58 description
="Color to use for animated field highlights",
60 default
=(1.0, 1.0, 1.0)
63 highlight_blend
: bpy
.props
.FloatProperty(
64 name
="Highlight Blend",
65 description
="How much the highlight color influences the field color",
69 def draw(self
, context
):
70 draw_ui(self
, self
.layout
)
73 class RenderScreen(bpy
.types
.Operator
):
74 bl_idname
= "render.render_screen"
75 bl_label
= "Render Screen"
76 bl_description
= "Capture the screen for each animation frame and write to the render output path"
81 _theme_key
= (0, 0, 0)
82 _theme_key_sel
= (0, 0, 0)
83 _theme_anim
= (0, 0, 0)
84 _theme_anim_sel
= (0, 0, 0)
85 _theme_driven
= (0, 0, 0)
86 _theme_driven_sel
= (0, 0, 0)
88 def modal(self
, context
, event
):
89 if event
.type in {'RIGHTMOUSE', 'ESC'}:
93 if event
.type == 'TIMER':
95 f_curr
= scene
.frame_current
97 bpy
.ops
.screen
.screenshot(filepath
=context
.scene
.render
.frame_path(frame
=f_curr
))
99 if f_curr
< scene
.frame_end
:
100 scene
.frame_set(f_curr
+ 1)
105 return {'RUNNING_MODAL'}
107 def execute(self
, context
):
108 # Adjust animation highlight (theme)
109 prefs
= context
.preferences
110 addon_prefs
= prefs
.addons
[__name__
].preferences
111 theme
= prefs
.themes
[0].user_interface
.wcol_state
113 if addon_prefs
.anim_highlight
== "hide":
114 self
._theme
_blend
= theme
.blend
116 elif addon_prefs
.anim_highlight
== "replace":
117 self
._theme
_blend
= theme
.blend
118 self
._theme
_key
= theme
.inner_key
.copy()
119 self
._theme
_key
_sel
= theme
.inner_key_sel
.copy()
120 self
._theme
_anim
= theme
.inner_anim
.copy()
121 self
._theme
_anim
_sel
= theme
.inner_anim_sel
.copy()
122 self
._theme
_driven
= theme
.inner_driven
.copy()
123 self
._theme
_driven
_sel
= theme
.inner_driven_sel
.copy()
125 theme
.blend
= addon_prefs
.highlight_blend
126 theme
.inner_key
= addon_prefs
.highlight_color
127 theme
.inner_key_sel
= addon_prefs
.highlight_color
128 theme
.inner_anim
= addon_prefs
.highlight_color
129 theme
.inner_anim_sel
= addon_prefs
.highlight_color
130 theme
.inner_driven
= addon_prefs
.highlight_color
131 theme
.inner_driven_sel
= addon_prefs
.highlight_color
134 scene
= context
.scene
135 self
._f
_initial
= scene
.frame_current
136 scene
.frame_set(scene
.frame_start
)
139 wm
= context
.window_manager
140 self
._timer
= wm
.event_timer_add(addon_prefs
.delay
, window
=context
.window
)
141 wm
.modal_handler_add(self
)
142 return {'RUNNING_MODAL'}
144 def stop(self
, context
):
146 wm
= context
.window_manager
147 wm
.event_timer_remove(self
._timer
)
150 context
.scene
.frame_set(self
._f
_initial
)
153 prefs
= context
.preferences
154 addon_prefs
= prefs
.addons
[__name__
].preferences
155 theme
= prefs
.themes
[0].user_interface
.wcol_state
157 if addon_prefs
.anim_highlight
== "hide":
158 theme
.blend
= self
._theme
_blend
159 elif addon_prefs
.anim_highlight
== "replace":
160 theme
.blend
= self
._theme
_blend
161 theme
.inner_key
= self
._theme
_key
162 theme
.inner_key_sel
= self
._theme
_key
_sel
163 theme
.inner_anim
= self
._theme
_anim
164 theme
.inner_anim_sel
= self
._theme
_anim
_sel
165 theme
.inner_driven
= self
._theme
_driven
166 theme
.inner_driven_sel
= self
._theme
_driven
_sel
169 class VIEW3D_PT_ui_animation_render(bpy
.types
.Panel
):
170 bl_space_type
= 'VIEW_3D'
171 bl_region_type
= 'UI'
173 bl_label
= "UI Animation Render"
174 bl_options
= {'DEFAULT_CLOSED'}
176 def draw(self
, context
):
178 layout
.use_property_split
= False
180 prefs
= context
.preferences
181 addon_prefs
= prefs
.addons
[__name__
].preferences
183 layout
.operator(RenderScreen
.bl_idname
)
184 draw_ui(addon_prefs
, layout
)
190 bpy
.utils
.register_class(UIAnimationRenderPreferences
)
191 bpy
.utils
.register_class(RenderScreen
)
192 bpy
.utils
.register_class(VIEW3D_PT_ui_animation_render
)
194 wm
= bpy
.context
.window_manager
196 if wm
.keyconfigs
.addon
:
197 km
= wm
.keyconfigs
.addon
.keymaps
.new(name
='Screen', space_type
='EMPTY')
198 km
.keymap_items
.new('render.render_screen', 'F12', 'PRESS', shift
=True, ctrl
=True)
204 bpy
.utils
.unregister_class(UIAnimationRenderPreferences
)
205 bpy
.utils
.unregister_class(RenderScreen
)
206 bpy
.utils
.unregister_class(VIEW3D_PT_ui_animation_render
)
209 wm
= bpy
.context
.window_manager
210 wm
.keyconfigs
.addon
.keymaps
.remove(km
)