Basic pango markup helpers
[amazing.git] / lib / amazing / widget.rb
blobf38f7ad1ae759f7eb08a9037927f3a839d3e8490
1 # Copyright (C) 2008 Dag Odenhall <dag.odenhall@gmail.com>
2 # Licensed under the Academic Free License version 3.0
4 require 'amazing/helpers/pango_markup'
5 require 'erb'
7 module Amazing
9   # Raised by widgets, and is then rescued and logged
10   class WidgetError < Exception
11   end
13   # Parent class for widget construction, example:
14   #
15   #   class Clock < Widget
16   #     description "Displays date and time"
17   #     dependency "some/library", "how to get the library (url, gem name...)"
18   #     option :time_format, "Time format as described in DATE(1)", "%R"
19   #     field :time, "Formatted time"
20   #     default "@time"
21   # 
22   #     init do
23   #       @time = Time.now.strftime(@time_format)
24   #       raise WidgetError, "An error occured!" if some_error?
25   #     end
26   #   end
27   class Widget
28     include Helpers::PangoMarkup
29     include ERB::Util
31     def initialize(opts={})
32       self.class.dependencies.each do |name, description|
33         begin
34           require name
35         rescue LoadError
36           raise WidgetError, "Missing dependency #{name.inspect}#{if description then " [#{description}]" end}"
37         end
38       end
39       self.class.options.each do |key, value|
40         instance_variable_set "@#{key}".to_sym, value[:default]
41       end
42       opts.each do |key, value|
43         instance_variable_set "@#{key}".to_sym, value
44       end
45       self.class.fields.each do |key, value|
46         instance_variable_set "@#{key}".to_sym, value[:default]
47       end
48       self.class.init.each do |block|
49         instance_eval(&block)
50       end
51       @default = case self.class.default
52       when Proc
53         instance_eval(&self.class.default)
54       when String
55         instance_eval(self.class.default)
56       end
57     end
59     def self.description(description=nil)
60       if description
61         @description = description
62       else
63         @description
64       end
65     end
67     def self.dependency(name, description=nil)
68       @dependencies ||= {}
69       @dependencies[name] = description
70     end
72     def self.dependencies
73       @dependencies || {}
74     end
76     def self.option(name, description=nil, default=nil)
77       @options ||= {}
78       @options[name] = {:description => description, :default => default}
79     end
81     def self.options
82       @options || {}
83     end
85     def self.field(name, description=nil, default=nil)
86       @fields ||= {}
87       @fields[name] = {:description => description, :default => default}
88     end
90     def self.fields
91       @fields || {}
92     end
94     def self.default(format=nil, &block) # :yields:
95       if format
96         @default = format
97       elsif block
98         @default = block
99       else
100         @default
101       end
102     end
104     def self.init(&block) # :yields:
105       if block
106         @init ||= []
107         @init << block
108       else
109         @init
110       end
111     end
113     def formatize(format=nil)
114       ERB.new(case format
115       when Proc
116         instance_eval(&format)
117       when String
118         instance_eval(format)
119       else
120         case self.class.default
121         when Proc
122           instance_eval(&self.class.default)
123         when String
124           instance_eval(self.class.default)
125         end
126       end.to_s).result(binding())
127     end
128   end