android_motion_query 0.1.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 +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
|
+

|
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: []
|