3 from gi
.repository
import GObject
, Gdk
, Gtk
6 sys
.path
= ["./py"] + sys
.path
9 from gui_tools
import *
13 #import drum_pattern_editor
15 class SceneDialog(SelectObjectDialog
):
16 title
= "Select a scene"
17 def __init__(self
, parent
):
18 SelectObjectDialog
.__init
__(self
, parent
)
19 def update_model(self
, model
):
20 for s
in cbox
.Config
.sections("scene:"):
22 model
.append((s
.name
[6:], "Scene", s
.name
, title
))
23 for s
in cbox
.Config
.sections("instrument:"):
25 model
.append((s
.name
[11:], "Instrument", s
.name
, title
))
26 for s
in cbox
.Config
.sections("layer:"):
28 model
.append((s
.name
[6:], "Layer", s
.name
, title
))
30 class NewLayerDialog(SelectObjectDialog
):
31 title
= "Create a layer"
32 def __init__(self
, parent
):
33 SelectObjectDialog
.__init
__(self
, parent
)
34 def update_model(self
, model
):
35 for engine_name
, wclass
in instr_gui
.instrument_window_map
.items():
36 model
.append((engine_name
, "Engine", engine_name
, ""))
38 class LoadLayerDialog(SelectObjectDialog
):
39 title
= "Load a layer"
40 def __init__(self
, parent
):
41 SelectObjectDialog
.__init
__(self
, parent
)
42 def update_model(self
, model
):
43 for s
in cbox
.Config
.sections("instrument:"):
45 model
.append((s
.name
[11:], "Instrument", s
.name
, title
))
46 for s
in cbox
.Config
.sections("layer:"):
48 model
.append((s
.name
[6:], "Layer", s
.name
, title
))
50 class PlayPatternDialog(SelectObjectDialog
):
51 title
= "Play a drum pattern"
52 def __init__(self
, parent
):
53 SelectObjectDialog
.__init
__(self
, parent
)
54 def update_model(self
, model
):
55 model
.append((None, "Stop", "", ""))
56 for s
in cbox
.Config
.sections("drumpattern:"):
58 model
.append((s
.name
[12:], "Pattern", s
.name
, title
))
59 for s
in cbox
.Config
.sections("drumtrack:"):
61 model
.append((s
.name
[10:], "Track", s
.name
, title
))
63 in_channels_ls
= Gtk
.ListStore(GObject
.TYPE_INT
, GObject
.TYPE_STRING
)
64 in_channels_ls
.append((0, "All"))
65 out_channels_ls
= Gtk
.ListStore(GObject
.TYPE_INT
, GObject
.TYPE_STRING
)
66 out_channels_ls
.append((0, "Same"))
67 for i
in range(1, 17):
68 in_channels_ls
.append((i
, str(i
)))
69 out_channels_ls
.append((i
, str(i
)))
70 notes_ls
= Gtk
.ListStore(GObject
.TYPE_INT
, GObject
.TYPE_STRING
)
71 opt_notes_ls
= Gtk
.ListStore(GObject
.TYPE_INT
, GObject
.TYPE_STRING
)
72 opt_notes_ls
.append((-1, "N/A"))
73 for i
in range(0, 128):
74 notes_ls
.append((i
, note_to_name(i
)))
75 opt_notes_ls
.append((i
, note_to_name(i
)))
76 transpose_ls
= Gtk
.ListStore(GObject
.TYPE_INT
, GObject
.TYPE_STRING
)
77 for i
in range(-60, 61):
78 transpose_ls
.append((i
, str(i
)))
80 class SceneLayersModel(Gtk
.ListStore
):
82 Gtk
.ListStore
.__init
__(self
, GObject
.TYPE_STRING
, GObject
.TYPE_BOOLEAN
,
83 GObject
.TYPE_INT
, GObject
.TYPE_INT
, GObject
.TYPE_BOOLEAN
,
84 GObject
.TYPE_INT
, GObject
.TYPE_INT
, GObject
.TYPE_INT
, GObject
.TYPE_INT
, GObject
.TYPE_STRING
)
85 #def make_row_item(self, opath, tree_path):
86 # return opath % self[(1 + int(tree_path))]
87 def make_row_item(self
, opath
, tree_path
):
88 return cbox
.Document
.uuid_cmd(self
[int(tree_path
)][-1], opath
)
89 def refresh(self
, scene_status
):
91 for layer
in scene_status
.layers
:
93 self
.append((ls
.instrument_name
, ls
.enable
!= 0, ls
.in_channel
, ls
.out_channel
, ls
.consume
!= 0, ls
.low_note
, ls
.high_note
, ls
.fixed_note
, ls
.transpose
, layer
.uuid
))
95 class SceneLayersView(Gtk
.TreeView
):
96 def __init__(self
, model
):
97 Gtk
.TreeView
.__init
__(self
, model
)
98 self
.enable_model_drag_source(Gdk
.ModifierType
.BUTTON1_MASK
, [("text/plain", 0, 1)], Gdk
.DragAction
.MOVE
)
99 self
.enable_model_drag_dest([("text/plain", Gtk
.TargetFlags
.SAME_APP | Gtk
.TargetFlags
.SAME_WIDGET
, 1)], Gdk
.DragAction
.MOVE
)
100 self
.connect('drag_data_get', self
.drag_data_get
)
101 self
.connect('drag_data_received', self
.drag_data_received
)
102 self
.insert_column_with_attributes(0, "On?", standard_toggle_renderer(model
, "/enable", 1), active
=1)
103 self
.insert_column_with_attributes(1, "Name", Gtk
.CellRendererText(), text
=0)
104 self
.insert_column_with_data_func(2, "In Ch#", standard_combo_renderer(model
, in_channels_ls
, "/in_channel", 2), lambda column
, cell
, model
, iter, data
: cell
.set_property('text', "%s" % model
[iter][2] if model
[iter][2] != 0 else 'All'), None)
105 self
.insert_column_with_data_func(3, "Out Ch#", standard_combo_renderer(model
, out_channels_ls
, "/out_channel", 3), lambda column
, cell
, model
, iter, data
: cell
.set_property('text', "%s" % model
[iter][3] if model
[iter][3] != 0 else 'Same'), None)
106 self
.insert_column_with_attributes(4, "Eat?", standard_toggle_renderer(model
, "/consume", 4), active
=4)
107 self
.insert_column_with_data_func(5, "Lo N#", standard_combo_renderer(model
, notes_ls
, "/low_note", 5), lambda column
, cell
, model
, iter, data
: cell
.set_property('text', note_to_name(model
[iter][5])), None)
108 self
.insert_column_with_data_func(6, "Hi N#", standard_combo_renderer(model
, notes_ls
, "/high_note", 6), lambda column
, cell
, model
, iter, data
: cell
.set_property('text', note_to_name(model
[iter][6])), None)
109 self
.insert_column_with_data_func(7, "Fix N#", standard_combo_renderer(model
, opt_notes_ls
, "/fixed_note", 7), lambda column
, cell
, model
, iter, data
: cell
.set_property('text', note_to_name(model
[iter][7])), None)
110 self
.insert_column_with_attributes(8, "Transpose", standard_combo_renderer(model
, transpose_ls
, "/transpose", 8), text
=8)
111 def drag_data_get(self
, treeview
, context
, selection
, target_id
, etime
):
112 cursor
= treeview
.get_cursor()
113 if cursor
is not None:
114 selection
.set('text/plain', 8, str(cursor
[0][0]))
115 def drag_data_received(self
, treeview
, context
, x
, y
, selection
, info
, etime
):
116 src_row
= int(selection
.data
)
117 dest_row_info
= treeview
.get_dest_row_at_pos(x
, y
)
118 if dest_row_info
is not None:
119 dest_row
= dest_row_info
[0][0]
120 #print src_row, dest_row, dest_row_info[1]
121 scene
= cbox
.Document
.get_scene()
122 scene
.move_layer(src_row
, dest_row
)
123 self
.get_model().refresh(scene
.status())
125 class SceneAuxBusesModel(Gtk
.ListStore
):
127 Gtk
.ListStore
.__init
__(self
, GObject
.TYPE_STRING
, GObject
.TYPE_STRING
)
128 def refresh(self
, scene_status
):
130 for aux_name
, aux_obj
in scene_status
.auxes
.items():
131 slot
= aux_obj
.slot
.status()
132 self
.append((slot
.insert_preset
, slot
.insert_engine
))
134 class SceneAuxBusesView(Gtk
.TreeView
):
135 def __init__(self
, model
):
136 Gtk
.TreeView
.__init
__(self
, model
)
137 self
.insert_column_with_attributes(0, "Name", Gtk
.CellRendererText(), text
=0)
138 self
.insert_column_with_attributes(1, "Engine", Gtk
.CellRendererText(), text
=1)
139 def get_current_row(self
):
140 if self
.get_cursor()[0] is None:
142 row
= self
.get_cursor()[0][0]
143 return row
+ 1, self
.get_model()[row
]
145 class StatusBar(Gtk
.Statusbar
):
147 Gtk
.Statusbar
.__init
__(self
)
148 self
.sample_rate_label
= Gtk
.Label("")
149 self
.pack_start(self
.sample_rate_label
, False, False, 2)
150 self
.status
= self
.get_context_id("Status")
151 self
.sample_rate
= self
.get_context_id("Sample rate")
152 self
.push(self
.status
, "")
153 self
.push(self
.sample_rate
, "-")
154 def update(self
, status
, sample_rate
):
155 self
.pop(self
.status
)
156 self
.push(self
.status
, status
)
157 self
.sample_rate_label
.set_text("%s Hz" % sample_rate
)
159 class MainWindow(Gtk
.Window
):
161 Gtk
.Window
.__init
__(self
, Gtk
.WindowType
.TOPLEVEL
)
162 self
.vbox
= Gtk
.VBox(spacing
= 5)
165 set_timer(self
, 30, self
.update
)
166 #self.drum_pattern_editor = None
167 self
.drumkit_editor
= None
170 self
.menu_bar
= Gtk
.MenuBar()
172 self
.menu_bar
.append(create_menu("_Scene", [
173 ("_Load", self
.load_scene
),
174 ("_Quit", self
.quit
),
176 self
.menu_bar
.append(create_menu("_Layer", [
177 ("_New", self
.layer_new
),
178 ("_Load", self
.layer_load
),
179 ("_Remove", self
.layer_remove
),
181 self
.menu_bar
.append(create_menu("_AuxBus", [
182 ("_Add", self
.aux_bus_add
),
183 ("_Edit", self
.aux_bus_edit
),
184 ("_Remove", self
.aux_bus_remove
),
186 self
.menu_bar
.append(create_menu("_Tools", [
187 ("_Drum Kit Editor", self
.tools_drumkit_editor
),
188 ("_Play Drum Pattern", self
.tools_play_drum_pattern
),
189 #("_Edit Drum Pattern", self.tools_drum_pattern_editor),
190 ("_Un-zombify", self
.tools_unzombify
),
191 ("_Object list", self
.tools_object_list
),
192 ("_Wave bank dump", self
.tools_wave_bank_dump
),
195 self
.vbox
.pack_start(self
.menu_bar
, False, False, 0)
196 rt_status
= cbox
.Document
.get_rt().status()
197 scene
= cbox
.Document
.get_scene()
198 self
.nb
= Gtk
.Notebook()
199 self
.vbox
.add(self
.nb
)
200 self
.nb
.append_page(self
.create_master(scene
), Gtk
.Label("Master"))
201 self
.status_bar
= StatusBar()
202 self
.vbox
.pack_start(self
.status_bar
, False, False, 0)
203 self
.create_instrument_pages(scene
.status(), rt_status
)
205 def create_master(self
, scene
):
206 scene_status
= scene
.status()
207 self
.master_info
= left_label("")
208 self
.timesig_info
= left_label("")
211 t
.set_col_spacings(5)
212 t
.set_row_spacings(5)
214 t
.attach(bold_label("Scene"), 0, 1, 0, 1, Gtk
.AttachOptions
.SHRINK | Gtk
.AttachOptions
.FILL
, Gtk
.AttachOptions
.SHRINK
)
215 self
.scene_label
= left_label(scene_status
.name
)
216 t
.attach(self
.scene_label
, 1, 3, 0, 1, Gtk
.AttachOptions
.SHRINK | Gtk
.AttachOptions
.FILL
, Gtk
.AttachOptions
.SHRINK
)
218 self
.title_label
= left_label(scene_status
.title
)
219 t
.attach(bold_label("Title"), 0, 1, 1, 2, Gtk
.AttachOptions
.SHRINK | Gtk
.AttachOptions
.FILL
, Gtk
.AttachOptions
.SHRINK
)
220 t
.attach(self
.title_label
, 1, 3, 1, 2, Gtk
.AttachOptions
.SHRINK | Gtk
.AttachOptions
.FILL
, Gtk
.AttachOptions
.SHRINK
)
222 t
.attach(bold_label("Play pos"), 0, 1, 2, 3, Gtk
.AttachOptions
.SHRINK | Gtk
.AttachOptions
.FILL
, Gtk
.AttachOptions
.SHRINK
)
223 t
.attach(self
.master_info
, 1, 3, 2, 3, Gtk
.AttachOptions
.EXPAND | Gtk
.AttachOptions
.FILL
, Gtk
.AttachOptions
.SHRINK
)
225 t
.attach(bold_label("Time sig"), 0, 1, 3, 4, Gtk
.AttachOptions
.SHRINK | Gtk
.AttachOptions
.FILL
, Gtk
.AttachOptions
.SHRINK
)
226 t
.attach(self
.timesig_info
, 1, 2, 3, 4, Gtk
.AttachOptions
.SHRINK | Gtk
.AttachOptions
.FILL
, Gtk
.AttachOptions
.SHRINK
)
227 hb
= Gtk
.HButtonBox()
228 b
= Gtk
.Button("Play")
229 b
.connect('clicked', lambda w
: cbox
.Transport
.play())
230 hb
.pack_start(b
, False, False, 5)
231 b
= Gtk
.Button("Stop")
232 b
.connect('clicked', lambda w
: cbox
.Transport
.stop())
233 hb
.pack_start(b
, False, False, 5)
234 b
= Gtk
.Button("Rewind")
235 b
.connect('clicked', lambda w
: cbox
.Transport
.seek_ppqn(0))
236 hb
.pack_start(b
, False, False, 5)
237 b
= Gtk
.Button("Panic")
238 b
.connect('clicked', lambda w
: cbox
.Transport
.panic())
239 hb
.pack_start(b
, False, False, 5)
240 t
.attach(hb
, 2, 3, 3, 4, Gtk
.AttachOptions
.EXPAND
, Gtk
.AttachOptions
.SHRINK
)
242 t
.attach(bold_label("Tempo"), 0, 1, 4, 5, Gtk
.AttachOptions
.SHRINK | Gtk
.AttachOptions
.FILL
, Gtk
.AttachOptions
.SHRINK
)
243 self
.tempo_adj
= Gtk
.Adjustment(40, 40, 300, 1, 5, 0)
244 self
.tempo_adj
.connect('value_changed', adjustment_changed_float
, cbox
.VarPath("/master/set_tempo"))
245 t
.attach(standard_hslider(self
.tempo_adj
), 1, 3, 4, 5, Gtk
.AttachOptions
.EXPAND | Gtk
.AttachOptions
.FILL
, Gtk
.AttachOptions
.SHRINK
)
247 t
.attach(bold_label("Transpose"), 0, 1, 5, 6, Gtk
.AttachOptions
.SHRINK | Gtk
.AttachOptions
.FILL
, Gtk
.AttachOptions
.SHRINK
)
248 self
.transpose_adj
= Gtk
.Adjustment(scene_status
.transpose
, -24, 24, 1, 5, 0)
249 self
.transpose_adj
.connect('value_changed', adjustment_changed_int
, cbox
.VarPath('/scene/transpose'))
250 t
.attach(standard_align(Gtk
.SpinButton(adjustment
= self
.transpose_adj
), 0, 0, 0, 0), 1, 3, 5, 6, Gtk
.AttachOptions
.EXPAND | Gtk
.AttachOptions
.FILL
, Gtk
.AttachOptions
.SHRINK
)
252 self
.layers_model
= SceneLayersModel()
253 self
.layers_view
= SceneLayersView(self
.layers_model
)
254 t
.attach(standard_vscroll_window(-1, 160, self
.layers_view
), 0, 3, 7, 8, Gtk
.AttachOptions
.EXPAND | Gtk
.AttachOptions
.FILL
, Gtk
.AttachOptions
.SHRINK
)
256 self
.auxes_model
= SceneAuxBusesModel()
257 self
.auxes_view
= SceneAuxBusesView(self
.auxes_model
)
258 t
.attach(standard_vscroll_window(-1, 120, self
.auxes_view
), 0, 3, 8, 9, Gtk
.AttachOptions
.EXPAND | Gtk
.AttachOptions
.FILL
, Gtk
.AttachOptions
.SHRINK
)
260 me
= cbox
.Document
.get_engine().master_effect
261 me_status
= me
.status()
263 hb
= Gtk
.HBox(spacing
= 5)
264 self
.master_chooser
= fx_gui
.InsertEffectChooser(me
.path
, "slot", me_status
.insert_engine
, me_status
.insert_preset
, me_status
.bypass
, self
)
265 hb
.pack_start(self
.master_chooser
.fx_engine
, True, True, 0)
266 hb
.pack_start(self
.master_chooser
.fx_preset
, True, True, 5)
267 hb
.pack_start(self
.master_chooser
.fx_edit
, False, False, 5)
268 hb
.pack_start(self
.master_chooser
.fx_bypass
, False, False, 5)
270 t
.attach(bold_label("Master effect"), 0, 1, 6, 7, Gtk
.AttachOptions
.SHRINK
, Gtk
.AttachOptions
.SHRINK
)
271 t
.attach(standard_align(hb
, 0, 0, 0, 0), 1, 3, 6, 7, Gtk
.AttachOptions
.EXPAND | Gtk
.AttachOptions
.FILL
, Gtk
.AttachOptions
.SHRINK
)
273 self
.layers_model
.refresh(scene_status
)
274 self
.auxes_model
.refresh(scene_status
)
281 def load_scene(self
, w
):
282 d
= SceneDialog(self
)
285 if response
== Gtk
.ResponseType
.OK
:
286 scene
= cbox
.Document
.get_scene()
287 item_name
, item_type
, item_key
, item_label
= d
.get_selected_object()
288 if item_type
== 'Scene':
289 scene
.load(item_name
)
290 elif item_type
== 'Layer':
292 scene
.add_layer(item_name
)
293 elif item_type
== 'Instrument':
295 scene
.add_instrument_layer(item_name
)
296 scene_status
= scene
.status()
297 self
.scene_label
.set_text(scene_status
.name
)
298 self
.title_label
.set_text(scene_status
.title
)
299 self
.refresh_instrument_pages(scene_status
)
303 def layer_load(self
, w
):
304 d
= LoadLayerDialog(self
)
307 if response
== Gtk
.ResponseType
.OK
:
308 scene
= cbox
.Document
.get_scene()
309 item_name
, item_type
, item_key
, item_label
= d
.get_selected_object()
310 if item_type
== 'Layer':
311 scene
.add_layer(item_name
)
312 elif item_type
== 'Instrument':
313 scene
.add_instrument_layer(item_name
)
314 self
.refresh_instrument_pages()
318 def layer_new(self
, w
):
319 d
= NewLayerDialog(self
)
322 if response
== Gtk
.ResponseType
.OK
:
323 scene
= cbox
.Document
.get_scene()
324 keys
= scene
.status().instruments
.keys()
325 engine_name
= d
.get_selected_object()[0]
326 for i
in range(1, 1001):
327 name
= "%s%s" % (engine_name
, i
)
330 scene
.add_new_instrument_layer(name
, engine_name
)
331 self
.refresh_instrument_pages()
335 def layer_remove(self
, w
):
336 if self
.layers_view
.get_cursor()[0] is not None:
337 pos
= self
.layers_view
.get_cursor()[0][0]
338 cbox
.Document
.get_scene().delete_layer(pos
)
339 self
.refresh_instrument_pages()
341 def aux_bus_add(self
, w
):
342 d
= fx_gui
.LoadEffectDialog(self
)
345 cbox
.do_cmd("/scene/load_aux", None, [d
.get_selected_object()[0]])
346 self
.refresh_instrument_pages()
349 def aux_bus_remove(self
, w
):
350 rowid
, row
= self
.auxes_view
.get_current_row()
353 cbox
.do_cmd("/scene/delete_aux", None, [row
[0]])
354 self
.refresh_instrument_pages()
356 def aux_bus_edit(self
, w
):
357 rowid
, row
= self
.auxes_view
.get_current_row()
360 wclass
= fx_gui
.effect_window_map
[row
[1]]
361 popup
= wclass("Aux: %s" % row
[0], self
, "/scene/aux/%s/slot/engine" % row
[0])
365 def tools_unzombify(self
, w
):
366 cbox
.do_cmd("/rt/cycle", None, [])
368 def tools_drumkit_editor(self
, w
):
369 if self
.drumkit_editor
is None:
370 self
.drumkit_editor
= drumkit_editor
.EditorDialog(self
)
371 self
.refresh_instrument_pages()
372 self
.drumkit_editor
.connect('destroy', self
.on_drumkit_editor_destroy
)
373 self
.drumkit_editor
.show_all()
374 self
.drumkit_editor
.present()
376 def on_drumkit_editor_destroy(self
, w
):
377 self
.drumkit_editor
= None
379 def tools_object_list(self
, w
):
382 def tools_wave_bank_dump(self
, w
):
383 for w
in cbox
.get_thing('/waves/list', '/waveform', [str]):
384 info
= cbox
.GetThings("/waves/info", ["filename", "name", "bytes", "loop"], [w
])
385 print("%s: %d bytes, loop = %s" % (info
.filename
, info
.bytes
, info
.loop
))
387 def tools_play_drum_pattern(self
, w
):
388 d
= PlayPatternDialog(self
)
391 if response
== Gtk
.ResponseType
.OK
:
392 row
= d
.get_selected_object()
393 if row
[1] == 'Pattern':
394 song
= cbox
.Document().get_song()
395 song
.loop_single_pattern(lambda: song
.load_drum_pattern(row
[0]))
396 elif row
[1] == 'Track':
397 song
= cbox
.Document().get_song()
398 song
.loop_single_pattern(lambda: song
.load_drum_track(row
[0]))
399 elif row
[1] == 'Stop':
400 song
= cbox
.Document().get_song()
402 song
.update_playback()
403 tracks
= song
.status().tracks
405 for track_item
in tracks
:
406 track_item
.track
.set_external_output(cbox
.Document
.get_scene().uuid
)
407 song
.update_playback()
412 def tools_drum_pattern_editor(self
, w
):
413 if self
.drum_pattern_editor
is None:
414 length
= drum_pattern_editor
.PPQN
* 4
415 pat_data
= cbox
.Pattern
.get_pattern()
416 if pat_data
is not None:
417 pat_data
, length
= pat_data
418 self
.drum_pattern_editor
= drum_pattern_editor
.DrumSeqWindow(length
, pat_data
)
419 self
.drum_pattern_editor
.set_title("Drum pattern editor")
420 self
.drum_pattern_editor
.show_all()
421 self
.drum_pattern_editor
.connect('destroy', self
.on_drum_pattern_editor_destroy
)
422 self
.drum_pattern_editor
.pattern
.connect('changed', self
.on_drum_pattern_changed
)
423 self
.drum_pattern_editor
.pattern
.changed()
424 self
.drum_pattern_editor
.present()
426 def on_drum_pattern_changed(self
, pattern
):
428 for i
in pattern
.items():
430 data
+= cbox
.Pattern
.serialize_event(int(i
.pos
), 0x90 + ch
, int(i
.row
), int(i
.vel
))
432 data
+= cbox
.Pattern
.serialize_event(int(i
.pos
+ i
.len - 1), 0x80 + ch
, int(i
.row
), int(i
.vel
))
434 data
+= cbox
.Pattern
.serialize_event(int(i
.pos
+ 1), 0x80 + ch
, int(i
.row
), int(i
.vel
))
436 length
= pattern
.get_length()
438 song
= cbox
.Document().get_song()
439 song
.loop_single_pattern(lambda: song
.pattern_from_blob(data
, length
))
441 def on_drum_pattern_editor_destroy(self
, w
):
442 self
.drum_pattern_editor
= None
444 def refresh_instrument_pages(self
, scene_status
= None):
445 self
.delete_instrument_pages()
446 rt_status
= cbox
.Document
.get_rt().status()
447 if scene_status
is None:
448 scene_status
= cbox
.Document
.get_scene().status()
449 self
.layers_model
.refresh(scene_status
)
450 self
.auxes_model
.refresh(scene_status
)
451 self
.create_instrument_pages(scene_status
, rt_status
)
453 self
.title_label
.set_text(scene_status
.title
)
455 def create_instrument_pages(self
, scene_status
, rt_status
):
456 self
.path_widgets
= {}
457 self
.path_popups
= {}
458 self
.fx_choosers
= {}
460 outputs_ls
= Gtk
.ListStore(GObject
.TYPE_STRING
, GObject
.TYPE_INT
)
461 for out
in range(0, rt_status
.audio_channels
[1]//2):
462 outputs_ls
.append(("Out %s/%s" % (out
* 2 + 1, out
* 2 + 2), out
))
464 auxbus_ls
= Gtk
.ListStore(GObject
.TYPE_STRING
, GObject
.TYPE_STRING
)
465 auxbus_ls
.append(("", ""))
466 for bus_name
in scene_status
.auxes
.keys():
467 auxbus_ls
.append(("Aux: %s" % bus_name
, bus_name
))
469 for iname
, (iengine
, iobj
) in scene_status
.instruments
.items():
470 ipath
= "/scene/instr/%s" % iname
471 idata
= iobj
.status()
472 #attribs = cbox.GetThings("/scene/instr_info", ['engine', 'name'], [i])
473 #markup += '<b>Instrument %d:</b> engine %s, name %s\n' % (i, attribs.engine, attribs.name)
474 b
= Gtk
.VBox(spacing
= 5)
475 b
.set_border_width(5)
476 b
.pack_start(Gtk
.Label("Engine: %s" % iengine
), False, False, 5)
477 b
.pack_start(Gtk
.HSeparator(), False, False, 5)
478 t
= Gtk
.Table(1 + idata
.outputs
, 7)
479 t
.set_col_spacings(5)
480 t
.attach(bold_label("Instr. output", 0.5), 0, 1, 0, 1, Gtk
.AttachOptions
.SHRINK
, Gtk
.AttachOptions
.SHRINK
)
481 t
.attach(bold_label("Send to", 0.5), 1, 2, 0, 1, Gtk
.AttachOptions
.SHRINK
, Gtk
.AttachOptions
.SHRINK
)
482 t
.attach(bold_label("Gain [dB]", 0.5), 2, 3, 0, 1, 0, Gtk
.AttachOptions
.SHRINK
)
483 t
.attach(bold_label("Effect", 0.5), 3, 4, 0, 1, 0, Gtk
.AttachOptions
.SHRINK
)
484 t
.attach(bold_label("Preset", 0.5), 4, 7, 0, 1, 0, Gtk
.AttachOptions
.SHRINK
)
485 b
.pack_start(t
, False, False, 5)
488 for o
in range(1, idata
.outputs
+ 1):
489 is_aux
= o
>= idata
.aux_offset
491 opath
= "%s/output/%s" % (ipath
, o
)
492 output_name
= "Out %s" % o
494 opath
= "%s/aux/%s" % (ipath
, o
- idata
.aux_offset
+ 1)
495 output_name
= "Aux %s" % (o
- idata
.aux_offset
+ 1)
496 odata
= cbox
.GetThings(opath
+ "/status", ['gain', 'output', 'bus', 'insert_engine', 'insert_preset', 'bypass'], [])
497 engine
= odata
.insert_engine
498 preset
= odata
.insert_preset
499 bypass
= odata
.bypass
501 t
.attach(Gtk
.Label(output_name
), 0, 1, y
, y
+ 1, Gtk
.AttachOptions
.SHRINK
, Gtk
.AttachOptions
.SHRINK
)
504 cb
= standard_combo(outputs_ls
, odata
.output
- 1)
505 cb
.connect('changed', combo_value_changed
, cbox
.VarPath(opath
+ '/output'), 1)
507 cb
= standard_combo(auxbus_ls
, ls_index(auxbus_ls
, odata
.bus
, 1))
508 cb
.connect('changed', combo_value_changed_use_column
, cbox
.VarPath(opath
+ '/bus'), 1)
509 t
.attach(cb
, 1, 2, y
, y
+ 1, Gtk
.AttachOptions
.SHRINK
, Gtk
.AttachOptions
.SHRINK
)
511 adj
= Gtk
.Adjustment(odata
.gain
, -96, 24, 1, 6, 0)
512 adj
.connect('value_changed', adjustment_changed_float
, cbox
.VarPath(opath
+ '/gain'))
513 t
.attach(standard_hslider(adj
), 2, 3, y
, y
+ 1, Gtk
.AttachOptions
.EXPAND | Gtk
.AttachOptions
.FILL
, Gtk
.AttachOptions
.SHRINK
)
515 chooser
= fx_gui
.InsertEffectChooser(opath
, "%s: %s" % (iname
, output_name
), engine
, preset
, bypass
, self
)
516 self
.fx_choosers
[opath
] = chooser
517 t
.attach(chooser
.fx_engine
, 3, 4, y
, y
+ 1, 0, Gtk
.AttachOptions
.SHRINK
)
518 t
.attach(chooser
.fx_preset
, 4, 5, y
, y
+ 1, 0, Gtk
.AttachOptions
.SHRINK
)
519 t
.attach(chooser
.fx_edit
, 5, 6, y
, y
+ 1, 0, Gtk
.AttachOptions
.SHRINK
)
520 t
.attach(chooser
.fx_bypass
, 6, 7, y
, y
+ 1, 0, Gtk
.AttachOptions
.SHRINK
)
522 if iengine
in instr_gui
.instrument_window_map
:
523 b
.pack_start(Gtk
.HSeparator(), False, False, 5)
524 b
.pack_start(instr_gui
.instrument_window_map
[iengine
](iname
, iobj
), True, True, 5)
525 self
.nb
.append_page(b
, Gtk
.Label(iname
))
528 def delete_instrument_pages(self
):
529 while self
.nb
.get_n_pages() > 1:
530 self
.nb
.remove_page(self
.nb
.get_n_pages() - 1)
534 master
= cbox
.Transport
.status()
535 if master
.tempo
is not None:
536 self
.master_info
.set_markup('%s (%s)' % (master
.pos
, master
.pos_ppqn
))
537 self
.timesig_info
.set_markup("%s/%s" % tuple(master
.timesig
))
538 self
.tempo_adj
.set_value(master
.tempo
)
539 state
= cbox
.Document
.get_rt().status().state
540 self
.status_bar
.update(state
[1], master
.sample_rate
)
549 w
.connect('destroy', do_quit
)