android_motion_query 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/LICENSE.txt +21 -0
- data/README.md +186 -0
- data/lib/android_motion_query.rb +14 -0
- data/lib/android_motion_query/adapters.rb +26 -0
- data/lib/android_motion_query/amq.rb +66 -0
- data/lib/android_motion_query/colors.rb +3 -0
- data/lib/android_motion_query/events.rb +11 -0
- data/lib/android_motion_query/screen.rb +27 -0
- data/lib/android_motion_query/stylesheet.rb +264 -0
- data/lib/android_motion_query/version.rb +3 -0
- data/lib/android_motion_query/views.rb +75 -0
- metadata +69 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: d3835347be88f8b42c279a29b9b446338dfbc29e
|
4
|
+
data.tar.gz: deae968ca52cb5b0b2e9a3dcd0035b8e7a46cb68
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: c023102ff26902db3704a7fbd01eeded609b615e9aacb79813a77848024158983e76d707494ee7f1be961bd4def3c0bf5c49e6ef18c720033bf6c176ccaa0629
|
7
|
+
data.tar.gz: 2ecccde46ba389558abbfa07b749dcf5d95721420fb22cb244addc4c5e1f4d7588aa72609d8ac63410975a9a7bc7acf2f4cd6135b70616649205c75308a5187e
|
data/LICENSE.txt
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
The MIT License (MIT)
|
2
|
+
|
3
|
+
Copyright (c) 2017 Abdullah Esmail
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
7
|
+
in the Software without restriction, including without limitation the rights
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
10
|
+
furnished to do so, subject to the following conditions:
|
11
|
+
|
12
|
+
The above copyright notice and this permission notice shall be included in
|
13
|
+
all copies or substantial portions of the Software.
|
14
|
+
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
21
|
+
THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,186 @@
|
|
1
|
+
# Android Motion Query
|
2
|
+
|
3
|
+
`android_motion_query` was created to make android development on RubyMotion as enjoyable and productive as possible.
|
4
|
+
It also tries to make an android app look just like a ruby app, without losing any native functionality.
|
5
|
+
|
6
|
+
If you don't like dealing with XML layouts and long method names, `android_motion_query` might be for you.
|
7
|
+
|
8
|
+
`android_motion_query` was inspired by the wonderful [rmq](http://github.com/infinitered/rmq/) gem for iOS.
|
9
|
+
|
10
|
+
## Installation
|
11
|
+
|
12
|
+
|
13
|
+
Add this line to your application's Gemfile:
|
14
|
+
|
15
|
+
```ruby
|
16
|
+
gem 'android_motion_query', '~> 0.1.0'
|
17
|
+
```
|
18
|
+
|
19
|
+
And then execute:
|
20
|
+
|
21
|
+
$ bundle
|
22
|
+
|
23
|
+
Or install it yourself as:
|
24
|
+
|
25
|
+
$ gem install android_motion_query
|
26
|
+
|
27
|
+
## Usage
|
28
|
+
|
29
|
+
The general rule is to create a top-level layout and add views to it.
|
30
|
+
Each view accepts a style method.
|
31
|
+
|
32
|
+
#### Tiny Example:
|
33
|
+
|
34
|
+
To create a LinearLayout and add a TextView widget to it:
|
35
|
+
|
36
|
+
```ruby
|
37
|
+
amq.linear_layout(:layout_style) do |my_layout|
|
38
|
+
my_layout.text_view(:some_information)
|
39
|
+
end
|
40
|
+
```
|
41
|
+
|
42
|
+
The style for the LinearLayout is `:layout_style` and the TextView has a `:some_information` style.
|
43
|
+
|
44
|
+
How do you define styles?
|
45
|
+
|
46
|
+
Styles are defined in a separate class that inherit from `AndroidMotionQuery::Stylesheet`.
|
47
|
+
|
48
|
+
Each style is passed a wrapper of the android view:
|
49
|
+
|
50
|
+
```ruby
|
51
|
+
def layout_style(st)
|
52
|
+
st.width = :mp # or :wc for MATCH_PARENT and WRAP_CONTENT respectively
|
53
|
+
st.height = :mp # could also provide an integer to be set directly
|
54
|
+
st.background_color = '#CF7D33' # or you can do :white, :black, :green, etc
|
55
|
+
st.orientation = :vertical # or :horizontal
|
56
|
+
end
|
57
|
+
|
58
|
+
def some_information(st)
|
59
|
+
st.width = :mp
|
60
|
+
st.height = :wc
|
61
|
+
st.text = 'Hello Android Motion Query'
|
62
|
+
st.text_color = :blue
|
63
|
+
st.text_alignment = :center # or :bottom, :top, :center_right, etc
|
64
|
+
st.margin_top = 10
|
65
|
+
end
|
66
|
+
```
|
67
|
+
|
68
|
+
|
69
|
+
#### Complete Example:
|
70
|
+
|
71
|
+
```ruby
|
72
|
+
class MainActivity < AMQScreen
|
73
|
+
def on_create(saved_state)
|
74
|
+
amq.stylesheet = HomeStyle
|
75
|
+
amq.linear_layout(:top_layout) do |top|
|
76
|
+
top.image_button(:bench_button)
|
77
|
+
top.image_button(:flower_button)
|
78
|
+
top.linear_layout(:directions) do |direction_layout|
|
79
|
+
direction_layout.text_view(:left_text)
|
80
|
+
direction_layout.button(:right_button)
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
def coffee_message(view)
|
86
|
+
amq.toast('This is a message for COFFEE LOVERS :)', gravity: :center)
|
87
|
+
end
|
88
|
+
|
89
|
+
def random_thing(view)
|
90
|
+
puts "This should be printed when I click the button"
|
91
|
+
end
|
92
|
+
|
93
|
+
def another_toast(view)
|
94
|
+
amq.toast("This is a purple", gravity: :top_right, length: :long)
|
95
|
+
end
|
96
|
+
end
|
97
|
+
```
|
98
|
+
|
99
|
+
The previous code produces the following app:
|
100
|
+
|
101
|
+
![Sample Screenshot](screenshot.png)
|
102
|
+
|
103
|
+
|
104
|
+
The following is the `HomeStyle` class that styles the screen:
|
105
|
+
```ruby
|
106
|
+
class HomeStyle < AMQStylesheet
|
107
|
+
def top_layout(st)
|
108
|
+
st.width = :mp
|
109
|
+
st.height = 0
|
110
|
+
st.weight_sum = 4
|
111
|
+
st.orientation = :vertical
|
112
|
+
st.background_color = '#A87E54'
|
113
|
+
end
|
114
|
+
|
115
|
+
def bench_button(st)
|
116
|
+
st.width = :mp
|
117
|
+
st.margin_top = 10
|
118
|
+
st.margin_bottom = 10
|
119
|
+
st.background_image = 'bench' # <-- image is resources/drawable/bench.png
|
120
|
+
st.click = :coffee_message
|
121
|
+
shared_button_styles(st)
|
122
|
+
end
|
123
|
+
|
124
|
+
def flower_button(st)
|
125
|
+
st.width = :mp
|
126
|
+
st.background_image = 'flower'
|
127
|
+
st.click = :random_thing
|
128
|
+
shared_button_styles(st)
|
129
|
+
end
|
130
|
+
|
131
|
+
def shared_button_styles(st)
|
132
|
+
st.height = 0
|
133
|
+
st.padding = 0
|
134
|
+
st.margin_left = 10
|
135
|
+
st.margin_right = 10
|
136
|
+
st.scale_type = :fit_xy
|
137
|
+
st.weight = 1.5
|
138
|
+
end
|
139
|
+
|
140
|
+
def directions(st)
|
141
|
+
st.orientation = :horizontal
|
142
|
+
st.weight = 1
|
143
|
+
st.weight_sum = 2
|
144
|
+
st.width = :mp
|
145
|
+
st.height = 0
|
146
|
+
st.margin_top = 10
|
147
|
+
end
|
148
|
+
|
149
|
+
def left_text(st)
|
150
|
+
st.weight = 1
|
151
|
+
st.text = 'android_query is AWESOME!'
|
152
|
+
st.text_alignment = :center
|
153
|
+
end
|
154
|
+
|
155
|
+
def right_button(st)
|
156
|
+
st.weight = 1
|
157
|
+
st.text = 'Click Me'
|
158
|
+
st.click = :another_toast
|
159
|
+
st.background_color = '#927FD5'
|
160
|
+
st.text_color = :white
|
161
|
+
end
|
162
|
+
end
|
163
|
+
```
|
164
|
+
|
165
|
+
## Todo List
|
166
|
+
- [ ] Refactor - create more "single responsibility" classes and have smaller functions (this will never be "done", it's just here as a constant reminder)
|
167
|
+
- [ ] Set automatic IDs for views
|
168
|
+
- [ ] Add wrappers for all built-in android widgets (currently android_query supports 5 widgets)
|
169
|
+
- [x] Add support for LinearLayouts
|
170
|
+
- [ ] Add support for RelativeLayouts
|
171
|
+
- [ ] Add support for FrameLayouts
|
172
|
+
- [ ] Add support for AbsoluteLayouts (worth it? AbsoluteLayout is deprecated a long time ago)
|
173
|
+
- [x] Add support for working with custom widgets/views (throught `aqv.new_view()`)
|
174
|
+
- [ ] Add support for `view.click { block of code }`
|
175
|
+
- [ ] Add support for @string values (strings.xml)
|
176
|
+
- [x] Add support for @drawable values (images in the resources/drawable directory)
|
177
|
+
- [ ] Add support for easy and quick animations
|
178
|
+
- [ ] Add support for rounded corners (first attempt failed, this is harder than I thought)
|
179
|
+
|
180
|
+
## Contributing
|
181
|
+
|
182
|
+
Bug reports and pull requests are welcome on GitHub at https://github.com/aesmail/android_query.
|
183
|
+
|
184
|
+
## License
|
185
|
+
|
186
|
+
The gem is available as open source under the terms of the [MIT License](http://opensource.org/licenses/MIT).
|
@@ -0,0 +1,14 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
|
3
|
+
require 'rubygems'
|
4
|
+
|
5
|
+
unless defined?(Motion::Project::Config)
|
6
|
+
raise "This file must be required within a RubyMotion project Rakefile."
|
7
|
+
end
|
8
|
+
|
9
|
+
Motion::Project::App.setup do |app|
|
10
|
+
Dir.glob(File.join(File.dirname(__FILE__), "android_motion_query/**/*.rb")).each do |file|
|
11
|
+
app.files.unshift(file)
|
12
|
+
app.api_version = '21'
|
13
|
+
end
|
14
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
class AMQAdapter < Android::Widget::BaseAdapter
|
2
|
+
attr_accessor :mContext, :items
|
3
|
+
|
4
|
+
def initialize(context, list, options={})
|
5
|
+
self.mContext = context
|
6
|
+
self.items = list
|
7
|
+
end
|
8
|
+
|
9
|
+
def getCount
|
10
|
+
self.items.count
|
11
|
+
end
|
12
|
+
|
13
|
+
def getItemId(position)
|
14
|
+
0
|
15
|
+
end
|
16
|
+
|
17
|
+
def getItem(position)
|
18
|
+
self.items[position]
|
19
|
+
end
|
20
|
+
|
21
|
+
def getView(position, convert_view, parent)
|
22
|
+
text_view = Android::Widget::TextView.new(self.mContext)
|
23
|
+
text_view.text = self.items[position]
|
24
|
+
text_view
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,66 @@
|
|
1
|
+
class AndroidMotionQuery
|
2
|
+
attr_accessor :activity, :root, :view_ids
|
3
|
+
attr_reader :stylesheet
|
4
|
+
|
5
|
+
def initialize(activity)
|
6
|
+
self.activity = activity
|
7
|
+
self
|
8
|
+
end
|
9
|
+
|
10
|
+
def stylesheet=(style)
|
11
|
+
@stylesheet = style.new
|
12
|
+
end
|
13
|
+
|
14
|
+
def create_android_query_view(view, style_method, layout_params, options = {}, &block)
|
15
|
+
self.root = AMQView.new(view, self.activity, self.stylesheet, style_method, layout_params, options)
|
16
|
+
self.stylesheet.apply_style_for(self.root, style_method, layout_params)
|
17
|
+
block.call(self.root) if block_given?
|
18
|
+
self.activity.setContentView(self.root.get)
|
19
|
+
end
|
20
|
+
|
21
|
+
def find(id)
|
22
|
+
self.root.get.findViewById(id).tag
|
23
|
+
end
|
24
|
+
|
25
|
+
def linear_layout(style_method, &block)
|
26
|
+
view = Android::Widget::LinearLayout.new(self.activity)
|
27
|
+
layout_params = Android::Widget::LinearLayout::LayoutParams
|
28
|
+
create_android_query_view(view, style_method, layout_params, {}, &block)
|
29
|
+
end
|
30
|
+
|
31
|
+
def relative_layout(style_method, &block)
|
32
|
+
view = Android::Widget::RelativeLayout.new(self.activity)
|
33
|
+
layout_params = Android::Widget::RelativeLayout::Params
|
34
|
+
create_android_query_view(view, style_method, layout_params, {}, &block)
|
35
|
+
end
|
36
|
+
|
37
|
+
def toast(text, options = {})
|
38
|
+
options = {
|
39
|
+
gravity: :bottom,
|
40
|
+
length: :short
|
41
|
+
}.merge(options)
|
42
|
+
|
43
|
+
gravity_options = {
|
44
|
+
top: Android::View::Gravity::TOP,
|
45
|
+
left: Android::View::Gravity::LEFT,
|
46
|
+
right: Android::View::Gravity::RIGHT,
|
47
|
+
bottom: Android::View::Gravity::BOTTOM,
|
48
|
+
center: Android::View::Gravity::CENTER,
|
49
|
+
bottom_right: Android::View::Gravity::BOTTOM | Android::View::Gravity::RIGHT,
|
50
|
+
bottom_left: Android::View::Gravity::BOTTOM | Android::View::Gravity::LEFT,
|
51
|
+
center_right: Android::View::Gravity::CENTER | Android::View::Gravity::RIGHT,
|
52
|
+
center_left: Android::View::Gravity::CENTER | Android::View::Gravity::LEFT,
|
53
|
+
top_right: Android::View::Gravity::TOP | Android::View::Gravity::RIGHT,
|
54
|
+
top_left: Android::View::Gravity::TOP | Android::View::Gravity::LEFT,
|
55
|
+
}
|
56
|
+
|
57
|
+
length_options = {
|
58
|
+
short: Android::Widget::Toast::LENGTH_SHORT,
|
59
|
+
long: Android::Widget::Toast::LENGTH_LONG,
|
60
|
+
}
|
61
|
+
|
62
|
+
the_toast = Android::Widget::Toast.makeText(self.activity, text, length_options[options[:length]])
|
63
|
+
the_toast.setGravity(gravity_options[options[:gravity]], 0, 0)
|
64
|
+
the_toast.show
|
65
|
+
end
|
66
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
class AMQScreen < Android::App::Activity
|
2
|
+
attr_accessor :amq
|
3
|
+
def onCreate(savedInstance)
|
4
|
+
super
|
5
|
+
self.create_amq_object
|
6
|
+
self.on_create(savedInstance)
|
7
|
+
end
|
8
|
+
|
9
|
+
def create_amq_object
|
10
|
+
self.amq = AndroidMotionQuery.new(self)
|
11
|
+
end
|
12
|
+
|
13
|
+
def open(screen, extra={})
|
14
|
+
intent = Android::Content::Intent.new(self, screen)
|
15
|
+
extra.each {|k, v| intent.putExtra(k.to_s, v) }
|
16
|
+
startActivity(intent)
|
17
|
+
end
|
18
|
+
|
19
|
+
def extras
|
20
|
+
# TODO implement a way to get information from the putExtra() method
|
21
|
+
# puts self.getIntent.getExtras
|
22
|
+
# if k
|
23
|
+
# package_name = self.getPackageName
|
24
|
+
# self.getExtras
|
25
|
+
# self.getExtras
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,264 @@
|
|
1
|
+
INPUT_TYPE = Android::Text::InputType
|
2
|
+
|
3
|
+
class AMQStylesheet
|
4
|
+
def apply_style_for(view, style_name, layout_params)
|
5
|
+
style_view = AMQStylesheetElement.new(view, layout_params)
|
6
|
+
self.send(style_name.to_s, style_view)
|
7
|
+
view.get.setLayoutParams(style_view.params)
|
8
|
+
view.get.tag = view
|
9
|
+
view
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
|
14
|
+
|
15
|
+
class AMQStylesheetElement
|
16
|
+
attr_accessor :view, :params, :radius
|
17
|
+
|
18
|
+
LAYOUT_SIZE_OPTIONS = {
|
19
|
+
mp: Android::View::ViewGroup::LayoutParams::MATCH_PARENT,
|
20
|
+
wc: Android::View::ViewGroup::LayoutParams::WRAP_CONTENT,
|
21
|
+
}
|
22
|
+
|
23
|
+
ORIENTATION_OPTIONS = {
|
24
|
+
vertical: Android::Widget::LinearLayout::VERTICAL,
|
25
|
+
horizontal: Android::Widget::LinearLayout::HORIZONTAL,
|
26
|
+
}
|
27
|
+
|
28
|
+
def initialize(view, layout_params)
|
29
|
+
self.view = view
|
30
|
+
self.params = layout_params.new(LAYOUT_SIZE_OPTIONS[:mp], LAYOUT_SIZE_OPTIONS[:wc])
|
31
|
+
self
|
32
|
+
end
|
33
|
+
|
34
|
+
def id=(number)
|
35
|
+
|
36
|
+
self.view.get.id = number
|
37
|
+
end
|
38
|
+
|
39
|
+
def text=(t)
|
40
|
+
self.view.get.text = t
|
41
|
+
end
|
42
|
+
|
43
|
+
def width=(w)
|
44
|
+
if w == :mp || w == :wc
|
45
|
+
self.params.width = LAYOUT_SIZE_OPTIONS[w]
|
46
|
+
else
|
47
|
+
self.params.width = w
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
def height=(h)
|
52
|
+
if h == :mp || h == :wc
|
53
|
+
self.params.height = LAYOUT_SIZE_OPTIONS[h]
|
54
|
+
else
|
55
|
+
self.params.height = h
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
def orientation=(o)
|
60
|
+
if o == :vertical || o == :horizontal
|
61
|
+
self.view.get.orientation = ORIENTATION_OPTIONS[o]
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
def weight_sum=(number)
|
66
|
+
self.view.get.weightSum = number
|
67
|
+
end
|
68
|
+
|
69
|
+
def weight=(number)
|
70
|
+
self.params.weight = number
|
71
|
+
end
|
72
|
+
|
73
|
+
def padding_left=(number)
|
74
|
+
left, top, right, bottom = get_padding
|
75
|
+
self.padding = [number, top, right, bottom]
|
76
|
+
end
|
77
|
+
|
78
|
+
def padding_right=(number)
|
79
|
+
left, top, right, bottom = get_padding
|
80
|
+
self.padding = [left, top, number, bottom]
|
81
|
+
end
|
82
|
+
|
83
|
+
def padding_top=(number)
|
84
|
+
left, top, right, bottom = get_padding
|
85
|
+
self.padding = [left, number, right, bottom]
|
86
|
+
end
|
87
|
+
|
88
|
+
def padding_bottom=(number)
|
89
|
+
left, top, right, bottom = get_padding
|
90
|
+
self.padding = [left, top, right, number]
|
91
|
+
end
|
92
|
+
|
93
|
+
def padding=(number)
|
94
|
+
if number.class == Array && number.count == 4
|
95
|
+
left, top, right, bottom = number
|
96
|
+
self.view.get.setPadding(left, top, right, bottom)
|
97
|
+
elsif number.class == Fixnum
|
98
|
+
self.view.get.setPadding(number, number, number, number)
|
99
|
+
else
|
100
|
+
raise "Invalid value (#{number}) set as padding for #{self.view.get}"
|
101
|
+
end
|
102
|
+
end
|
103
|
+
|
104
|
+
def get_padding
|
105
|
+
v = self.view.get
|
106
|
+
[v.getPaddingLeft, v.getPaddingTop, v.getPaddingRight, v.getPaddingBottom]
|
107
|
+
end
|
108
|
+
|
109
|
+
def margin_left=(number)
|
110
|
+
left, top, right, bottom = get_margins
|
111
|
+
self.margin = [number, top, right, bottom]
|
112
|
+
end
|
113
|
+
|
114
|
+
def margin_right=(number)
|
115
|
+
left, top, right, bottom = get_margins
|
116
|
+
self.margin = [left, top, number, bottom]
|
117
|
+
end
|
118
|
+
|
119
|
+
def margin_top=(number)
|
120
|
+
left, top, right, bottom = get_margins
|
121
|
+
self.margin = [left, number, right, bottom]
|
122
|
+
end
|
123
|
+
|
124
|
+
def margin_bottom=(number)
|
125
|
+
left, top, right, bottom = get_margins
|
126
|
+
self.margin = [left, top, right, number]
|
127
|
+
end
|
128
|
+
|
129
|
+
def get_margins
|
130
|
+
lp = self.params
|
131
|
+
[lp.leftMargin, lp.topMargin, lp.rightMargin, lp.bottomMargin]
|
132
|
+
end
|
133
|
+
|
134
|
+
def margin=(number)
|
135
|
+
if number.class == Array && number.count == 4
|
136
|
+
left, top, right, bottom = number
|
137
|
+
self.params.setMargins(left, top, right, bottom)
|
138
|
+
elsif number.class == Fixnum
|
139
|
+
self.params.setMargins(number, number, number, number)
|
140
|
+
else
|
141
|
+
raise "Invalid value (#{number}) set as margin for #{self.view.get}"
|
142
|
+
end
|
143
|
+
end
|
144
|
+
|
145
|
+
def extra=(something)
|
146
|
+
self.view.extra = something
|
147
|
+
end
|
148
|
+
|
149
|
+
def click=(method_name)
|
150
|
+
self.view.get.onClickListener = AMQClickListener.new(self.view.activity, method_name)
|
151
|
+
end
|
152
|
+
|
153
|
+
# TODO find a solution for rounded corners (with or without images)
|
154
|
+
# def corner_radius=(radius)
|
155
|
+
# self.radius ||= radius
|
156
|
+
# drawable = self.view.get.getDrawable
|
157
|
+
# if drawable
|
158
|
+
# self.draw_image_with_radius(drawable, self.radius)
|
159
|
+
# else
|
160
|
+
# shape = Android::Graphics::GradientDrawable.new
|
161
|
+
# shape.cornerRadius = self.radius
|
162
|
+
# self.view.get.background = shape
|
163
|
+
# end
|
164
|
+
# end
|
165
|
+
# TODO find a solution for rounded corners (with or without images)
|
166
|
+
# def draw_image_with_radius(image, radius)
|
167
|
+
# self.radius ||= radius
|
168
|
+
# width = image.getWidth
|
169
|
+
# height = image.getHeight
|
170
|
+
# result = Android::Graphics::Bitmap.createBitmap(width, height, Android::Graphics::Bitmap::Config::ARGB_8888)
|
171
|
+
# canvas = Android::Graphics::Canvas.new(result)
|
172
|
+
# canvas.drawARGB(0, 0, 0, 0)
|
173
|
+
# paint = Android::Graphics::Paint.new
|
174
|
+
# paint.antiAlias = true
|
175
|
+
# paint.color = AQColor.parse_color('#000000')
|
176
|
+
# rect = Android::Graphics::Rect.new(0, 0, width, height)
|
177
|
+
# rect_f = Android::Graphics::RectF.new(rect)
|
178
|
+
# canvas.drawRoundRect(rect_f, self.radius, self.radius, paint)
|
179
|
+
# paint.xfermode = Android::Graphics::PorterDuffXfermode.new(Android::Graphics::PorterDuff::Mode::SRC_IN)
|
180
|
+
# canvas.drawBitmap(raw, rect, rect, paint)
|
181
|
+
# result
|
182
|
+
# end
|
183
|
+
|
184
|
+
def background_color=(color)
|
185
|
+
self.view.get.backgroundColor = AMQColor.parse_color(color.to_s)
|
186
|
+
end
|
187
|
+
|
188
|
+
def background_image=(image_name)
|
189
|
+
context = self.view.get.getContext
|
190
|
+
resource_id = context.getResources.getIdentifier(image_name, "drawable", context.getPackageName)
|
191
|
+
self.view.get.setImageResource(resource_id)
|
192
|
+
end
|
193
|
+
|
194
|
+
def scale_type=(option)
|
195
|
+
scale_types = {
|
196
|
+
center: Android::Widget::ImageView::ScaleType::CENTER,
|
197
|
+
center_crop: Android::Widget::ImageView::ScaleType::CENTER_CROP,
|
198
|
+
center_inside: Android::Widget::ImageView::ScaleType::CENTER_INSIDE,
|
199
|
+
fit_center: Android::Widget::ImageView::ScaleType::FIT_CENTER,
|
200
|
+
fit_end: Android::Widget::ImageView::ScaleType::FIT_END,
|
201
|
+
fit_start: Android::Widget::ImageView::ScaleType::FIT_START,
|
202
|
+
fit_xy: Android::Widget::ImageView::ScaleType::FIT_XY,
|
203
|
+
matrix: Android::Widget::ImageView::ScaleType::MATRIX,
|
204
|
+
}
|
205
|
+
self.view.get.scaleType = scale_types[option]
|
206
|
+
end
|
207
|
+
|
208
|
+
def text_alignment=(alignment)
|
209
|
+
self.gravity = alignment
|
210
|
+
end
|
211
|
+
|
212
|
+
def text_color=(color)
|
213
|
+
self.view.get.textColor = AMQColor.parse_color(color.to_s)
|
214
|
+
end
|
215
|
+
|
216
|
+
def hint=(t)
|
217
|
+
self.view.get.hint = t
|
218
|
+
end
|
219
|
+
|
220
|
+
INPUT_TYPES = {
|
221
|
+
normal: INPUT_TYPE::TYPE_CLASS_TEXT,
|
222
|
+
password: INPUT_TYPE::TYPE_CLASS_TEXT | INPUT_TYPE::TYPE_TEXT_VARIATION_PASSWORD,
|
223
|
+
visible_password: INPUT_TYPE::TYPE_CLASS_TEXT | INPUT_TYPE::TYPE_TEXT_VARIATION_VISIBLE_PASSWORD,
|
224
|
+
number: INPUT_TYPE::TYPE_CLASS_NUMBER,
|
225
|
+
email: INPUT_TYPE::TYPE_CLASS_TEXT | INPUT_TYPE::TYPE_TEXT_VARIATION_EMAIL_ADDRESS,
|
226
|
+
phone: INPUT_TYPE::TYPE_CLASS_PHONE,
|
227
|
+
date: INPUT_TYPE::TYPE_CLASS_DATETIME | INPUT_TYPE::TYPE_DATETIME_VARIATION_DATE,
|
228
|
+
time: INPUT_TYPE::TYPE_CLASS_DATETIME | INPUT_TYPE::TYPE_DATETIME_VARIATION_TIME,
|
229
|
+
datetime: INPUT_TYPE::TYPE_CLASS_DATETIME,
|
230
|
+
}
|
231
|
+
|
232
|
+
def input_type=(text_type)
|
233
|
+
if INPUT_TYPES.keys.include? text_type
|
234
|
+
self.view.get.inputType = INPUT_TYPES[text_type]
|
235
|
+
else
|
236
|
+
puts "The value #{text_type} is not a supported input_type value. Defaulting to normal text."
|
237
|
+
self.input_type = :normal
|
238
|
+
end
|
239
|
+
end
|
240
|
+
|
241
|
+
GRAVITY = Android::View::Gravity
|
242
|
+
GRAVITY_OPTIONS = {
|
243
|
+
top: GRAVITY::TOP,
|
244
|
+
left: GRAVITY::LEFT,
|
245
|
+
right: GRAVITY::RIGHT,
|
246
|
+
bottom: GRAVITY::BOTTOM,
|
247
|
+
center: GRAVITY::CENTER,
|
248
|
+
bottom_right: GRAVITY::BOTTOM | GRAVITY::RIGHT,
|
249
|
+
bottom_left: GRAVITY::BOTTOM | GRAVITY::LEFT,
|
250
|
+
center_right: GRAVITY::CENTER | GRAVITY::RIGHT,
|
251
|
+
center_left: GRAVITY::CENTER | GRAVITY::LEFT,
|
252
|
+
top_right: GRAVITY::TOP | GRAVITY::RIGHT,
|
253
|
+
top_left: GRAVITY::TOP | GRAVITY::LEFT,
|
254
|
+
}
|
255
|
+
|
256
|
+
def gravity=(alignment)
|
257
|
+
if GRAVITY_OPTIONS.keys.include? alignment
|
258
|
+
self.view.get.gravity = GRAVITY_OPTIONS[alignment]
|
259
|
+
else
|
260
|
+
puts "The value #{alignment} is not a supported gravity value. Defaulting to center."
|
261
|
+
self.gravity = :center
|
262
|
+
end
|
263
|
+
end
|
264
|
+
end
|
@@ -0,0 +1,75 @@
|
|
1
|
+
class AMQView
|
2
|
+
attr_accessor :view, :activity, :stylesheet, :style_name, :layout_params, :options, :extra
|
3
|
+
|
4
|
+
def initialize(view, activity, stylesheet, style_name, layout_params, options = {})
|
5
|
+
self.view = view
|
6
|
+
self.activity = activity
|
7
|
+
self.stylesheet = stylesheet
|
8
|
+
self.style_name = style_name
|
9
|
+
self.layout_params = layout_params
|
10
|
+
self.options = {
|
11
|
+
parent: nil,
|
12
|
+
}.merge(options)
|
13
|
+
end
|
14
|
+
|
15
|
+
# convenience methods
|
16
|
+
def id; get.id end
|
17
|
+
def id=(vid); get.id = vid end
|
18
|
+
def get; self.view end
|
19
|
+
def left; get.getLeft end
|
20
|
+
def right; get.getRight end
|
21
|
+
def bottom; get.getBottom end
|
22
|
+
def top; get.getTop end
|
23
|
+
def width; get.getWidth end
|
24
|
+
def height; get.getHeight end
|
25
|
+
def text; get.text end
|
26
|
+
def text=(t); get.text = t end
|
27
|
+
|
28
|
+
def create_android_query_view(view, style_method, layout_params, options = {}, &block)
|
29
|
+
aqv = AMQView.new(view, self.activity, self.stylesheet, style_method, layout_params, options)
|
30
|
+
self.stylesheet.apply_style_for(aqv, style_method, layout_params)
|
31
|
+
self.get.addView(aqv.get)
|
32
|
+
block.call(aqv) if block_given?
|
33
|
+
aqv
|
34
|
+
end
|
35
|
+
|
36
|
+
def linear_layout(style_method, &block)
|
37
|
+
view = Android::Widget::LinearLayout.new(self.activity)
|
38
|
+
lp = Android::Widget::LinearLayout::LayoutParams
|
39
|
+
create_android_query_view(view, style_method, lp, {}, &block)
|
40
|
+
end
|
41
|
+
|
42
|
+
def text_view(style_method, &block)
|
43
|
+
view = Android::Widget::TextView.new(self.activity)
|
44
|
+
new_view(view, style_method, &block)
|
45
|
+
end
|
46
|
+
|
47
|
+
def edit_text(style_method, &block)
|
48
|
+
view = Android::Widget::EditText.new(self.activity)
|
49
|
+
new_view(view, style_method, &block)
|
50
|
+
end
|
51
|
+
|
52
|
+
def button(style_method, &block)
|
53
|
+
view = Android::Widget::Button.new(self.activity)
|
54
|
+
new_view(view, style_method, &block)
|
55
|
+
end
|
56
|
+
|
57
|
+
def image_view(style_method, &block)
|
58
|
+
view = Android::Widget::ImageView.new(self.activity)
|
59
|
+
new_view(view, style_method, &block)
|
60
|
+
end
|
61
|
+
|
62
|
+
def image_button(style_method, &block)
|
63
|
+
view = Android::Widget::ImageButton.new(self.activity)
|
64
|
+
new_view(view, style_method, &block)
|
65
|
+
end
|
66
|
+
|
67
|
+
def grid_view(style_method, &block)
|
68
|
+
view = Android::Widget::GridView.new(self)
|
69
|
+
new_view(view, style_method, &block)
|
70
|
+
end
|
71
|
+
|
72
|
+
def new_view(view, style_method, &block)
|
73
|
+
create_android_query_view(view, style_method, self.layout_params, {}, &block)
|
74
|
+
end
|
75
|
+
end
|
metadata
ADDED
@@ -0,0 +1,69 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: android_motion_query
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Abdullah Esmail
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2017-11-08 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: rake
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ">="
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '0'
|
20
|
+
type: :development
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ">="
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '0'
|
27
|
+
description: Making RubyMotion android development easy and enjoyable
|
28
|
+
email:
|
29
|
+
- abdullah.esmail@gmail.com
|
30
|
+
executables: []
|
31
|
+
extensions: []
|
32
|
+
extra_rdoc_files: []
|
33
|
+
files:
|
34
|
+
- LICENSE.txt
|
35
|
+
- README.md
|
36
|
+
- lib/android_motion_query.rb
|
37
|
+
- lib/android_motion_query/adapters.rb
|
38
|
+
- lib/android_motion_query/amq.rb
|
39
|
+
- lib/android_motion_query/colors.rb
|
40
|
+
- lib/android_motion_query/events.rb
|
41
|
+
- lib/android_motion_query/screen.rb
|
42
|
+
- lib/android_motion_query/stylesheet.rb
|
43
|
+
- lib/android_motion_query/version.rb
|
44
|
+
- lib/android_motion_query/views.rb
|
45
|
+
homepage: https://github.com/aesmail/android-query
|
46
|
+
licenses:
|
47
|
+
- MIT
|
48
|
+
metadata: {}
|
49
|
+
post_install_message:
|
50
|
+
rdoc_options: []
|
51
|
+
require_paths:
|
52
|
+
- lib
|
53
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
54
|
+
requirements:
|
55
|
+
- - ">="
|
56
|
+
- !ruby/object:Gem::Version
|
57
|
+
version: '0'
|
58
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
59
|
+
requirements:
|
60
|
+
- - ">="
|
61
|
+
- !ruby/object:Gem::Version
|
62
|
+
version: '0'
|
63
|
+
requirements: []
|
64
|
+
rubyforge_project:
|
65
|
+
rubygems_version: 2.6.11
|
66
|
+
signing_key:
|
67
|
+
specification_version: 4
|
68
|
+
summary: Making RubyMotion android development easy and enjoyable
|
69
|
+
test_files: []
|