13f07c0a69c4e4fb2869302f0a9ad878307a40c4
[blender.git] / release / scripts / startup / bl_ui / space_nla.py
1 # ##### BEGIN GPL LICENSE BLOCK #####
2 #
3 #  This program is free software; you can redistribute it and/or
4 #  modify it under the terms of the GNU General Public License
5 #  as published by the Free Software Foundation; either version 2
6 #  of the License, or (at your option) any later version.
7 #
8 #  This program is distributed in the hope that it will be useful,
9 #  but WITHOUT ANY WARRANTY; without even the implied warranty of
10 #  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11 #  GNU General Public License for more details.
12 #
13 #  You should have received a copy of the GNU General Public License
14 #  along with this program; if not, write to the Free Software Foundation,
15 #  Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
16 #
17 # ##### END GPL LICENSE BLOCK #####
18
19 # <pep8 compliant>
20
21 import bpy
22 from bpy.types import Header, Menu, Panel
23 from .space_dopesheet import (
24     DopesheetFilterPopoverBase,
25     dopesheet_filter,
26 )
27
28
29 class NLA_HT_header(Header):
30     bl_space_type = 'NLA_EDITOR'
31
32     def draw(self, context):
33         layout = self.layout
34
35         st = context.space_data
36
37         row = layout.row(align=True)
38         row.template_header()
39
40         NLA_MT_editor_menus.draw_collapsible(context, layout)
41
42         layout.separator_spacer()
43
44         dopesheet_filter(layout, context)
45
46         layout.popover(
47             panel="NLA_PT_filters",
48             text="",
49             icon='FILTER',
50         )
51
52         layout.prop(st, "auto_snap", text="")
53
54
55 class NLA_PT_filters(DopesheetFilterPopoverBase, Panel):
56     bl_space_type = 'NLA_EDITOR'
57     bl_region_type = 'HEADER'
58     bl_label = "Filters"
59
60     def draw(self, context):
61         layout = self.layout
62
63         DopesheetFilterPopoverBase.draw_generic_filters(context, layout)
64         layout.separator()
65         DopesheetFilterPopoverBase.draw_search_filters(context, layout)
66         layout.separator()
67         DopesheetFilterPopoverBase.draw_standard_filters(context, layout)
68
69
70 class NLA_MT_editor_menus(Menu):
71     bl_idname = "NLA_MT_editor_menus"
72     bl_label = ""
73
74     def draw(self, context):
75         layout = self.layout
76         layout.menu("NLA_MT_view")
77         layout.menu("NLA_MT_select")
78         layout.menu("NLA_MT_marker")
79         layout.menu("NLA_MT_edit")
80         layout.menu("NLA_MT_add")
81
82
83 class NLA_MT_view(Menu):
84     bl_label = "View"
85
86     def draw(self, context):
87         layout = self.layout
88
89         st = context.space_data
90
91         layout.operator("nla.properties", icon='MENU_PANEL')
92
93         layout.separator()
94
95         layout.prop(st, "use_realtime_update")
96         layout.prop(st, "show_frame_indicator")
97
98         layout.prop(st, "show_seconds")
99         layout.prop(st, "show_locked_time")
100
101         layout.prop(st, "show_strip_curves")
102         layout.prop(st, "show_local_markers")
103         layout.prop(st, "show_marker_lines")
104
105         layout.separator()
106         layout.operator("anim.previewrange_set")
107         layout.operator("anim.previewrange_clear")
108         layout.operator("nla.previewrange_set")
109
110         layout.separator()
111         layout.operator("nla.view_all")
112         layout.operator("nla.view_selected")
113         layout.operator("nla.view_frame")
114
115         layout.separator()
116         layout.menu("INFO_MT_area")
117
118
119 class NLA_MT_select(Menu):
120     bl_label = "Select"
121
122     def draw(self, context):
123         layout = self.layout
124
125         layout.operator("nla.select_all", text="All").action = 'SELECT'
126         layout.operator("nla.select_all", text="None").action = 'DESELECT'
127         layout.operator("nla.select_all", text="Invert").action = 'INVERT'
128
129         layout.separator()
130         layout.operator("nla.select_box").axis_range = False
131         layout.operator("nla.select_box", text="Border Axis Range").axis_range = True
132
133         layout.separator()
134         props = layout.operator("nla.select_leftright", text="Before Current Frame")
135         props.extend = False
136         props.mode = 'LEFT'
137         props = layout.operator("nla.select_leftright", text="After Current Frame")
138         props.extend = False
139         props.mode = 'RIGHT'
140
141
142 class NLA_MT_marker(Menu):
143     bl_label = "Marker"
144
145     def draw(self, context):
146         layout = self.layout
147
148         from .space_time import marker_menu_generic
149         marker_menu_generic(layout, context)
150
151
152 class NLA_MT_edit(Menu):
153     bl_label = "Edit"
154
155     def draw(self, context):
156         layout = self.layout
157
158         scene = context.scene
159
160         layout.menu("NLA_MT_edit_transform", text="Transform")
161
162         layout.operator_menu_enum("nla.snap", "type", text="Snap")
163
164         layout.separator()
165         layout.operator("nla.duplicate", text="Duplicate").linked = False
166         layout.operator("nla.duplicate", text="Linked Duplicate").linked = True
167         layout.operator("nla.split")
168         layout.operator("nla.delete")
169
170         layout.separator()
171         layout.operator("nla.mute_toggle")
172
173         layout.separator()
174         layout.operator("nla.apply_scale")
175         layout.operator("nla.clear_scale")
176         layout.operator("nla.action_sync_length").active = False
177
178         layout.separator()
179         layout.operator("nla.make_single_user")
180
181         layout.separator()
182         layout.operator("nla.swap")
183         layout.operator("nla.move_up")
184         layout.operator("nla.move_down")
185
186         # TODO: this really belongs more in a "channel" (or better, "track") menu
187         layout.separator()
188         layout.operator_menu_enum("anim.channels_move", "direction", text="Track Ordering...")
189         layout.operator("anim.channels_clean_empty")
190
191         layout.separator()
192         # TODO: names of these tools for 'tweak-mode' need changing?
193         if scene.is_nla_tweakmode:
194             layout.operator("nla.tweakmode_exit", text="Stop Editing Stashed Action").isolate_action = True
195             layout.operator("nla.tweakmode_exit", text="Stop Tweaking Strip Actions")
196         else:
197             layout.operator("nla.tweakmode_enter", text="Start Editing Stashed Action").isolate_action = True
198             layout.operator("nla.tweakmode_enter", text="Start Tweaking Strip Actions")
199
200
201 class NLA_MT_add(Menu):
202     bl_label = "Add"
203
204     def draw(self, context):
205         layout = self.layout
206
207         layout.operator("nla.actionclip_add")
208         layout.operator("nla.transition_add")
209         layout.operator("nla.soundclip_add")
210
211         layout.separator()
212         layout.operator("nla.meta_add")
213         layout.operator("nla.meta_remove")
214
215         layout.separator()
216         layout.operator("nla.tracks_add").above_selected = False
217         layout.operator("nla.tracks_add", text="Add Tracks Above Selected").above_selected = True
218
219         layout.separator()
220         layout.operator("nla.selected_objects_add")
221
222
223 class NLA_MT_edit_transform(Menu):
224     bl_label = "Transform"
225
226     def draw(self, context):
227         layout = self.layout
228
229         layout.operator("transform.translate", text="Move")
230         layout.operator("transform.transform", text="Extend").mode = 'TIME_EXTEND'
231         layout.operator("transform.transform", text="Scale").mode = 'TIME_SCALE'
232
233
234 class NLA_MT_snap_pie(Menu):
235     bl_label = "Snap"
236
237     def draw(self, context):
238         layout = self.layout
239         pie = layout.menu_pie()
240
241         pie.operator("nla.snap", text="Current Frame").type = 'CFRA'
242         pie.operator("nla.snap", text="Nearest Frame").type = 'NEAREST_FRAME'
243         pie.operator("nla.snap", text="Nearest Second").type = 'NEAREST_SECOND'
244         pie.operator("nla.snap", text="Nearest Marker").type = 'NEAREST_MARKER'
245
246
247 classes = (
248     NLA_HT_header,
249     NLA_MT_edit,
250     NLA_MT_editor_menus,
251     NLA_MT_view,
252     NLA_MT_select,
253     NLA_MT_marker,
254     NLA_MT_add,
255     NLA_MT_edit_transform,
256     NLA_MT_snap_pie,
257     NLA_PT_filters,
258 )
259
260 if __name__ == "__main__":  # only for live edit.
261     from bpy.utils import register_class
262     for cls in classes:
263         register_class(cls)