RUIC 0.4.6 → 0.5.0
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.
- checksums.yaml +4 -4
- data/.yardopts +3 -3
- data/HISTORY +63 -52
- data/README.md +220 -220
- data/bin/ruic +12 -11
- data/gui/TODO +2 -2
- data/gui/appattributesmodel.rb +51 -51
- data/gui/appelementsmodel.rb +126 -126
- data/gui/launch.rb +19 -19
- data/gui/makefile +14 -14
- data/gui/resources/style/dark.qss +459 -459
- data/gui/window.rb +90 -90
- data/gui/window.ui +753 -753
- data/lib/ruic.rb +182 -175
- data/lib/ruic/application.rb +2 -2
- data/lib/ruic/assets.rb +436 -421
- data/lib/ruic/attributes.rb +170 -165
- data/lib/ruic/behaviors.rb +1 -1
- data/lib/ruic/interfaces.rb +23 -1
- data/lib/ruic/presentation.rb +100 -34
- data/lib/ruic/ripl-after-result.rb +24 -24
- data/lib/ruic/statemachine.rb +1 -1
- data/lib/ruic/version.rb +3 -3
- data/ruic.gemspec +25 -25
- data/test/MetaData-simple.xml +28 -28
- data/test/MetaData.xml +435 -435
- data/test/customclasses.ruic +31 -21
- data/test/filtering.ruic +43 -43
- data/test/futureassets.ruic +8 -8
- data/test/nonmaster.ruic +0 -0
- data/test/paths.ruic +18 -18
- data/test/projects/CustomClasses/CustomClasses.uia +7 -7
- data/test/projects/CustomClasses/CustomClasses.uip +7 -1
- data/test/projects/CustomClasses/FutureAsset.uip +17 -17
- data/test/projects/CustomClasses/scripts/DataDrivenTime.lua +58 -0
- data/test/projects/CustomClasses/scripts/TimeDrivenAttribute.lua +49 -0
- data/test/projects/Paths/Paths.uia +4 -4
- data/test/projects/Paths/Paths.uip +98 -98
- data/test/projects/SimpleScene/SimpleScene.uia +4 -4
- data/test/projects/SimpleScene/SimpleScene.uip +35 -35
- data/test/properties.ruic +82 -82
- data/test/referencematerials.ruic +52 -52
- data/test/usage.ruic +20 -20
- metadata +32 -4
data/lib/ruic/attributes.rb
CHANGED
@@ -1,165 +1,170 @@
|
|
1
|
-
#encoding: utf-8
|
2
|
-
class UIC::Property
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
def
|
9
|
-
def
|
10
|
-
def
|
11
|
-
def
|
12
|
-
def
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
end
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
class
|
34
|
-
self.default = 0
|
35
|
-
def get(asset,slide); super.
|
36
|
-
end
|
37
|
-
class
|
38
|
-
self.default =
|
39
|
-
def get(asset,slide); super
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
end
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
def
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
@object
|
106
|
-
|
107
|
-
end
|
108
|
-
def
|
109
|
-
raise "ObjectRef
|
110
|
-
@
|
111
|
-
write_value!
|
112
|
-
end
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
class
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
@property
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
def
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
alias_method :
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
end
|
1
|
+
#encoding: utf-8
|
2
|
+
class UIC::Property
|
3
|
+
# Each property has a generic default value
|
4
|
+
class << self; attr_accessor :default; end
|
5
|
+
|
6
|
+
# …and instances of a particular property can have their own default value
|
7
|
+
attr_accessor :default
|
8
|
+
def initialize(el); @el = el; end
|
9
|
+
def name; @name||=@el['name']; end
|
10
|
+
def type; @type||=@el['type']; end
|
11
|
+
def formal; @formal||=@el['formalName'] || @el['name']; end
|
12
|
+
def min; @el['min']; end
|
13
|
+
def max; @el['max']; end
|
14
|
+
def description; @desc||=@el['description']; end
|
15
|
+
def default; @default ||= (@el['default'] || self.class.default); end
|
16
|
+
def get(asset,slide)
|
17
|
+
if asset.slide? || asset.has_slide?(slide)
|
18
|
+
asset.presentation.get_attribute(asset,name,slide) || default
|
19
|
+
end
|
20
|
+
end
|
21
|
+
def set(asset,new_value,slide_name_or_index)
|
22
|
+
asset.presentation.set_attribute(asset,name,slide_name_or_index,new_value)
|
23
|
+
end
|
24
|
+
def inspect
|
25
|
+
"<#{type} '#{name}'>"
|
26
|
+
end
|
27
|
+
|
28
|
+
class String < self
|
29
|
+
self.default = ''
|
30
|
+
end
|
31
|
+
MultiLineString = String
|
32
|
+
|
33
|
+
class Float < self
|
34
|
+
self.default = 0.0
|
35
|
+
def get(asset,slide); super.to_f; end
|
36
|
+
end
|
37
|
+
class Long < self
|
38
|
+
self.default = 0
|
39
|
+
def get(asset,slide); super.to_i; end
|
40
|
+
end
|
41
|
+
class Boolean < self
|
42
|
+
self.default = false
|
43
|
+
def get(asset,slide); super=='True'; end
|
44
|
+
def set(asset,new_value,slide_name_or_index)
|
45
|
+
super( asset, new_value ? 'True' : 'False', slide_name_or_index )
|
46
|
+
end
|
47
|
+
end
|
48
|
+
class Vector < self
|
49
|
+
self.default = '0 0 0'
|
50
|
+
def get(asset,slide)
|
51
|
+
VectorValue.new(asset,self,slide,super)
|
52
|
+
end
|
53
|
+
def set(asset,new_value,slide_name_or_index)
|
54
|
+
new_value = new_value.join(' ') if new_value.is_a?(Array)
|
55
|
+
super( asset, new_value, slide_name_or_index )
|
56
|
+
end
|
57
|
+
end
|
58
|
+
Rotation = Vector
|
59
|
+
Color = Vector
|
60
|
+
Float2 = Vector
|
61
|
+
class Image < self
|
62
|
+
self.default = nil
|
63
|
+
def get(asset,slide)
|
64
|
+
if idref = super
|
65
|
+
result = asset.presentation.asset_by_id( idref[1..-1] )
|
66
|
+
# slide ? result.on_slide( slide ) : result
|
67
|
+
# Getting the asset on a particular slide makes it weird
|
68
|
+
end
|
69
|
+
end
|
70
|
+
def set(asset,new_value,slide)
|
71
|
+
raise "Setting image attributes not yet supported"
|
72
|
+
end
|
73
|
+
end
|
74
|
+
class Texture < String
|
75
|
+
def get(asset,slide)
|
76
|
+
if path=super
|
77
|
+
path.empty? ? nil : path.gsub( '\\', '/' ).sub( /^.\// ,'' )
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
class ObjectRef < self
|
83
|
+
self.default = nil
|
84
|
+
def get(asset,slide)
|
85
|
+
ref = super
|
86
|
+
type = :absolute
|
87
|
+
obj = nil
|
88
|
+
unless ref=='' || ref.nil?
|
89
|
+
type = ref[0]=='#' ? :absolute : :path
|
90
|
+
ref = type==:absolute ? asset.presentation.asset_by_id( ref[1..-1] ) : asset.presentation.at( ref, asset )
|
91
|
+
end
|
92
|
+
ObjectReference.new(asset,self,slide,ref,type)
|
93
|
+
end
|
94
|
+
def set(asset,new_object,slide)
|
95
|
+
get(asset,slide).object = new_object
|
96
|
+
end
|
97
|
+
end
|
98
|
+
|
99
|
+
class ObjectReference
|
100
|
+
attr_reader :object, :type
|
101
|
+
def initialize(asset,property,slide,object=nil,type=nil)
|
102
|
+
@asset = asset
|
103
|
+
@name = property.name
|
104
|
+
@slide = slide
|
105
|
+
@object = object
|
106
|
+
@type = type
|
107
|
+
end
|
108
|
+
def object=(new_object)
|
109
|
+
raise "ObjectRef must be set to an asset (not a #{new_object.class.name})" unless new_object.is_a?(UIC::MetaData::AssetBase)
|
110
|
+
@object = new_object
|
111
|
+
write_value!
|
112
|
+
end
|
113
|
+
def type=(new_type)
|
114
|
+
raise "ObjectRef types must be either :absolute or :path (not #{new_type.inspect})" unless [:absolute,:path].include?(new_type)
|
115
|
+
@type = new_type
|
116
|
+
write_value!
|
117
|
+
end
|
118
|
+
private
|
119
|
+
def write_value!
|
120
|
+
path = case @object
|
121
|
+
when NilClass then ""
|
122
|
+
else case @type
|
123
|
+
when :absolute then "##{@object.el['id']}"
|
124
|
+
when :path then @asset.presentation.path_to( @object, @asset ).sub(/^[^:.]+:/,'')
|
125
|
+
# when :root then @asset.presentation.path_to( @object ).sub(/^[^:.]+:/,'')
|
126
|
+
end
|
127
|
+
end
|
128
|
+
@asset.presentation.set_attribute( @asset, @name, @slide, path )
|
129
|
+
end
|
130
|
+
end
|
131
|
+
|
132
|
+
Import = String #TODO: a real class
|
133
|
+
Mesh = String #TODO: a real class
|
134
|
+
Renderable = String #TODO: a real class
|
135
|
+
Font = String #TODO: a real class
|
136
|
+
FontSize = Long
|
137
|
+
|
138
|
+
StringListOrInt = String #TODO: a real class
|
139
|
+
|
140
|
+
class VectorValue
|
141
|
+
attr_reader :x, :y, :z
|
142
|
+
def initialize(asset,property,slide,str)
|
143
|
+
@asset = asset
|
144
|
+
@property = property
|
145
|
+
@slide = slide
|
146
|
+
@x, @y, @z = str.split(/\s+/).map(&:to_f)
|
147
|
+
end
|
148
|
+
def setall
|
149
|
+
@property.set( @asset, to_s, @slide )
|
150
|
+
end
|
151
|
+
def x=(n); @x=n; setall end
|
152
|
+
def y=(n); @y=n; setall end
|
153
|
+
def z=(n); @z=n; setall end
|
154
|
+
alias_method :r, :x
|
155
|
+
alias_method :g, :y
|
156
|
+
alias_method :b, :z
|
157
|
+
alias_method :r=, :x=
|
158
|
+
alias_method :g=, :y=
|
159
|
+
alias_method :b=, :z=
|
160
|
+
def inspect
|
161
|
+
"<#{@asset.path}.#{@property.name}: #{self}>"
|
162
|
+
end
|
163
|
+
def to_s
|
164
|
+
to_a.join(' ')
|
165
|
+
end
|
166
|
+
def to_a
|
167
|
+
[x,y,z]
|
168
|
+
end
|
169
|
+
end
|
170
|
+
end
|
data/lib/ruic/behaviors.rb
CHANGED
data/lib/ruic/interfaces.rb
CHANGED
@@ -8,7 +8,7 @@ module UIC::FileBacked
|
|
8
8
|
|
9
9
|
# @param relative [String] a file path relative to this file.
|
10
10
|
# @return [String] the full path resolved relative to this file.
|
11
|
-
def
|
11
|
+
def resolve_file_path( relative )
|
12
12
|
File.expand_path( relative.gsub('\\','/'), File.dirname(file) )
|
13
13
|
end
|
14
14
|
|
@@ -63,6 +63,7 @@ module UIC::ElementBacked
|
|
63
63
|
end
|
64
64
|
|
65
65
|
module ClassMethods
|
66
|
+
# Add methods to instances of the class which gets/sets from an XML attribute.
|
66
67
|
# @param name [String] the name of an XML attribute to expose.
|
67
68
|
# @param getblock [Proc] a proc to run
|
68
69
|
def xmlattribute(name,getblock=nil,&setblock)
|
@@ -77,3 +78,24 @@ module UIC::PresentableHash
|
|
77
78
|
flat_map{ |k,v| [ k, *(v.is_a?(Array) ? v.map{|v2| "\t#{v2.to_s}" } : v) ] }
|
78
79
|
end
|
79
80
|
end
|
81
|
+
|
82
|
+
# Create an array of rows representing a tree of elements.
|
83
|
+
# @param root [Object] the root of the tree.
|
84
|
+
# @param children [Block] a block that returns an array of child objects when passed an item in the tree.
|
85
|
+
# @return [Array<Array>] array of lines pairing the indent string for the line with the element, or `nil` if the indent line is a separator.
|
86
|
+
def UIC.tree_hierarchy( root, &children )
|
87
|
+
queue = [[root,"",true]]
|
88
|
+
[].tap do |results|
|
89
|
+
until queue.empty?
|
90
|
+
item,indent,last = queue.pop
|
91
|
+
kids = children[item]
|
92
|
+
extra = indent.empty? ? '' : last ? '\\-' : '|-'
|
93
|
+
results << [ indent+extra, item ]
|
94
|
+
results << [ indent, nil ] if last and kids.empty?
|
95
|
+
indent += last ? ' ' : '| '
|
96
|
+
parts = kids.map{ |k| [k,indent,false] }.reverse
|
97
|
+
parts.first[2] = true unless parts.empty?
|
98
|
+
queue.concat parts
|
99
|
+
end
|
100
|
+
end
|
101
|
+
end
|
data/lib/ruic/presentation.rb
CHANGED
@@ -21,35 +21,14 @@ class UIC::Presentation
|
|
21
21
|
@scene = @graph.at('Scene')
|
22
22
|
@logic = @doc.at('Logic')
|
23
23
|
|
24
|
-
|
25
|
-
@doc.xpath('/UIP/Project/Classes/*').each do |reference|
|
26
|
-
path = app.path_to(reference['sourcepath'])
|
27
|
-
raise "Cannot find file '#{path}' referenced by #{self.inspect}" unless File.exist?( path )
|
28
|
-
metaklass = case reference.name
|
29
|
-
when 'CustomMaterial'
|
30
|
-
meta = Nokogiri.XML(File.read(path,encoding:'utf-8')).at('/*/MetaData')
|
31
|
-
from = app.metadata.by_name[ 'MaterialBase' ]
|
32
|
-
app.metadata.create_class( meta, from, reference.name )
|
33
|
-
when 'Effect'
|
34
|
-
meta = Nokogiri.XML(File.read(path,encoding:'utf-8')).at('/*/MetaData')
|
35
|
-
from = app.metadata.by_name[ 'Effect' ]
|
36
|
-
app.metadata.create_class( meta, from, reference.name )
|
37
|
-
when 'Behavior'
|
38
|
-
lua = File.read(path,encoding:'utf-8')
|
39
|
-
meta = lua[ /--\[\[(.+?)(?:--)?\]\]/m, 1 ]
|
40
|
-
meta = Nokogiri.XML("<MetaData>#{meta}</MetaData>").root
|
41
|
-
from = app.metadata.by_name[ 'Behavior' ]
|
42
|
-
app.metadata.create_class( meta, from, reference.name )
|
43
|
-
end
|
44
|
-
@class_by_ref[ "##{reference['id']}" ] = metaklass
|
45
|
-
nil
|
46
|
-
end
|
47
|
-
|
24
|
+
generate_custom_classes
|
48
25
|
rebuild_caches_from_document
|
49
26
|
|
50
27
|
@asset_by_el = {} # indexed by asset graph element
|
51
28
|
@slides_for = {} # indexed by asset graph element
|
52
29
|
@slides_by_el = {} # indexed by slide state element
|
30
|
+
|
31
|
+
nil
|
53
32
|
end
|
54
33
|
|
55
34
|
# @return [String] the xml representation of this presentation. Formatted to match UI Composer Studio's formatting as closely as possible (for minimal diffs after update).
|
@@ -59,6 +38,35 @@ class UIC::Presentation
|
|
59
38
|
.sub('"?>','" ?>')
|
60
39
|
end
|
61
40
|
|
41
|
+
# Scan the .uip for custom classes that will be needed to generate assets.
|
42
|
+
# Called once during initial load of the file.
|
43
|
+
# @return [nil]
|
44
|
+
def generate_custom_classes
|
45
|
+
parent_class_name = {
|
46
|
+
'CustomMaterial' => 'MaterialBase',
|
47
|
+
'Effect' => 'Effect',
|
48
|
+
'Behavior' => 'Behavior'
|
49
|
+
}
|
50
|
+
@class_by_ref = {}
|
51
|
+
@doc.xpath('/UIP/Project/Classes/*').each do |reference|
|
52
|
+
path = resolve_file_path( reference['sourcepath'] )
|
53
|
+
raise "Cannot find file '#{path}' referenced by #{self.inspect}" unless File.exist?( path )
|
54
|
+
parent_class = app.metadata.by_name[ parent_class_name[reference.name] ]
|
55
|
+
parent_props = parent_class.properties
|
56
|
+
new_defaults = Hash[ reference.attributes.map{ |name,attr| [name,attr.value] }.select{ |name,val| parent_props[name] } ]
|
57
|
+
property_el = case reference.name
|
58
|
+
when 'CustomMaterial', 'Effect'
|
59
|
+
Nokogiri.XML(File.read(path,encoding:'utf-8')).at('/*/MetaData')
|
60
|
+
when 'Behavior'
|
61
|
+
lua = File.read(path,encoding:'utf-8')
|
62
|
+
meta = lua[ /--\[\[(.+?)(?:--)?\]\]/m, 1 ]
|
63
|
+
Nokogiri.XML("<MetaData>#{meta}</MetaData>").root
|
64
|
+
end
|
65
|
+
@class_by_ref[ "##{reference['id']}" ] = app.metadata.create_class( property_el, parent_class, reference.name, new_defaults )
|
66
|
+
end
|
67
|
+
nil
|
68
|
+
end
|
69
|
+
|
62
70
|
# Update the presentation to be in-sync with the document.
|
63
71
|
# Must be called whenever the in-memory representation of the XML document is changed.
|
64
72
|
# Called automatically by all necessary methods; only necessary if script (dangerously)
|
@@ -165,13 +173,13 @@ class UIC::Presentation
|
|
165
173
|
end
|
166
174
|
private :asset_for_el
|
167
175
|
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
|
176
|
+
def referenced_files
|
177
|
+
(
|
178
|
+
(images + behaviors + effects + meshes + materials ).map(&:file)
|
179
|
+
+ effects.flat_map(&:images)
|
180
|
+
+ fonts
|
181
|
+
).sort_by{ |f| parts = f.split(/[\/\\]/); [parts.length,parts] }
|
182
|
+
end
|
175
183
|
|
176
184
|
# @return [MetaData::Scene] the root scene asset for the presentation.
|
177
185
|
def scene
|
@@ -536,6 +544,64 @@ class UIC::Presentation
|
|
536
544
|
end
|
537
545
|
end
|
538
546
|
|
547
|
+
# @return [Array<MetaData::AssetBase>] array of layers in the presentation.
|
548
|
+
def layers; find _type:'Layer'; end
|
549
|
+
|
550
|
+
# @return [Array<MetaData::AssetBase>] array of effects in the presentation.
|
551
|
+
def effects; find _type:'Effect'; end
|
552
|
+
|
553
|
+
# @return [Array<MetaData::AssetBase>] array of groups in the presentation.
|
554
|
+
def groups; find _type:'Group'; end
|
555
|
+
|
556
|
+
# @return [Array<MetaData::AssetBase>] array of cameras in the presentation.
|
557
|
+
def cameras; find _type:'Camera'; end
|
558
|
+
|
559
|
+
# @return [Array<MetaData::AssetBase>] array of lights in the presentation.
|
560
|
+
def lights; find _type:'Light'; end
|
561
|
+
|
562
|
+
# @return [Array<MetaData::AssetBase>] array of components in the presentation (not including the Scene).
|
563
|
+
def components; find _type:'Component'; end
|
564
|
+
|
565
|
+
# @return [Array<MetaData::AssetBase>] array of model nodes in the presentation.
|
566
|
+
def models; find _type:'Model'; end
|
567
|
+
alias_method :meshes, :models
|
568
|
+
|
569
|
+
# @return [Array<MetaData::AssetBase>] array of materials in the presentation (includes Referenced and Custom Materials).
|
570
|
+
def materials
|
571
|
+
# Loop through all assets so that the resulting array of multiple sub-classes is in scene graph order
|
572
|
+
material = app.metadata.by_name['MaterialBase']
|
573
|
+
find.select{ |asset| asset.is_a?(material) }
|
574
|
+
end
|
575
|
+
|
576
|
+
# @return [Array<MetaData::AssetBase>] array of image elements in the presentation.
|
577
|
+
def images; find _type:'Image'; end
|
578
|
+
|
579
|
+
# @return [Array<MetaData::AssetBase>] array of behavior elements in the presentation.
|
580
|
+
def behaviors; find _type:'Behavior'; end
|
581
|
+
|
582
|
+
# @return [Array<MetaData::AssetBase>] array of alias nodes in the presentation.
|
583
|
+
def aliases; find _type:'Alias'; end
|
584
|
+
|
585
|
+
# @return [Array<MetaData::AssetBase>] array of path nodes in the presentation.
|
586
|
+
def paths; find _type:'Path'; end
|
587
|
+
|
588
|
+
# @return [Array<MetaData::AssetBase>] array of path anchor points in the presentation.
|
589
|
+
def anchor_points; find _type:'PathAnchorPoint'; end
|
590
|
+
|
591
|
+
# @return [Array<MetaData::AssetBase>] array of text elements in the presentation.
|
592
|
+
def texts; find _type:'Text'; end
|
593
|
+
|
594
|
+
# @param root [MetaData::AssetBase] the asset to find the hierarchy under.
|
595
|
+
# @return [String] a visual hierarchy under the specified asset.
|
596
|
+
def hierarchy( root=scene )
|
597
|
+
elide = ->(str){ str.length>64 ? str.sub(/(^.{30}).+?(.{30})$/,'\1...\2') : str }
|
598
|
+
hier = UIC.tree_hierarchy(root){ |e| e.children }
|
599
|
+
cols = hier.map{ |i,a| a ? [ [i,a.name].join, a.type, elide[a.path] ] : [i,"",""] }
|
600
|
+
maxs = cols.transpose.map{ |col| col.map(&:length).max }
|
601
|
+
tmpl = maxs.map{ |n| "%-#{n}s" }.join(' ')
|
602
|
+
cols.map{ |a| tmpl % a }.join("\n").prepend("\n").extend(RUIC::SelfInspecting)
|
603
|
+
end
|
604
|
+
|
539
605
|
# @private
|
540
606
|
def inspect
|
541
607
|
"<#{self.class} #{File.basename(file)}>"
|
@@ -548,8 +614,8 @@ def UIC.Presentation( uip_path=nil )
|
|
548
614
|
UIC::Presentation.new( uip_path )
|
549
615
|
end
|
550
616
|
|
551
|
-
# An {Application::Presentation} is a {Presentation} that is associated with a specific `.uia` application.
|
552
|
-
# In addition to normal {Presentation} methods it
|
617
|
+
# An {Application::Presentation Application::Presentation} is a {UIC::Presentation UIC::Presentation} that is associated with a specific `.uia` application.
|
618
|
+
# In addition to normal {UIC::Presentation} methods it adds methods related to its presence in the application.
|
553
619
|
class UIC::Application::Presentation < UIC::Presentation
|
554
620
|
include UIC::ElementBacked
|
555
621
|
# @!parse extend UIC::ElementBacked::ClassMethods
|
@@ -577,7 +643,7 @@ class UIC::Application::Presentation < UIC::Presentation
|
|
577
643
|
def initialize(application,el)
|
578
644
|
self.owner = application
|
579
645
|
self.el = el
|
580
|
-
super( application.
|
646
|
+
super( application.resolve_file_path(src) )
|
581
647
|
end
|
582
648
|
alias_method :app, :owner
|
583
649
|
|