formotion 1.3.1 → 1.4.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +8 -8
- data/.travis.yml +1 -0
- data/Formotion.gemspec +1 -1
- data/LIST_OF_ROW_TYPES.md +115 -3
- data/README.md +1 -0
- data/examples/KitchenSink/app/app_delegate.rb +16 -2
- data/lib/formotion.rb +9 -1
- data/lib/formotion/form/form.rb +7 -0
- data/lib/formotion/form/form_delegate.rb +2 -2
- data/lib/formotion/patch/ui_image.rb +45 -0
- data/lib/formotion/patch/ui_text_view_placeholder.rb +4 -1
- data/lib/formotion/row/row.rb +13 -1
- data/lib/formotion/row_type/base.rb +13 -4
- data/lib/formotion/row_type/button.rb +1 -0
- data/lib/formotion/row_type/check_row.rb +2 -1
- data/lib/formotion/row_type/date_row.rb +3 -0
- data/lib/formotion/row_type/image_row.rb +6 -1
- data/lib/formotion/row_type/map_row.rb +79 -0
- data/lib/formotion/row_type/multi_choice_row.rb +25 -0
- data/lib/formotion/row_type/object_row.rb +30 -0
- data/lib/formotion/row_type/options_row.rb +2 -2
- data/lib/formotion/row_type/paged_image_row.rb +257 -0
- data/lib/formotion/row_type/picker_row.rb +2 -0
- data/lib/formotion/row_type/slider_row.rb +2 -2
- data/lib/formotion/row_type/static_row.rb +1 -1
- data/lib/formotion/row_type/string_row.rb +3 -7
- data/lib/formotion/row_type/subform_row.rb +3 -1
- data/lib/formotion/row_type/switch_row.rb +2 -2
- data/lib/formotion/row_type/tags_row.rb +172 -0
- data/lib/formotion/row_type/template_row.rb +3 -3
- data/lib/formotion/row_type/text_row.rb +5 -1
- data/lib/formotion/row_type/web_view_row.rb +44 -0
- data/lib/formotion/version.rb +1 -1
- data/resources/tags_row-selected.png +0 -0
- data/resources/tags_row-selected@2x.png +0 -0
- data/resources/tags_row.png +0 -0
- data/resources/tags_row@2x.png +0 -0
- data/spec/form_spec.rb +26 -0
- data/spec/functional/date_row_spec.rb +6 -0
- data/spec/functional/picker_row_spec.rb +5 -0
- data/spec/row_type/back_spec.rb +1 -1
- data/spec/row_type/base_spec.rb +3 -3
- data/spec/row_type/string_spec.rb +14 -3
- data/spec/row_type/subform_spec.rb +1 -1
- data/spec/row_type/submit_spec.rb +1 -1
- data/spec/row_type/text_spec.rb +7 -0
- metadata +17 -6
checksums.yaml
CHANGED
@@ -1,15 +1,15 @@
|
|
1
1
|
---
|
2
2
|
!binary "U0hBMQ==":
|
3
3
|
metadata.gz: !binary |-
|
4
|
-
|
4
|
+
ZmYyOTdkNGExNDMzMzU5Mjg5NjMxZGIxZWE4NzcxY2NjNjM5ZDBjMA==
|
5
5
|
data.tar.gz: !binary |-
|
6
|
-
|
6
|
+
YWJmNzEwODljYmUzN2ZhN2I0MTE4YmFkYWI1ODhhMDkzOTQxYzNjZg==
|
7
7
|
!binary "U0hBNTEy":
|
8
8
|
metadata.gz: !binary |-
|
9
|
-
|
10
|
-
|
11
|
-
|
9
|
+
YzYyMTNkZjI3MWE3YTFiMGY5MzBiMTc4MWEyOGVmNGE5NGE3Y2I5MDgxZjM1
|
10
|
+
MDMxZDliM2Y0OWY2ZjhkODFjMjczYTIyMDI2MDNkNWU0YzIzYzRiOTYzNzRk
|
11
|
+
Yjg3ZGRmN2UwZWY3OTdmODY5YjBiZTEzNWU1NDg3ZjE3NjFiYzE=
|
12
12
|
data.tar.gz: !binary |-
|
13
|
-
|
14
|
-
|
15
|
-
|
13
|
+
NzQzNzdmYmM5YjJkY2YxZDU5YjliM2RmYzUyZDIyMzIyM2NjYjVkYmViZTA2
|
14
|
+
MWZmYTgxMGEyMmY4NmM1NmJjZDA1NWE3YTE4ZDRkNWEwNzA5NzYxZTgzMzU2
|
15
|
+
ZTFkZWZkODQ0MWU4ZjViNzIyY2FkMTUyN2FjMjUwYzhlNjk0ZTk=
|
data/.travis.yml
CHANGED
data/Formotion.gemspec
CHANGED
@@ -14,7 +14,7 @@ Gem::Specification.new do |s|
|
|
14
14
|
s.test_files = s.files.grep(%r{^(test|spec|features)/})
|
15
15
|
s.require_paths = ["lib"]
|
16
16
|
|
17
|
-
s.add_dependency "bubble-wrap", "
|
17
|
+
s.add_dependency "bubble-wrap", "~> 1.3.0"
|
18
18
|
s.add_dependency "motion-require", "~> 0.0.3"
|
19
19
|
s.add_development_dependency 'rake'
|
20
20
|
end
|
data/LIST_OF_ROW_TYPES.md
CHANGED
@@ -5,7 +5,8 @@
|
|
5
5
|
[Phone](#phone)<br/>
|
6
6
|
[Number](#number)<br/>
|
7
7
|
[Currency](#currency)<br/>
|
8
|
-
[Date](#date)
|
8
|
+
[Date](#date)<br/>
|
9
|
+
[Object](#object)<br/>
|
9
10
|
|
10
11
|
**Other**<br/>
|
11
12
|
[Static](#static)<br/>
|
@@ -16,7 +17,11 @@
|
|
16
17
|
[Option](#option)<br/>
|
17
18
|
[Picker](#picker)<br/>
|
18
19
|
[Subform](#subform)<br/>
|
19
|
-
[Template](#template)
|
20
|
+
[Template](#template)<br/>
|
21
|
+
[MapView](#mapview)<br/>
|
22
|
+
[WebView](#webview)<br/>
|
23
|
+
[PagedImage](#pagedimage)<br/>
|
24
|
+
[Tags](#tags)<br/>
|
20
25
|
|
21
26
|
**Buttons**<br/>
|
22
27
|
[Button](#button)<br/>
|
@@ -89,6 +94,34 @@ The `TextRow` is a multiline text input row and opens the default keyboard when
|
|
89
94
|
To define the height of the row set the property `row_height`.
|
90
95
|
|
91
96
|
|
97
|
+
#### <a name="text_fonts"></a> Text row with Big Font
|
98
|
+
![Text Row](https://github.com/clayallsopp/formotion/wiki/row-types/text_big_font.png)
|
99
|
+
|
100
|
+
```ruby
|
101
|
+
{
|
102
|
+
title: "Big Text",
|
103
|
+
key: :text,
|
104
|
+
type: :text,
|
105
|
+
font: {name: 'Helvetica', size: 24},
|
106
|
+
placeholder: "Enter your big text here",
|
107
|
+
row_height: 100
|
108
|
+
}
|
109
|
+
```
|
110
|
+
|
111
|
+
#### <a name="text_fonts"></a> Text row with Small Font
|
112
|
+
![Text Row](https://github.com/clayallsopp/formotion/wiki/row-types/text_small_font.png)
|
113
|
+
|
114
|
+
```ruby
|
115
|
+
{
|
116
|
+
title: "Small Text",
|
117
|
+
key: :text,
|
118
|
+
type: :text,
|
119
|
+
font: {name: 'Chalkduster', size: 8},
|
120
|
+
placeholder: "Enter your small text here",
|
121
|
+
row_height: 100
|
122
|
+
}
|
123
|
+
```
|
124
|
+
|
92
125
|
### <a name="email"></a> Email row
|
93
126
|
![Email row](https://github.com/clayallsopp/formotion/wiki/row-types/email.png)
|
94
127
|
```ruby
|
@@ -186,6 +219,21 @@ Note: If you use `:date_time` or `:time` for the type, `:minute_interval` will b
|
|
186
219
|
the default is the Apple default of 1.
|
187
220
|
|
188
221
|
|
222
|
+
### <a name="object"></a> Object row
|
223
|
+
|
224
|
+
```ruby
|
225
|
+
{
|
226
|
+
title: "My Data",
|
227
|
+
type: :object,
|
228
|
+
value: object # an object
|
229
|
+
}
|
230
|
+
```
|
231
|
+
|
232
|
+
Same as StringRow with the difference that it would not change the row.value to string.
|
233
|
+
The object needs a to_s method.
|
234
|
+
|
235
|
+
|
236
|
+
|
189
237
|
## Other
|
190
238
|
|
191
239
|
### <a name="static"></a> Static row
|
@@ -378,6 +426,69 @@ Use a `:display_key` to show the value of the subform in the row:
|
|
378
426
|
}
|
379
427
|
```
|
380
428
|
|
429
|
+
|
430
|
+
### <a name="mapview"></a> MapView row
|
431
|
+
![MapView row](https://github.com/rheoli/formotion/wiki/row-types/Mapview.png)
|
432
|
+
```ruby
|
433
|
+
{
|
434
|
+
title: "Map",
|
435
|
+
type: :map_view,
|
436
|
+
value: coordinates, # of type CLLocationCoordinate2D
|
437
|
+
row_height: 200 # for better viewing
|
438
|
+
}
|
439
|
+
```
|
440
|
+
|
441
|
+
Shows a map with a pin at the coordinates from value.
|
442
|
+
|
443
|
+
|
444
|
+
### <a name="webview"></a> WebView row
|
445
|
+
![WebView row](https://github.com/rheoli/formotion/wiki/row-types/Webview.png)
|
446
|
+
```ruby
|
447
|
+
{
|
448
|
+
title: "Page",
|
449
|
+
type: :web_view,
|
450
|
+
value: html, # HTML code to be shown
|
451
|
+
row_height: 200 # for better viewing
|
452
|
+
}
|
453
|
+
```
|
454
|
+
|
455
|
+
|
456
|
+
### <a name="pagedimage"></a> PagedImage row
|
457
|
+
![Pagedimage row](https://github.com/rheoli/formotion/wiki/row-types/Pagedimage.png)
|
458
|
+
```ruby
|
459
|
+
{
|
460
|
+
title: "Photos",
|
461
|
+
type: :paged_image,
|
462
|
+
value: images, # array of UIImage's
|
463
|
+
row_height: 200 # for better viewing
|
464
|
+
}
|
465
|
+
```
|
466
|
+
Same functionality as ImageRow but you can scroll through many photos.
|
467
|
+
|
468
|
+
|
469
|
+
### <a name="tags"></a> Tags row
|
470
|
+
![Tags row](https://github.com/rheoli/formotion/wiki/row-types/Tags.png)
|
471
|
+
```ruby
|
472
|
+
{
|
473
|
+
title: "Tags",
|
474
|
+
type: :tags,
|
475
|
+
value: ["Beer","Dark Beer"],
|
476
|
+
row_height: 200 # for better viewing
|
477
|
+
}
|
478
|
+
```
|
479
|
+
|
480
|
+
Add on_tap callback:
|
481
|
+
```ruby
|
482
|
+
row.on_tap do |row|
|
483
|
+
... # will be called when '+' in editable mode will touched
|
484
|
+
# add the new tag with row.object.add_tag(new_tag)
|
485
|
+
end
|
486
|
+
|
487
|
+
```
|
488
|
+
Show/Edit tags.
|
489
|
+
|
490
|
+
|
491
|
+
|
381
492
|
## Buttons
|
382
493
|
|
383
494
|
### <a name="button"></a> Button row
|
@@ -386,10 +497,11 @@ Use a `:display_key` to show the value of the subform in the row:
|
|
386
497
|
{
|
387
498
|
title: "Any Button",
|
388
499
|
type: :button,
|
500
|
+
key: :some_button
|
389
501
|
}
|
390
502
|
|
391
503
|
# later...
|
392
|
-
form.
|
504
|
+
form.row(:some_button).on_tap do |row|
|
393
505
|
# do something when tapped
|
394
506
|
end
|
395
507
|
```
|
data/README.md
CHANGED
@@ -57,10 +57,24 @@ class AppDelegate
|
|
57
57
|
type: :string,
|
58
58
|
row_height: 60
|
59
59
|
}, {
|
60
|
-
|
60
|
+
title: "Text",
|
61
|
+
key: :text,
|
62
|
+
type: :text,
|
63
|
+
placeholder: "Enter your text here",
|
64
|
+
row_height: 100
|
65
|
+
}, {
|
66
|
+
title: "Big Text",
|
67
|
+
key: :text,
|
68
|
+
type: :text,
|
69
|
+
font: {name: 'Helvetica', size: 24},
|
70
|
+
placeholder: "Enter your big text here",
|
71
|
+
row_height: 100
|
72
|
+
}, {
|
73
|
+
title: "Small Text",
|
61
74
|
key: :text,
|
62
75
|
type: :text,
|
63
|
-
|
76
|
+
font: {name: 'Chalkduster', size: 8},
|
77
|
+
placeholder: "Enter your small text here",
|
64
78
|
row_height: 100
|
65
79
|
}, {
|
66
80
|
title: "Check",
|
data/lib/formotion.rb
CHANGED
@@ -1,7 +1,15 @@
|
|
1
1
|
require File.expand_path(File.join(File.dirname(__FILE__), "formotion/version"))
|
2
2
|
require 'bubble-wrap/core'
|
3
|
+
require 'bubble-wrap/font'
|
3
4
|
require 'bubble-wrap/camera'
|
4
5
|
|
5
6
|
require 'motion-require'
|
6
7
|
|
7
|
-
Motion::Require.all(Dir.glob(File.expand_path('../formotion/**/*.rb', __FILE__)))
|
8
|
+
Motion::Require.all(Dir.glob(File.expand_path('../formotion/**/*.rb', __FILE__)))
|
9
|
+
|
10
|
+
Motion::Project::App.setup do |app|
|
11
|
+
app.frameworks<<'CoreLocation' unless app.frameworks.include?('CoreLocation')
|
12
|
+
app.frameworks<<'MapKit' unless app.frameworks.include?('MapKit')
|
13
|
+
|
14
|
+
app.resources_dirs << File.join(File.dirname(__FILE__), '../resources')
|
15
|
+
end
|
data/lib/formotion/form/form.rb
CHANGED
@@ -35,7 +35,7 @@ module Formotion
|
|
35
35
|
previous_row, next_row = nil
|
36
36
|
|
37
37
|
last_row = self.sections[-1] && self.sections[-1].rows[-1]
|
38
|
-
if last_row
|
38
|
+
if last_row && last_row.type != :text
|
39
39
|
last_row.return_key ||= UIReturnKeyDone
|
40
40
|
end
|
41
41
|
|
@@ -92,7 +92,7 @@ module Formotion
|
|
92
92
|
def tableView(tableView, didSelectRowAtIndexPath:indexPath)
|
93
93
|
tableView.deselectRowAtIndexPath(indexPath, animated:true)
|
94
94
|
row = row_for_index_path(indexPath)
|
95
|
-
row.object.
|
95
|
+
row.object._on_select(tableView, self)
|
96
96
|
end
|
97
97
|
|
98
98
|
def tableView(tableView, editingStyleForRowAtIndexPath:indexPath)
|
@@ -0,0 +1,45 @@
|
|
1
|
+
class UIImage
|
2
|
+
|
3
|
+
# Resize Image
|
4
|
+
# target_size: Array or CGSize
|
5
|
+
# upscale: Boolean (false = do not upscale image)
|
6
|
+
#
|
7
|
+
# Code ideas from http://stackoverflow.com/questions/15653953/resize-image-in-iphone
|
8
|
+
#
|
9
|
+
def resize_image_to_size(target_size, upscale=true)
|
10
|
+
image_size = self.size
|
11
|
+
|
12
|
+
# convert Array to CGSize
|
13
|
+
if target_size.is_a?(Array)
|
14
|
+
target_size = CGSizeMake(target_size[0], target_size[1])
|
15
|
+
end
|
16
|
+
# when target_size no CGSize set to image_size
|
17
|
+
unless target_size.is_a?(CGSize)
|
18
|
+
target_size = image_size
|
19
|
+
end
|
20
|
+
|
21
|
+
# do not upscale when requested
|
22
|
+
if !upscale and (target_size.width > image_size.width or target_size.height > image_size.height)
|
23
|
+
target_size = image_size
|
24
|
+
end
|
25
|
+
|
26
|
+
unless CGSizeEqualToSize(image_size, target_size)
|
27
|
+
width_factor = target_size.width / image_size.width
|
28
|
+
height_factor = target_size.height / image_size.height
|
29
|
+
if width_factor < height_factor
|
30
|
+
target_size.height = image_size.height * width_factor
|
31
|
+
else
|
32
|
+
target_size.width = image_size.width * height_factor
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
UIGraphicsBeginImageContext(target_size)
|
37
|
+
resize_rect = CGRectMake(0, 0, target_size.width, target_size.height)
|
38
|
+
self.drawInRect resize_rect
|
39
|
+
resized_image = UIGraphicsGetImageFromCurrentImageContext()
|
40
|
+
UIGraphicsEndImageContext()
|
41
|
+
|
42
|
+
resized_image
|
43
|
+
end
|
44
|
+
|
45
|
+
end
|
@@ -55,7 +55,10 @@ class UITextView
|
|
55
55
|
end
|
56
56
|
|
57
57
|
def placeholder_rect
|
58
|
-
|
58
|
+
x_offset = font.xHeight
|
59
|
+
y_offset = font.capHeight + font.descender
|
60
|
+
|
61
|
+
CGRectMake(self.contentInset.left + x_offset, self.contentInset.top + y_offset, self.frame.size.width - self.contentInset.left - self.contentInset.right - x_offset, self.frame.size.height - self.contentInset.top - self.contentInset.bottom - y_offset)
|
59
62
|
end
|
60
63
|
|
61
64
|
def placeholder_color
|
data/lib/formotion/row/row.rb
CHANGED
@@ -88,10 +88,18 @@ module Formotion
|
|
88
88
|
# In a date/time or time picker, the minute interval can
|
89
89
|
# be set. That allows picking by every 15 minutes, etc.
|
90
90
|
:minute_interval,
|
91
|
+
#-Resize image when needed (size as Array [1500,1500])
|
92
|
+
:max_image_size,
|
93
|
+
# Font for String and Text rows
|
94
|
+
:font,
|
91
95
|
# Display an inputAccessoryView when editing a StringRow.
|
92
96
|
# OPTIONS: :done (a black translucent toolbar with a right-aligned "Done" button)
|
93
97
|
# DEFAULT is nil
|
94
|
-
:input_accessory
|
98
|
+
:input_accessory,
|
99
|
+
# Cell selection style
|
100
|
+
# OPTIONS: :blue, :gray, :none
|
101
|
+
# DEFAULT is :blue
|
102
|
+
:selection_style
|
95
103
|
]
|
96
104
|
PROPERTIES.each {|prop|
|
97
105
|
attr_accessor prop
|
@@ -257,6 +265,10 @@ module Formotion
|
|
257
265
|
@text_alignment = const_int_get("UITextAlignment", alignment)
|
258
266
|
end
|
259
267
|
|
268
|
+
def selection_style=(style)
|
269
|
+
@selection_style = const_int_get("UITableViewCellSelectionStyle", style || :blue)
|
270
|
+
end
|
271
|
+
|
260
272
|
def editable=(editable)
|
261
273
|
case editable
|
262
274
|
when TrueClass
|
@@ -56,17 +56,26 @@ module Formotion
|
|
56
56
|
|
57
57
|
# method gets triggered when tableView(tableView, didSelectRowAtIndexPath:indexPath)
|
58
58
|
# in UITableViewDelegate is executed
|
59
|
-
def
|
59
|
+
def _on_select(tableView, tableViewDelegate)
|
60
60
|
# row class should call super and proceed if false is return (not handled here)
|
61
61
|
if row.on_tap_callback
|
62
62
|
# Not all row types will want to define on_tap, but call it if so
|
63
|
-
row.on_tap_callback.call(self.row)
|
64
|
-
|
63
|
+
if row.on_tap_callback.call(self.row) != false
|
64
|
+
on_select(tableView, tableViewDelegate)
|
65
|
+
true
|
66
|
+
else
|
67
|
+
false
|
68
|
+
end
|
65
69
|
else
|
66
|
-
|
70
|
+
on_select(tableView, tableViewDelegate)
|
67
71
|
end
|
68
72
|
end
|
69
73
|
|
74
|
+
# Override in subclass
|
75
|
+
def on_select(tableView, tableViewDelegate)
|
76
|
+
false
|
77
|
+
end
|
78
|
+
|
70
79
|
# called when the delete editing style was triggered tableView:commitEditingStyle:forRowAtIndexPath:
|
71
80
|
def on_delete(tableView, tableViewDelegate)
|
72
81
|
if row.on_delete_callback
|
@@ -11,6 +11,7 @@ module Formotion
|
|
11
11
|
# for just this one UITableViewCell object, in order to
|
12
12
|
# center it's labels horizontally.
|
13
13
|
def build_cell(cell)
|
14
|
+
cell.selectionStyle = self.row.selection_style || UITableViewCellSelectionStyleBlue
|
14
15
|
cell.swizzle(:layoutSubviews) do
|
15
16
|
def layoutSubviews
|
16
17
|
old_layoutSubviews
|
@@ -14,6 +14,7 @@ module Formotion
|
|
14
14
|
# instantiate long-lived objects in them.
|
15
15
|
# Maybe that logic should be moved elsewhere?
|
16
16
|
def build_cell(cell)
|
17
|
+
cell.selectionStyle = self.row.selection_style || UITableViewCellSelectionStyleBlue
|
17
18
|
update_cell_value(cell)
|
18
19
|
observe(self.row, "value") do |old_value, new_value|
|
19
20
|
update_cell_value(cell)
|
@@ -36,4 +37,4 @@ module Formotion
|
|
36
37
|
|
37
38
|
end
|
38
39
|
end
|
39
|
-
end
|
40
|
+
end
|