RUIC 0.4.0 → 0.4.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
File without changes
@@ -64,6 +64,7 @@ class UIC::Application
64
64
  presos = presentations
65
65
  presos.find{ |pres| pres.id==initial_id } || presos.first
66
66
  end
67
+ alias_method :main, :main_presentation
67
68
 
68
69
  def main_presentation=(presentation)
69
70
  # TODO: set to Presentation or PresentationAsset
@@ -1,282 +1,288 @@
1
- #encoding: utf-8
2
- class UIC::Asset
3
- class Root
4
- @properties = {}
5
- class << self
6
- attr_reader :name
7
- def properties
8
- (ancestors[1].respond_to?(:properties) ? ancestors[1].properties : {}).merge(@properties)
9
- end
10
-
11
- def each
12
- (@by_name.values - [self]).each{ |klass| yield klass }
13
- end
14
- include Enumerable
15
-
16
- def inspect
17
- "<#{@name}>"
18
- end
19
- end
20
-
21
- def properties
22
- self.class.properties
23
- end
24
-
25
- def at(sub_path)
26
- presentation.at(sub_path,@el)
27
- end
28
- alias_method :/, :at
29
-
30
- attr_accessor :presentation, :el
31
- def initialize( presentation, element )
32
- @presentation = presentation
33
- @el = element
34
- end
35
-
36
- def type
37
- self.class.name
38
- # self.class.name.split('::').last
39
- end
40
-
41
- def parent
42
- presentation.parent_asset(@el)
43
- end
44
-
45
- def children
46
- presentation.child_assets(@el)
47
- end
48
-
49
- def find(criteria={},&block)
50
- criteria[:_under] ||= self
51
- presentation.find(criteria,&block)
52
- end
53
-
54
- # Find the owning component (even if you are a component)
55
- def component
56
- presentation.owning_component(@el)
57
- end
58
-
59
- def component?
60
- @el.name == 'Component'
61
- end
62
-
63
- def master?
64
- presentation.master?(@el)
65
- end
66
-
67
- def slide?
68
- false
69
- end
70
-
71
- def has_slide?(slide_name_or_index)
72
- presentation.has_slide?(@el,slide_name_or_index)
73
- end
74
-
75
- def slides
76
- presentation.slides_for(@el)
77
- end
78
-
79
- def on_slide(slide_name_or_index)
80
- if has_slide?(slide_name_or_index)
81
- UIC::SlideValues.new( self, slide_name_or_index )
82
- end
83
- end
84
-
85
- def path
86
- @path ||= @presentation.path_to(@el)
87
- end
88
-
89
- def name
90
- properties['name'].get( self, presentation.slide_index(@el) )
91
- end
92
-
93
- def name=( new_name )
94
- properties['name'].set( self, new_name, presentation.slide_index(@el) )
95
- end
96
-
97
- # Get the value(s) of an attribute
98
- def [](attribute_name, slide_name_or_index=nil)
99
- if property = properties[attribute_name]
100
- if slide_name_or_index
101
- property.get( self, slide_name_or_index ) if has_slide?(slide_name_or_index)
102
- else
103
- UIC::ValuesPerSlide.new(@presentation,self,property)
104
- end
105
- end
106
- end
107
-
108
- # Set the value of an attribute, either across all slides, or on a particular slide
109
- # el['foo'] = 42
110
- # el['foo',0] = 42
111
- def []=( attribute_name, slide_name_or_index=nil, new_value )
112
- if property = properties[attribute_name] then
113
- property.set(self,new_value,slide_name_or_index)
114
- end
115
- end
116
-
117
- def to_xml
118
- @el.to_xml
119
- end
120
- def inspect
121
- "<asset #{@el.name}##{@el['id']}>"
122
- end
123
-
124
- def to_s
125
- "<#{type} #{path}>"
126
- end
127
-
128
- def ==(other)
129
- (self.class==other.class) && (el==other.el)
130
- end
131
- alias_method :eql?, :==
132
- end
133
-
134
- attr_reader :by_name
135
-
136
- HIER = {}
137
- %w[Asset Slide Scene].each{ |s| HIER[s] = 'Root' }
138
- %w[Node Behavior Effect Image Layer MaterialBase RenderPlugin].each{ |s| HIER[s]='Asset' }
139
- %w[Camera Component Group Light Model Text].each{ |s| HIER[s]='Node' }
140
- %w[Material ReferencedMaterial].each{ |s| HIER[s]='MaterialBase' }
141
-
142
- def initialize(xml)
143
- @by_name = {'Root'=>Root}
144
-
145
- doc = Nokogiri.XML(xml)
146
- hack_in_slide_names!(doc)
147
-
148
- HIER.each do |class_name,parent_class_name|
149
- parent_class = @by_name[parent_class_name]
150
- el = doc.root.at(class_name)
151
- @by_name[class_name] = create_class(el,parent_class,el.name)
152
- UIC::Asset.const_set( el.name, @by_name[class_name] ) # give the class instance a name by pointing a constant to it :/
153
- end
154
-
155
- # Extend well-known classes with script interfaces after they are created
156
- @by_name['State'] = @by_name['Slide']
157
- @by_name['Slide'].instance_eval do
158
- attr_accessor :index, :name
159
- define_method :inspect do
160
- "<slide ##{index} of #{@el['component'] || @el.parent['component']}>"
161
- end
162
- define_method(:slide?){ true }
163
- end
164
-
165
- refmat = @by_name['ReferencedMaterial']
166
- @by_name['MaterialBase'].instance_eval do
167
- define_method :replace_with_referenced_material do
168
- type=='ReferencedMaterial' ? self : presentation.replace_asset( self, 'ReferencedMaterial', name:name )
169
- end
170
- end
171
- end
172
-
173
- # Creates a class from MetaData.xml with accessors for the <Property> listed.
174
- # Instances of the class are associated with a presentation and know how to
175
- # get/set values in that XML based on value types, slides, defaults.
176
- # Also used to create classes from effects, materials, and behavior preambles.
177
- def create_class(el,parent_class,name='CustomAsset')
178
- Class.new(parent_class) do
179
- @name = name
180
- @properties = Hash[ el.css("Property").map do |e|
181
- type = e['type'] || (e['list'] ? 'String' : 'Float')
182
- type = "Float" if type=="float"
183
- property = UIC::Property.const_get(type).new(e)
184
- [ property.name, UIC::Property.const_get(type).new(e) ]
185
- end ]
186
- end
187
- end
188
-
189
- def new_instance(presentation,el)
190
- @by_name[el.name].new(presentation,el)
191
- end
192
-
193
- def hack_in_slide_names!(doc)
194
- doc.at('Slide') << '<Property name="name" formalName="Name" type="String" default="Slide" hidden="True" />'
195
- end
196
- end
197
-
198
- def UIC.Meta(metadata_path)
199
- UIC::Asset.new(File.read(metadata_path,encoding:'utf-8'))
200
- end
201
-
202
- class UIC::SlideCollection
203
- include Enumerable
204
- attr_reader :length
205
- def initialize(slides)
206
- @length = slides.length-1
207
- @slides = slides
208
- @lookup = {}
209
- slides.each do |s|
210
- @lookup[s.index] = s
211
- @lookup[s.name] = s
212
- end
213
- end
214
- def each
215
- @slides.each{ |s| yield(s) }
216
- end
217
- def [](index_or_name)
218
- @lookup[ index_or_name ]
219
- end
220
- def inspect
221
- "[ #{@slides.map(&:inspect).join ', '} ]"
222
- end
223
- def to_ary
224
- @slides
225
- end
226
- end
227
-
228
- class UIC::ValuesPerSlide
229
- def initialize(presentation,asset,property)
230
- raise unless presentation.is_a?(UIC::Presentation)
231
- raise unless asset.is_a?(UIC::Asset::Root)
232
- raise unless property.is_a?(UIC::Property)
233
- @preso = presentation
234
- @asset = asset
235
- @el = asset.el
236
- @property = property
237
- end
238
- def value
239
- values.first
240
- end
241
- def [](slide_name_or_index)
242
- @property.get( @asset, slide_name_or_index )
243
- end
244
- def []=(slide_name_or_index,new_value)
245
- @property.set( @asset, new_value, slide_name_or_index )
246
- end
247
- def linked?
248
- @preso.attribute_linked?(@el,@property.name)
249
- end
250
- def unlink
251
- @preso.unlink_attribute( @el, @property.name )
252
- end
253
- def link
254
- @preso.link_attribute( @el, @property.name )
255
- end
256
- def values
257
- @asset.slides.map{ |s| self[s.name] }
258
- end
259
- def inspect
260
- "<Values of '#{@asset.name}.#{@property.name}' across slides>"
261
- end
262
- alias_method :to_s, :inspect
263
- end
264
-
265
- class UIC::SlideValues
266
- def initialize( asset, slide )
267
- @asset = asset
268
- @slide = slide
269
- end
270
- def [](attribute_name)
271
- @asset[attribute_name,@slide]
272
- end
273
- def []=( attribute_name, new_value )
274
- @asset[attribute_name,@slide] = new_value
275
- end
276
- def method_missing( name, *args, &blk )
277
- asset.send(name,*args,&blk)
278
- end
279
- def inspect
280
- "<#{@asset.inspect} on slide #{@slide.inspect}>"
281
- end
1
+ #encoding: utf-8
2
+ class UIC::Asset
3
+ class Root
4
+ @properties = {}
5
+ class << self
6
+ attr_reader :name
7
+ def properties
8
+ (ancestors[1].respond_to?(:properties) ? ancestors[1].properties : {}).merge(@properties)
9
+ end
10
+
11
+ def each
12
+ (@by_name.values - [self]).each{ |klass| yield klass }
13
+ end
14
+ include Enumerable
15
+
16
+ def inspect
17
+ "<#{@name}>"
18
+ end
19
+ end
20
+
21
+ def properties
22
+ self.class.properties
23
+ end
24
+
25
+ def at(sub_path)
26
+ presentation.at(sub_path,@el)
27
+ end
28
+ alias_method :/, :at
29
+
30
+ attr_accessor :presentation, :el
31
+ def initialize( presentation, element )
32
+ @presentation = presentation
33
+ @el = element
34
+ end
35
+
36
+ def type
37
+ self.class.name
38
+ # self.class.name.split('::').last
39
+ end
40
+
41
+ def parent
42
+ presentation.parent_asset(@el)
43
+ end
44
+
45
+ def children
46
+ presentation.child_assets(@el)
47
+ end
48
+
49
+ def find(criteria={},&block)
50
+ criteria[:_under] ||= self
51
+ presentation.find(criteria,&block)
52
+ end
53
+
54
+ # Find the owning component (even if you are a component)
55
+ def component
56
+ presentation.owning_component(@el)
57
+ end
58
+
59
+ def component?
60
+ @el.name == 'Component'
61
+ end
62
+
63
+ def master?
64
+ presentation.master?(@el)
65
+ end
66
+
67
+ def slide?
68
+ false
69
+ end
70
+
71
+ def has_slide?(slide_name_or_index)
72
+ presentation.has_slide?(@el,slide_name_or_index)
73
+ end
74
+
75
+ def slides
76
+ presentation.slides_for(@el)
77
+ end
78
+
79
+ def on_slide(slide_name_or_index)
80
+ if has_slide?(slide_name_or_index)
81
+ UIC::SlideValues.new( self, slide_name_or_index )
82
+ end
83
+ end
84
+
85
+ def path
86
+ @path ||= @presentation.path_to(@el)
87
+ end
88
+
89
+ def name
90
+ properties['name'].get( self, presentation.slide_index(@el) )
91
+ end
92
+
93
+ def name=( new_name )
94
+ properties['name'].set( self, new_name, presentation.slide_index(@el) )
95
+ end
96
+
97
+ # Get the value(s) of an attribute
98
+ def [](attribute_name, slide_name_or_index=nil)
99
+ if property = properties[attribute_name]
100
+ if slide_name_or_index
101
+ property.get( self, slide_name_or_index ) if has_slide?(slide_name_or_index)
102
+ else
103
+ UIC::ValuesPerSlide.new(@presentation,self,property)
104
+ end
105
+ end
106
+ end
107
+
108
+ # Set the value of an attribute, either across all slides, or on a particular slide
109
+ # el['foo'] = 42
110
+ # el['foo',0] = 42
111
+ def []=( attribute_name, slide_name_or_index=nil, new_value )
112
+ if property = properties[attribute_name] then
113
+ property.set(self,new_value,slide_name_or_index)
114
+ end
115
+ end
116
+
117
+ def to_xml
118
+ @el.to_xml
119
+ end
120
+ def inspect
121
+ "<asset #{@el.name}##{@el['id']}>"
122
+ end
123
+
124
+ def to_s
125
+ "<#{type} #{path}>"
126
+ end
127
+
128
+ def ==(other)
129
+ (self.class==other.class) && (el==other.el)
130
+ end
131
+ alias_method :eql?, :==
132
+ end
133
+
134
+ attr_reader :by_name
135
+
136
+ HIER = {}
137
+ %w[Asset Slide Scene].each{ |s| HIER[s] = 'Root' }
138
+ %w[Node Behavior Effect Image Layer MaterialBase PathAnchorPoint RenderPlugin].each{ |s| HIER[s]='Asset' }
139
+ %w[Alias Camera Component Group Light Model Text Path].each{ |s| HIER[s]='Node' }
140
+ %w[Material ReferencedMaterial].each{ |s| HIER[s]='MaterialBase' }
141
+
142
+ def initialize(xml)
143
+ @by_name = {'Root'=>Root}
144
+
145
+ doc = Nokogiri.XML(xml)
146
+ hack_in_slide_names!(doc)
147
+
148
+ HIER.each do |class_name,parent_class_name|
149
+ parent_class = @by_name[parent_class_name]
150
+ el = doc.root.at(class_name)
151
+ @by_name[class_name] = create_class(el,parent_class,el.name)
152
+ UIC::Asset.const_set( el.name, @by_name[class_name] ) # give the class instance a name by pointing a constant to it :/
153
+ end
154
+
155
+ # Extend well-known classes with script interfaces after they are created
156
+ @by_name['State'] = @by_name['Slide']
157
+ @by_name['Slide'].instance_eval do
158
+ attr_accessor :index, :name
159
+ define_method :inspect do
160
+ "<slide ##{index} of #{@el['component'] || @el.parent['component']}>"
161
+ end
162
+ define_method(:slide?){ true }
163
+ end
164
+
165
+ refmat = @by_name['ReferencedMaterial']
166
+ @by_name['MaterialBase'].instance_eval do
167
+ define_method :replace_with_referenced_material do
168
+ type=='ReferencedMaterial' ? self : presentation.replace_asset( self, 'ReferencedMaterial', name:name )
169
+ end
170
+ end
171
+
172
+ @by_name['Path'].instance_eval do
173
+ define_method(:anchors){ find _type:'PathAnchorPoint' }
174
+ end
175
+
176
+ end
177
+
178
+ # Creates a class from MetaData.xml with accessors for the <Property> listed.
179
+ # Instances of the class are associated with a presentation and know how to
180
+ # get/set values in that XML based on value types, slides, defaults.
181
+ # Also used to create classes from effects, materials, and behavior preambles.
182
+ def create_class(el,parent_class,name='CustomAsset')
183
+ Class.new(parent_class) do
184
+ @name = name
185
+ @properties = Hash[ el.css("Property").map do |e|
186
+ type = e['type'] || (e['list'] ? 'String' : 'Float')
187
+ type = "Float" if type=="float"
188
+ property = UIC::Property.const_get(type).new(e)
189
+ [ property.name, UIC::Property.const_get(type).new(e) ]
190
+ end ]
191
+ end
192
+ end
193
+
194
+ def new_instance(presentation,el)
195
+ klass = @by_name[el.name] || create_class(el,@by_name['Asset'],el.name)
196
+ klass.new(presentation,el)
197
+ end
198
+
199
+ def hack_in_slide_names!(doc)
200
+ doc.at('Slide') << '<Property name="name" formalName="Name" type="String" default="Slide" hidden="True" />'
201
+ end
202
+ end
203
+
204
+ def UIC.Meta(metadata_path)
205
+ UIC::Asset.new(File.read(metadata_path,encoding:'utf-8'))
206
+ end
207
+
208
+ class UIC::SlideCollection
209
+ include Enumerable
210
+ attr_reader :length
211
+ def initialize(slides)
212
+ @length = slides.length-1
213
+ @slides = slides
214
+ @lookup = {}
215
+ slides.each do |s|
216
+ @lookup[s.index] = s
217
+ @lookup[s.name] = s
218
+ end
219
+ end
220
+ def each
221
+ @slides.each{ |s| yield(s) }
222
+ end
223
+ def [](index_or_name)
224
+ @lookup[ index_or_name ]
225
+ end
226
+ def inspect
227
+ "[ #{@slides.map(&:inspect).join ', '} ]"
228
+ end
229
+ def to_ary
230
+ @slides
231
+ end
232
+ end
233
+
234
+ class UIC::ValuesPerSlide
235
+ def initialize(presentation,asset,property)
236
+ raise unless presentation.is_a?(UIC::Presentation)
237
+ raise unless asset.is_a?(UIC::Asset::Root)
238
+ raise unless property.is_a?(UIC::Property)
239
+ @preso = presentation
240
+ @asset = asset
241
+ @el = asset.el
242
+ @property = property
243
+ end
244
+ def value
245
+ values.first
246
+ end
247
+ def [](slide_name_or_index)
248
+ @property.get( @asset, slide_name_or_index )
249
+ end
250
+ def []=(slide_name_or_index,new_value)
251
+ @property.set( @asset, new_value, slide_name_or_index )
252
+ end
253
+ def linked?
254
+ @preso.attribute_linked?(@el,@property.name)
255
+ end
256
+ def unlink
257
+ @preso.unlink_attribute( @el, @property.name )
258
+ end
259
+ def link
260
+ @preso.link_attribute( @el, @property.name )
261
+ end
262
+ def values
263
+ @asset.slides.map{ |s| self[s.name] }
264
+ end
265
+ def inspect
266
+ "<Values of '#{@asset.name}.#{@property.name}' across slides>"
267
+ end
268
+ alias_method :to_s, :inspect
269
+ end
270
+
271
+ class UIC::SlideValues
272
+ def initialize( asset, slide )
273
+ @asset = asset
274
+ @slide = slide
275
+ end
276
+ def [](attribute_name)
277
+ @asset[attribute_name,@slide]
278
+ end
279
+ def []=( attribute_name, new_value )
280
+ @asset[attribute_name,@slide] = new_value
281
+ end
282
+ def method_missing( name, *args, &blk )
283
+ asset.send(name,*args,&blk)
284
+ end
285
+ def inspect
286
+ "<#{@asset.inspect} on slide #{@slide.inspect}>"
287
+ end
282
288
  end