formotion 1.3.1 → 1.4.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 +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
|
+

|
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
|
+

|
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
|

|
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
|
+

|
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
|
+

|
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
|
+

|
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
|
+

|
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
|