midinous 1.0.4 → 1.0.8

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: '087d361408672ac98221ecb150db5de9a9174628926a161c397edbef8ab6c9c5'
4
- data.tar.gz: 035ce40f9e72ee926cf06d03760eac8afe81165539c0c3fd0fcac221250a7c29
3
+ metadata.gz: 89ce42f2e2944cfdff16e619467accf34d03027a47151f67c21793fe9f794c6d
4
+ data.tar.gz: 89f30cf29078a6c1800015a9daff0573364623819b6f372de03e4b63a9ffe20a
5
5
  SHA512:
6
- metadata.gz: cb1c9a4a684aacd1297515073797b0c9d6443cd2ac82307927a3eca537fb9837e2b4c34ca2941ef78c6265ce56064170a8bd263e7e4b1964c667d272d8211175
7
- data.tar.gz: a10869ab6d2651dba2bd57ea6336fad8c41e40743cf615296c32ac66bbdd6fef90e5a711f720aa2c2fc05e3168b4e80be00961bae6653afd407f85cbb459bec2
6
+ metadata.gz: e52a3bf73a9e77ba7f7e5ca0d968c227c6ec090c4da2982fc77edf4c23030ffce31bc6696788f22349dd2aea8756e3735df7405d15673685935be9036cebd72b
7
+ data.tar.gz: e7d4013eb378bfb232c3bdc0bebc22bfbc8f9396d72097f61ef94ed6816e89264c0a017e8f34b9b669cdb7a26eb5f8a6cd23d40a4cf8e1cc5aff4bbd4c83a9ce
@@ -296,7 +296,6 @@ class Canvas_Control
296
296
 
297
297
  def canvas_del
298
298
  @nouspoints = Pl.delete_points(@nouspoints)
299
- UI::canvas.queue_draw
300
299
  end
301
300
 
302
301
  def canvas_bg_draw(cr)
@@ -0,0 +1,92 @@
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
+ module UniMIDI
19
+ class Loader
20
+ class << self
21
+ def clear_devices
22
+ @devices = nil
23
+ end
24
+ end
25
+ end
26
+ end
27
+
28
+ module MIDIWinMM
29
+ module Map
30
+ def reattach_funcs
31
+ attach_function :midiInOpen, [:pointer, :uint, :input_callback, :DWORD_PTR, :DWORD], :MMRESULT
32
+ end
33
+ end
34
+
35
+ #References MIDIWinMM\input.rb
36
+ class Input
37
+ def enable(options = {}, &block)
38
+ init_input_buffer
39
+ handle_ptr = FFI::MemoryPointer.new(FFI.type_size(:int))
40
+ initialize_local_buffer
41
+ @event_callback = get_event_callback
42
+ Map.winmm_func(:midiInOpen, handle_ptr, @id, @event_callback, 0, Device::WinmmCallbackFlag)
43
+
44
+ @handle = handle_ptr.read_int
45
+
46
+ #Map.winmm_func(:midiInPrepareHeader, @handle, @header.pointer, @header.size)
47
+ #Map.winmm_func(:midiInAddBuffer, @handle, @header.pointer, @header.size)
48
+ Map.winmm_func(:midiInStart, @handle)
49
+
50
+ @enabled = true
51
+
52
+ unless block.nil?
53
+ begin
54
+ yield(self)
55
+ ensure
56
+ close
57
+ end
58
+ else
59
+ self
60
+ end
61
+ end
62
+ alias_method :start, :enable
63
+ alias_method :open, :enable
64
+ end
65
+
66
+
67
+ end
68
+
69
+ class GuiListener < MIDIEye::Listener
70
+
71
+ GUI_LISTEN_INTERVAL = 1.0 / 10
72
+
73
+ def gui_listen_loop
74
+ loop do
75
+ poll
76
+ @event.trigger_enqueued
77
+ sleep(GUI_LISTEN_INTERVAL)
78
+ end
79
+ end
80
+
81
+ def gui_listen
82
+ @listener = Thread.new do
83
+ begin
84
+ gui_listen_loop
85
+ rescue Exception => exception
86
+ Thread.main.raise(exception)
87
+ end
88
+ end
89
+ @listener.abort_on_exception = true
90
+ true
91
+ end
92
+ end
data/lib/midinous/init.rb CHANGED
@@ -15,6 +15,7 @@
15
15
  # You should have received a copy of the GNU General Public License
