motion-prime 0.1.1 → 0.1.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.
- checksums.yaml +15 -0
- data/.travis.yml +3 -5
- data/CHANGELOG.md +5 -0
- data/Gemfile.lock +1 -1
- data/README.md +32 -31
- data/Rakefile +8 -1
- data/motion-prime/elements/_text_height_mixin.rb +17 -0
- data/motion-prime/elements/draw.rb +34 -20
- data/motion-prime/elements/draw/image.rb +26 -3
- data/motion-prime/elements/draw/label.rb +22 -5
- data/motion-prime/elements/label.rb +2 -9
- data/motion-prime/helpers/has_search_bar.rb +2 -0
- data/motion-prime/sections/base.rb +20 -10
- data/motion-prime/sections/draw.rb +9 -0
- data/motion-prime/sections/form.rb +51 -10
- data/motion-prime/sections/form/base_field_section.rb +30 -4
- data/motion-prime/sections/form/password_field_section.rb +1 -1
- data/motion-prime/sections/form/string_field_section.rb +1 -1
- data/motion-prime/sections/form/text_field_section.rb +1 -1
- data/motion-prime/sections/tabbed.rb +76 -0
- data/motion-prime/sections/table.rb +3 -1
- data/motion-prime/styles/base.rb +3 -0
- data/motion-prime/version.rb +1 -1
- data/motion-prime/views/view_styler.rb +4 -0
- data/travis.sh +8 -0
- metadata +9 -33
checksums.yaml
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
---
|
2
|
+
!binary "U0hBMQ==":
|
3
|
+
metadata.gz: !binary |-
|
4
|
+
OGZjZGVmYWUxZTgzYTU0MTg4ZjZiYjAwOTY5NTMxNTdmNjk5ZDFjZQ==
|
5
|
+
data.tar.gz: !binary |-
|
6
|
+
ZDM0ZmM0MDg4YTcwYmQ1YjI2OTViZDI2ZjgxMWE0NTBjYWVjMTgwOA==
|
7
|
+
!binary "U0hBNTEy":
|
8
|
+
metadata.gz: !binary |-
|
9
|
+
NjBiMzg3NTM2NjY3Y2RkMzA0ODY3OWNkNjRmY2Y3OThiZDBmNmJmYjE3OTcw
|
10
|
+
NzhlNGMxZjBkYmNkMTc5ODY4Y2VhMzlhZmE2ZDFmNDNiMjUzMWIxMzRhZDA1
|
11
|
+
YzQxOGZiMGRhZDU3ZmIyZWFhM2ExYjgwYmUxZDljOTZlY2M1N2E=
|
12
|
+
data.tar.gz: !binary |-
|
13
|
+
Y2M0ZjQzMWU0NjZlYWE5MDg4NzBjYzI0MmRlOWU1MjA1YzFkYzgwMzRjYzFi
|
14
|
+
OTIzOWVhOGQzMDJiYzFmNTIxZmNmYzJjNGE0N2YyMWI4MDMzNDc2ZGEyMzkx
|
15
|
+
ZTVlZDZkM2RlMzQyM2FkOGMzZjg5ZGYzY2JiNjg0NGJlMmE3NzM=
|
data/.travis.yml
CHANGED
data/CHANGELOG.md
ADDED
data/Gemfile.lock
CHANGED
data/README.md
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
# MotionPrime [](https://travis-ci.org/droidlabs/motion-prime)
|
2
2
|
|
3
3
|

