Rev. | 23 |
---|---|
大小 | 5,931 字节 |
时间 | 2012-01-21 18:01:59 |
作者 | toshinagata1964 |
Log Message | Version 0.6.1 |
# Copyright (c) 2010-2012 Toshi Nagata. All rights reserved.
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation version 2 of the License.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
class Sequence
# The commands in this file are hardcoded so that the names should not be modified
def change_control_number
hash = RubyDialog.run("Change Control Number") {
@bind_global_settings = "change_control_number_dialog"
layout(1,
layout(2,
item(:text, :title=>"Old control number"),
item(:textfield, :width=>40, :range=>[0, 127], :tag=>"old"),
item(:text, :title=>"New control number"),
item(:textfield, :width=>40, :range=>[0, 127], :tag=>"new")),
item(:checkbox, :title=>"Change only editable tracks", :tag=>"editable_only"),
item(:checkbox, :title=>"Change only selected events", :tag=>"selection_only"))
}
if hash[:status] == 0
old = Integer(hash["old"])
new = Integer(hash["new"])
editable_only = hash["editable_only"]
selection_only = hash["selection_only"]
each_track { |tr|
next if editable_only && !tr.editable?
sel = (selection_only ? tr.selection : tr.all_events)
sel = sel.select { |pt| pt.kind == :control && pt.code == old }
sel.modify_code([new]) # modify_code(new) offsets the control numbers, which is not what we want
}
end
end
def shift_selected_events
hash = RubyDialog.run("Shift Selected Events") {
@bind_global_settings = "shift_selected_events_dialog"
layout(1,
item(:text, :title=>"Shift amount"),
layout(6,
item(:text, :title=>"bar"),
item(:textfield, :width=>50, :tag=>"bar"),
item(:text, :title=>"beat"),
item(:textfield, :width=>50, :tag=>"beat"),
item(:text, :title=>"tick"),
item(:textfield, :width=>50, :tag=>"tick")),
item(:checkbox, :title=>"Shift backward", :tag=>"backward"))
}
p hash
if hash[:status] == 0
bar = hash["bar"].to_f
beat = hash["beat"].to_f
tick = hash["tick"].to_f
sign = (hash["backward"] == 0 ? 1 : -1)
if (bar == 0 && beat == 0)
delta = sign * tick
else
range = tick_for_selection(true)
return if range[0] < 0
origin = tick_to_measure(range[0])
delta = measure_to_tick(origin[0] + sign * bar, origin[1] + sign * beat, origin[2] + sign * tick) - range[0]
end
p self
each_track { |tr|
puts tr
next if !tr.editable?
tr.selection.modify_tick(delta)
# The following code does _not_ work:
# tr.each_selected { |pt| pt.tick = pt.tick + delta }
# This is because changing tick may change the event position, so that 'pt'
# may not point the correct event
}
end
end
def scale_selected_time_dialog
s_tick, e_tick = self.editing_range
return [] if s_tick < 0
duration = e_tick - s_tick
s_str = tick_to_measure(s_tick).join(".")
e_str = tick_to_measure(e_tick).join(".")
new_e_tick = e_tick
new_duration = duration
seq = self
hash = RubyDialog.run("Scale Selected Time") {
@bind_global_settings = "scale_selected_time_dialog"
str_to_tick = proc { |str|
a = str.scan(/\d+/)
while a.length < 3; a.unshift("1"); end
seq.measure_to_tick(a[0].to_i, a[1].to_i, a[2].to_i)
}
layout(1,
layout(2,
item(:text, :title=>"Start:"),
item(:textfield, :width=>100, :tag=>"start", :value=>s_str,
:action=>proc { |it|
new_e_tick = s_tick + value("new_duration").to_i
s_tick = str_to_tick.call(it[:value])
if s_tick > e_tick
s_tick = e_tick
set_value("start", seq.tick_to_measure(s_tick).join("."))
end
duration = e_tick - s_tick
set_value("duration", sprintf("%d", duration))
new_duration = new_e_tick - s_tick
set_value("new_duration", sprintf("%d", new_duration))
}),
item(:text, :title=>"End:"),
item(:textfield, :width=>100, :tag=>"end", :value=>e_str,
:action=>proc { |it|
e_tick = str_to_tick.call(it[:value])
if s_tick > e_tick
e_tick = s_tick
set_value("end", seq.tick_to_measure(e_tick).join("."))
end
e_tick = s_tick + 1 if s_tick >= e_tick
duration = e_tick - s_tick
set_value("duration", sprintf("%d", duration))
}),
item(:text, :title=>"Duration:"),
item(:textfield, :width=>50, :tag=>"duration", :value=>sprintf("%d", duration),
:action=>proc { |it|
duration = it[:value].to_i
if duration < 0
duration = 0
set_value("duration", "0")
end
e_tick = s_tick + duration
set_value("end", seq.tick_to_measure(e_tick).join("."))
})
),
layout(2,
item(:radio, :title=>"Specify end tick", :tag=>"new_end_radio", :value=>1),
item(:textfield, :width=>100, :tag=>"new_end", :value=>e_str,
:action=>proc { |it|
val_tick = str_to_tick.call(it[:value])
if val_tick != new_e_tick
set_value("new_duration", sprintf("%d", val_tick - s_tick))
set_value("new_duration_radio", 0)
set_value("new_end_radio", 1)
new_e_tick = val_tick
new_duration = new_e_tick - s_tick
end
}),
item(:radio, :title=>"Specify duration", :tag=>"new_duration_radio"),
item(:textfield, :width=>50, :tag=>"new_duration", :value=>duration.to_s,
:action=>proc { |it|
d = Integer(it[:value])
if d != new_duration
val_str = seq.tick_to_measure(s_tick + d).join(".")
set_value("new_end", val_str)
set_value("new_duration_radio", 1)
set_value("new_end_radio", 0)
new_duration = d
new_e_tick = s_tick + d
end
}),
item(:checkbox, :title=>"Insert TEMPO event to keep absolute timings", :tag=>"insert_tempo"),
-1)
)
}
if hash[:status] == 0
return [s_tick, e_tick, new_duration, hash["insert_tempo"]]
else
return []
end
end
end