16
16
  # along with Midinous. If not, see <https://www.gnu.org/licenses/>.
17
17
 
18
+ require "midinous/extensions"
18
19
  require "midinous/proc_midi"
19
20
  require "midinous/constants"
20
21
  require "midinous/logic"
@@ -22,6 +23,7 @@ require "midinous/style/ui"
22
23
  require "midinous/canvas"
23
24
  require "midinous/key_bindings"
24
25
 
26
+
25
27
  class Init_Prog
26
28
 
27
29
  def initialize #Build the user interface, initiate the objects in the program
@@ -129,8 +131,8 @@ module Event_Router
129
131
  UI::stop.signal_connect("button-press-event") {CC.canvas_stop}
130
132
  UI::play.signal_connect("button-press-event") {CC.canvas_play}
131
133
  UI::scale_combo.signal_connect("changed") {CC.set_scale(UI::scale_combo.active_iter[0],CC.root_note)}
132
-
133
- #For menu items
134
+
135
+ #For menu items
134
136
  UI::in_device_items.each_with_index {|i, idx| i.signal_connect("button-press-event") {UI.set_device(idx,"i")}}
135
137
  UI::out_device_items.each_with_index {|o, idx| o.signal_connect("button-press-event") {UI.set_device(idx,"o")}}
136
138
  UI::in_channel_items.each do |i|
@@ -139,6 +141,20 @@ module Event_Router
139
141
  UI.regen_status
140
142
  end
141
143
  end
144
+
145
+ UI::edit_io.signal_connect("button-press-event") do
146
+ UI::clear_io_menu_items
147
+ Pm.regenerate
148
+ UI::set_io_menu_items
149
+ UI::in_device_items.each_with_index {|i, idx| i.signal_connect("button-press-event") {UI.set_device(idx,"i")}}
150
+ UI::out_device_items.each_with_index {|o, idx| o.signal_connect("button-press-event") {UI.set_device(idx,"o")}}
151
+ UI::in_channel_items.each do |i|
152
+ i.signal_connect("button-press-event") do
153
+ Pm.in_chan = i.label.to_i
154
+ UI.regen_status
155
+ end
156
+ end
157
+ end
142
158
 
143
159
  UI::help_about.signal_connect("button-press-event") {UI::about_window.visible = true}
144
160
  UI::help_notes.signal_connect("button-press-event") {UI::notes_window.visible = true}
@@ -191,7 +207,7 @@ module Event_Router
191
207
  UI::canvas.signal_connect("set-path-mode-v") {Pl.set_path_mode("vert")}
192
208
  UI::canvas.signal_connect("note-inc-up") {Pl.inc_note(1)}
193
209
  UI::canvas.signal_connect("note-inc-dn") {Pl.inc_note(-1)}
194
- UI::canvas.signal_connect("path-rotate-bck") {Pl.play_mode_rotate_selected("-")}
195
- UI::canvas.signal_connect("path-rotate-fwd") {Pl.play_mode_rotate_selected("+")}
210
+ UI::canvas.signal_connect("path-rotate-bck") {Pl.path_rotate("-")}
211
+ UI::canvas.signal_connect("path-rotate-fwd") {Pl.path_rotate("+")}
196
212
  end
197
213
 
@@ -117,10 +117,10 @@ module Logic_Controls #various reusable functions useful for checks and math
117
117
  end
118
118
  end
119
119
 
120
- def round_num_to_grid(num)
120
+ def round_num_to_grid(num) #2050
121
121
  temp = num % CC.grid_spacing
122
122
  num -= temp if temp < (CC.grid_spacing/2)
123
- num -= n-temp+CC.grid_spacing if temp >= (CC.grid_spacing/2)
123
+ num = (num-temp)+CC.grid_spacing if temp >= (CC.grid_spacing/2)
124
124
  return num
125
125
  end
126
126
 
@@ -71,7 +71,7 @@ class Point_Logic
71
71
  def set_note_via_devc(note)
72
72
  CC.nouspoints.find_all(&:selected).each {|n| n.note = note}
73
73
  Pm.note_send(Pm.in_chan,note,100)
