motion-prime 0.1.1 → 0.1.2
Sign up to get free protection for your applications and to get access to all the features.
- 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 [![Build Status](https://travis-ci.org/
|
1
|
+
# MotionPrime [![Build Status](https://travis-ci.org/droidlabs/motion-prime.png)](https://travis-ci.org/droidlabs/motion-prime)
|
2
2
|
|
3
3
|
![Prime](https://s3-us-west-2.amazonaws.com/webmate/assets/prime.jpg)
|
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
|