Ruby: key_frames function, improvements in scripts

Originally committed to SVN as r934.
This commit is contained in:
pomyk 2007-02-08 18:29:50 +00:00
parent 99cc856076
commit 8d837d6a90
4 changed files with 69 additions and 30 deletions

View file

@ -42,6 +42,7 @@
#include "text_file_reader.h" #include "text_file_reader.h"
#include "options.h" #include "options.h"
#include "vfr.h" #include "vfr.h"
#include "video_context.h"
#include "main.h" #include "main.h"
#include "frame_main.h" #include "frame_main.h"
#include "subs_grid.h" #include "subs_grid.h"
@ -115,6 +116,7 @@ namespace Automation4 {
rb_define_module_function(RubyAegisub, "text_extents",reinterpret_cast<RB_HOOK>(&RubyTextExtents), 2); rb_define_module_function(RubyAegisub, "text_extents",reinterpret_cast<RB_HOOK>(&RubyTextExtents), 2);
rb_define_module_function(RubyAegisub, "frame_to_time",reinterpret_cast<RB_HOOK>(&RubyFrameToTime), 1); rb_define_module_function(RubyAegisub, "frame_to_time",reinterpret_cast<RB_HOOK>(&RubyFrameToTime), 1);
rb_define_module_function(RubyAegisub, "time_to_frame",reinterpret_cast<RB_HOOK>(&RubyTimeToFrame), 1); rb_define_module_function(RubyAegisub, "time_to_frame",reinterpret_cast<RB_HOOK>(&RubyTimeToFrame), 1);
rb_define_module_function(RubyAegisub, "key_frames",reinterpret_cast<RB_HOOK>(&RubyKeyFrames), 0);
rb_define_module_function(rb_eException, "set_backtrace",reinterpret_cast<RB_HOOK>(&backtrace_hook), 1); rb_define_module_function(rb_eException, "set_backtrace",reinterpret_cast<RB_HOOK>(&backtrace_hook), 1);
rb_define_module_function(RubyScript::RubyAegisub, "progress_set",reinterpret_cast<RB_HOOK>(&RubyProgressSink::RubySetProgress), 1); rb_define_module_function(RubyScript::RubyAegisub, "progress_set",reinterpret_cast<RB_HOOK>(&RubyProgressSink::RubySetProgress), 1);
rb_define_module_function(RubyScript::RubyAegisub, "progress_task",reinterpret_cast<RB_HOOK>(&RubyProgressSink::RubySetTask), 1); rb_define_module_function(RubyScript::RubyAegisub, "progress_task",reinterpret_cast<RB_HOOK>(&RubyProgressSink::RubySetTask), 1);
@ -164,7 +166,7 @@ namespace Automation4 {
void RubyScript::Destroy() void RubyScript::Destroy()
{ {
if(loaded) { if(loaded) {
ruby_finalize(); // broken in 1.9 ?_? // ruby_finalize(); // broken in 1.9 ?_?
} }
// remove features // remove features
@ -232,6 +234,29 @@ namespace Automation4 {
return Qnil; return Qnil;
} }
//////////////////////////////////////////////////////////////////////////
// output: [[keyframe indices], [keyframe times in ms]]
VALUE RubyScript::RubyKeyFrames(VALUE self)
{
if(!VideoContext::Get()->KeyFramesLoaded())
return Qnil;
wxArrayInt key_frames = VideoContext::Get()->GetKeyFrames();
VALUE frames = rb_ary_new();
VALUE times = rb_ary_new();
for(int i = 0; i < key_frames.size(); ++i)
{
rb_ary_push(frames, INT2FIX(key_frames[i]));
rb_ary_push(times, INT2FIX(VFR_Output.GetTimeAtFrame(key_frames[i], true)));
}
VALUE res = rb_ary_new();
rb_ary_push(res, frames);
rb_ary_push(res, times);
return res;
}
wxString RubyScript::GetError() wxString RubyScript::GetError()
{ {
return wxString(error + _T("\n") + backtrace); return wxString(error + _T("\n") + backtrace);

View file

@ -168,6 +168,7 @@ namespace Automation4 {
static VALUE RubyTextExtents(VALUE self, VALUE style, VALUE text); static VALUE RubyTextExtents(VALUE self, VALUE style, VALUE text);
static VALUE RubyFrameToTime(VALUE self, VALUE frame); static VALUE RubyFrameToTime(VALUE self, VALUE frame);
static VALUE RubyTimeToFrame(VALUE self, VALUE time); static VALUE RubyTimeToFrame(VALUE self, VALUE time);
static VALUE RubyKeyFrames(VALUE self);
static VALUE backtrace_hook(VALUE self, VALUE backtr); static VALUE backtrace_hook(VALUE self, VALUE backtr);
public: public:

View file

@ -17,10 +17,9 @@ def k_replace_macro(subs, sel, act)
cfg = k_replace_cfg(subs, nil) cfg = k_replace_cfg(subs, nil)
ok, opt = display_dialog(cfg, nil) ok, opt = display_dialog(cfg, nil)
return if not ok # cancelled return if not ok # cancelled
# write_options(subs, $script_name, opt)
i = 0 write_options(subs, {$script_name => opt})
subs.each do |l| subs.each do |l|
i += 1
k_replace(l, opt[:templ], opt[:strip]) if l[:class] == :dialogue && # replace if its dialogue k_replace(l, opt[:templ], opt[:strip]) if l[:class] == :dialogue && # replace if its dialogue
(opt[:style] =="" || l[:style] == opt[:style]) # and has the right style (opt[:style] =="" || l[:style] == opt[:style]) # and has the right style
end end
@ -32,6 +31,7 @@ def k_replace_filter(subs, opt)
k_replace(l, opt[:templ], opt[:strip]) if l[:class] == :dialogue && # replace if its dialogue k_replace(l, opt[:templ], opt[:strip]) if l[:class] == :dialogue && # replace if its dialogue
opt[:style] =="" || l[:style] == opt[:style] # and has the right style opt[:style] =="" || l[:style] == opt[:style] # and has the right style
end end
write_options(subs, {$script_name => opt})
return subs return subs
end end
@ -53,11 +53,12 @@ Calculation example:
\\t(%$start+$dur*2%,$end,\\fscx90) \\t(%$start+$dur*2%,$end,\\fscx90)
head head
opt = read_options(subs, $script_name) opt = read_options(subs, $script_name)
s_name = $script_name.to_sym
cfg = ScriptCfg.new # helper class for building dialogs cfg = ScriptCfg.new # helper class for building dialogs
cfg.header header_text, :x => 1, :width => 1 cfg.header header_text, :x => 1, :width => 1
cfg.edit :templ, "template", :text => opt[:templ] cfg.edit :templ, "template", :text => opt[s_name][:templ]
cfg.dropdown :style, "Style", :items => styles, :value => opt[:style] cfg.dropdown :style, "Style", :items => styles, :value => opt[s_name][:style]
cfg.checkbox :strip, "", :label => "Strip tags?", :value => (opt[:strip] == "true" ? true : false) cfg.checkbox :strip, "", :label => "Strip tags?", :value => (opt[s_name][:strip] == "true" ? true : false)
cfg.to_ary # convert to array cfg.to_ary # convert to array
end end

View file

@ -61,31 +61,43 @@ module Aegisub
end end
# inserts line with options into the file # inserts lines with options into [Script Info] section
def write_options(subs, name, opt, sep = "~~") def write_options(subs, opt, sep = "~~")
i = 0 subs.collect! do |l|
while subs[i][:class] != :info do if l[:class] == :info
i += 1 info = true
value = opt.delete(l[:key])
l[:value] = value.instance_of?(Hash) ? value.to_a.flatten!.join(sep) : value.to_s if value
l
else
if info
r = [l]
opt.each do |key, val|
r << {:class => :info, :key => key,
:value => value.instance_of?(Hash) ? value.to_a.flatten!.join(sep) : value.to_s,
:section => "[Script Info]"}
end
info = false
r
else
l
end
end end
while subs[i][:class] == :info do
i += 1
end end
l = {:class => :info, :key => name, :value => opt.to_a.flatten!.join(sep), :section => "[Script Info]"}
subs = subs.insert(i, l)
end end
# returns hash with options loaded from the subs # returns a hash with options from [Script Info] section
def read_options(subs, name, sep = "~~") def read_options(subs, name, sep = "~~")
i = 0 opt = {}
i += 1 while subs[i][:class] != :info subs.each { |l| opt[l[:key].to_sym] = l[:value] if l[:class] == :info }
i += 1 while subs[i][:class] == :info && subs[i][:key] != name n_sym = name.to_sym
return {} if subs[i][:class] != :info if opt[n_sym] # parsing of script specific options
a = subs[i][:value].split(sep) a = opt[n_sym].split(sep)
h = {} h = {}
(a.size/2).times do |j| (a.size/2).times { |j| h[a[2*j].to_sym] = a[2*j+1] }
h[a[2*j].to_sym] = a[2*j+1] opt[n_sym] = h
end end
return h return opt
end end
end end