74
- GLib::Timeout.add(1000) do
74
+ GLib::Timeout.add(100) do
75
75
  Pm.note_rlse(1,note)
76
76
  false
77
77
  end
@@ -129,34 +129,43 @@ class Point_Logic
129
129
  @copy_pos = origins.min
130
130
  @copy_type = type
131
131
  @mempointsbuff = CC.nouspoints.find_all(&:selected)
132
+ @paste_count = 0
132
133
  end
133
134
  def paste_points
134
135
  return if @mempointsbuff.empty?
135
136
  copy_lookup = {}
137
+
138
+ # Clone the cut copy of pasted points if someone wants to cutpaste more than once
139
+ # Then turn the cut operation into the copy operation
140
+ copy_points("copy") if @paste_count == 1
136
141
 
137
142
  # Clone the points and track old point => new point
138
143
  @mempointsbuff.each do |n|
139
- n.selected = false if @copy_type == "copy"
140
- mem_point = n.clone
141
- @mempoints << mem_point
142
- copy_lookup[n.object_id] = mem_point
144
+ n.selected = false if @copy_type == "copy"
145
+ mem_point = n.clone
146
+ @mempoints << mem_point
147
+ copy_lookup[n.object_id] = mem_point
143
148
  end
144
149
 
145
150
  # Update the point relations
146
151
  @mempoints.each do |n|
147
- n.path_to = n.path_to.map { |pt| copy_lookup[pt.object_id] }.compact
148
- n.path_from = n.path_from.map { |pf| copy_lookup[pf.object_id] }.compact
152
+ n.path_to = n.path_to.map { |pt| copy_lookup[pt.object_id] }.compact
153
+ n.path_from = n.path_from.map { |pf| copy_lookup[pf.object_id] }.compact
149
154
  end
150
155
 
151
156
  @paste_count = 0 if @copy_type == "copy"
152
- CC.nouspoints.reject!(&:selected) if @copy_type == "cut" && @paste_count == 0
157
+ delete_points(CC.nouspoints) if @copy_type == "cut" && @paste_count == 0
153
158
  @paste_count += 1
154
-
159
+
155
160
  paste_pos = CC.mouse_last_pos
156
- diff = round_to_grid([paste_pos[0] - @copy_pos[0],paste_pos[1] - @copy_pos[1]])
157
- @mempoints.each {|m| m.set_destination(diff)}
161
+ diff = round_to_grid([paste_pos[0] - @copy_pos[0],paste_pos[1] - @copy_pos[1]])
162
+ @mempoints.each do |m|
163
+ m.set_destination(diff)
164
+ m.selected = true
165
+ end
158
166
  @mempoints.each {|m| CC.nouspoints << m} if paste_check(diff,@mempoints)
159
167
  @mempoints = []
168
+
160
169
  populate_prop(CC.nouspoints)
161
170
  UI::canvas.queue_draw
162
171
  end
@@ -258,8 +267,8 @@ class Point_Logic
258
267
  else UI::prop_mod_button.sensitive = false
259
268
  end
260
269
  when "X-coordinate", "Y-coordinate"
261
- if round_num_to_grid(text.to_i) >= CC.grid_spacing &&
262
- round_num_to_grid(text.to_i) <= (CANVAS_SIZE - CC.grid_spacing)
270
+ if text.to_i >= CC.grid_spacing &&
271
+ text.to_i <= (CANVAS_SIZE - CC.grid_spacing)
263
272
  then
264
273
  UI::prop_mod_button.sensitive = true
265
274
  else UI::prop_mod_button.sensitive = false
@@ -317,9 +326,9 @@ class Point_Logic
317
326
  when "Channel"
318
327
  points.find_all(&:selected).each {|p| p.channel = UI::prop_mod.text.to_i}
319
328
  when "X-coordinate"
320
- points.find(&:selected).x = UI::prop_mod.text.to_i
329
+ points.find(&:selected).x = round_num_to_grid(UI::prop_mod.text.to_i)
321
330
  when "Y-coordinate"
322
- points.find(&:selected).y = UI::prop_mod.text.to_i
331
+ points.find(&:selected).y = round_num_to_grid(UI::prop_mod.text.to_i)
323
332
  when "Color"
