UI: layout support for fixed size buttons, and use for file browser open/cancel
[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 from bpy.types import Header, Menu, Panel
22 from bpy.app.translations import contexts as i18n_contexts
23 from bl_ui.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         layout.template_header()
38
39         NLA_MT_editor_menus.draw_collapsible(context, layout)
40
41         layout.separator_spacer()
42
43         dopesheet_filter(layout, context)
44
45         layout.popover(
46             panel="NLA_PT_filters",
47             text="",
48             icon='FILTER',
49         )
50
51         layout.prop(st, "auto_snap", text="")
52
53
54 class NLA_PT_filters(DopesheetFilterPopoverBase, Panel):
55     bl_space_type = 'NLA_EDITOR'
56     bl_region_type = 'HEADER'
57     bl_label = "Filters"
58
59     def draw(self, context):
60         layout = self.layout
61
62         DopesheetFilterPopoverBase.draw_generic_filters(context, layout)
63         layout.separator()
64         DopesheetFilterPopoverBase.draw_search_filters(context, layout)
65         layout.separator()
66         DopesheetFilterPopoverBase.draw_standard_filters(context, layout)
67
68
69 class NLA_MT_editor_menus(Menu):
70     bl_idname = "NLA_MT_editor_menus"
71     bl_label = ""
72
73     def draw(self, _context):
74         layout = self.layout
75         layout.menu("NLA_MT_view")
76         layout.menu("NLA_MT_select")
77         layout.menu("NLA_MT_marker")
78         layout.menu("NLA_MT_edit")
79         layout.menu("NLA_MT_add")
80
81
82 class NLA_MT_view(Menu):
83     bl_label = "View"
84
85     def draw(self, context):
86         layout = self.layout
87
88         st = context.space_data
89
90         layout.prop(st, "show_region_ui")
91         layout.separator()
92
93         layout.prop(st, "use_realtime_update")
94
95         layout.prop(st, "show_seconds")
96         layout.prop(st, "show_locked_time")
97
98         layout.prop(st, "show_strip_curves")
99         layout.prop(st, "show_local_markers")
100         layout.prop(st, "show_marker_lines")
101
102         layout.separator()
103         layout.operator("anim.previewrange_set")
104         layout.operator("anim.previewrange_clear")
105         layout.operator("nla.previewrange_set")
106
107         layout.separator()
108         layout.operator("nla.view_all")
109         layout.operator("nla.view_selected")
110         layout.operator("nla.view_frame")
111
112         layout.separator()
113         layout.menu("INFO_MT_area")
114
115
116 class NLA_MT_select(Menu):
117     bl_label = "Select"
118
119     def draw(self, _context):
120         layout = self.layout
121
122         layout.operator("nla.select_all", text="All").action = 'SELECT'
123         layout.operator("nla.select_all", text="None").action = 'DESELECT'
124         layout.operator("nla.select_all", text="Invert").action = 'INVERT'
125
126         layout.separator()
127         layout.operator("nla.select_box").axis_range = False
128         layout.operator("nla.select_box", text="Box Select (Axis Range)").axis_range = True
129
130         layout.separator()
131         props = layout.operator("nla.select_leftright", text="Before Current Frame")
132         props.extend = False
133         props.mode = 'LEFT'
134         props = layout.operator("nla.select_leftright", text="After Current Frame")
135         props.extend = False
136         props.mode = 'RIGHT'
137
138
139 class NLA_MT_marker(Menu):
140     bl_label = "Marker"
141
142     def draw(self, context):
143         layout = self.layout
144
145         from bl_ui.space_time import marker_menu_generic
146         marker_menu_generic(layout, context)
147
148
149 class NLA_MT_edit(Menu):
150     bl_label = "Edit"
151
152     def draw(self, context):
153         layout = self.layout
154
155         scene = context.scene
156
157         layout.menu("NLA_MT_edit_transform", text="Transform")
158
159         layout.operator_menu_enum("nla.snap", "type", text="Snap")
160
161         layout.separator()
162         layout.operator("nla.duplicate", text="Duplicate").linked = False
163         layout.operator("nla.duplicate", text="Linked Duplicate").linked = True
164         layout.operator("nla.split")
165         layout.operator("nla.delete")
166
167         layout.separator()
168         layout.operator("nla.mute_toggle")
169
170         layout.separator()
171         layout.operator("nla.apply_scale")
172         layout.operator("nla.clear_scale")
173         layout.operator("nla.action_sync_length").active = False
174
175         layout.separator()
176         layout.operator("nla.make_single_user")
177
178         layout.separator()
179         layout.operator("nla.swap")
180         layout.operator("nla.move_up")
181         layout.operator("nla.move_down")
182
183         # TODO: this really belongs more in a "channel" (or better, "track") menu
184         layout.separator()
185         layout.operator_menu_enum("anim.channels_move", "direction", text="Track Ordering...")
186         layout.operator("anim.channels_clean_empty")
187
188         layout.separator()
189         # TODO: names of these tools for 'tweak-mode' need changing?
190         if scene.is_nla_tweakmode:
191             layout.operator("nla.tweakmode_exit", text="Stop Editing Stashed Action").isolate_action = True
192             layout.operator("nla.tweakmode_exit", text="Stop Tweaking Strip Actions")
193         else:
194             layout.operator("nla.tweakmode_enter", text="Start Editing Stashed Action").isolate_action = True
195             layout.operator("nla.tweakmode_enter", text="Start Tweaking Strip Actions")
196
197
198 class NLA_MT_add(Menu):
199     bl_label = "Add"
200     bl_translation_context = i18n_contexts.operator_default
201
202     def draw(self, _context):
203         layout = self.layout
204
205         layout.operator("nla.actionclip_add")
206         layout.operator("nla.transition_add")
207         layout.operator("nla.soundclip_add")
208
209         layout.separator()
210         layout.operator("nla.meta_add")
211         layout.operator("nla.meta_remove")
212
213         layout.separator()
214         layout.operator("nla.tracks_add").above_selected = False
215         layout.operator("nla.tracks_add", text="Add Tracks Above Selected").above_selected = True
216
217         layout.separator()
218         layout.operator("nla.selected_objects_add")
219
220
221 class NLA_MT_edit_transform(Menu):
222     bl_label = "Transform"
223
224     def draw(self, _context):
225         layout = self.layout
226
227         layout.operator("transform.translate", text="Move")
228         layout.operator("transform.transform", text="Extend").mode = 'TIME_EXTEND'
229         layout.operator("transform.transform", text="Scale").mode = 'TIME_SCALE'
230
231
232 class NLA_MT_snap_pie(Menu):
233     bl_label = "Snap"
234
235     def draw(self, _context):
236         layout = self.layout
237         pie = layout.menu_pie()
238
239         pie.operator("nla.snap", text="Current Frame").type = 'CFRA'
240         pie.operator("nla.snap", text="Nearest Frame").type = 'NEAREST_FRAME'
241         pie.operator("nla.snap", text="Nearest Second").type = 'NEAREST_SECOND'
242         pie.operator("nla.snap", text="Nearest Marker").type = 'NEAREST_MARKER'
243
244
245 class NLA_MT_context_menu(Menu):
246     bl_label = "NLA Context Menu"
247
248     def draw(self, context):
249         layout = self.layout
250         scene = context.scene
251
252         if scene.is_nla_tweakmode:
253             layout.operator("nla.tweakmode_exit", text="Stop Editing Stashed Action").isolate_action = True
254             layout.operator("nla.tweakmode_exit", text="Stop Tweaking Strip Actions")
255         else:
256             layout.operator("nla.tweakmode_enter", text="Start Editing Stashed Action").isolate_action = True
257             layout.operator("nla.tweakmode_enter", text="Start Tweaking Strip Actions")
258
259         layout.separator()
260
261         layout.operator("nla.duplicate", text="Duplicate").linked = False
262         layout.operator("nla.duplicate", text="Linked Duplicate").linked = True
263
264         layout.separator()
265
266         layout.operator("nla.split")
267         layout.operator("nla.delete")
268
269         layout.separator()
270
271         layout.operator("nla.swap")
272
273         layout.separator()
274
275         layout.operator_menu_enum("nla.snap", "type", text="Snap")
276
277
278 class NLA_MT_channel_context_menu(Menu):
279     bl_label = "NLA Channel Context Menu"
280
281     def draw(self, _context):
282         layout = self.layout
283
284         layout.operator_menu_enum("anim.channels_move", "direction", text="Track Ordering...")
285         layout.operator("anim.channels_clean_empty")
286
287
288 classes = (
289     NLA_HT_header,
290     NLA_MT_edit,
291     NLA_MT_editor_menus,
292     NLA_MT_view,
293     NLA_MT_select,
294     NLA_MT_marker,
295     NLA_MT_add,
296     NLA_MT_edit_transform,
297     NLA_MT_snap_pie,
298     NLA_MT_context_menu,
299     NLA_MT_channel_context_menu,
300     NLA_PT_filters,
301 )
302
303 if __name__ == "__main__":  # only for live edit.
304     from bpy.utils import register_class
305     for cls in classes:
306         register_class(cls)