|
4
4
|
|
@@ -21,44 +21,45 @@ The main feature of MotionPrime is one more layer on UI elements: Section.
|
|
21
21
|
|
22
22
|
# edit Rakefile
|
23
23
|
|
24
|
-
###
|
24
|
+
### 4. Run application
|
25
25
|
|
26
26
|
$ rake
|
27
27
|
|
28
28
|
## Hello World (Sample)
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
end
|
35
|
-
end
|
36
|
-
|
37
|
-
# app/screens/main_screen.rb
|
38
|
-
class MainScreen < ApplicationScreen
|
39
|
-
title 'Main screen'
|
40
|
-
|
41
|
-
def render
|
42
|
-
@main_section = MyProfileSection.new(model: User.first)
|
43
|
-
@main_section.render(to: self)
|
44
|
-
end
|
45
|
-
end
|
46
|
-
|
47
|
-
# app/sections/my_profile.rb
|
48
|
-
class MyProfileSection < MotionPrime::BaseSection
|
49
|
-
element :title, text: "Hello World"
|
50
|
-
element :avatar, image: "images/avatar.png", type: :image
|
29
|
+
```ruby
|
30
|
+
# app/app_delegate.rb
|
31
|
+
class AppDelegate < MotionPrime::BaseAppDelegate
|
32
|
+
def on_load(app, options)
|
33
|
+
open_root_screen MainScreen.new
|
51
34
|
end
|
35
|
+
end
|
52
36
|
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
width: 300, height: 20, color: :black,
|
57
|
-
top: 10, left: 5, background_color: :white
|
37
|
+
# app/screens/main_screen.rb
|
38
|
+
class MainScreen < ApplicationScreen
|
39
|
+
title 'Main screen'
|
58
40
|
|
59
|
-
|
60
|
-
|
41
|
+
def render
|
42
|
+
@main_section = MyProfileSection.new(model: User.first)
|
43
|
+
@main_section.render(to: self)
|
61
44
|
end
|
45
|
+
end
|
46
|
+
|
47
|
+
# app/sections/my_profile.rb
|
48
|
+
class MyProfileSection < MotionPrime::BaseSection
|
49
|
+
element :title, text: "Hello World"
|
50
|
+
element :avatar, image: "images/avatar.png", type: :image
|
51
|
+
end
|
52
|
+
|
53
|
+
# app/styles/my_profile.rb
|
54
|
+
MotionPrime::Styles.define :my_profile do
|
55
|
+
style :title,
|
56
|
+
width: 300, height: 20, color: :black,
|
57
|
+
top: 10, left: 5, background_color: :white
|
58
|
+
|
59
|
+
style :avatar,
|
60
|
+
width: 90, height: 90, top: 40, left: 5
|
61
|
+
end
|
62
|
+
```
|
62
63
|
|
63
64
|
## Contributing
|
64
65
|
|
data/Rakefile
CHANGED
@@ -1,9 +1,16 @@
|
|
1
1
|
# -*- coding: utf-8 -*-
|
2
|
+
require "bundler/gem_tasks"
|
3
|
+
namespace :gem do
|
4
|
+
task :release do
|
5
|
+
helper = Bundler::GemHelper.new
|
6
|
+
helper.release_gem(helper.send :built_gem_path)
|
7
|
+
end
|
8
|
+
end
|
9
|
+
|
2
10
|
$:.unshift("/Library/RubyMotion/lib")
|
3
11
|
require 'motion/project/template/ios'
|
4
12
|
require "rubygems"
|
5
13
|
require "bundler"
|
6
|
-
require "bundler/gem_tasks"
|
7
14
|
require 'motion-cocoapods'
|
8
15
|
Bundler.setup
|
9
16
|
Bundler.require
|
@@ -0,0 +1,17 @@
|
|
1
|
+
module MotionPrime
|
2
|
+
module ElementTextHeightMixin
|
3
|
+
def height
|
4
|
+
width = computed_options[:width]
|
5
|
+
font = computed_options[:font] || :system.uifont
|
6
|
+
raise "Please set element width for height calculation" unless width
|
7
|
+
computed_options[:text].sizeWithFont(font,
|
8
|
+
constrainedToSize: [width, Float::MAX],
|
9
|
+
lineBreakMode: UILineBreakModeWordWrap).height
|
10
|
+
end
|
11
|
+
|
12
|
+
def outer_height
|
13
|
+
height + computed_options[:top].to_i +
|
14
|
+
computed_options[:bottom].to_i
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -10,42 +10,56 @@ module MotionPrime
|
|
10
10
|
@view ||= section.container_view
|
11
11
|
end
|
12
12
|
|
13
|
-
def
|
14
|
-
width
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
13
|
+
def computed_max_width
|
14
|
+
view.bounds.size.width
|
15
|
+
end
|
16
|
+
|
17
|
+
def computed_max_height
|
18
|
+
view.bounds.size.height
|
19
|
+
end
|
19
20
|
|
21
|
+
def computed_width
|
22
|
+
width = computed_options[:width]
|
20
23
|
width = 0.0 if width.nil?
|
21
|
-
max_width = view.bounds.size.width
|
22
24
|
|
23
|
-
# calculate
|
25
|
+
# calculate width if width is relative, e.g 0.7
|
24
26
|
if width > 0 && width <= 1
|
25
|
-
|
27
|
+
computed_max_width * width
|
26
28
|
else
|
27
|
-
|
29
|
+
computed_max_width < width ? width : computed_max_width
|
28
30
|
end
|
29
31
|
end
|
30
32
|
|
31
|
-
def
|
33
|
+
def computed_height
|
32
34
|
height = computed_options[:height]
|
33
|
-
top = computed_options[:top]
|
34
|
-
bottom = computed_options[:bottom]
|
35
|
-
return top if top
|
36
|
-
return 0 if bottom.nil?
|
37
|
-
|
38
35
|
height = 0.0 if height.nil?
|
39
|
-
max_height = view.bounds.size.height
|
40
36
|
|
41
|
-
# calculate
|
37
|
+
# calculate height if height is relative, e.g 0.7
|
42
38
|
if height > 0 && height <= 1
|
43
|
-
|
39
|
+
computed_max_height * height
|
44
40
|
else
|
45
|
-
|
41
|
+
computed_max_height < height ? height : computed_max_height
|
46
42
|
end
|
47
43
|
end
|
48
44
|
|
45
|
+
def computed_left
|
46
|
+
left = computed_options[:left]
|
47
|
+
right = computed_options[:right]
|
48
|
+
return left if left
|
49
|
+
return 0 if right.nil?
|
50
|
+
|
51
|
+
computed_max_width - (computed_width + right)
|
52
|
+
end
|
53
|
+
|
54
|
+
def computed_top
|
55
|
+
top = computed_options[:top]
|
56
|
+
bottom = computed_options[:bottom]
|
57
|
+
return top if top
|
58
|
+
return 0 if bottom.nil?
|
59
|
+
|
60
|
+
computed_max_height - (computed_height + bottom)
|
61
|
+
end
|
62
|
+
|
49
63
|
class << self
|
50
64
|
def factory(type, options = {})
|
51
65
|
class_name = "#{type.classify}DrawElement"
|
@@ -3,6 +3,7 @@ module MotionPrime
|
|
3
3
|
class ImageDrawElement < DrawElement
|
4
4
|
attr_accessor :image_data
|
5
5
|
def draw_in(rect)
|
6
|
+
return if computed_options[:hidden]
|
6
7
|
image_rect = CGRectMake(
|
7
8
|
computed_left,
|
8
9
|
computed_top,
|
@@ -15,11 +16,12 @@ module MotionPrime
|
|
15
16
|
# draw image from resources
|
16
17
|
elsif computed_options[:image]
|
17
18
|
self.image_data = computed_options[:image].uiimage
|
18
|
-
image_data
|
19
|
+
draw_with_layer(image_data, image_rect)
|
19
20
|
# show default image and download image from url
|
20
21
|
elsif computed_options[:url]
|
21
22
|
if computed_options[:default]
|
22
|
-
computed_options[:default].uiimage
|
23
|
+
self.image_data = computed_options[:default].uiimage
|
24
|
+
draw_with_layer(image_data, image_rect)
|
23
25
|
end
|
24
26
|
manager = SDWebImageManager.sharedManager
|
25
27
|
manager.downloadWithURL(computed_options[:url],
|
@@ -33,11 +35,32 @@ module MotionPrime
|
|
33
35
|
section.container_view.setNeedsDisplay
|
34
36
|
else
|
35
37
|
# if it's second call, we should just draw image
|
36
|
-
|
38
|
+
draw_with_layer(image_data, image_rect)
|
37
39
|
end
|
38
40
|
end
|
39
41
|
} )
|
40
42
|
end
|
41
43
|
end
|
44
|
+
|
45
|
+
def draw_with_layer(image, rect)
|
46
|
+
if computed_options[:layer]
|
47
|
+
layer = CALayer.layer
|
48
|
+
layer.frame = CGRectMake(0, 0, image.size.width, image.size.height)
|
49
|
+
layer.contents = image.CGImage
|
50
|
+
|
51
|
+
if radius = computed_options[:layer][:corner_radius]
|
52
|
+
layer.masksToBounds = true
|
53
|
+
layer.cornerRadius = radius
|
54
|
+
end
|
55
|
+
|
56
|
+
UIGraphicsBeginImageContext(image.size);
|
57
|
+
layer.renderInContext(UIGraphicsGetCurrentContext())
|
58
|
+
image = UIGraphicsGetImageFromCurrentImageContext()
|
59
|
+
UIGraphicsEndImageContext()
|
60
|
+
image.drawInRect(rect)
|
61
|
+
else
|
62
|
+
image.drawInRect(rect)
|
63
|
+
end
|
64
|
+
end
|
42
65
|
end
|
43
66
|
end
|
@@ -1,13 +1,30 @@
|
|
1
1
|
motion_require '../draw.rb'
|
2
2
|
module MotionPrime
|
3
3
|
class LabelDrawElement < DrawElement
|
4
|
+
include MotionPrime::ElementTextHeightMixin
|
5
|
+
|
4
6
|
def draw_in(rect)
|
5
|
-
|
7
|
+
options = computed_options
|
8
|
+
return if options[:hidden]
|
9
|
+
color = options[:text_color]
|
6
10
|
color.uicolor.set if color
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
+
if options[:number_of_lines] != 0
|
12
|
+
options[:text].to_s.drawAtPoint(
|
13
|
+
CGPointMake(computed_left, computed_top),
|
14
|
+
withFont: options[:font].uifont
|
15
|
+
)
|
16
|
+
else
|
17
|
+
rect = CGRectMake(
|
18
|
+
computed_left, computed_top, computed_width, computed_height
|
19
|
+
)
|
20
|
+
line_break = options.has_key?(:line_break_mode) ? options[:line_break_mode] : :wordwrap
|
21
|
+
alignment = options.has_key?(:text_alignment) ? options[:text_alignment] : :left
|
22
|
+
options[:text].to_s.drawInRect(
|
23
|
+
rect, withFont: options[:font].uifont,
|
24
|
+
lineBreakMode: line_break.uilinebreakmode,
|
25
|
+
alignment: alignment.uitextalignment
|
26
|
+
)
|
27
|
+
end
|
11
28
|
end
|
12
29
|
end
|
13
30
|
end
|
@@ -1,5 +1,7 @@
|
|
1
1
|
module MotionPrime
|
2
2
|
class LabelElement < BaseElement
|
3
|
+
include MotionPrime::ElementTextHeightMixin
|
4
|
+
|
3
5
|
after_render :size_to_fit
|
4
6
|
|
5
7
|
def size_to_fit
|
@@ -7,14 +9,5 @@ module MotionPrime
|
|
7
9
|
view.sizeToFit
|
8
10
|
end
|
9
11
|
end
|
10
|
-
|
11
|
-
def height
|
12
|
-
width = computed_options[:width]
|
13
|
-
font = computed_options[:font] || :system.uifont
|
14
|
-
raise "Please set element width for height calculation" unless width
|
15
|
-
computed_options[:text].sizeWithFont(font,
|
16
|
-
constrainedToSize: [width, Float::MAX],
|
17
|
-
lineBreakMode:UILineBreakModeWordWrap).height
|
18
|
-
end
|
19
12
|
end
|
20
13
|
end
|
@@ -22,13 +22,18 @@ module MotionPrime
|
|
22
22
|
def initialize(options = {})
|
23
23
|
@options = options
|
24
24
|
@model = options[:model]
|
25
|
-
@name = options[:name] ||= self.class.name.underscore.gsub(/\_section$/, '')
|
25
|
+
@name = options[:name] ||= self.class.name.demodulize.underscore.gsub(/\_section$/, '')
|
26
26
|
create_elements
|
27
|
+
self.hide if container_options[:hidden]
|
28
|
+
end
|
29
|
+
|
30
|
+
def elements_options
|
31
|
+
self.class.elements_options || {}
|
27
32
|
end
|
28
33
|
|
29
34
|
def create_elements
|
30
35
|
self.elements = {}
|
31
|
-
|
36
|
+
elements_options.each do |key, opts|
|
32
37
|
# we should clone options to prevent overriding options
|
33
38
|
# in next element with same name in another class
|
34
39
|
options = opts.clone
|
@@ -39,7 +44,7 @@ module MotionPrime
|
|
39
44
|
|
40
45
|
def render(container_options = {})
|
41
46
|
self.container_options.merge!(container_options)
|
42
|
-
self.screen =
|
47
|
+
self.screen = container_options.delete(:to)
|
43
48
|
run_callbacks :render do
|
44
49
|
render!
|
45
50
|
end
|
@@ -59,6 +64,18 @@ module MotionPrime
|
|
59
64
|
element(name).view
|
60
65
|
end
|
61
66
|
|
67
|
+
def hide
|
68
|
+
elements.values.each do |element|
|
69
|
+
element.view.hidden = true
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
def show
|
74
|
+
elements.values.each do |element|
|
75
|
+
element.view.hidden = false
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
62
79
|
def container_options
|
63
80
|
@container_options ||= self.class.container_options.try(:clone) || {}
|
64
81
|
end
|
@@ -71,13 +88,6 @@ module MotionPrime
|
|
71
88
|
container_options[:styles]
|
72
89
|
end
|
73
90
|
|
74
|
-
def benchmark(name, &block)
|
75
|
-
Benchmark.bm do |x|
|
76
|
-
puts "Benchmark: #{name}"
|
77
|
-
x.report(&block)
|
78
|
-
end
|
79
|
-
end
|
80
|
-
|
81
91
|
class << self
|
82
92
|
def element(name, options = {}, &block)
|
83
93
|
options[:type] ||= :label
|
@@ -41,6 +41,15 @@ module MotionPrime
|
|
41
41
|
end
|
42
42
|
end
|
43
43
|
|
44
|
+
def hide
|
45
|
+
container_view.hidden = true
|
46
|
+
end
|
47
|
+
|
48
|
+
def show
|
49
|
+
container_view.hidden = false
|
50
|
+
end
|
51
|
+
|
52
|
+
# @container_view (DMViewWithSection) will call this method on draw
|
44
53
|
def draw_in(rect)
|
45
54
|
draw_background(rect)
|
46
55
|
draw_elements(rect)
|
@@ -21,7 +21,7 @@ module MotionPrime
|
|
21
21
|
KEYBOARD_HEIGHT_LANDSCAPE = 162
|
22
22
|
|
23
23
|
class_attribute :fields_options
|
24
|
-
attr_accessor :
|
24
|
+
attr_accessor :fields, :field_indexes, :keyboard_visible
|
25
25
|
|
26
26
|
after_render :bind_keyboard_events
|
27
27
|
|
@@ -30,23 +30,60 @@ module MotionPrime
|
|
30
30
|
end
|
31
31
|
|
32
32
|
def render_table
|
33
|
+
@data_stamp = Time.now.to_i
|
33
34
|
init_form_fields
|
34
|
-
|
35
|
-
|
36
|
-
|
35
|
+
self.table_view = screen.table_view(
|
36
|
+
styles: [:base_form, name.to_sym], delegate: self, dataSource: self
|
37
|
+
).view
|
37
38
|
end
|
38
39
|
|
39
40
|
def render_cell(index, table)
|
41
|
+
cell = cached_cell(index)
|
42
|
+
return cell if cell
|
43
|
+
item = data[index.row]
|
44
|
+
|
40
45
|
screen.table_view_cell styles: [:base_form_field, :"#{name}_field"], reuse_identifier: cell_name(table, index) do
|
41
|
-
|
46
|
+
item.render(to: screen)
|
42
47
|
end
|
43
48
|
end
|
44
49
|
|
45
|
-
#
|
46
|
-
#
|
50
|
+
# Returns element based on field name and element name
|
51
|
+
#
|
52
|
+
# Examples:
|
53
|
+
# form.element("email:input")
|
54
|
+
#
|
55
|
+
# @param String name with format "fieldname:elementname"
|
56
|
+
# @return MotionPrime::BaseElement element
|
47
57
|
def element(name)
|
48
58
|
field_name, element_name = name.split(':')
|
49
|
-
|
59
|
+
field(field_name).element(element_name.to_sym)
|
60
|
+
end
|
61
|
+
|
62
|
+
# Returns field by name
|
63
|
+
#
|
64
|
+
# Examples:
|
65
|
+
# form.field(:email)
|
66
|
+
#
|
67
|
+
# @param String field name
|
68
|
+
# @return MotionPrime::BaseFieldSection field
|
69
|
+
def field(field_name)
|
70
|
+
self.fields[field_name.to_sym]
|
71
|
+
end
|
72
|
+
|
73
|
+
# Set focus on field cell
|
74
|
+
#
|
75
|
+
# Examples:
|
76
|
+
# form.focus_on(:title)
|
77
|
+
#
|
78
|
+
# @param String field name
|
79
|
+
# @return MotionPrime::BaseFieldSection field
|
80
|
+
def focus_on(field_name, animated = true)
|
81
|
+
# unfocus other field
|
82
|
+
data.each do |item|
|
83
|
+
item.blur
|
84
|
+
end
|
85
|
+
# focus on field
|
86
|
+
field(field_name).focus
|
50
87
|
end
|
51
88
|
|
52
89
|
def on_edit(field); end
|
@@ -63,13 +100,13 @@ module MotionPrime
|
|
63
100
|
|
64
101
|
def set_height_with_keyboard
|
65
102
|
return if keyboard_visible
|
66
|
-
self.
|
103
|
+
self.table_view.height -= KEYBOARD_HEIGHT_PORTRAIT
|
67
104
|
self.keyboard_visible = true
|
68
105
|
end
|
69
106
|
|
70
107
|
def set_height_without_keyboard
|
71
108
|
return unless keyboard_visible
|
72
|
-
self.
|
109
|
+
self.table_view.height += KEYBOARD_HEIGHT_PORTRAIT
|
73
110
|
self.keyboard_visible = false
|
74
111
|
end
|
75
112
|
|
@@ -94,9 +131,13 @@ module MotionPrime
|
|
94
131
|
|
95
132
|
def init_form_fields
|
96
133
|
self.fields = {}
|
134
|
+
self.field_indexes = {}
|
135
|
+
index = 0
|
97
136
|
(self.class.fields_options || []).each do |key, field|
|
98
137
|
klass = "MotionPrime::#{field[:type].classify}FieldSection".constantize
|
99
138
|
self.fields[key] = klass.new(field.merge(form: self))
|
139
|
+
self.field_indexes[key] = index
|
140
|
+
index += 1
|
100
141
|
end
|
101
142
|
end
|
102
143
|
end
|
@@ -16,11 +16,37 @@ module MotionPrime
|
|
16
16
|
@container_options || super
|
17
17
|
end
|
18
18
|
|
19
|
-
def
|
20
|
-
first_element = elements.first
|
21
|
-
|
22
|
-
|
19
|
+
def cell
|
20
|
+
first_element = elements.values.first
|
21
|
+
first_element.view.superview
|
22
|
+
end
|
23
|
+
|
24
|
+
def focus(begin_editing = true)
|
25
|
+
# scroll to cell
|
26
|
+
path = form.table_view.indexPathForCell cell
|
27
|
+
form.table_view.scrollToRowAtIndexPath path,
|
23
28
|
atScrollPosition: UITableViewScrollPositionTop, animated: true
|
29
|
+
# focus on text field
|
30
|
+
return unless begin_editing
|
31
|
+
elements.values.each do |element|
|
32
|
+
if element.view.is_a?(UITextField)
|
33
|
+
element.view.becomeFirstResponder && return
|
34
|
+
end
|
35
|
+
end
|
36
|
+
self
|
37
|
+
rescue
|
38
|
+
puts "can't focus on element #{self.class.name}"
|
39
|
+
end
|
40
|
+
|
41
|
+
def blur
|
42
|
+
elements.values.each do |element|
|
43
|
+
if element.view.is_a?(UITextField)
|
44
|
+
element.view.resignFirstResponder && return
|
45
|
+
end
|
46
|
+
end
|
47
|
+
self
|
48
|
+
rescue
|
49
|
+
puts "can't blur on element #{self.class.name}"
|
24
50
|
end
|
25
51
|
end
|
26
52
|
end
|
@@ -0,0 +1,76 @@
|
|
1
|
+
module MotionPrime
|
2
|
+
class TabbedSection < BaseSection
|
3
|
+
# MotionPrime::TabbedSection is base class for building tabbed views.
|
4
|
+
|
5
|
+
# == Basic Sample
|
6
|
+
# class MySection < MotionPrime::TabbedSection
|
7
|
+
# tab :info, default: true, page_section: :info_tab
|
8
|
+
# tab :map, page_section: :map_tab
|
9
|
+
# # page_section options will be converted to section class and added to section.
|
10
|
+
# # e.g. in this sample: InfoTabSection.new(model: model).render(to: screen)
|
11
|
+
# end
|
12
|
+
#
|
13
|
+
|
14
|
+
class_attribute :tabs_options, :tabs_default
|
15
|
+
attr_accessor :tab_pages
|
16
|
+
|
17
|
+
element :control, type: :segmented_control,
|
18
|
+
styles: [:base_segmented_control], items: proc { tab_control_items }
|
19
|
+
|
20
|
+
after_render :render_tab_pages
|
21
|
+
after_render :render_tab_controls
|
22
|
+
|
23
|
+
def tab_options
|
24
|
+
@tab_options ||= self.class.tabs_options
|
25
|
+
end
|
26
|
+
|
27
|
+
def tab_control_items
|
28
|
+
@tab_control_items ||= tab_options.values.map{ |o| o[:name] }
|
29
|
+
end
|
30
|
+
|
31
|
+
def tab_default
|
32
|
+
@tab_default ||= self.class.tabs_default || 0
|
33
|
+
end
|
34
|
+
|
35
|
+
def render_tab_pages
|
36
|
+
@tab_pages = []
|
37
|
+
index = 0
|
38
|
+
tab_options.each do |key, options|
|
39
|
+
section_class = options[:page_section].classify
|
40
|
+
page = "::#{section_class}Section".constantize.new(model: model)
|
41
|
+
page.render(to: screen)
|
42
|
+
page.hide if index != tab_default
|
43
|
+
@tab_pages << page
|
44
|
+
index += 1
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
def render_tab_controls
|
49
|
+
control = element(:control).view
|
50
|
+
control.addTarget(
|
51
|
+
self, action: :on_click, forControlEvents: UIControlEventValueChanged
|
52
|
+
)
|
53
|
+
control.setSelectedSegmentIndex(tab_default)
|
54
|
+
end
|
55
|
+
|
56
|
+
# on clicn to control
|
57
|
+
# @param UISegemtedControl control
|
58
|
+
def on_click(*control)
|
59
|
+
@tab_pages.each_with_index do |page, i|
|
60
|
+
page.hide if control.selectedSegment != i
|
61
|
+
end
|
62
|
+
@tab_pages[control.selectedSegment].show
|
63
|
+
end
|
64
|
+
|
65
|
+
class << self
|
66
|
+
def tab(id, options = {})
|
67
|
+
options[:name] = id.to_s.titleize
|
68
|
+
options[:id] = id
|
69
|
+
|
70
|
+
self.tabs_options ||= {}
|
71
|
+
self.tabs_default = tabs_options.length if options[:default]
|
72
|
+
self.tabs_options[id] = options
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
@@ -25,7 +25,9 @@ module MotionPrime
|
|
25
25
|
|
26
26
|
def render_table
|
27
27
|
@data_stamp = Time.now.to_i
|
28
|
-
self.table_view = screen.table_view(
|
28
|
+
self.table_view = screen.table_view(
|
29
|
+
styles: [:base_table, name.to_sym], delegate: self, data_source: self
|
30
|
+
).view
|
29
31
|
end
|
30
32
|
|
31
33
|
def render_cell(index, table)
|
data/motion-prime/styles/base.rb
CHANGED
data/motion-prime/version.rb
CHANGED
@@ -106,6 +106,10 @@ module MotionPrime
|
|
106
106
|
# apply options
|
107
107
|
if key.end_with?('title_color')
|
108
108
|
view.setTitleColor value.uicolor, forState: UIControlStateNormal
|
109
|
+
elsif key.end_with?('alignment')
|
110
|
+
view.setValue value.uitextalignment, forKey: key.camelize
|
111
|
+
elsif key.end_with?('line_break_mode')
|
112
|
+
view.setValue value.uilinebreakmode, forKey: key.camelize
|
109
113
|
elsif key.end_with?('title_shadow_color')
|
110
114
|
view.setTitleShadowColor value.uicolor, forState: UIControlStateNormal
|
111
115
|
elsif key.end_with?('color')
|
data/travis.sh
ADDED
metadata
CHANGED
@@ -1,20 +1,18 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: motion-prime
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
5
|
-
prerelease:
|
4
|
+
version: 0.1.2
|
6
5
|
platform: ruby
|
7
6
|
authors:
|
8
7
|
- Iskander Haziev
|
9
8
|
autorequire:
|
10
9
|
bindir: bin
|
11
10
|
cert_chain: []
|
12
|
-
date: 2013-07-
|
11
|
+
date: 2013-07-28 00:00:00.000000000 Z
|
13
12
|
dependencies:
|
14
13
|
- !ruby/object:Gem::Dependency
|
15
14
|
name: rake
|
16
15
|
requirement: !ruby/object:Gem::Requirement
|
17
|
-
none: false
|
18
16
|
requirements:
|
19
17
|
- - ! '>='
|
20
18
|
- !ruby/object:Gem::Version
|
@@ -22,7 +20,6 @@ dependencies:
|
|
22
20
|
type: :development
|
23
21
|
prerelease: false
|
24
22
|
version_requirements: !ruby/object:Gem::Requirement
|
25
|
-
none: false
|
26
23
|
requirements:
|
27
24
|
- - ! '>='
|
28
25
|
- !ruby/object:Gem::Version
|
@@ -30,7 +27,6 @@ dependencies:
|
|
30
27
|
- !ruby/object:Gem::Dependency
|
31
28
|
name: motion-stump
|
32
29
|
requirement: !ruby/object:Gem::Requirement
|
33
|
-
none: false
|
34
30
|
requirements:
|
35
31
|
- - ! '>='
|
36
32
|
- !ruby/object:Gem::Version
|
@@ -38,7 +34,6 @@ dependencies:
|
|
38
34
|
type: :development
|
39
35
|
prerelease: false
|
40
36
|
version_requirements: !ruby/object:Gem::Requirement
|
41
|
-
none: false
|
42
37
|
requirements:
|
43
38
|
- - ! '>='
|
44
39
|
- !ruby/object:Gem::Version
|
@@ -46,7 +41,6 @@ dependencies:
|
|
46
41
|
- !ruby/object:Gem::Dependency
|
47
42
|
name: motion-redgreen
|
48
43
|
requirement: !ruby/object:Gem::Requirement
|
49
|
-
none: false
|
50
44
|
requirements:
|
51
45
|
- - ! '>='
|
52
46
|
- !ruby/object:Gem::Version
|
@@ -54,7 +48,6 @@ dependencies:
|
|
54
48
|
type: :development
|
55
49
|
prerelease: false
|
56
50
|
version_requirements: !ruby/object:Gem::Requirement
|
57
|
-
none: false
|
58
51
|
requirements:
|
59
52
|
- - ! '>='
|
60
53
|
- !ruby/object:Gem::Version
|
@@ -62,7 +55,6 @@ dependencies:
|
|
62
55
|
- !ruby/object:Gem::Dependency
|
63
56
|
name: cocoapods
|
64
57
|
requirement: !ruby/object:Gem::Requirement
|
65
|
-
none: false
|
66
58
|
requirements:
|
67
59
|
- - ! '>='
|
68
60
|
- !ruby/object:Gem::Version
|
@@ -70,7 +62,6 @@ dependencies:
|
|
70
62
|
type: :runtime
|
71
63
|
prerelease: false
|
72
64
|
version_requirements: !ruby/object:Gem::Requirement
|
73
|
-
none: false
|
74
65
|
requirements:
|
75
66
|
- - ! '>='
|
76
67
|
- !ruby/object:Gem::Version
|
@@ -78,7 +69,6 @@ dependencies:
|
|
78
69
|
- !ruby/object:Gem::Dependency
|
79
70
|
name: motion-cocoapods
|
80
71
|
requirement: !ruby/object:Gem::Requirement
|
81
|
-
none: false
|
82
72
|
requirements:
|
83
73
|
- - ! '>='
|
84
74
|
- !ruby/object:Gem::Version
|
@@ -86,7 +76,6 @@ dependencies:
|
|
86
76
|
type: :runtime
|
87
77
|
prerelease: false
|
88
78
|
version_requirements: !ruby/object:Gem::Requirement
|
89
|
-
none: false
|
90
79
|
requirements:
|
91
80
|
- - ! '>='
|
92
81
|
- !ruby/object:Gem::Version
|
@@ -94,7 +83,6 @@ dependencies:
|
|
94
83
|
- !ruby/object:Gem::Dependency
|
95
84
|
name: motion-require
|
96
85
|
requirement: !ruby/object:Gem::Requirement
|
97
|
-
none: false
|
98
86
|
requirements:
|
99
87
|
- - ! '>='
|
100
88
|
- !ruby/object:Gem::Version
|
@@ -102,7 +90,6 @@ dependencies:
|
|
102
90
|
type: :runtime
|
103
91
|
prerelease: false
|
104
92
|
version_requirements: !ruby/object:Gem::Requirement
|
105
|
-
none: false
|
106
93
|
requirements:
|
107
94
|
- - ! '>='
|
108
95
|
- !ruby/object:Gem::Version
|
@@ -110,7 +97,6 @@ dependencies:
|
|
110
97
|
- !ruby/object:Gem::Dependency
|
111
98
|
name: motion-support
|
112
99
|
requirement: !ruby/object:Gem::Requirement
|
113
|
-
none: false
|
114
100
|
requirements:
|
115
101
|
- - ! '>='
|
116
102
|
- !ruby/object:Gem::Version
|
@@ -118,7 +104,6 @@ dependencies:
|
|
118
104
|
type: :runtime
|
119
105
|
prerelease: false
|
120
106
|
version_requirements: !ruby/object:Gem::Requirement
|
121
|
-
none: false
|
122
107
|
requirements:
|
123
108
|
- - ! '>='
|
124
109
|
- !ruby/object:Gem::Version
|
@@ -126,7 +111,6 @@ dependencies:
|
|
126
111
|
- !ruby/object:Gem::Dependency
|
127
112
|
name: bubble-wrap
|
128
113
|
requirement: !ruby/object:Gem::Requirement
|
129
|
-
none: false
|
130
114
|
requirements:
|
131
115
|
- - ! '>='
|
132
116
|
- !ruby/object:Gem::Version
|
@@ -134,7 +118,6 @@ dependencies:
|
|
134
118
|
type: :runtime
|
135
119
|
prerelease: false
|
136
120
|
version_requirements: !ruby/object:Gem::Requirement
|
137
|
-
none: false
|
138
121
|
requirements:
|
139
122
|
- - ! '>='
|
140
123
|
- !ruby/object:Gem::Version
|
@@ -142,7 +125,6 @@ dependencies:
|
|
142
125
|
- !ruby/object:Gem::Dependency
|
143
126
|
name: sugarcube
|
144
127
|
requirement: !ruby/object:Gem::Requirement
|
145
|
-
none: false
|
146
128
|
requirements:
|
147
129
|
- - ! '>='
|
148
130
|
- !ruby/object:Gem::Version
|
@@ -150,7 +132,6 @@ dependencies:
|
|
150
132
|
type: :runtime
|
151
133
|
prerelease: false
|
152
134
|
version_requirements: !ruby/object:Gem::Requirement
|
153
|
-
none: false
|
154
135
|
requirements:
|
155
136
|
- - ! '>='
|
156
137
|
- !ruby/object:Gem::Version
|
@@ -158,7 +139,6 @@ dependencies:
|
|
158
139
|
- !ruby/object:Gem::Dependency
|
159
140
|
name: nano-store
|
160
141
|
requirement: !ruby/object:Gem::Requirement
|
161
|
-
none: false
|
162
142
|
requirements:
|
163
143
|
- - ! '>='
|
164
144
|
- !ruby/object:Gem::Version
|
@@ -166,7 +146,6 @@ dependencies:
|
|
166
146
|
type: :runtime
|
167
147
|
prerelease: false
|
168
148
|
version_requirements: !ruby/object:Gem::Requirement
|
169
|
-
none: false
|
170
149
|
requirements:
|
171
150
|
- - ! '>='
|
172
151
|
- !ruby/object:Gem::Version
|
@@ -180,6 +159,7 @@ extra_rdoc_files: []
|
|
180
159
|
files:
|
181
160
|
- .gitignore
|
182
161
|
- .travis.yml
|
162
|
+
- CHANGELOG.md
|
183
163
|
- Gemfile
|
184
164
|
- Gemfile.lock
|
185
165
|
- README.md
|
@@ -208,6 +188,7 @@ files:
|
|
208
188
|
- motion-prime/app_delegate.rb
|
209
189
|
- motion-prime/config/base.rb
|
210
190
|
- motion-prime/config/config.rb
|
191
|
+
- motion-prime/elements/_text_height_mixin.rb
|
211
192
|
- motion-prime/elements/base.rb
|
212
193
|
- motion-prime/elements/button.rb
|
213
194
|
- motion-prime/elements/draw.rb
|
@@ -244,6 +225,7 @@ files:
|
|
244
225
|
- motion-prime/sections/form/string_field_section.rb
|
245
226
|
- motion-prime/sections/form/submit_field_section.rb
|
246
227
|
- motion-prime/sections/form/text_field_section.rb
|
228
|
+
- motion-prime/sections/tabbed.rb
|
247
229
|
- motion-prime/sections/table.rb
|
248
230
|
- motion-prime/sections/table/refresh_mixin.rb
|
249
231
|
- motion-prime/styles/base.rb
|
@@ -275,36 +257,30 @@ files:
|
|
275
257
|
- spec/models/store_extension_spec.rb
|
276
258
|
- spec/models/store_spec.rb
|
277
259
|
- spec/screens/base_screen_spec.rb
|
260
|
+
- travis.sh
|
278
261
|
homepage: ''
|
279
262
|
licenses:
|
280
263
|
- ''
|
264
|
+
metadata: {}
|
281
265
|
post_install_message:
|
282
266
|
rdoc_options: []
|
283
267
|
require_paths:
|
284
268
|
- lib
|
285
269
|
required_ruby_version: !ruby/object:Gem::Requirement
|
286
|
-
none: false
|
287
270
|
requirements:
|
288
271
|
- - ! '>='
|
289
272
|
- !ruby/object:Gem::Version
|
290
273
|
version: '0'
|
291
|
-
segments:
|
292
|
-
- 0
|
293
|
-
hash: 2686622756988521932
|
294
274
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
295
|
-
none: false
|
296
275
|
requirements:
|
297
276
|
- - ! '>='
|
298
277
|
- !ruby/object:Gem::Version
|
299
278
|
version: '0'
|
300
|
-
segments:
|
301
|
-
- 0
|
302
|
-
hash: 2686622756988521932
|
303
279
|
requirements: []
|
304
280
|
rubyforge_project:
|
305
|
-
rubygems_version:
|
281
|
+
rubygems_version: 2.0.5
|
306
282
|
signing_key:
|
307
|
-
specification_version:
|
283
|
+
specification_version: 4
|
308
284
|
summary: RubyMotion apps development framework
|
309
285
|
test_files:
|
310
286
|
- spec/config/store_spec.rb
|