324
333
  points.find_all(&:selected).each {|p| p.set_default_color(hex_to_color("##{UI::prop_mod.text}"))}
325
334
  when "Path Mode"
@@ -368,14 +377,17 @@ class Point_Logic
368
377
  n.play_modes.rotate!(dir) until n.play_modes[0] == "portal"
369
378
  when "portal"
370
379
  n.play_modes.rotate!(dir) until n.play_modes[0] == "robin"
380
+ when "random","split"
381
+ n.play_modes.rotate!(dir) until n.play_modes[0] == "robin"
371
382
  end
372
383
  else
373
384
  n.play_modes.rotate!(dir)
374
385
  end
386
+ populate_prop(CC.nouspoints.find_all)
375
387
  UI::canvas.queue_draw
376
388
  end
377
389
  end
378
- def play_mode_rotate_selected(dir)
390
+ def path_rotate(dir)
379
391
  CC.nouspoints.find_all(&:selected).each do |n|
380
392
  case dir
381
393
  when "+"
@@ -384,6 +396,7 @@ class Point_Logic
384
396
  n.path_to.rotate!(-1)
385
397
  end
386
398
  end
399
+
387
400
  UI::canvas.queue_draw
388
401
  end
389
402
 
@@ -402,11 +415,15 @@ class Point_Logic
402
415
  points.reject!(&:selected)
403
416
  UI::prop_list_model.clear
404
417
  UI::prop_mod.text = ""
418
+ UI::canvas.queue_draw
405
419
  return points
406
420
  end
407
421
  def delete_paths_to(points)
408
422
  points.find_all {|f| !f.path_to.length.zero? && f.selected == true}.each {|n| n.path_to.each {|b| b.path_from.reject! {|g| g == n }}}
409
- points.find_all {|f| !f.path_to.length.zero? && f.selected == true}.each {|n| n.path_to = []}
423
+ points.find_all {|f| !f.path_to.length.zero? && f.selected == true}.each do |n|
424
+ n.path_to = []
425
+ play_mode_rotate(1)
426
+ end
410
427
  UI::canvas.queue_draw
411
428
  end
412
429
  def delete_paths_from(points)
@@ -15,34 +15,10 @@
15
15
  # You should have received a copy of the GNU General Public License
16
16
  # along with Midinous. If not, see <https://www.gnu.org/licenses/>.
17
17
 
18
- class GuiListener < MIDIEye::Listener
19
-
20
- GUI_LISTEN_INTERVAL = 1.0 / 10
21
-
22
- def gui_listen_loop
23
- loop do
24
- poll
25
- @event.trigger_enqueued
26
- sleep(GUI_LISTEN_INTERVAL)
27
- end
28
- end
29
-
30
- def gui_listen
31
- @listener = Thread.new do
32
- begin
33
- gui_listen_loop
34
- rescue Exception => exception
35
- Thread.main.raise(exception)
36
- end
37
- end
38
- @listener.abort_on_exception = true
39
- true
40
- end
41
- end
42
-
43
18
  class Proc_Midi
44
19
  attr_accessor :out_list, :in_list, :in_chan
45
20
  attr_reader :out_id, :in_id, :in, :midi_in
21
+
46
22
  def initialize(oid,iid)
47
23
  @out_list = []
48
24
  @in_list = []
@@ -54,12 +30,38 @@ class Proc_Midi
54
30
 
55
31
  @in_id = iid
56
32
  @in_list = UniMIDI::Input.all
57
- unless @in_list.empty?
33
+ unless @in_list.length <= 1
58
34
  @in = UniMIDI::Input.use(@in_id)
59
35
  set_listener
60
36
  end
61
37
  end
62
-
38
+ def regenerate
39
+ @midi_in.close unless @midi_in.nil?
40
+ @in_list.each do |i|
41
+ #i.clear_buffer
42
+ i.close
43
+ end
44
+ @out_list.each {|o| o.close}
45
+ UniMIDI::Input.all.each {|i| i = nil}
46
+ UniMIDI::Output.all.each {|o| o = nil}
47
+
48
+ @in = nil
49
+ @out = nil
50
+
51
+ @in_list = []
52
+ @out_list = []
53
+
54
+ UniMIDI::Loader.clear_devices
55
+
56
+ @in_list = UniMIDI::Input.all
57
+ @out_list = UniMIDI::Output.all
58
+
59
+ UI.set_device(0,"i")
60
+ UI.set_device(0,"o")
61
+
62
+ set_listener unless @in_list.length <= 1
63
+ end
64
+
63
65
  #Restart the listener
