From 2c25c90e2aaf57a7508a7988f58b2784d5071a7e Mon Sep 17 00:00:00 2001 From: Tilman Sauerbeck Date: Sat, 26 Mar 2005 01:32:38 +0000 Subject: [PATCH] Initial commit. --- AUTHORS | 5 + COPYING | 24 ++ ChangeLog | 87 ++++++++ Rakefile | 32 +++ TODO | 6 + bin/redact | 5 + lib/redact/app.rb | 230 +++++++++++++++++++ lib/redact/part.rb | 506 ++++++++++++++++++++++++++++++++++++++++++ lib/redact/program.rb | 187 ++++++++++++++++ lib/redact/redact.rb | 347 +++++++++++++++++++++++++++++ lib/redact/source.rb | 78 +++++++ test/crossfade.rb | 54 +++++ test/red_rect.rb | 9 + test/test_basic.rb | 29 +++ 14 files changed, 1599 insertions(+) create mode 100644 AUTHORS create mode 100644 COPYING create mode 100644 ChangeLog create mode 100644 Rakefile create mode 100644 TODO create mode 100755 bin/redact create mode 100644 lib/redact/app.rb create mode 100644 lib/redact/part.rb create mode 100644 lib/redact/program.rb create mode 100644 lib/redact/redact.rb create mode 100644 lib/redact/source.rb create mode 100644 test/crossfade.rb create mode 100644 test/red_rect.rb create mode 100644 test/test_basic.rb diff --git a/AUTHORS b/AUTHORS new file mode 100644 index 0000000..ebd7770 --- /dev/null +++ b/AUTHORS @@ -0,0 +1,5 @@ +-- +$Id: AUTHORS 1 2005-03-26 01:32:38Z tilman $ +++ + +Tilman Sauerbeck (tilman at code-monkey de) diff --git a/COPYING b/COPYING new file mode 100644 index 0000000..06616aa --- /dev/null +++ b/COPYING @@ -0,0 +1,24 @@ +-- +$Id: COPYING 1 2005-03-26 01:32:38Z tilman $ +++ + +Copyright (c) 2005 Tilman Sauerbeck (tilman at code-monkey de) + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/ChangeLog b/ChangeLog new file mode 100644 index 0000000..2574181 --- /dev/null +++ b/ChangeLog @@ -0,0 +1,87 @@ +-- +$Id: ChangeLog 1 2005-03-26 01:32:38Z tilman $ +++ + +2005-03-22 Tilman Sauerbeck (tilman at code-monkey de) + * lib/redact/app.rb: The default extension for Edje files is + 'edj' now +2005-03-20 Tilman Sauerbeck (tilman at code-monkey de) + * lib/redact/redact.rb, test/{red_rect,crossfade}.rb: + Use symbols for part/program types. Also, you need to provide + the part/program type now, there's no default anymore. This + fixes/works around the problem where you accidentally defined + a part when you just wanted to get a reference to an existing + part + +2005-03-19 Tilman Sauerbeck (tilman at code-monkey de) + * test/crossfade.rb: Updated to work with + TextDescription#set_fit change + +2005-03-17 Tilman Sauerbeck (tilman at code-monkey de) + * lib/redact/app.rb: Store the source of files that are read + with File.read, too + * lib/redact/{source,app}.rb: Write a fontmap, so edje_decc can + dump the fonts that are used in the Edje + * lib/redact/part.rb: Added TextDescription#set_fit + +2005-03-16 Tilman Sauerbeck (tilman at code-monkey de) + * lib/redact/{source,app}.rb: Write theme source to EET file, + too + * bin/redact, lib/redact/app.rb, test/test_basic.rb: Improved + commandline option handling + * lib/redact/redact.rb: Set the 'compiler' value in the + Edje_File EDD + * lib/redact/app.rb: Add support for the 'image_dir' and 'font_dir' + options. They aren't evaluated yet, though. + +2005-03-14 Tilman Sauerbeck (tilman at code-monkey de) + * lib/redact/redact.rb: Fixed stupid exceptions + +2005-03-06 Tilman Sauerbeck (tilman at code-monkey de) + * lib/redact/program.rb: Fixed a typo that resulted in an invalid + reader method + * lib/redact/{redact,program}.rb: Added support for basic + programs (signal, source, after parameters only) + * Rakefile: use FileUtils to for the install task + +2005-03-02 Tilman Sauerbeck (tilman at code-monkey de) + * lib/redact/part.rb: Set the default offset for rel2 to -1,-1 + * lib/redact/part.rb: Enable smoothing by default for non-image + parts, too. + * lib/redact/part.rb: Use sane defaults for the other fill + parameters + * lib/redact/part.rb: Fixed default values for outline and + shadow color + +2005-02-26 Tilman Sauerbeck (tilman at code-monkey de) + * lib/redact/app.rb: Don't indent empty lines of Embryo code + * lib/redact/{app, redact, part}.rb: Added support for embedded + fonts + * lib/redact/redact.rb: When doing part/program-lookups in + Embryo code, use non-greedy matching of quotes + * lib/redact/program.rb: signal and source are set to empty + strings by default now, instead of nil + * lib/redact/part.rb: Rename color2 and color3 to outline_color + and shadow_color, respectively. + * lib/redact/part.rb: Make outline_color and shadow_color + writeable + * lib/redact/part.rb: Renamed clip_to to clip and made it + readable + * lib/redact/part.rb: Made TextDescription::text_min writeable + * lib/redact/part.rb: Made TextDescription::text_align writeable + * lib/redact/part.rb: Added support for tween images + * lib/redact/{redact, part}.rb: Split Part into various classes + * lib/redact/{redact, part, program}.rb: Code cleanup + * lib/redact/{redact, part}.rb: Don't make Part::type readable + +2005-02-23 Tilman Sauerbeck (tilman at code-monkey de) + * lib/redact/app.rb: Use edje-config to figure out the + Embryo include directory + +2005-02-22 Tilman Sauerbeck (tilman at code-monkey de) + * lib/redact/app.rb: Enable zlib compression for the edje_file + and collections EET entries + * lib/redact/app.rb, lib/redact/redact.rb: Reworked the way + Embryo scripts are saved/processed + * lib/redact/app.rb: Delete the temporary redact.sma file when + we're done with it diff --git a/Rakefile b/Rakefile new file mode 100644 index 0000000..9900d36 --- /dev/null +++ b/Rakefile @@ -0,0 +1,32 @@ +# $Id: Rakefile 1 2005-03-26 01:32:38Z tilman $ + +require "rake/clean" +require "rake/testtask" + +CLOBBER.include(FileList["test/*.eet"]) + +sitelibdir = Config::CONFIG["sitelibdir"] +destdir = "#{ENV["DESTDIR"]}" +prefix = ENV["PREFIX"] || "/usr/local" + +task :install do |t| + ddir = destdir + prefix + "/bin" + FileUtils::Verbose.install("bin/redact", ddir, :mode => 0755) + + ddir = destdir + sitelibdir + "/redact" + + FileUtils::Verbose.mkdir(ddir) unless File.directory?(ddir) + + ["app", "part", "program", "redact"].each do |file| + FileUtils::Verbose.install("lib/redact/#{file}.rb", ddir, + :mode => 0644) + end +end + +task :test + +Rake::TestTask.new do |t| + t.libs << "lib" + t.test_files = FileList["test/test*.rb"] + t.verbose = true +end diff --git a/TODO b/TODO new file mode 100644 index 0000000..16eac2f --- /dev/null +++ b/TODO @@ -0,0 +1,6 @@ +-- +$Id: TODO 1 2005-03-26 01:32:38Z tilman $ +++ + +* Add support for the various 'fill' properties in ImageDescription +* Respect --image_dir and --font_dir command line switches diff --git a/bin/redact b/bin/redact new file mode 100755 index 0000000..f33931c --- /dev/null +++ b/bin/redact @@ -0,0 +1,5 @@ +#!/usr/bin/ruby -w + +require "redact/app" + +Redact::App.new(ARGV).run diff --git a/lib/redact/app.rb b/lib/redact/app.rb new file mode 100644 index 0000000..de66628 --- /dev/null +++ b/lib/redact/app.rb @@ -0,0 +1,230 @@ +#-- +# $Id: app.rb 1 2005-03-26 01:32:38Z tilman $ +# +# Copyright (c) 2005 Tilman Sauerbeck (tilman at code-monkey de) +# +# Permission is hereby granted, free of charge, to any person obtaining +# a copy of this software and associated documentation files (the +# "Software"), to deal in the Software without restriction, including +# without limitation the rights to use, copy, modify, merge, publish, +# distribute, sublicense, and/or sell copies of the Software, and to +# permit persons to whom the Software is furnished to do so, subject to +# the following conditions: +# +# The above copyright notice and this permission notice shall be +# included in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +require "redact/redact.rb" +require "redact/source.rb" +require "ftools" +require "pathname" +require "ostruct" +require "optparse" + +SCRIPT_LINES__ = {} + +module Redact + class App + def initialize(args) + @filename = nil + @options = OpenStruct.new + @option_parser = parse_args(args) + + @options.input = args.first + if @options.input.nil? + puts @option_parser.help + exit + end + + @options.output ||= @options.input.sub(/.[^.]+$/, ".edj") + end + + def run + EDJE.clear + SCRIPT_LINES__.clear + + begin + load @options.input + rescue LoadError + raise("Cannot load '#{@options.input}'") + end + + @filename = Pathname.new(@options.input).cleanpath.to_s + + if EDJE.collections.empty? + raise("No collections found") + end + + amx = compile_embryo + + Eet::File.open(@options.output, "w") do |ef| + dump_amx(amx, ef) + + dump_header(ef) + dump_collections(ef) + dump_fonts(ef) + dump_images(ef) + dump_source(ef) + dump_fontmap(ef) + end + end + + private + def parse_args(args) + OptionParser.new do |o| + o.banner = "Usage: redact [options] INPUT_FILE" + + o.separator "" + o.separator "Specific options:" + + o.on("-o", "--output OUTPUT_FILE", + "Write Edje to OUTPUT_FILE") do |file| + @options.output = file + end + + o.on("--image_dir IMAGE_DIR", + "Add IMAGE_DIR to the image lookup path") do |dir| + @options.image_dir = dir + end + + o.on("--font_dir FONT_DIR", + "Add FONT_DIR to the font lookup path") do |dir| + @options.font_dir = dir + end + + o.separator "" + o.separator "Common options:" + + o.on_tail("-h", "--help", "Show this message") do + puts o + exit + end + + o.on_tail("--version", "Show version") do + puts <" + dump_sma(tf, col) + tf.flush + + out = "/tmp/redact.amx" + File.rm_f(out) + + incl = `edje-config --datadir`.strip + c = "embryo_cc " + + "-i #{incl}/include " + + "-o #{out} #{tf.path}" + system(c) + + ret[col.id] = IO.read(out) + File.rm_f(out) + File.unlink(tf.path) + end + end + + ret + end + + def dump_sma(tf, col) + if col.has_embryo?(false) + tf.puts col.script.to_embryo(col) + end + + col.programs.each_value do |p| + next unless p.is_a?(ExecScriptProgram) + + s = p.script.to_embryo(col).gsub(/^(.+)$/, "\t\\1") + + tf.puts <(b) + @id <=> b.id + end + + def clip=(part) + if self == part + raise(ArgumentError, "cannot clip part to itself") + elsif part.nil? + @clip = nil + elsif part.collection != @collection + raise(ArgumentError, "parts' collections not identical") + else + @clip = part + end + end + + def description(name = "default", value = 0.0) + d = @descriptions[desc_key(name, value)] + + block_given? ? (yield d) : d + end + + protected + def description_class + Description + end + + def to_eet_name + "Edje_Part" + end + + def to_eet_properties + other_desc = @descriptions.dup + other_desc.delete(desc_key("default", 0.0)) + + confine_id = @dragable.confine.nil? ? + -1 : @dragable.confine.id + + {"name" => [@name], + "id" => [@id], + "type" => [@type, :char], + "effect" => [0, :char], + "mouse_events" => [@mouse_events], + "repeat_events" => [@repeat_events], + "clip_to_id" => [@clip.nil? ? -1 : @clip.id], + "default_desc" => [description("default", 0.0)], + "other_desc" => [other_desc], + "dragable.x" => [@dragable.enabled[0], :char], + "dragable.step_x" => [@dragable.step[0]], + "dragable.count_x" => [@dragable.count[0]], + "dragable.y" => [@dragable.enabled[1], :char], + "dragable.step_y" => [@dragable.step[1]], + "dragable.count_y" => [@dragable.count[1]], + "dragable.counfine_id" => [confine_id]} # not a typo! + end + + private + def desc_key(name, value) + name + "\0" + value.to_s + end + end + + class SwallowPart < Part + def initialize(collection, id, name) + super + + @type = TYPE_SWALLOW + end + end + + class TextPart < Part + EFFECT_NONE = 0 + EFFECT_PLAIN = 1 + EFFECT_OUTLINE = 2 + EFFECT_SOFT_OUTLINE = 3 + EFFECT_SHADOW = 4 + EFFECT_SOFT_SHADOW = 5 + EFFECT_OUTLINE_SHADOW = 6 + EFFECT_OUTLINE_SOFT_SHADOW = 7 + + attr_accessor :effect + + def initialize(collection, id, name) + super + + @type = TYPE_TEXT + @effect = EFFECT_NONE + end + + protected + def description_class + TextDescription + end + + def to_eet_properties + super.merge!({"effect" => [@effect, :char]}) + end + end + + class ImagePart < Part + def initialize(collection, id, name) + super + + @type = TYPE_IMAGE + end + + protected + def description_class + ImageDescription + end + end + + class Dragable + attr_reader :enabled, :step, :count, :confine + + def initialize(part) + @part= part + + @enabled = [false, false] + @step = [0, 0] + @count = [0, 0] + @confine = nil + end + + def confine=(part) + if part == self + raise(ArgumentError, "cannot confine part to itself") + elsif !part.nil? && part.collection != @part.collection + raise(ArgumentError, "parts' collections not identical") + else + @confine = part + end + end + end + + class Relation + attr_reader :rel, :to_id, :offset + + def initialize(rel, offset) + @rel = [rel, rel] + @to_id = [-1, -1] + @offset = [offset, offset] + end + + def set_rel(x, y) + @rel = [x, y] + end + + def set_offset(x, y) + @offset = [x, y] + end + + def to=(part) + @to_id = [].fill(part.nil? ? -1 : part.id, 0..1) + end + end + + class Description + attr_reader :rel + attr_accessor :visible + + def initialize(name = "default", value = 0.0) + @name = name.to_str.dup.freeze + @value = value.freeze + @visible = true + @align = [0.5, 0.5] + @min = [0, 0] + @max = [-1, -1] + @step_x = 0 + @step_y = 0 + @rel = [Relation.new(0.0, 0), Relation.new(1.0, -1)] + @color = [].fill(255, 0..3) + @color_class = "" + end + + def set_align(x = 0.5, y = 0.5) + @align = [x, y] + end + + def set_size(w, h) + set_min(w, h) + set_max(w, h) + end + + def set_min(w, h) + @min = [w, h] + end + + def set_max(w, h) + @max = [w, h] + end + + def color=(c) + @color = parse_hex_color(c) + end + + protected + def parse_hex_color(c) + md = c.match(/^#?(([[:xdigit:]]{2}){1,4})$/) + if md.nil? + raise(ArgumentError, "Argument is not a hex string") + end + + pairs = md.captures.shift.split(/(..)/).delete_if do |item| + item == "" + end + + pairs.push("00") while pairs.length < 3 + pairs.push("ff") if pairs.length == 3 + + pairs.map { |p| p.hex } + end + + def to_eet_name + "Edje_Part_Description" + end + + def to_eet_properties + {"state.name" => [@name], + "state.value" => [@value, :double], + "visible" => [@visible], + "align.x" => [@align[0], :double], + "align.y" => [@align[1], :double], + "min.w" => [@min[0]], + "min.h" => [@min[1]], + "max.w" => [@max[0]], + "max.h" => [@max[1]], + "step.x" => [@step_x], + "step.y" => [@step_y], + "aspect.min" => [0.0, :double], + "aspect.max" => [0.0, :double], + "aspect.prefer" => [0, :char], + "rel1.relative_x" => [@rel[0].rel[0], :double], + "rel1.relative_y" => [@rel[0].rel[1], :double], + "rel1.offset_x" => [@rel[0].offset[0]], + "rel1.offset_y" => [@rel[0].offset[1]], + "rel1.id_x" => [@rel[0].to_id[0]], + "rel1.id_y" => [@rel[0].to_id[1]], + "rel2.relative_x" => [@rel[1].rel[0], :double], + "rel2.relative_y" => [@rel[1].rel[1], :double], + "rel2.offset_x" => [@rel[1].offset[0]], + "rel2.offset_y" => [@rel[1].offset[1]], + "rel2.id_x" => [@rel[1].to_id[0]], + "rel2.id_y" => [@rel[1].to_id[1]], + "color_class" => [@color_class], + "color.r" => [@color[0], :char], + "color.g" => [@color[1], :char], + "color.b" => [@color[2], :char], + "color.a" => [@color[3], :char], + + # image properties + "image.id" => [-1], + "image.tween_list" => [nil], + "border.l" => [0], + "border.r" => [0], + "border.t" => [0], + "border.b" => [0], + "fill.smooth" => [true], + "fill.pos_rel_x" => [0.0, :double], + "fill.pos_abs_x" => [0], + "fill.rel_x" => [1.0, :double], + "fill.abs_x" => [0], + "fill.pos_rel_y" => [0.0, :double], + "fill.pos_abs_y" => [0], + "fill.rel_y" => [1.0, :double], + "fill.abs_y" => [0], + + # text properties + "color2.r" => [0, :char], + "color2.g" => [0, :char], + "color2.b" => [0, :char], + "color2.a" => [255, :char], + "color3.r" => [0, :char], + "color3.g" => [0, :char], + "color3.b" => [0, :char], + "color3.a" => [128, :char], + "text.text" => [""], + "text.text_class" => [""], + "text.font" => [""], + "text.size" => [0], + "text.fit_x" => [false], + "text.fit_y" => [false], + "text.min_x" => [0], + "text.min_y" => [0], + "text.align.x" => [0.0, :double], + "text.align.y" => [0.0, :double], + "text.id_source" => [-1], + "text.id_text_source" => [-1]} + end + end + + class Tween + def initialize(image) + @id = image.id + end + + def to_eet_name + "Edje_Part_Image_Id" + end + end + + class Tweens < Array + def <<(im) + image = EDJE.image_dir.find { |e| e.filename == im } + if image.nil? + image = ImageDirectoryEntry.new(im) + EDJE.image_dir << image + end + + super(Tween.new(image)) + end + end + + class ImageDescription < Description + attr_reader :image, :auto_rel, :tweens + + def initialize(name = "default", value = 0.0) + super + + @image = nil + @tweens = Tweens.new + @border = [0, 0, 0, 0] + @fill_smooth = true + @auto_rel = false + end + + def image=(im) + return if !@image.nil? && im == @image.filename + + @image = EDJE.image_dir.find { |e| e.filename == im } + if @image.nil? + @image = ImageDirectoryEntry.new(im) + EDJE.image_dir << @image + end + + self.auto_rel = @auto_rel + end + + def auto_rel=(b) + @auto_rel = b + + if @auto_rel && !@image.nil? + off = @rel[0].offset + + @rel[1].set_rel(0.0, 0.0) + @rel[1].set_offset(off[0] + @image.image.width - 1, + off[1] + @image.image.height - 1) + end + end + + def set_border(l = 0, r = 0, t = 0, b = 0) + @border = [r, r, t, b] + end + + def to_eet_properties + super.merge!( + {"image.id" => [@image.nil? ? -1 : @image.id], + "image.tween_list" => [@tweens], + "border.l" => [@border[0]], + "border.r" => [@border[1]], + "border.t" => [@border[2]], + "border.b" => [@border[3]], + "fill.smooth" => [@fill_smooth], + "fill.pos_rel_x" => [0.0, :double], + "fill.pos_abs_x" => [0], + "fill.rel_x" => [1.0, :double], + "fill.abs_x" => [0], + "fill.pos_rel_y" => [0.0, :double], + "fill.pos_abs_y" => [0], + "fill.rel_y" => [1.0, :double], + "fill.abs_y" => [0]}) + end + end + + class TextDescription < Description + attr_reader :font + attr_accessor :text, :font_size + + def initialize(name = "default", value = 0.0) + super + + @outline_color = [0, 0, 0, 255] + @shadow_color = [0, 0, 0, 128] + @text = "" + @text_class = "" + @font = "" + @font_size = 0 + @fit = [false, false] + @text_min = [false, false] + @text_align = [0.5, 0.5] + @text_id_source = -1 + @text_id_text_source = -1 + end + + def set_fit(x = false, y = false) + @fit = [x, y] + end + + def set_text_min(x = false, y = false) + @text_min = [x, y] + end + + def set_text_align(x = 0.5, y = 0.5) + @text_align = [x, y] + end + + def font=(f) + md = f.to_str.match(/.*\.ttf/) + unless md.nil? + found = EDJE.font_dir.find { |font| font.filename == f } + if found.nil? + EDJE.font_dir << FontDirectoryEntry.new(f) + end + end + + @font = f.dup + end + + def outline_color=(c) + @outline_color = parse_hex_color(c) + end + + def shadow_color=(c) + @shadow_color = parse_hex_color(c) + end + + def to_eet_properties + super.merge!( + {"color2.r" => [@outline_color[0], :char], + "color2.g" => [@outline_color[1], :char], + "color2.b" => [@outline_color[2], :char], + "color2.a" => [@outline_color[3], :char], + "color3.r" => [@shadow_color[0], :char], + "color3.g" => [@shadow_color[1], :char], + "color3.b" => [@shadow_color[2], :char], + "color3.a" => [@shadow_color[3], :char], + "text.text" => [@text], + "text.text_class" => [@text_class], + "text.font" => [@font], + "text.size" => [@font_size], + "text.fit_x" => [@fit[0]], + "text.fit_y" => [@fit[1]], + "text.min_x" => [@text_min[0]], + "text.min_y" => [@text_min[1]], + "text.align.x" => [@text_align[0], :double], + "text.align.y" => [@text_align[1], :double], + "text.id_source" => [@text_id_source], + "text.id_text_source" => [@text_id_text_source]}) + end + end +end diff --git a/lib/redact/program.rb b/lib/redact/program.rb new file mode 100644 index 0000000..78f2ca9 --- /dev/null +++ b/lib/redact/program.rb @@ -0,0 +1,187 @@ +#-- +# $Id: program.rb 1 2005-03-26 01:32:38Z tilman $ +# +# Copyright (c) 2005 Tilman Sauerbeck (tilman at code-monkey de) +# +# Permission is hereby granted, free of charge, to any person obtaining +# a copy of this software and associated documentation files (the +# "Software"), to deal in the Software without restriction, including +# without limitation the rights to use, copy, modify, merge, publish, +# distribute, sublicense, and/or sell copies of the Software, and to +# permit persons to whom the Software is furnished to do so, subject to +# the following conditions: +# +# The above copyright notice and this permission notice shall be +# included in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +module Redact + class Program + TYPE_BASE = 0 + TYPE_SET_STATE = 1 + TYPE_STOP_PROGRAM = 2 + TYPE_EMIT_SIGNAL = 3 + #TYPE_SET_DRAG_VAL = 4 + #TYPE_STEP_DRAG_VAL = 5 + #TYPE_PAGE_DRAG_VAL = 6 + TYPE_EXEC_SCRIPT = 7 + + include Comparable + + attr_reader :collection, :id, :name, :after + attr_accessor :signal, :source, :in_from, :in_range + + def initialize(collection, id, name) + @collection = collection + @id = id + + @name = name.to_str.dup.freeze + @type = TYPE_BASE + + @after = ProgramArgs.new(collection) + @in_from = 0.0 + @in_range = 0.0 + @signal = "" + @source = "" + end + + def <=>(b) + @id <=> b.id + end + + def to_eet_name + "Edje_Program" + end + + def to_eet_properties + {"id" => [@id], + "name" => [@name], + "action" => [@type], + "signal" => [@signal], + "source" => [@source], + "in.from" => [@in_from, :double], + "in.range" => [@in_range, :double], + "after" => [@after]} + end + end + + class SetStateProgram < Program + MODE_LINEAR = 1 + MODE_SINUSOIDAL = 2 + MODE_ACCELERATE = 3 + MODE_DECELERATE = 4 + + attr_reader :targets + attr_accessor :state, :value, :mode, :time + + def initialize(collection, id, name) + super + + @type = TYPE_SET_STATE + @state = "default" + @value = 0.0 + @mode = MODE_LINEAR + @time = 0.0 + @targets = ProgramArgs.new(collection) + end + + def to_eet_properties + super.merge!( + {"state" => [@state], + "value" => [@value, :double], + "tween.mode" => [@mode], + "tween.time" => [@time, :double], + "targets" => [@targets]}) + end + end + + class StopProgramProgram < Program + def initialize(collection, id, name) + super + + @type = TYPE_STOP_PROGRAM + @targets = ProgramArgs.new(collection) + end + + def to_eet_properties + super.merge!({"targets" => [@targets]}) + end + end + + class EmitSignalProgram < Program + attr_accessor :emission_signal, :emission_source + + def initialize(collection, id, name) + super + + @type = TYPE_EMIT_SIGNAL + @emission_signal = nil + @emission_source = nil + end + + def to_eet_properties + super.merge!( + {"state" => [@emission_signal], + "state2" => [@emission_source]}) + end + end + + class ExecScriptProgram < Program + attr_accessor :script + + def initialize(collection, id, name) + super + + @type = TYPE_EXEC_SCRIPT + @script = nil + end + end + + class ProgramArgs < Array + attr_reader :collection + + def initialize(collection) + @collection = collection + end + + def <<(v) + if v.collection != @collection + raise(ArgumentError, "items not in the same collection") + end + + super + end + end + + class ProgramArg + attr_reader :collection + + def initialize(v) + @collection = v.collection + @id = v.id + end + + def to_eet_properties + {"id" => [@id]} + end + end + + class ProgramAfter < ProgramArg + def to_eet_name + "Edje_Program_After" + end + end + + class ProgramTarget < ProgramArg + def to_eet_name + "Edje_Program_Target" + end + end +end diff --git a/lib/redact/redact.rb b/lib/redact/redact.rb new file mode 100644 index 0000000..59740f7 --- /dev/null +++ b/lib/redact/redact.rb @@ -0,0 +1,347 @@ +#-- +# $Id: redact.rb 1 2005-03-26 01:32:38Z tilman $ +# +# Copyright (c) 2005 Tilman Sauerbeck (tilman at code-monkey de) +# +# Permission is hereby granted, free of charge, to any person obtaining +# a copy of this software and associated documentation files (the +# "Software"), to deal in the Software without restriction, including +# without limitation the rights to use, copy, modify, merge, publish, +# distribute, sublicense, and/or sell copies of the Software, and to +# permit persons to whom the Software is furnished to do so, subject to +# the following conditions: +# +# The above copyright notice and this permission notice shall be +# included in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +require "eet" +require "imlib2" +require "redact/part" +require "redact/program" + +class Object + undef :id +end + +class String + def to_embryo(collection) + unless strip.length > 0 + raise(Redact::RedactError, "invalid embryo code") + end + + s = strip.dup + + {"part" => collection.parts, + "program" => collection.programs}.each do |entity, ary| + s.gsub!(/#{entity.upcase}:\"(.*?)\"/) do |m| + found = ary.find { |(k, p)| p.name == $1 } + if found.nil? + raise(Redact::RedactError, + "#{entity} not found - #{$1}") + else + found.last.id + end + end + end + + s + end +end + +module Redact + VERSION = "0.0.1" + + class RedactError < StandardError; end + + class Edje + attr_reader :collections, :data, :collection_dir, :image_dir, + :font_dir + + def initialize + clear + end + + def clear + @font_dir = FontDirectory.new + @image_dir = ImageDirectory.new + @collection_dir = CollectionDirectory.new + + @collections = Hash.new do |h, k| + c = Collection.new(k, h.size) + + @collection_dir << CollectionDirectoryEntry.new(c) + h[k] = c + end + + @data = DataHash.new + end + + def collection(name) + c = @collections[name] + + block_given? ? (yield c) : c + end + + def to_eet_name + "Edje_File" + end + + def to_eet_properties + {"compiler" => ["redact"], + "version" => [2], + "feature_ver" => [1], + "font_dir" => [@font_dir, :sub], + "image_dir" => [@image_dir, :sub], + "collection_dir" => [@collection_dir, :sub], + "data" => [@data]} + end + end + + class DataHash < Hash + def [](key) + super.value + end + + def []=(key, value) + super(key, HashEntry.new(key, value)) + end + end + + class HashEntry + attr_reader :key, :value + + def initialize(key, value) + @key = key.to_str.dup.freeze + @value = value.to_str.dup.freeze + end + + def to_eet_name + "Edje_Data" + end + end + + class FontDirectory < Array + def to_eet_name + "Edje_Font_Directory" + end + + def to_eet_properties + {"entries" => [self]} + end + end + + class FontDirectoryEntry + attr_reader :filename + + def initialize(filename) + @filename = filename.to_str.dup.freeze + end + + def to_eet_name + "Edje_Font_Directory_Entry" + end + + def to_eet_properties + {"entry" => [@filename]} + end + end + + class ImageDirectory < Array + def <<(entry) + super + + entry.id = size - 1 + end + + def to_eet_name + "Edje_Image_Directory" + end + + def to_eet_properties + {"entries" => [self]} + end + end + + class ImageDirectoryEntry + attr_reader :filename, :image, :id + + def initialize(filename) + @filename = filename.to_str.dup.freeze + @image = Imlib2::Image.load(@filename) + @id = -1 + @source_type = 1 # COMP + @source_param = 1 # COMP + end + + def id=(id) + if id < 0 + raise(ArgumentError, "invalid ID - #{id}") + elsif @id != -1 + raise(RedactError, "ID already set") + else + @id = id + end + end + + def to_eet_name + "Edje_Image_Directory_Entry" + end + + def to_eet_properties + {"entry" => [@filename], + "source_type" => [@source_type], + "source_param" => [@source_param], + "id" => [@id]} + end + end + + class CollectionDirectory < Array + def to_eet_name + "Edje_Part_Collection_Directory" + end + + def to_eet_properties + {"entries" => [self]} + end + end + + class CollectionDirectoryEntry + def initialize(col) + @name = col.name.to_str.dup.freeze + @id = col.id + end + + def to_eet_name + "Edje_Part_Collection_Directory_Entry" + end + + def to_eet_properties + {"entry" => [@name], + "id" => [@id]} + end + end + + class Collection + attr_reader :name, :id, :data, :min, :max, :parts, :programs + attr_accessor :script + + def initialize(name, id) + @name = name.to_str.dup.freeze + @id = id + + @min = [0, 0] + @max = [0, 0] + @data = DataHash.new + + @parts = {} + @programs = {} + + @script = nil + end + + def part(name, type = :invalid) + p = @parts[name] + if p.nil? + klass = case type + when :rect + Part + when :swallow + SwallowPart + when :text + TextPart + when :image + ImagePart + else + raise(ArgumentError, + "invalid program type - #{type.to_s}") + end + + p = klass.new(self, @parts.size, name) + @parts[name] = p + end + + block_given? ? (yield p) : p + end + + def program(name, type = :invalid) + p = @programs[name] + if p.nil? + klass = case type + when :base + Program + when :set_state + SetStateProgram + when :stop_program + StopProgramProgram + when :emit_signal + EmitSignalProgram + when :exec_script + ExecScriptProgram + else + raise(ArgumentError, + "invalid program type - #{type.to_s}") + end + + p = klass.new(self, @programs.size, name) + @programs[name] = p + end + + block_given? ? (yield p) : p + end + + def set_size(w, h) + set_min(w, h) + set_max(w, h) + end + + def set_min(w, h) + @min = [w, h] + end + + def set_max(w, h) + @max = [w, h] + end + + def has_embryo?(search_programs = true) + if !@script.nil? && @script.to_str.strip.length > 0 + true + elsif search_programs + p = @programs.find do |(k, p)| + p.is_a?(ExecScriptProgram) + end + + !p.nil? + end + end + + def to_eet_name + "Edje_Part_Collection" + end + + def to_eet_properties + # sort parts and programs by id, since edje doesn't sort + # them on load + parts = @parts.to_a.map { |(key, value)| value }.sort + programs = @programs.to_a.map { |(key, value)| value }.sort + + {"id" => [@id], + "parts" => [parts], + "programs" => [programs], + "data" => [@data], + "prop.min.w" => [@min[0]], + "prop.min.h" => [@min[1]], + "prop.max.w" => [@max[0]], + "prop.max.h" => [@max[1]]} + end + end + + EDJE = Redact::Edje.new +end diff --git a/lib/redact/source.rb b/lib/redact/source.rb new file mode 100644 index 0000000..2662aff --- /dev/null +++ b/lib/redact/source.rb @@ -0,0 +1,78 @@ +#-- +# $Id: source.rb 1 2005-03-26 01:32:38Z tilman $ +# +# Copyright (c) 2005 Tilman Sauerbeck (tilman at code-monkey de) +# +# Permission is hereby granted, free of charge, to any person obtaining +# a copy of this software and associated documentation files (the +# "Software"), to deal in the Software without restriction, including +# without limitation the rights to use, copy, modify, merge, publish, +# distribute, sublicense, and/or sell copies of the Software, and to +# permit persons to whom the Software is furnished to do so, subject to +# the following conditions: +# +# The above copyright notice and this permission notice shall be +# included in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +module Redact + class SourceFile + attr_reader :filename, :contents + + def initialize(filename, contents) + @filename = filename.to_str.dup.freeze + @contents = contents.to_str.dup.freeze + end + + def to_eet_name + "srcfile" + end + + def to_eet_properties + {"name" => [@filename], + "file" => [@contents]} + end + end + + class SourceFiles < Array + def to_eet_name + "srcfile_list" + end + + def to_eet_properties + {"list" => [self]} + end + end + + class FontMapEntry + def initialize(font) + @font = font + end + + def to_eet_name + "font" + end + + def to_eet_properties + {"file" => [@font.filename], + "name" => [@font.filename]} + end + end + + class FontMap < Array + def to_eet_name + "font_list" + end + + def to_eet_properties + {"list" => [self]} + end + end +end diff --git a/test/crossfade.rb b/test/crossfade.rb new file mode 100644 index 0000000..7e132f2 --- /dev/null +++ b/test/crossfade.rb @@ -0,0 +1,54 @@ +# $Id: crossfade.rb 1 2005-03-26 01:32:38Z tilman $ + +include Redact + +EDJE.collection("crossfade") do |c| + c.part("background", :rect).description do |d| + d.color = "#ffffff" + end + + c.part("rect_red", :rect) do |p| + p.description do |d| + d.color = "#00ff0000" + d.rel[1].set_rel(1.0, 0.0) + end + + p.description("default", 1.0) do |d| + d.color = "#ff" + d.rel[1].set_rel(1.0, 0.4) + end + end + + c.part("rect_green", :rect) do |p| + p.description do |d| + d.color = "#ff000080" + d.rel[0].set_rel(0.0, 1.0) + end + + p.description("default", 1.0) do |d| + d.color = "#00ff" + d.rel[0].set_rel(0.0, 0.6) + end + end + + c.part("text", :text) do |p| + p.description do |d| + d.color = "#00" + + d.text = "cuddletech" + d.font = "Vera" + d.font_size = 12 + d.set_fit(true, false) + end + end + + c.program("animate", :set_state) do |p| + p.signal = "mouse,clicked,1" + p.source = "background" + p.value = 1.0 + p.mode = SetStateProgram::MODE_ACCELERATE + p.time = 1.0 + p.targets << ProgramTarget.new(c.part("rect_red")) + p.targets << ProgramTarget.new(c.part("rect_green")) + end +end diff --git a/test/red_rect.rb b/test/red_rect.rb new file mode 100644 index 0000000..5f12d7f --- /dev/null +++ b/test/red_rect.rb @@ -0,0 +1,9 @@ +# $Id: red_rect.rb 1 2005-03-26 01:32:38Z tilman $ + +include Redact + +EDJE.collection("red_rect") do |c| + c.part("rect", :rect) do |p| + p.description.color = "#ff" + end +end diff --git a/test/test_basic.rb b/test/test_basic.rb new file mode 100644 index 0000000..48dc0d5 --- /dev/null +++ b/test/test_basic.rb @@ -0,0 +1,29 @@ +# $Id: test_basic.rb 1 2005-03-26 01:32:38Z tilman $ + +require "redact/app" +require "test/unit" +require "ftools" + +class TestRedact < Test::Unit::TestCase + def test_red_rect + title = "red_rect" + base = File.join(File.dirname(__FILE__), title) + file = base + ".rb" + args = [file, "-o", file + ".eet"] + + assert_nothing_raised do + Redact::App.new(args).run + end + end + + def test_crossfade + title = "crossfade" + base = File.join(File.dirname(__FILE__), title) + file = base + ".rb" + args = [file, "-o", file + ".eet"] + + assert_nothing_raised do + Redact::App.new(args).run + end + end +end -- 2.30.2