ruboto 0.5.2
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.
- data/COPYING +19 -0
- data/Gemfile +4 -0
- data/Gemfile.lock +21 -0
- data/README.md +293 -0
- data/Rakefile +114 -0
- data/assets/Rakefile +386 -0
- data/assets/res/drawable-hdpi/icon.png +0 -0
- data/assets/res/drawable-ldpi/icon.png +0 -0
- data/assets/res/drawable-mdpi/icon.png +0 -0
- data/assets/res/layout/get_ruboto_core.xml +25 -0
- data/assets/samples/sample_activity.rb +21 -0
- data/assets/samples/sample_activity_test.rb +21 -0
- data/assets/samples/sample_broadcast_receiver.rb +6 -0
- data/assets/samples/sample_broadcast_receiver_test.rb +1 -0
- data/assets/samples/sample_service.rb +14 -0
- data/assets/samples/sample_service_test.rb +1 -0
- data/assets/src/InheritingActivity.java +195 -0
- data/assets/src/InheritingBroadcastReceiver.java +27 -0
- data/assets/src/InheritingClass.java +19 -0
- data/assets/src/InheritingService.java +9 -0
- data/assets/src/RubotoActivity.java +111 -0
- data/assets/src/RubotoBroadcastReceiver.java +51 -0
- data/assets/src/RubotoService.java +61 -0
- data/assets/src/org/ruboto/RubotoDialog.java +11 -0
- data/assets/src/org/ruboto/Script.java +545 -0
- data/assets/src/org/ruboto/test/ActivityTest.java +63 -0
- data/assets/src/org/ruboto/test/InstrumentationTestRunner.java +124 -0
- data/assets/src/ruboto.rb +621 -0
- data/assets/test/assets/scripts/test_helper.rb +13 -0
- data/bin/ruboto +5 -0
- data/lib/java_class_gen/InheritingClass.java.erb +10 -0
- data/lib/java_class_gen/android_api.xml +1 -0
- data/lib/ruboto.rb +16 -0
- data/lib/ruboto/api.rb +21 -0
- data/lib/ruboto/commands/base.rb +392 -0
- data/lib/ruboto/core_ext/array.rb +6 -0
- data/lib/ruboto/core_ext/object.rb +10 -0
- data/lib/ruboto/util/asset_copier.rb +27 -0
- data/lib/ruboto/util/build.rb +201 -0
- data/lib/ruboto/util/code_formatting.rb +22 -0
- data/lib/ruboto/util/log_action.rb +20 -0
- data/lib/ruboto/util/main_fix.rb +13 -0
- data/lib/ruboto/util/objectspace.rb +8 -0
- data/lib/ruboto/util/scan_in_api.rb +40 -0
- data/lib/ruboto/util/update.rb +420 -0
- data/lib/ruboto/util/verify.rb +87 -0
- data/lib/ruboto/util/xml_element.rb +200 -0
- data/lib/ruboto/version.rb +3 -0
- data/test/activity/image_button_activity.rb +21 -0
- data/test/activity/image_button_activity_test.rb +21 -0
- data/test/activity/image_button_and_button_activity.rb +24 -0
- data/test/activity/image_button_and_button_activity_test.rb +27 -0
- data/test/activity/option_menu_activity.rb +21 -0
- data/test/activity/option_menu_activity_test.rb +20 -0
- data/test/activity/stack_activity.rb +21 -0
- data/test/activity/stack_activity_test.rb +23 -0
- data/test/app_test_methods.rb +41 -0
- data/test/minimal_app_test.rb +23 -0
- data/test/rake_test.rb +40 -0
- data/test/ruboto_gen_test.rb +32 -0
- data/test/ruboto_gen_with_psych_test.rb +16 -0
- data/test/ruboto_update_test.rb +5 -0
- data/test/ruboto_update_with_psych_test.rb +18 -0
- data/test/service_test.rb +49 -0
- data/test/test_helper.rb +177 -0
- data/test/update_test_methods.rb +33 -0
- metadata +157 -0
@@ -0,0 +1,87 @@
|
|
1
|
+
require 'ruboto/api'
|
2
|
+
require 'yaml'
|
3
|
+
|
4
|
+
module Ruboto
|
5
|
+
module Util
|
6
|
+
module Verify
|
7
|
+
###########################################################################
|
8
|
+
#
|
9
|
+
# Verify the presence of important components
|
10
|
+
#
|
11
|
+
|
12
|
+
def verify_manifest
|
13
|
+
abort "cannot find your AndroidManifest.xml to extract info from it. Make sure you're in the root directory of your app" unless
|
14
|
+
File.exists? 'AndroidManifest.xml'
|
15
|
+
@manifest ||= REXML::Document.new(File.read('AndroidManifest.xml')).root
|
16
|
+
end
|
17
|
+
|
18
|
+
def save_manifest
|
19
|
+
File.open("AndroidManifest.xml", 'w') {|f| verify_manifest.document.write(f, 4)}
|
20
|
+
end
|
21
|
+
|
22
|
+
def verify_test_manifest
|
23
|
+
abort "cannot find your test AndroidManifest.xml to extract info from it. Make sure you're in the root directory of your app" \
|
24
|
+
unless File.exists? 'test/AndroidManifest.xml'
|
25
|
+
@manifest ||= REXML::Document.new(File.read('test/AndroidManifest.xml')).root
|
26
|
+
end
|
27
|
+
|
28
|
+
def save_test_manifest
|
29
|
+
File.open("test/AndroidManifest.xml", 'w') {|f| verify_test_manifest.document.write(f, 4)}
|
30
|
+
end
|
31
|
+
|
32
|
+
def verify_package
|
33
|
+
verify_manifest
|
34
|
+
@package ||= @manifest.attribute('package').value
|
35
|
+
end
|
36
|
+
|
37
|
+
def verify_activity
|
38
|
+
verify_manifest
|
39
|
+
@activity ||= @manifest.elements['application/activity'].attribute('android:name').value
|
40
|
+
end
|
41
|
+
|
42
|
+
def verify_sdk_versions
|
43
|
+
verify_manifest
|
44
|
+
@uses_sdk ||= @manifest.elements["uses-sdk"]
|
45
|
+
abort "you must specify your sdk level in the manifest (e.g., <uses-sdk android:minSdkVersion='3' android:targetSdkVersion='8' />)" unless @uses_sdk
|
46
|
+
@uses_sdk
|
47
|
+
end
|
48
|
+
|
49
|
+
def verify_min_sdk
|
50
|
+
verify_sdk_versions
|
51
|
+
@min_sdk ||= @uses_sdk.attribute('android:minSdkVersion').value
|
52
|
+
abort "you must specify a minimum sdk level in the manifest (e.g., <uses-sdk android:minSdkVersion='3' android:targetSdkVersion='8' />)" unless @min_sdk
|
53
|
+
@min_sdk
|
54
|
+
end
|
55
|
+
|
56
|
+
def verify_target_sdk
|
57
|
+
verify_sdk_versions
|
58
|
+
@target_sdk ||= @uses_sdk.attribute('android:targetSdkVersion').value
|
59
|
+
abort "you must specify a target sdk level in the manifest (e.g., <uses-sdk android:minSdkVersion='3' android:targetSdkVersion='8' />)" unless @target_sdk
|
60
|
+
@target_sdk
|
61
|
+
end
|
62
|
+
|
63
|
+
def verify_strings
|
64
|
+
abort "cannot find your strings.xml to extract info from it. Make sure you're in the root directory of your app" unless
|
65
|
+
File.exists? 'res/values/strings.xml'
|
66
|
+
@strings ||= REXML::Document.new(File.read('res/values/strings.xml'))
|
67
|
+
end
|
68
|
+
|
69
|
+
def verify_api
|
70
|
+
Ruboto::API.api
|
71
|
+
end
|
72
|
+
|
73
|
+
def verify_ruboto_config
|
74
|
+
if File.exists? 'ruboto.yml'
|
75
|
+
@ruboto_config ||= YAML::load_file('ruboto.yml')
|
76
|
+
else
|
77
|
+
@ruboto_config = {}
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
def save_ruboto_config
|
82
|
+
File.open("ruboto.yml", 'w') {|f| YAML.dump verify_ruboto_config}
|
83
|
+
end
|
84
|
+
|
85
|
+
end
|
86
|
+
end
|
87
|
+
end
|
@@ -0,0 +1,200 @@
|
|
1
|
+
require 'ruboto/util/code_formatting'
|
2
|
+
require 'ruboto/util/verify'
|
3
|
+
require 'ruboto/api'
|
4
|
+
|
5
|
+
module Ruboto
|
6
|
+
module Util
|
7
|
+
###########################################################################
|
8
|
+
#
|
9
|
+
# XMLElement:
|
10
|
+
# Extends Hash to simulate a REXML::Element (but much faster) and provides
|
11
|
+
# information in the necessary format to generate Java code.
|
12
|
+
#
|
13
|
+
class XMLElement < Hash
|
14
|
+
include Ruboto::Util::CodeFormatting
|
15
|
+
include Ruboto::Util::Verify
|
16
|
+
|
17
|
+
def root
|
18
|
+
Ruboto::API.api
|
19
|
+
end
|
20
|
+
|
21
|
+
def name
|
22
|
+
self["name"]
|
23
|
+
end
|
24
|
+
|
25
|
+
def attribute(name)
|
26
|
+
self["values"][name]
|
27
|
+
end
|
28
|
+
|
29
|
+
def add_element(name, attributes)
|
30
|
+
new_element = XMLElement.new
|
31
|
+
new_element["name"] = name
|
32
|
+
new_element["values"] = attributes
|
33
|
+
|
34
|
+
self[name] = [] unless self[name]
|
35
|
+
self[name] << new_element
|
36
|
+
|
37
|
+
new_element
|
38
|
+
end
|
39
|
+
|
40
|
+
def get_elements(name)
|
41
|
+
self[name] or []
|
42
|
+
end
|
43
|
+
|
44
|
+
def find_class_or_interface(klass, a_type)
|
45
|
+
abort "ERROR: Can't parse package from #{klass}" unless klass.match(/([a-z.]+)\.([A-Z][A-Za-z.]+)/)
|
46
|
+
|
47
|
+
package = self["package"].find{|i| i.attribute("name") == $1}
|
48
|
+
abort "ERROR: Can't find package #{$1}" unless package
|
49
|
+
if a_type == "either"
|
50
|
+
package["class"].find{|i| i.attribute("name") == $2} or package["interface"].find{|i| i.attribute("name") == $2}
|
51
|
+
else
|
52
|
+
package[a_type].find{|i| i.attribute("name") == $2}
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
def find_class(package_and_class)
|
57
|
+
find_class_or_interface(package_and_class, "class")
|
58
|
+
end
|
59
|
+
|
60
|
+
def find_interface(package_and_interface)
|
61
|
+
find_class_or_interface(package_and_interface, "interface")
|
62
|
+
end
|
63
|
+
|
64
|
+
def all_methods(method_base="all", method_include="", method_exclude="", implements="")
|
65
|
+
# get all the methogs
|
66
|
+
all_methods = get_elements("method")
|
67
|
+
|
68
|
+
# establish the base set of methods
|
69
|
+
working_methods = case method_base
|
70
|
+
when "all" then
|
71
|
+
all_methods
|
72
|
+
when "none" then
|
73
|
+
[]
|
74
|
+
when "abstract" then
|
75
|
+
all_methods.select{|i| i.attribute("abstract") == "true"}
|
76
|
+
when "on" then
|
77
|
+
all_methods.select{|i| i.attribute("name").match(/^on[A-Z]/)}
|
78
|
+
end
|
79
|
+
|
80
|
+
# make sure to include requested methods
|
81
|
+
include_methods = method_include.split(",") if method_include.is_a?(String)
|
82
|
+
all_methods.each{|i| working_methods << i if include_methods.include?(i.attribute("name"))}
|
83
|
+
|
84
|
+
# make sure to exclude rejected methods
|
85
|
+
exclude_methods = method_exclude.split(",") if method_exclude.is_a?(String)
|
86
|
+
working_methods = working_methods.select{|i| not exclude_methods.include?(i.attribute("name"))}
|
87
|
+
|
88
|
+
# remove methods marked final
|
89
|
+
working_methods = working_methods.select{|i| (not i.attribute("final")) or i.attribute("final") == "false"}
|
90
|
+
|
91
|
+
# get additional methods from parent
|
92
|
+
if name =="class" and attribute("extends")
|
93
|
+
parent = root.find_class(attribute("extends"))
|
94
|
+
parent_methods = parent.all_methods(method_base, method_include, method_exclude)
|
95
|
+
working_signatures = working_methods.map(&:method_signature)
|
96
|
+
working_methods += parent_methods.select{|i| not working_signatures.include?(i.method_signature)}
|
97
|
+
end
|
98
|
+
|
99
|
+
# get additional methods from interfaces
|
100
|
+
if name =="class" and implements != ""
|
101
|
+
implements.split(",").each do |i|
|
102
|
+
interface = root.find_interface(i)
|
103
|
+
abort("Unkown interface: #{i}") unless interface
|
104
|
+
working_signatures = working_methods.map(&:method_signature)
|
105
|
+
working_methods += interface.all_methods.select{|j| not working_signatures.include?(j.method_signature)}
|
106
|
+
end
|
107
|
+
end
|
108
|
+
|
109
|
+
working_methods
|
110
|
+
end
|
111
|
+
|
112
|
+
def parameters
|
113
|
+
get_elements("parameter").map {|p| [p.attribute("name"), p.attribute("type").gsub("<", "<").gsub(">", ">")]}
|
114
|
+
end
|
115
|
+
|
116
|
+
def method_signature
|
117
|
+
"#{attribute("name")}(#{parameters.map{|i| i[1]}.join(',')})"
|
118
|
+
end
|
119
|
+
|
120
|
+
def constant_string
|
121
|
+
"CB_" + attribute("name").gsub(/[A-Z]/) {|i| "_#{i}"}.upcase.gsub(/^ON_/, "")
|
122
|
+
end
|
123
|
+
|
124
|
+
def super_string
|
125
|
+
if attribute("api_added") and
|
126
|
+
attribute("api_added").to_i > verify_min_sdk.to_i and
|
127
|
+
attribute("api_added").to_i <= verify_target_sdk.to_i
|
128
|
+
nil
|
129
|
+
elsif attribute("abstract") == "true"
|
130
|
+
nil
|
131
|
+
elsif name == "method"
|
132
|
+
"super.#{attribute("name")}(#{parameters.map{|i| i[0]}.join(", ")});"
|
133
|
+
elsif name == "constructor"
|
134
|
+
"super(#{parameters.map{|i| i[0]}.join(", ")});"
|
135
|
+
end
|
136
|
+
end
|
137
|
+
|
138
|
+
def default_return
|
139
|
+
return nil unless attribute("return")
|
140
|
+
case attribute("return")
|
141
|
+
when "boolean" then "return false;"
|
142
|
+
when "int" then "return 0;"
|
143
|
+
when "void" then nil
|
144
|
+
else "return null;"
|
145
|
+
end
|
146
|
+
end
|
147
|
+
|
148
|
+
def super_return
|
149
|
+
rv = super_string
|
150
|
+
return rv unless attribute("return")
|
151
|
+
rv ? "return #{rv}" : default_return
|
152
|
+
end
|
153
|
+
|
154
|
+
def ruby_call
|
155
|
+
rv = []
|
156
|
+
|
157
|
+
params = parameters
|
158
|
+
args = ""
|
159
|
+
if params.size > 1
|
160
|
+
args = ", new Object[]{" + params.map{|i| i[0]}.join(", ") + "}"
|
161
|
+
elsif params.size > 0
|
162
|
+
args = ", " + params.map{|i| i[0]}.join(", ")
|
163
|
+
end
|
164
|
+
|
165
|
+
return_cast = ""
|
166
|
+
convert_return = ""
|
167
|
+
if attribute("return") && attribute("return") != "void"
|
168
|
+
if (attribute("return").include?(".") or attribute("return") == "int[]")
|
169
|
+
return_class = attribute("return")
|
170
|
+
elsif attribute("return") == 'int'
|
171
|
+
return_class = 'Integer'
|
172
|
+
else
|
173
|
+
return_class = attribute("return").capitalize
|
174
|
+
end
|
175
|
+
return_cast = "return (#{return_class.gsub("<", "<").gsub(">", ">")}) " if return_class
|
176
|
+
convert_return = ", #{return_class}.class"
|
177
|
+
end
|
178
|
+
|
179
|
+
rv << "#{return_cast}Script.callMethod(callbackProcs[#{constant_string}], \"call\" #{args}#{convert_return});"
|
180
|
+
rv
|
181
|
+
end
|
182
|
+
|
183
|
+
def method_definition
|
184
|
+
method_call(
|
185
|
+
(attribute("return") ? attribute("return") : "void"),
|
186
|
+
attribute("name"), parameters,
|
187
|
+
if_else(
|
188
|
+
"callbackProcs[#{constant_string}] != null",
|
189
|
+
[super_string] + ruby_call,
|
190
|
+
[super_return]
|
191
|
+
)
|
192
|
+
).indent.join("\n")
|
193
|
+
end
|
194
|
+
|
195
|
+
def constructor_definition(class_name)
|
196
|
+
method_call("", class_name, parameters, [super_string]).indent.join("\n")
|
197
|
+
end
|
198
|
+
end
|
199
|
+
end
|
200
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
require 'ruboto'
|
2
|
+
|
3
|
+
ruboto_import_widgets :ImageButton, :LinearLayout, :TextView
|
4
|
+
|
5
|
+
$activity.handle_create do |bundle|
|
6
|
+
setTitle File.basename(__FILE__).chomp('_activity.rb').split('_').map{|s| "#{s[0..0].upcase}#{s[1..-1]}" }.join(' ')
|
7
|
+
|
8
|
+
setup_content do
|
9
|
+
linear_layout :orientation => LinearLayout::VERTICAL do
|
10
|
+
@text_view = text_view :text => 'What hath Matz wrought?', :id => 42
|
11
|
+
image_button :image_resource => $package.R::drawable::icon, :width => :wrap_content, :id => 43
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
handle_click do |view|
|
16
|
+
if view.id == 43
|
17
|
+
@text_view.setText 'What hath Matz wrought!'
|
18
|
+
toast 'Flipped a bit via butterfly'
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
activity Java::org.ruboto.test_app.ImageButtonActivity
|
2
|
+
|
3
|
+
setup do |activity|
|
4
|
+
start = Time.now
|
5
|
+
loop do
|
6
|
+
@text_view = activity.findViewById(42)
|
7
|
+
break if @text_view || (Time.now - start > 60)
|
8
|
+
sleep 1
|
9
|
+
end
|
10
|
+
assert @text_view
|
11
|
+
end
|
12
|
+
|
13
|
+
test('initial setup') do |activity|
|
14
|
+
assert_equal "What hath Matz wrought?", @text_view.text
|
15
|
+
end
|
16
|
+
|
17
|
+
test('button changes text') do |activity|
|
18
|
+
button = activity.findViewById(43)
|
19
|
+
button.performClick
|
20
|
+
assert_equal "What hath Matz wrought!", @text_view.text
|
21
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
require 'ruboto'
|
2
|
+
|
3
|
+
ruboto_import_widgets :Button, :ImageButton, :LinearLayout, :TextView
|
4
|
+
|
5
|
+
$activity.handle_create do |bundle|
|
6
|
+
setTitle File.basename(__FILE__).chomp('_activity.rb').split('_').map{|s| "#{s[0..0].upcase}#{s[1..-1]}" }.join(' ')
|
7
|
+
|
8
|
+
setup_content do
|
9
|
+
linear_layout :orientation => LinearLayout::VERTICAL do
|
10
|
+
@text_view = text_view :text => 'What hath Matz wrought?', :id => 42
|
11
|
+
button :text => 'Button', :width => :wrap_content, :id => 44
|
12
|
+
image_button :image_resource => $package.R::drawable::icon, :width => :wrap_content, :id => 43
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
handle_click do |view|
|
17
|
+
if view.id == 43
|
18
|
+
@text_view.text = 'Image button pressed'
|
19
|
+
elsif view.id == 44
|
20
|
+
@text_view.text = 'Button pressed'
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
activity Java::org.ruboto.test_app.ImageButtonAndButtonActivity
|
2
|
+
|
3
|
+
setup do |activity|
|
4
|
+
start = Time.now
|
5
|
+
loop do
|
6
|
+
@text_view = activity.find_view_by_id 42
|
7
|
+
break if @text_view || (Time.now - start > 60)
|
8
|
+
sleep 1
|
9
|
+
end
|
10
|
+
assert @text_view
|
11
|
+
end
|
12
|
+
|
13
|
+
test('initial setup') do |activity|
|
14
|
+
assert_equal "What hath Matz wrought?", @text_view.text
|
15
|
+
end
|
16
|
+
|
17
|
+
test('button changes text') do |activity|
|
18
|
+
button = activity.find_view_by_id 44
|
19
|
+
button.perform_click
|
20
|
+
assert_equal 'Button pressed', @text_view.text
|
21
|
+
end
|
22
|
+
|
23
|
+
test('image button changes text') do |activity|
|
24
|
+
image_button = activity.find_view_by_id 43
|
25
|
+
image_button.perform_click
|
26
|
+
assert_equal 'Image button pressed', @text_view.text
|
27
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
require 'ruboto'
|
2
|
+
|
3
|
+
ruboto_import_widgets :ImageButton, :LinearLayout, :TextView
|
4
|
+
|
5
|
+
$activity.handle_create do |bundle|
|
6
|
+
setTitle File.basename(__FILE__).chomp('_activity.rb').split('_').map{|s| "#{s[0..0].upcase}#{s[1..-1]}" }.join(' ')
|
7
|
+
|
8
|
+
setup_content do
|
9
|
+
linear_layout :orientation => LinearLayout::VERTICAL do
|
10
|
+
@text_view = text_view :text => 'What hath Matz wrought?', :id => 42
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
handle_create_options_menu do |menu|
|
15
|
+
add_menu('Test') do
|
16
|
+
@text_view.setText 'What hath Matz wrought!'
|
17
|
+
toast 'Flipped a bit via butterfly'
|
18
|
+
end
|
19
|
+
true
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
activity Java::org.ruboto.test_app.OptionMenuActivity
|
2
|
+
|
3
|
+
setup do |activity|
|
4
|
+
start = Time.now
|
5
|
+
loop do
|
6
|
+
@text_view = activity.findViewById(42)
|
7
|
+
break if @text_view || (Time.now - start > 60)
|
8
|
+
sleep 1
|
9
|
+
end
|
10
|
+
assert @text_view
|
11
|
+
end
|
12
|
+
|
13
|
+
test('initial setup') do |activity|
|
14
|
+
assert_equal "What hath Matz wrought?", @text_view.text
|
15
|
+
end
|
16
|
+
|
17
|
+
test('option_menu changes text') do |activity|
|
18
|
+
activity.window.performPanelIdentifierAction(android.view.Window::FEATURE_OPTIONS_PANEL, 0, 0)
|
19
|
+
assert_equal "What hath Matz wrought!", @text_view.text
|
20
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
STACK_DEPTH_SCRIPT = java.lang.Thread.current_thread.stack_trace.length.to_s
|
2
|
+
require 'ruboto'
|
3
|
+
|
4
|
+
ruboto_import_widgets :Button, :LinearLayout, :TextView
|
5
|
+
|
6
|
+
$activity.handle_create do |bundle|
|
7
|
+
STACK_DEPTH_HANDLE_CREATE = java.lang.Thread.current_thread.stack_trace.length.to_s
|
8
|
+
setTitle File.basename(__FILE__).chomp('_activity.rb').split('_').map{|s| "#{s[0..0].upcase}#{s[1..-1]}" }.join(' ')
|
9
|
+
|
10
|
+
setup_content do
|
11
|
+
STACK_DEPTH_SETUP_CONTENT = java.lang.Thread.current_thread.stack_trace.length.to_s
|
12
|
+
linear_layout :orientation => LinearLayout::VERTICAL do
|
13
|
+
STACK_DEPTH_LINEAR_LAYOUT = java.lang.Thread.current_thread.stack_trace.length.to_s
|
14
|
+
@script_view = text_view :id => 42, :text => STACK_DEPTH_SCRIPT
|
15
|
+
@handle_create_view = text_view :id => 43, :text => STACK_DEPTH_HANDLE_CREATE
|
16
|
+
@setup_content_view = text_view :id => 44, :text => STACK_DEPTH_SETUP_CONTENT
|
17
|
+
@linear_layout_view = text_view :id => 45, :text => STACK_DEPTH_LINEAR_LAYOUT
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
end
|