64
66
  def set_listener
65
67
  @midi_in = GuiListener.new(@in)
@@ -71,15 +73,17 @@ class Proc_Midi
71
73
 
72
74
  #Select the output device
73
75
  def sel_out(id)
76
+ @out = UniMIDI::Output.all[@out_id].close
74
77
  @out = UniMIDI::Output.use(id)
75
78
  @out_id = id
76
79
  end
77
80
 
78
81
  #Select the input device
79
82
  def sel_in(id)
83
+ @in = UniMIDI::Input.all[@in_id].close
80
84
  @in = UniMIDI::Input.use(id)
81
85
  @in_id = id
82
- @midi_in.close
86
+ @midi_in.close unless @midi_in.nil?
83
87
  set_listener
84
88
  end
85
89
 
@@ -109,7 +113,7 @@ class NoteSender
109
113
  def stop
110
114
  Pm.note_rlse(@chan,@note)
111
115
  end
112
-
116
+
113
117
  end
114
118
 
115
119
  Pm = Proc_Midi.new(0,0)
@@ -14,7 +14,7 @@ the Free Software Foundation, either version 3 of the License, or
14
14
  (at your option) any later version.
15
15
 
16
16
  https://github.com/Nornec/Midinous
17
- https://nornec.bandcamp/com
17
+ https://nornec.bandcamp.com
18
18
  https://youtube.com/nornec
19
19
  https://rubygems.org/gems/midinous</property>
20
20
  </object>
@@ -486,7 +486,7 @@ Ctrl+Q -- Quit</property>
486
486
  <property name="visible">True</property>
487
487
  <property name="name">midinous_main</property>
488
488
  <property name="can_focus">False</property>
489
- <property name="resizable">True</property>
489
+ <property name="resizable">false</property>
490
490
  <property name="deletable">True</property>
491
491
  <property name="title" translatable="yes">Midinous</property>
492
492
  <property name="icon_name">accessories-calculator-symbolic</property>
@@ -567,6 +567,29 @@ Ctrl+Q -- Quit</property>
567
567
  </object>
568
568
  </child>
569
569
  </object>
570
+ </child>
571
+ <child>
572
+ <object class="GtkMenuItem">
573
+ <property name="visible">True</property>
574
+ <property name="can_focus">False</property>
575
+ <property name="label" translatable="yes">_Edit</property>
576
+ <property name="use_underline">True</property>
577
+ <child type="submenu">
578
+ <object class="GtkMenu" id="edit_menu">
579
+ <property name="visible">True</property>
580
+ <property name="can_focus">False</property>
581
+ <child>
582
+ <object class="GtkImageMenuItem" id="edit_io">
583
+ <property name="label">_IO Regenerate</property>
584
+ <property name="visible">True</property>
585
+ <property name="can_focus">False</property>
586
+ <property name="use_underline">True</property>
587
+ <property name="use_stock">True</property>
588
+ </object>
589
+ </child>
590
+ </object>
591
+ </child>
592
+ </object>
570
593
  </child>
571
594
  <child>
572
595
  <object class="GtkMenuItem">
@@ -104,6 +104,9 @@ class UI_Elements
104
104
  end
105
105
 
106
106
  #Menus
107
+ def edit_menu
108
+ @builder.get_object("edit_menu")
109
+ end
107
110
  def input_menu
108
111
  @builder.get_object("input_menu")
109
112
  end
@@ -133,6 +136,9 @@ class UI_Elements
133
136
  def file_quit
134
137
  @builder.get_object("file_quit")
135
138
  end
139
+ def edit_io
140
+ @builder.get_object("edit_io")
141
+ end
136
142
  def help_about
137
143
  @builder.get_object("help_about")
138
144
  end
@@ -299,18 +305,29 @@ class UI_Elements
299
305
  def scale_display
300
306
  @builder.get_object("scale_display")
301
307
  end
