midinous 1.0.0.beta

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,686 @@
1
+ # Copyright (C) 2019 James "Nornec" Ratliff
2
+ #
3
+ # This file is part of Midinous
4
+ #
5
+ # Midinous is free software: you can redistribute it and/or modify
6
+ # it under the terms of the GNU General Public License as published by
7
+ # the Free Software Foundation, either version 3 of the License, or
8
+ # (at your option) any later version.
9
+ #
10
+ # Midinous is distributed in the hope that it will be useful,
11
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
12
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
+ # GNU General Public License for more details.
14
+ #
15
+ # You should have received a copy of the GNU General Public License
16
+ # along with Midinous. If not, see <https://www.gnu.org/licenses/>.
17
+
18
+ class GtkRadioButtonEx < Gtk::RadioButton
19
+ type_register
20
+ def initialize
21
+ super()
22
+ end
23
+ define_signal('keybinding-event',nil,nil,nil)
24
+ end
25
+ class GtkButtonEx < Gtk::Button
26
+ type_register
27
+ def initialize
28
+ super()
29
+ end
30
+ define_signal('keybinding-event',nil,nil,nil)
31
+ end
32
+ class GtkCanvas < Gtk::DrawingArea
33
+ type_register
34
+ def initialize
35
+ super()
36
+ end
37
+ define_signal('delete-selected-event',nil,nil,nil)
38
+ define_signal('beat-up',nil,nil,nil)
39
+ define_signal('beat-dn',nil,nil,nil)
40
+ define_signal('beat-note-up',nil,nil,nil)
41
+ define_signal('beat-note-dn',nil,nil,nil)
42
+ define_signal('travel-event',nil,nil,nil)
43
+ define_signal('cycle-play-mode-bck',nil,nil,nil)
44
+ define_signal('cycle-play-mode-fwd',nil,nil,nil)
45
+ define_signal('set-start',nil,nil,nil)
46
+ define_signal('del-path-to',nil,nil,nil)
47
+ define_signal('del-path-from',nil,nil,nil)
48
+ define_signal('set-path-mode-h',nil,nil,nil)
49
+ define_signal('set-path-mode-v',nil,nil,nil)
50
+ define_signal('note-inc-up',nil,nil,nil)
51
+ define_signal('note-inc-dn',nil,nil,nil)
52
+ define_signal('path-rotate-bck',nil,nil,nil)
53
+ define_signal('path-rotate-fwd',nil,nil,nil)
54
+ end
55
+ class GtkPropEntry < Gtk::Entry
56
+ type_register
57
+ def initialize
58
+ super()
59
+ end
60
+ define_signal('keybinding-event',nil,nil,nil)
61
+ end
62
+
63
+ class UI_Elements
64
+ include Logic_Controls
65
+ # Construct a Gtk::Builder instance and load our UI description
66
+ attr_reader :menu_commands,:canvas_commands,:in_device_items,:out_device_items
67
+ def initialize
68
+ @current_file = nil
69
+ @operation_file = nil
70
+ @current_window = nil
71
+ @scale_iters = []
72
+ @in_device_items = []
73
+ @out_device_items = []
74
+ end
75
+ def build_ui
76
+ builder_file = "#{File.dirname(__FILE__)}/midinous.glade"
77
+
78
+ # Connect signal handlers to the constructed widgets
79
+ @builder = Gtk::Builder.new(:file => builder_file)
80
+
81
+ #Windows
82
+ def midinous
83
+ @builder.get_object("midinous")
84
+ end
85
+ def file_chooser
86
+ @builder.get_object("file_chooser")
87
+ end
88
+ def confirmer
89
+ @builder.get_object("confirmer")
90
+ end
91
+
92
+ #Menus
93
+ def input_menu
94
+ @builder.get_object("input_menu")
95
+ end
96
+ def output_menu
97
+ @builder.get_object("output_menu")
98
+ end
99
+
100
+ #Menu Items
101
+ def file_new
102
+ @builder.get_object("file_new")
103
+ end
104
+ def file_open
105
+ @builder.get_object("file_open")
106
+ end
107
+ def file_save
108
+ @builder.get_object("file_save")
109
+ end
110
+ def file_save_as
111
+ @builder.get_object("file_save_as")
112
+ end
113
+ def file_quit
114
+ @builder.get_object("file_quit")
115
+ end
116
+ def help_about
117
+ @builder.get_object("help_about")
118
+ end
119
+
120
+ #Drawing Areas
121
+ def canvas
122
+ @builder.get_object("canvas")
123
+ end
124
+ def canvas_viewport
125
+ @builder.get_object("canvas_viewport")
126
+ end
127
+ def canvas_scroll_window
128
+ @builder.get_object("canvas_scroll_window")
129
+ end
130
+
131
+ #Adjustments
132
+ def canvas_h_adj
133
+ @builder.get_object("canvas_scroll_h")
134
+ end
135
+ def canvas_v_adj
136
+ @builder.get_object("canvas_scroll_v")
137
+ end
138
+ def tempo_adj
139
+ @builder.get_object("tempo_adj")
140
+ end
141
+ def root_adj
142
+ @builder.get_object("root_adj")
143
+ end
144
+
145
+ #Buttons
146
+ def main_tool_1
147
+ @builder.get_object("main_tool_1")
148
+ end
149
+ def main_tool_2
150
+ @builder.get_object("main_tool_2")
151
+ end
152
+ def main_tool_3
153
+ @builder.get_object("main_tool_3")
154
+ end
155
+ def main_tool_4
156
+ @builder.get_object("main_tool_4")
157
+ end
158
+ def path_builder
159
+ @builder.get_object("path_builder")
160
+ end
161
+ def prop_mod_button
162
+ @builder.get_object("prop_mod_button")
163
+ end
164
+ def play
165
+ @builder.get_object("play")
166
+ end
167
+ def stop
168
+ @builder.get_object("stop")
169
+ end
170
+ def tempo
171
+ @builder.get_object("tempo")
172
+ end
173
+ def root_select
174
+ @builder.get_object("root_select")
175
+ end
176
+ def file_operation
177
+ @builder.get_object("file_operation")
178
+ end
179
+ def file_cancel
180
+ @builder.get_object("file_cancel")
181
+ end
182
+ def confirmer_confirm
183
+ @builder.get_object("confirmer_confirm")
184
+ end
185
+ def confirmer_cancel
186
+ @builder.get_object("confirmer_cancel")
187
+ end
188
+
189
+ #Button Areas
190
+ def logic_controls
191
+ @builder.get_object("logic_controls")
192
+ end
193
+
194
+ #Text Areas
195
+ def tool_descrip
196
+ @builder.get_object("tool_descrip")
197
+ end
198
+ def status_area
199
+ @builder.get_object("status_area")
200
+ end
201
+ def prop_mod
202
+ @builder.get_object("prop_mod")
203
+ end
204
+ def t_sig
205
+ @builder.get_object("t_sig")
206
+ end
207
+ def file_name
208
+ @builder.get_object("file_name")
209
+ end
210
+
211
+ #Labels
212
+ def perf_label
213
+ @builder.get_object("perf_label")
214
+ end
215
+ def tool_label
216
+ @builder.get_object("tool_label")
217
+ end
218
+ def tempo_label
219
+ @builder.get_object("tempo_label")
220
+ end
221
+ def property_label
222
+ @builder.get_object("property_label")
223
+ end
224
+ def modify_label
225
+ @builder.get_object("modify_label")
226
+ end
227
+ def t_sig_label
228
+ @builder.get_object("t_sig_label")
229
+ end
230
+ def confirmer_label
231
+ @builder.get_object("confirmer_label")
232
+ end
233
+ def scale_label
234
+ @builder.get_object("scale_label")
235
+ end
236
+
237
+ #Point Property Tree
238
+ def prop_list_model
239
+ @builder.get_object("prop_list_model")
240
+ end
241
+ def prop_list_view
242
+ @builder.get_object("prop_list_view")
243
+ end
244
+ def prop_list
245
+ @builder.get_object("prop_list")
246
+ end
247
+ def prop_list_col1_h
248
+ @builder.get_object("prop_list_col1_h")
249
+ end
250
+ def prop_list_col2_h
251
+ @builder.get_object("prop_list_col2_h")
252
+ end
253
+ def prop_list_col1
254
+ @builder.get_object("prop_list_col1")
255
+ end
256
+ def prop_list_col2
257
+ @builder.get_object("prop_list_col2")
258
+ end
259
+ def prop_list_selection
260
+ @builder.get_object("prop_list_selection")
261
+ end
262
+
263
+ #Scale Selection Combo Box
264
+ def scale_combo
265
+ @builder.get_object("scale_combo")
266
+ end
267
+ def scale_tree_model
268
+ @builder.get_object("scale_tree_model")
269
+ end
270
+ def scale_display
271
+ @builder.get_object("scale_display")
272
+ end
273
+
274
+ Pm.in_list.each {|i| @in_device_items << Gtk::ImageMenuItem.new(label: i.name)}
275
+ @in_device_items.each {|i| input_menu.append(i)}
276
+ input_menu.show_all
277
+
278
+ Pm.out_list.each {|o| @out_device_items << Gtk::ImageMenuItem.new(label: o.name)}
279
+ @out_device_items.each {|o| output_menu.append(o)}
280
+ output_menu.show_all
281
+
282
+ def set_device(id,type)
283
+ case type
284
+ when 'i'
285
+ Pm.sel_in(id)
286
+ when 'o'
287
+ Pm.sel_out(id)
288
+ end
289
+ regen_status
290
+ end
291
+
292
+ def regen_status
293
+ status_area.text = "Using: Output[#{Pm.out_list[Pm.out_id].name}] Input[#{Pm.in_list[Pm.in_id].name}]"
294
+ end
295
+
296
+ #Set up accelerators (keyboard shortcuts)
297
+ @menu_commands = Gtk::AccelGroup.new
298
+ @canvas_commands = Gtk::AccelGroup.new
299
+ midinous.add_accel_group(@menu_commands)
300
+ midinous.add_accel_group(@canvas_commands)
301
+
302
+ scale_cat_1 = scale_tree_model.append(nil)
303
+ scale_cat_1_sub_01 = scale_tree_model.append(scale_cat_1)
304
+ scale_cat_1_sub_02 = scale_tree_model.append(scale_cat_1)
305
+ scale_cat_1_sub_03 = scale_tree_model.append(scale_cat_1)
306
+ scale_cat_1_sub_04 = scale_tree_model.append(scale_cat_1)
307
+ scale_cat_1_sub_05 = scale_tree_model.append(scale_cat_1)
308
+ scale_cat_1_sub_06 = scale_tree_model.append(scale_cat_1)
309
+ scale_cat_2 = scale_tree_model.append(nil)
310
+ scale_cat_2_sub_01 = scale_tree_model.append(scale_cat_2)
311
+ scale_cat_2_sub_02 = scale_tree_model.append(scale_cat_2)
312
+ scale_cat_2_sub_03 = scale_tree_model.append(scale_cat_2)
313
+ scale_cat_2_sub_04 = scale_tree_model.append(scale_cat_2)
314
+ scale_cat_2_sub_05 = scale_tree_model.append(scale_cat_2)
315
+ scale_cat_2_sub_06 = scale_tree_model.append(scale_cat_2)
316
+ scale_cat_2_sub_07 = scale_tree_model.append(scale_cat_2)
317
+ scale_cat_2_sub_08 = scale_tree_model.append(scale_cat_2)
318
+ scale_cat_2_sub_09 = scale_tree_model.append(scale_cat_2)
319
+ scale_cat_3 = scale_tree_model.append(nil)
320
+ scale_cat_3_sub_01 = scale_tree_model.append(scale_cat_3)
321
+ scale_cat_3_sub_02 = scale_tree_model.append(scale_cat_3)
322
+ scale_cat_3_sub_03 = scale_tree_model.append(scale_cat_3)
323
+ scale_cat_3_sub_04 = scale_tree_model.append(scale_cat_3)
324
+ scale_cat_3_sub_05 = scale_tree_model.append(scale_cat_3)
325
+ scale_cat_3_sub_06 = scale_tree_model.append(scale_cat_3)
326
+ scale_cat_4 = scale_tree_model.append(nil)
327
+ scale_cat_4_sub_01 = scale_tree_model.append(scale_cat_4)
328
+ scale_cat_4_sub_02 = scale_tree_model.append(scale_cat_4)
329
+ scale_cat_4_sub_03 = scale_tree_model.append(scale_cat_4)
330
+ scale_cat_4_sub_04 = scale_tree_model.append(scale_cat_4)
331
+ scale_cat_4_sub_05 = scale_tree_model.append(scale_cat_4)
332
+ scale_cat_4_sub_06 = scale_tree_model.append(scale_cat_4)
333
+ scale_cat_5 = scale_tree_model.append(nil)
334
+ scale_cat_5_sub_01 = scale_tree_model.append(scale_cat_5)
335
+ scale_cat_5_sub_02 = scale_tree_model.append(scale_cat_5)
336
+ scale_cat_5_sub_03 = scale_tree_model.append(scale_cat_5)
337
+ scale_cat_5_sub_04 = scale_tree_model.append(scale_cat_5)
338
+ scale_cat_5_sub_05 = scale_tree_model.append(scale_cat_5)
339
+
340
+ scale_cat_1 [0] = "Pentatonic"
341
+ scale_cat_1_sub_01[0] = "Hirajoshi"
342
+ scale_cat_1_sub_02[0] = "Insen"
343
+ scale_cat_1_sub_03[0] = "Iwato"
344
+ scale_cat_1_sub_04[0] = "Pentatonic Major"
345
+ scale_cat_1_sub_05[0] = "Pentatonic Minor"
346
+ scale_cat_1_sub_06[0] = "Two Semitone Tritone"
347
+ scale_cat_2 [0] = "Traditional"
348
+ scale_cat_2_sub_01[0] = "Aeolian"
349
+ scale_cat_2_sub_02[0] = "Dorian"
350
+ scale_cat_2_sub_03[0] = "Harmonic Major"
351
+ scale_cat_2_sub_04[0] = "Harmonic Minor"
352
+ scale_cat_2_sub_05[0] = "Ionian"
353
+ scale_cat_2_sub_06[0] = "Locrian"
354
+ scale_cat_2_sub_07[0] = "Lydian"
355
+ scale_cat_2_sub_08[0] = "Mixolydian"
356
+ scale_cat_2_sub_09[0] = "Phrygian"
357
+ scale_cat_3 [0] = "Modified Traditional"
358
+ scale_cat_3_sub_01[0] = "Altered"
359
+ scale_cat_3_sub_02[0] = "Half Diminished"
360
+ scale_cat_3_sub_03[0] = "Locrian Major"
361
+ scale_cat_3_sub_04[0] = "Lydian Augmented"
362
+ scale_cat_3_sub_05[0] = "Melodic Minor"
363
+ scale_cat_3_sub_06[0] = "Ukrainian Dorian"
364
+ scale_cat_4 [0] = "Exotic"
365
+ scale_cat_4_sub_01[0] = "Augmented"
366
+ scale_cat_4_sub_02[0] = "Blues"
367
+ scale_cat_4_sub_03[0] = "Flamenco"
368
+ scale_cat_4_sub_04[0] = "Hungarian"
369
+ scale_cat_4_sub_05[0] = "Persian"
370
+ scale_cat_4_sub_06[0] = "Prometheus"
371
+ scale_cat_5 [0] = "Mathematical"
372
+ scale_cat_5_sub_01[0] = "Chromatic"
373
+ scale_cat_5_sub_02[0] = "Octatonic Whole"
374
+ scale_cat_5_sub_03[0] = "Octatonic Half"
375
+ scale_cat_5_sub_04[0] = "Tritone"
376
+ scale_cat_5_sub_05[0] = "Whole Tone"
377
+
378
+ @scale_iters << scale_cat_1_sub_01
379
+ @scale_iters << scale_cat_1_sub_02
380
+ @scale_iters << scale_cat_1_sub_03
381
+ @scale_iters << scale_cat_1_sub_04
382
+ @scale_iters << scale_cat_1_sub_05
383
+ @scale_iters << scale_cat_1_sub_06
384
+ @scale_iters << scale_cat_2_sub_01
385
+ @scale_iters << scale_cat_2_sub_02
386
+ @scale_iters << scale_cat_2_sub_03
387
+ @scale_iters << scale_cat_2_sub_04
388
+ @scale_iters << scale_cat_2_sub_05
389
+ @scale_iters << scale_cat_2_sub_06
390
+ @scale_iters << scale_cat_2_sub_07
391
+ @scale_iters << scale_cat_2_sub_08
392
+ @scale_iters << scale_cat_2_sub_09
393
+ @scale_iters << scale_cat_3_sub_01
394
+ @scale_iters << scale_cat_3_sub_02
395
+ @scale_iters << scale_cat_3_sub_03
396
+ @scale_iters << scale_cat_3_sub_04
397
+ @scale_iters << scale_cat_3_sub_05
398
+ @scale_iters << scale_cat_3_sub_06
399
+ @scale_iters << scale_cat_4_sub_01
400
+ @scale_iters << scale_cat_4_sub_02
401
+ @scale_iters << scale_cat_4_sub_03
402
+ @scale_iters << scale_cat_4_sub_04
403
+ @scale_iters << scale_cat_4_sub_05
404
+ @scale_iters << scale_cat_4_sub_06
405
+ @scale_iters << scale_cat_5_sub_01
406
+ @scale_iters << scale_cat_5_sub_02
407
+ @scale_iters << scale_cat_5_sub_03
408
+ @scale_iters << scale_cat_5_sub_04
409
+ @scale_iters << scale_cat_5_sub_05
410
+
411
+ scale_combo.active = 4
412
+ scale_combo.active_iter = scale_cat_5_sub_01
413
+
414
+ #Initialize the elements of the screen
415
+ midinous.add_events("key-press-mask")
416
+ canvas.add_events("button-press-mask")
417
+ canvas.add_events("button-release-mask")
418
+ canvas.add_events("pointer-motion-mask")
419
+ prop_mod.add_events("key-press-mask")
420
+
421
+ path_builder.sensitive = false
422
+ prop_mod_button.sensitive = false
423
+ stop.sensitive = false
424
+
425
+ tool_descrip.text = "Select"
426
+ t_sig.text = "4/4"
427
+
428
+ perf_label.markup = "<b>#{perf_label.text}</b>"
429
+ tempo_label.markup = "<b>#{tempo_label.text}</b>"
430
+ tool_label.markup = "<b>#{tool_label.text}</b>"
431
+ property_label.markup = "<b>#{property_label.text}</b>"
432
+ modify_label.markup = "<b>#{modify_label.text}</b>"
433
+ t_sig_label.markup = "<b>#{t_sig_label.text}</b>"
434
+ scale_label.markup = "<b>#{scale_label.text}</b>"
435
+
436
+ regen_status
437
+
438
+ #canvas.add_events(Gdk::EventMask::BUTTON_PRESS_MASK.nick) #This points to a nickname, basically a string like "button-press-mask" in this case
439
+
440
+ #Accel groups, parameter 2 is the modifier
441
+ # 0 - no modifier
442
+ # 1 - shift
443
+ # 2 - no modifier?
444
+ # 3 - shift again?
445
+ # 4 - Cntl
446
+ # 5 - Cntl+Shift
447
+
448
+ file_chooser.filter = Gtk::FileFilter.new
449
+ file_chooser.filter.add_pattern("*.nous")
450
+ file_chooser.filter.name = "nous file filter"
451
+ end
452
+ def confirm(type)
453
+ case type
454
+ when "new"
455
+ @current_window = "new_confirm"
456
+ confirmer_confirm.label = "Create New"
457
+ confirmer_label.markup = "<b> There are unsaved changes.</b> \n Do you wish to proceed? "
458
+ confirmer_cancel.visible = true
459
+ when "quit"
460
+ @current_window = "quit_confirm"
461
+ confirmer_confirm.label = "Quit"
462
+ confirmer_cancel.visible = true
463
+ confirmer_label.markup = "<b> There are unsaved changes.</b> \n Do you wish to proceed? "
464
+ when "path_warning"
465
+ @current_window = "path_warning"
466
+ confirmer_confirm.label = "OK"
467
+ confirmer_cancel.visible = false
468
+ confirmer_label.markup = "<b> WARNING:</b> Live composition detected. \n This may have affected round-robin point starting paths. "
469
+ end
470
+ confirmer.visible = true
471
+ end
472
+ def file_input_check(type)
473
+ case type
474
+ when "chooser"
475
+ unless UI::file_chooser.uri == nil
476
+ UI::file_name.text = UI::file_chooser.uri.split("/").last
477
+ else
478
+ UI::file_name.text = ""
479
+ end
480
+ when "name"
481
+ unless UI::file_name.text != "" ||
482
+ UI::file_chooser.uri != nil ||
483
+ UI::file_name.text.count(".") > 1
484
+ then
485
+ UI::file_operation.sensitive = false
486
+ else UI::file_operation.sensitive = true
487
+ end
488
+ end
489
+ end
490
+ def file_oper(type)
491
+ case type
492
+ when "open"
493
+ @current_window = "file_open"
494
+ file_chooser.title = "Open"
495
+ file_operation.label = "Open"
496
+ file_chooser.visible = true
497
+ file_name.editable = false
498
+ when "save"
499
+ @current_window = "file_save"
500
+ if @current_file == nil #If the working file does not exist yet
501
+ file_chooser.title = "Save As"
502
+ file_operation.label = "Save As"
503
+ file_name.editable = true
504
+ file_chooser.visible = true
505
+ else
506
+ save_operation #Resave the file if @current_file already exists
507
+ end
508
+ when "saveas"
509
+ @current_window = "file_save"
510
+ #If the working file does not exist yet, suggest a name
511
+ file_name.text = @current_file.split("\\").last unless @current_file == nil
512
+ file_chooser.title = "Save As"
513
+ file_operation.label = "Save As"
514
+ file_name.editable = true
515
+ file_chooser.visible = true
516
+ end
517
+ end
518
+ def confirm_act(choice)
519
+ if choice == "yes"
520
+ case @current_window
521
+ when "new_confirm"
522
+ CC.nouspoints = []
523
+ file_name.text = ""
524
+ CC.tempo = 120
525
+ CC.scale = "Chromatic"
526
+ CC.root_note = 60
527
+ CC.beats = 4
528
+ CC.beat_note = 4
529
+
530
+ CC.set_tempo(CC.tempo)
531
+ CC.set_scale(CC.scale,CC.root_note)
532
+ CC.canvas_grid_change(nil)
533
+ tempo_adj.value = CC.tempo
534
+ @scale_iters.each {|s| scale_combo.active_iter = s if s[0] == CC.scale}
535
+ root_adj.value = CC.root_note
536
+ @current_file = nil
537
+ midinous.title = "Midinous"
538
+ when "quit_confirm"
539
+ Gtk.main_quit
540
+ end
541
+ end
542
+ confirmer.visible = false
543
+ canvas.queue_draw
544
+ end
545
+ def file_oper_act(choice)
546
+ if choice == "yes"
547
+ case @current_window
548
+ when "file_open"
549
+ #Remove current points and load points from file
550
+ load_operation
551
+ when "file_save"
552
+ #Save nouspoints to a new, or existing file, window only if new
553
+ save_operation
554
+ end
555
+ end
556
+ file_chooser.visible = false
557
+ canvas.queue_draw
558
+ end
559
+
560
+ def save_operation
561
+
562
+ unless file_name.text[-5..-1] == ".nous"
563
+ @current_file = "#{file_chooser.current_folder_uri}/#{file_name.text}.nous"
564
+
565
+ else @current_file = "#{file_chooser.current_folder_uri}/#{file_name.text}"
566
+ end
567
+
568
+ operator = @current_file.sub("file:///","")
569
+ operator = operator.gsub("/","\\")
570
+
571
+ IO.binwrite(operator, "")
572
+ save = File.open(operator, "a")
573
+ issued_id = 0
574
+ CC.nouspoints.each do |n|
575
+ n.save_id = issued_id
576
+ issued_id += 1
577
+ end
578
+ CC.nouspoints.each do |n|
579
+ n.write_props(save)
580
+ save.write("\n")
581
+ end
582
+ save.write("#{CC.tempo}<~>")
583
+ save.write("#{CC.scale}<~>")
584
+ save.write("#{CC.root_note}<~>")
585
+ save.write("#{CC.beats}<~>")
586
+ save.write("#{CC.beat_note}")
587
+ midinous.title = "Midinous - #{operator}"
588
+ save.close
589
+ end
590
+ def load_operation
591
+ CC.canvas_stop
592
+ CC.nouspoints = []
593
+ @current_file = file_chooser.uri
594
+ operator = @current_file.sub("file:///","")
595
+ operator = operator.gsub("/","\\")
596
+
597
+ load = IO.binread(operator)
598
+ load = load.gsub("\r","")
599
+ load = load.split("\n")
600
+ load[0..-2].each do |point_line|
601
+ point_line = point_line.split("<~>")
602
+ CC.nouspoints << NousPoint.new(eval(point_line[1]),point_line[0].to_i)
603
+ end
604
+ CC.nouspoints.each do |n|
605
+ load.each do |point_line|
606
+ point_line = point_line.split("<~>")
607
+ if point_line[0].to_i == n.save_id
608
+ if point_line[2].match(/^([+]|-)[0-9]{1,2}$/)
609
+ n.note = point_line[2]
610
+ n.use_rel = true
611
+ elsif (point_line[2].to_i >= 0 &&
612
+ point_line[2].to_i <= 127 &&
613
+ !(point_line[2].include?("+") || point_line[2].include?("-")))
614
+ then
615
+ n.note = point_line[2].to_i
616
+ end
617
+ n.velocity = point_line[3].to_i
618
+ n.channel = point_line[4].to_i
619
+ n.duration = point_line[5].to_i
620
+ n.set_default_color(hex_to_color(point_line[6]))
621
+ n.repeat = point_line[7].to_i
622
+ n.play_modes = eval(point_line[8])
623
+ n.traveler_start = eval(point_line[9])
624
+ n.use_rel = eval(point_line[10])
625
+ n.path_mode = point_line[11]
626
+ n.path_to_rels = eval(point_line[12])
627
+ n.path_from_rels = eval(point_line[13])
628
+ n.path_to_rels.each {|ptr| n.path_to << CC.nouspoints.find {|f| ptr == f.save_id}}
629
+ n.path_from_rels.each {|pfr| n.path_from << CC.nouspoints.find {|f| pfr == f.save_id}}
630
+ end
631
+ end
632
+ end
633
+ load_last = load.last.split("<~>")
634
+ CC.tempo = load_last[0].to_f
635
+ CC.scale = load_last[1]
636
+ CC.root_note = load_last[2].to_i
637
+ CC.beats = load_last[3].to_i
638
+ CC.beat_note = load_last[4].to_i
639
+
640
+ CC.set_tempo(CC.tempo)
641
+ CC.set_scale(CC.scale,CC.root_note)
642
+ CC.canvas_grid_change(nil)
643
+ tempo_adj.value = CC.tempo
644
+ @scale_iters.each {|s| scale_combo.active_iter = s if s[0] == CC.scale}
645
+ root_adj.value = CC.root_note
646
+
647
+ midinous.title = "Midinous - #{operator}"
648
+ end
649
+ end
650
+
651
+ class Tool
652
+ attr_reader :tool_id
653
+ def initialize
654
+ @tool_id = 1
655
+ end
656
+ def set_tool(id)
657
+ @tool_id = id
658
+ unless @tool_id == 4
659
+ UI::path_builder.sensitive = false
660
+ end
661
+ case
662
+ when @tool_id == 1
663
+ UI::main_tool_1.active = true
664
+ UI::tool_descrip.text = "Select"
665
+ UI::canvas.queue_draw
666
+ when @tool_id == 2
667
+ UI::main_tool_2.active = true
668
+ UI::tool_descrip.text = "Place"
669
+ UI::canvas.queue_draw
670
+ when @tool_id == 3
671
+ UI::main_tool_3.active = true
672
+ UI::tool_descrip.text = "Move"
673
+ UI::canvas.queue_draw
674
+ when @tool_id == 4
675
+ UI::main_tool_4.active = true
676
+ UI::path_builder.sensitive = true
677
+ UI::tool_descrip.text = "Path"
678
+ UI::canvas.queue_draw
679
+ end
680
+ end
681
+
682
+ end
683
+
684
+ UI = UI_Elements.new() #Create a new UI_Elements object
685
+ UI::build_ui
686
+ Active_Tool = Tool.new
data/lib/midinous.rb ADDED
@@ -0,0 +1,21 @@
1
+ # Copyright (C) 2019 James "Nornec" Ratliff
2
+ #
3
+ # Midinous is free software: you can redistribute it and/or modify
4
+ # it under the terms of the GNU General Public License as published by
5
+ # the Free Software Foundation, either version 3 of the License, or
6
+ # (at your option) any later version.
7
+ #
8
+ # Midinous 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 Midinous. If not, see <https://www.gnu.org/licenses/>.
15
+
16
+ require "unimidi"
17
+ require "midi-eye"
18
+ require "gtk3"
19
+ require "midinous/init"
20
+
21
+ Gtk.main