302
-
303
- 16.times.with_index {|i| @in_channel_items << Gtk::ImageMenuItem.new(label: (i+1).to_s)}
304
- @in_channel_items.each {|i| input_channel_menu.append(i)}
305
- input_channel_menu.show_all
306
-
307
- Pm.in_list.each {|i| @in_device_items << Gtk::ImageMenuItem.new(label: i.name)}
308
- @in_device_items.each {|i| input_menu.append(i)}
309
- input_menu.show_all
310
-
311
- Pm.out_list.each {|o| @out_device_items << Gtk::ImageMenuItem.new(label: o.name)}
312
- @out_device_items.each {|o| output_menu.append(o)}
313
- output_menu.show_all
308
+ def clear_io_menu_items
309
+ @in_channel_items.each {|i| input_channel_menu.remove(i)}
310
+ @in_channel_items = []
311
+ @in_device_items.each {|i| input_menu.remove(i)}
312
+ @in_device_items = []
313
+ @out_device_items.each {|o| output_menu.remove(o)}
314
+ @out_device_items = []
315
+ end
316
+ def set_io_menu_items
317
+ unless Pm.in_list.length <= 1
318
+ 16.times.with_index {|i| @in_channel_items << Gtk::ImageMenuItem.new(label: (i+1).to_s)}
319
+ @in_channel_items.each {|i| input_channel_menu.append(i)}
320
+
321
+ Pm.in_list.each {|i| @in_device_items << Gtk::ImageMenuItem.new(label: i.name)}
322
+ @in_device_items.each {|i| input_menu.append(i)}
323
+ end
324
+ Pm.out_list.each {|o| @out_device_items << Gtk::ImageMenuItem.new(label: o.name)}
325
+ @out_device_items.each {|o| output_menu.append(o)}
326
+
327
+ input_channel_menu.show_all
328
+ input_menu.show_all
329
+ output_menu.show_all
330
+ end
314
331
 
315
332
  def set_device(id,type)
316
333
  case type
@@ -323,7 +340,7 @@ class UI_Elements
323
340
  end
324
341
 
325
342
  def regen_status
326
- unless Pm.in_list.empty?
343
+ unless Pm.in_list.length <= 1
327
344
  status_area.text = "Using: Output[#{Pm.out_list[Pm.out_id].name}] "\
328
345
  "Input[#{Pm.in_list[Pm.in_id].name} Channel: #{Pm.in_chan}]"
329
346
  else
@@ -471,8 +488,10 @@ class UI_Elements
471
488
  t_sig_label.markup = "<b>#{t_sig_label.text}</b>"
472
489
  scale_label.markup = "<b>#{scale_label.text}</b>"
473
490
 
491
+ set_io_menu_items
474
492
  regen_status
475
493
 
494
+
476
495
  #canvas.add_events(Gdk::EventMask::BUTTON_PRESS_MASK.nick) #This points to a nickname, basically a string like "button-press-mask" in this case
477
496
 
478
497
  #Accel groups, parameter 2 is the modifier
@@ -631,6 +650,7 @@ class UI_Elements
631
650
  @current_file = file_chooser.uri
632
651
  operator = @current_file.sub("file:///","")
633
652
  operator = operator.gsub("/","\\")
653
+ operator = operator.gsub("%20"," ")
634
654
 
635
655
  load = IO.binread(operator)
636
656
  load = load.gsub("\r","")
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: midinous
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.4
4
+ version: 1.0.8
5
5
  platform: ruby
6
6
  authors:
7
7
  - James "Nornec" Ratliff
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2019-11-14 00:00:00.000000000 Z
11
+ date: 2019-12-09 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: gtk3
@@ -66,6 +66,7 @@ files:
66
66
  - lib/midinous.rb
67
67
  - lib/midinous/canvas.rb
68
68
  - lib/midinous/constants.rb
69
+ - lib/midinous/extensions.rb
69
70
  - lib/midinous/init.rb
70
71
  - lib/midinous/key_bindings.rb
71
72
  - lib/midinous/logic.rb
@@ -87,7 +88,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
87
88
  requirements:
88
89
  - - "~>"
89
90
  - !ruby/object:Gem::Version
90
- version: 2.5.0
91
+ version: '2.5'
91
92
  required_rubygems_version: !ruby/object:Gem::Requirement
92
93
  requirements:
93
94
  - - ">="