ProMotion 0.6.5 → 0.7.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.
- data/README.md +79 -502
- data/Rakefile +30 -0
- data/app/app_delegate.rb +3 -1
- data/lib/ProMotion.rb +1 -1
- data/lib/ProMotion/cocoatouch/TableViewCell.rb +5 -1
- data/lib/ProMotion/delegate/delegate.rb +16 -0
- data/lib/ProMotion/delegate/delegate_helper.rb +88 -0
- data/lib/ProMotion/delegate/delegate_notifications.rb +61 -0
- data/lib/ProMotion/helpers/console.rb +3 -3
- data/lib/ProMotion/helpers/logger.rb +15 -15
- data/lib/ProMotion/helpers/view_helper.rb +7 -5
- data/lib/ProMotion/push_notifications/push_notification.rb +51 -0
- data/lib/ProMotion/screen_helpers/screen_elements.rb +2 -2
- data/lib/ProMotion/screen_helpers/screen_navigation.rb +5 -1
- data/lib/ProMotion/screen_helpers/screen_tabs.rb +2 -2
- data/lib/ProMotion/screens/_compatibility/formotion_screen.rb +65 -0
- data/lib/ProMotion/screens/_screen_module.rb +33 -20
- data/lib/ProMotion/screens/_table_screen_module.rb +4 -4
- data/lib/ProMotion/{screen_helpers → screens}/_tables/_refreshable_table.rb +2 -2
- data/lib/ProMotion/{screen_helpers → screens}/_tables/_searchable_table.rb +27 -34
- data/lib/ProMotion/screens/_tables/_sectioned_table.rb +5 -0
- data/lib/ProMotion/screens/_tables/_table.rb +149 -0
- data/lib/ProMotion/screens/_tables/grouped_table.rb +16 -0
- data/lib/ProMotion/screens/_tables/plain_table.rb +17 -0
- data/lib/ProMotion/screens/_tables/table_data.rb +148 -0
- data/lib/ProMotion/screens/_tables/table_view_cell_module.rb +156 -0
- data/lib/ProMotion/screens/table_screen.rb +3 -2
- data/lib/ProMotion/version.rb +1 -1
- data/spec/functional/func_screen_spec.rb +66 -0
- data/spec/functional/func_split_screen_spec.rb +66 -0
- data/spec/functional/func_table_screen_spec.rb +52 -0
- data/spec/helpers/functional_screen.rb +15 -0
- data/spec/helpers/table_screen.rb +32 -8
- data/spec/helpers/table_screen_refreshable.rb +1 -1
- data/spec/helpers/table_screen_searchable.rb +1 -1
- data/spec/helpers/test_delegate.rb +2 -0
- data/spec/unit/delegate_spec.rb +38 -0
- data/spec/{ios_version_spec.rb → unit/ios_version_spec.rb} +0 -0
- data/spec/{logger_spec.rb → unit/logger_spec.rb} +0 -0
- data/spec/{main_spec.rb → unit/main_spec.rb} +0 -0
- data/spec/{screen_helpers_spec.rb → unit/screen_helpers_spec.rb} +14 -6
- data/spec/{screen_module_spec.rb → unit/screen_module_spec.rb} +0 -0
- data/spec/{screen_spec.rb → unit/screen_spec.rb} +21 -3
- data/spec/{split_screen_in_tab_bar_spec.rb → unit/split_screen_in_tab_bar_spec.rb} +0 -0
- data/spec/{split_screen_open_screen_spec.rb → unit/split_screen_open_screen_spec.rb} +0 -0
- data/spec/{split_screen_spec.rb → unit/split_screen_spec.rb} +0 -0
- data/spec/unit/tables/table_module_spec.rb +108 -0
- data/spec/unit/tables/table_screen_spec.rb +92 -0
- data/spec/unit/tables/table_view_cell_spec.rb +106 -0
- data/spec/{view_helper_spec.rb → unit/view_helper_spec.rb} +0 -0
- metadata +50 -29
- data/lib/ProMotion/delegate.rb +0 -63
- data/lib/ProMotion/screen_helpers/_tables/_sectioned_table.rb +0 -270
- data/lib/ProMotion/screen_helpers/_tables/grouped_table.rb +0 -14
- data/lib/ProMotion/screen_helpers/_tables/plain_table.rb +0 -15
- data/spec/table_screen_spec.rb +0 -72
data/Rakefile
CHANGED
@@ -19,3 +19,33 @@ Motion::Project::App.setup do |app|
|
|
19
19
|
|
20
20
|
app.detect_dependencies = true
|
21
21
|
end
|
22
|
+
|
23
|
+
def all_files
|
24
|
+
App.config.spec_files
|
25
|
+
end
|
26
|
+
|
27
|
+
def functional_files
|
28
|
+
Dir.glob('./spec/functional/*.rb')
|
29
|
+
end
|
30
|
+
|
31
|
+
def unit_files
|
32
|
+
Dir.glob('./spec/unit/*.rb')
|
33
|
+
end
|
34
|
+
|
35
|
+
namespace :spec do
|
36
|
+
task :unit do
|
37
|
+
App.config.spec_mode = true
|
38
|
+
spec_files = all_files
|
39
|
+
spec_files -= functional_files
|
40
|
+
App.config.instance_variable_set("@spec_files", spec_files)
|
41
|
+
Rake::Task["simulator"].invoke
|
42
|
+
end
|
43
|
+
|
44
|
+
task :functional do
|
45
|
+
App.config.spec_mode = true
|
46
|
+
spec_files = all_files
|
47
|
+
spec_files -= unit_files
|
48
|
+
App.config.instance_variable_set("@spec_files", spec_files)
|
49
|
+
Rake::Task["simulator"].invoke
|
50
|
+
end
|
51
|
+
end
|
data/app/app_delegate.rb
CHANGED
data/lib/ProMotion.rb
CHANGED
@@ -6,7 +6,7 @@ require "ProMotion/version"
|
|
6
6
|
|
7
7
|
Motion::Project::App.setup do |app|
|
8
8
|
original_files = app.files
|
9
|
-
delegate = File.join(File.dirname(__FILE__), 'ProMotion/delegate.rb')
|
9
|
+
delegate = File.join(File.dirname(__FILE__), 'ProMotion/delegate/delegate.rb')
|
10
10
|
promotion_files = FileList[File.join(File.dirname(__FILE__), 'ProMotion/**/*.rb')].exclude(delegate).to_a
|
11
11
|
app.files = (promotion_files << delegate) + original_files
|
12
12
|
end
|
@@ -1,7 +1,10 @@
|
|
1
1
|
module ProMotion
|
2
2
|
class TableViewCell < UITableViewCell
|
3
|
+
include TableViewCellModule
|
4
|
+
|
3
5
|
attr_accessor :image_size
|
4
6
|
|
7
|
+
# TODO: Is this necessary?
|
5
8
|
def layoutSubviews
|
6
9
|
super
|
7
10
|
|
@@ -12,5 +15,6 @@ module ProMotion
|
|
12
15
|
self.imageView.frame = CGRectInset(f, size_inset_x, size_inset_y)
|
13
16
|
end
|
14
17
|
end
|
18
|
+
|
15
19
|
end
|
16
|
-
end
|
20
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
module ProMotion
|
2
|
+
class Delegate
|
3
|
+
|
4
|
+
include ProMotion::ScreenTabs
|
5
|
+
include ProMotion::SplitScreen if NSBundle.mainBundle.infoDictionary["UIDeviceFamily"].include?("2") # Only with iPad
|
6
|
+
include DelegateHelper
|
7
|
+
include DelegateNotifications
|
8
|
+
|
9
|
+
end
|
10
|
+
|
11
|
+
class AppDelegateParent < Delegate
|
12
|
+
def self.inherited(klass)
|
13
|
+
PM.logger.deprecated "PM::AppDelegateParent is deprecated. Use PM::Delegate."
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,88 @@
|
|
1
|
+
module ProMotion
|
2
|
+
module DelegateHelper
|
3
|
+
|
4
|
+
attr_accessor :window, :aps_notification, :home_screen
|
5
|
+
|
6
|
+
def application(application, didFinishLaunchingWithOptions:launch_options)
|
7
|
+
|
8
|
+
apply_status_bar
|
9
|
+
|
10
|
+
on_load application, launch_options
|
11
|
+
|
12
|
+
check_for_push_notification launch_options
|
13
|
+
|
14
|
+
true
|
15
|
+
|
16
|
+
end
|
17
|
+
|
18
|
+
def applicationWillTerminate(application)
|
19
|
+
|
20
|
+
on_unload if respond_to?(:on_unload)
|
21
|
+
|
22
|
+
end
|
23
|
+
|
24
|
+
def app_delegate
|
25
|
+
self
|
26
|
+
end
|
27
|
+
|
28
|
+
def app_window
|
29
|
+
self.window
|
30
|
+
end
|
31
|
+
|
32
|
+
def ui_window
|
33
|
+
(defined?(Motion) && defined?(Motion::Xray) && defined?(Motion::Xray::XrayWindow)) ? Motion::Xray::XrayWindow : UIWindow
|
34
|
+
end
|
35
|
+
|
36
|
+
def open_screen(screen, args={})
|
37
|
+
|
38
|
+
screen = screen.new if screen.respond_to?(:new)
|
39
|
+
screen.send(:on_load) if screen.respond_to?(:on_load)
|
40
|
+
|
41
|
+
self.home_screen = screen
|
42
|
+
|
43
|
+
self.window ||= self.ui_window.alloc.initWithFrame(UIScreen.mainScreen.bounds)
|
44
|
+
self.window.rootViewController = screen.pm_main_controller
|
45
|
+
self.window.makeKeyAndVisible
|
46
|
+
|
47
|
+
end
|
48
|
+
alias :open :open_screen
|
49
|
+
alias :open_root_screen :open_screen
|
50
|
+
alias :home :open_screen
|
51
|
+
|
52
|
+
def apply_status_bar
|
53
|
+
self.class.send(:apply_status_bar)
|
54
|
+
end
|
55
|
+
|
56
|
+
def status_bar?
|
57
|
+
UIApplication.sharedApplication.statusBarHidden
|
58
|
+
end
|
59
|
+
|
60
|
+
module ClassMethods
|
61
|
+
|
62
|
+
def status_bar(visible = true, opts={})
|
63
|
+
@status_bar_visible = visible
|
64
|
+
@status_bar_opts = opts
|
65
|
+
end
|
66
|
+
|
67
|
+
def apply_status_bar
|
68
|
+
@status_bar_visible ||= true
|
69
|
+
@status_bar_opts ||= { animation: :none }
|
70
|
+
UIApplication.sharedApplication.setStatusBarHidden(!@status_bar_visible, withAnimation:status_bar_animation(@status_bar_opts[:animation]))
|
71
|
+
end
|
72
|
+
|
73
|
+
def status_bar_animation(opt)
|
74
|
+
{
|
75
|
+
fade: UIStatusBarAnimationFade,
|
76
|
+
slide: UIStatusBarAnimationSlide,
|
77
|
+
none: UIStatusBarAnimationNone
|
78
|
+
}[opt] || UIStatusBarAnimationNone
|
79
|
+
end
|
80
|
+
|
81
|
+
end
|
82
|
+
|
83
|
+
def self.included(base)
|
84
|
+
base.extend(ClassMethods)
|
85
|
+
end
|
86
|
+
|
87
|
+
end
|
88
|
+
end
|
@@ -0,0 +1,61 @@
|
|
1
|
+
module ProMotion
|
2
|
+
module DelegateNotifications
|
3
|
+
|
4
|
+
attr_accessor :aps_notification
|
5
|
+
|
6
|
+
def check_for_push_notification(options)
|
7
|
+
if options && options[UIApplicationLaunchOptionsRemoteNotificationKey]
|
8
|
+
received_push_notification options[UIApplicationLaunchOptionsRemoteNotificationKey]
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
def register_for_push_notifications(*notification_types)
|
13
|
+
notification_types = Array.new(notification_types)
|
14
|
+
notification_types = [ :badge, :sound, :alert, :newsstand ] if notification_types.include?(:all)
|
15
|
+
|
16
|
+
types = UIRemoteNotificationTypeNone
|
17
|
+
types = types | UIRemoteNotificationTypeBadge if notification_types.include?(:badge)
|
18
|
+
types = types | UIRemoteNotificationTypeSound if notification_types.include?(:sound)
|
19
|
+
types = types | UIRemoteNotificationTypeAlert if notification_types.include?(:alert)
|
20
|
+
types = types | UIRemoteNotificationTypeNewsstandContentAvailability if notification_types.include?(:newsstand)
|
21
|
+
|
22
|
+
UIApplication.sharedApplication.registerForRemoteNotificationTypes types
|
23
|
+
end
|
24
|
+
|
25
|
+
def unregister_for_push_notifications
|
26
|
+
UIApplication.sharedApplication.unregisterForRemoteNotifications
|
27
|
+
end
|
28
|
+
|
29
|
+
def registered_push_notifications
|
30
|
+
mask = UIApplication.sharedApplication.enabledRemoteNotificationTypes
|
31
|
+
types = []
|
32
|
+
|
33
|
+
types << :badge if mask & UIRemoteNotificationTypeBadge
|
34
|
+
types << :sound if mask & UIRemoteNotificationTypeSound
|
35
|
+
types << :alert if mask & UIRemoteNotificationTypeAlert
|
36
|
+
types << :newsstand if mask & UIRemoteNotificationTypeNewsstandContentAvailability
|
37
|
+
|
38
|
+
types
|
39
|
+
end
|
40
|
+
|
41
|
+
def received_push_notification(notification)
|
42
|
+
@aps_notification = PM::PushNotification.new(notification)
|
43
|
+
on_push_notification(@aps_notification) if respond_to?(:on_push_notification)
|
44
|
+
end
|
45
|
+
|
46
|
+
# CocoaTouch
|
47
|
+
|
48
|
+
def application(application, didRegisterForRemoteNotificationsWithDeviceToken:device_token)
|
49
|
+
on_push_registration(device_token, nil) if respond_to?(:on_push_registration)
|
50
|
+
end
|
51
|
+
|
52
|
+
def application(application, didFailToRegisterForRemoteNotificationsWithError:error)
|
53
|
+
on_push_registration(nil, error) if respond_to?(:on_push_registration)
|
54
|
+
end
|
55
|
+
|
56
|
+
def application(application, didReceiveRemoteNotification:notification)
|
57
|
+
received_push_notification(notification)
|
58
|
+
end
|
59
|
+
|
60
|
+
end
|
61
|
+
end
|
@@ -8,19 +8,19 @@ module ProMotion
|
|
8
8
|
|
9
9
|
class << self
|
10
10
|
def log(log, with_color:color)
|
11
|
-
return if RUBYMOTION_ENV == "test"
|
11
|
+
return if defined?(RUBYMOTION_ENV) && RUBYMOTION_ENV == "test"
|
12
12
|
PM.logger.deprecated "ProMotion::Console.log is deprecated. Use PM.logger (see README)"
|
13
13
|
puts color[0] + NAME + log + color[1]
|
14
14
|
end
|
15
15
|
|
16
16
|
def log(log, withColor:color)
|
17
|
-
return if RUBYMOTION_ENV == "test"
|
17
|
+
return if defined?(RUBYMOTION_ENV) && RUBYMOTION_ENV == "test"
|
18
18
|
PM.logger.deprecated "ProMotion::Console.log is deprecated. Use PM.logger (see README)"
|
19
19
|
self.log(log, with_color:color)
|
20
20
|
end
|
21
21
|
|
22
22
|
def log(log)
|
23
|
-
return if RUBYMOTION_ENV == "test"
|
23
|
+
return if defined?(RUBYMOTION_ENV) && RUBYMOTION_ENV == "test"
|
24
24
|
PM.logger.deprecated "ProMotion::Console.log is deprecated. Use PM.logger (see README)"
|
25
25
|
log(log, with_color: DEFAULT_COLOR)
|
26
26
|
end
|
@@ -1,9 +1,9 @@
|
|
1
1
|
module ProMotion
|
2
2
|
class Logger
|
3
3
|
attr_accessor :level
|
4
|
-
|
4
|
+
|
5
5
|
NAME = "ProMotion::Logger: "
|
6
|
-
|
6
|
+
|
7
7
|
COLORS = {
|
8
8
|
default: [ '', '' ],
|
9
9
|
red: [ "\e[0;31m", "\e[0m" ],
|
@@ -13,7 +13,7 @@ module ProMotion
|
|
13
13
|
purple: [ "\e[0;35m", "\e[0m" ],
|
14
14
|
cyan: [ "\e[0;36m", "\e[0m" ]
|
15
15
|
}
|
16
|
-
|
16
|
+
|
17
17
|
LEVELS = {
|
18
18
|
off: [],
|
19
19
|
error: [:error],
|
@@ -22,17 +22,17 @@ module ProMotion
|
|
22
22
|
verbose: [:error, :warn, :info, :debug, :verbose],
|
23
23
|
debug: [:error, :warn, :info, :debug, :verbose]
|
24
24
|
}
|
25
|
-
|
25
|
+
|
26
26
|
def level
|
27
27
|
@level ||= :debug
|
28
28
|
end
|
29
|
-
|
29
|
+
|
30
30
|
def levels
|
31
31
|
LEVELS[self.level] || []
|
32
32
|
end
|
33
|
-
|
33
|
+
|
34
34
|
# Usage: PM.logger.log("ERROR", "message here", :red)
|
35
|
-
def log(label, message_text, color)
|
35
|
+
def log(label, message_text, color)
|
36
36
|
return if RUBYMOTION_ENV == "test"
|
37
37
|
color = COLORS[color] || COLORS[:default]
|
38
38
|
puts color[0] + NAME + "[#{label}] #{message_text}" + color[1]
|
@@ -40,26 +40,26 @@ module ProMotion
|
|
40
40
|
|
41
41
|
def error(message)
|
42
42
|
self.log('ERROR', message, :red) if self.levels.include?(:error)
|
43
|
-
end
|
43
|
+
end
|
44
44
|
|
45
45
|
def deprecated(message)
|
46
46
|
self.log('DEPRECATED', message, :yellow) if self.levels.include?(:warn)
|
47
|
-
end
|
47
|
+
end
|
48
48
|
|
49
|
-
def warn(message)
|
49
|
+
def warn(message)
|
50
50
|
self.log('WARN', message, :yellow) if self.levels.include?(:warn)
|
51
51
|
end
|
52
|
-
|
53
|
-
def debug(message)
|
52
|
+
|
53
|
+
def debug(message)
|
54
54
|
self.log('DEBUG', message, :purple) if self.levels.include?(:debug)
|
55
|
-
end
|
55
|
+
end
|
56
56
|
|
57
|
-
def info(message)
|
57
|
+
def info(message)
|
58
58
|
self.log('INFO', message, :green) if self.levels.include?(:info)
|
59
59
|
end
|
60
60
|
|
61
61
|
end
|
62
|
-
|
62
|
+
|
63
63
|
module_function
|
64
64
|
|
65
65
|
def logger
|
@@ -6,13 +6,15 @@ module ProMotion
|
|
6
6
|
end
|
7
7
|
|
8
8
|
def set_attribute(element, k, v)
|
9
|
+
return element unless element
|
10
|
+
|
9
11
|
if v.is_a?(Hash) && element.respond_to?(k)
|
10
12
|
sub_element = element.send(k)
|
11
|
-
set_attributes
|
12
|
-
elsif v.is_a?(Array) && element.respond_to?("#{k}")
|
13
|
-
element.send("#{k}", *v)
|
13
|
+
set_attributes(sub_element, v) if sub_element
|
14
14
|
elsif element.respond_to?("#{k}=")
|
15
15
|
element.send("#{k}=", v)
|
16
|
+
elsif v.is_a?(Array) && element.respond_to?("#{k}") && element.method("#{k}").arity == v.length
|
17
|
+
element.send("#{k}", *v)
|
16
18
|
else
|
17
19
|
# Doesn't respond. Check if snake case.
|
18
20
|
if k.to_s.include?("_")
|
@@ -48,7 +50,7 @@ module ProMotion
|
|
48
50
|
end
|
49
51
|
|
50
52
|
def frame_from_array(array)
|
51
|
-
PM.logger.deprecated "`frame_from_array` is deprecated and will be removed. Use RubyMotion's built-in [[x, y], [width, height]]."
|
53
|
+
PM.logger.deprecated "`frame_from_array` is deprecated and will be removed. Use RubyMotion's built-in [[x, y], [width, height]] or CGRectMake(x, y, w, h)."
|
52
54
|
return CGRectMake(array[0], array[1], array[2], array[3]) if array.length == 4
|
53
55
|
PM.logger.error "frame_from_array expects an array with four elements: [x, y, width, height]"
|
54
56
|
CGRectZero.dup
|
@@ -68,4 +70,4 @@ module ProMotion
|
|
68
70
|
end
|
69
71
|
|
70
72
|
end
|
71
|
-
end
|
73
|
+
end
|
@@ -0,0 +1,51 @@
|
|
1
|
+
module ProMotion
|
2
|
+
class PushNotification
|
3
|
+
|
4
|
+
attr_accessor :notification
|
5
|
+
|
6
|
+
def initialize(n)
|
7
|
+
self.notification = n
|
8
|
+
end
|
9
|
+
|
10
|
+
def to_s
|
11
|
+
self.notification.inspect
|
12
|
+
end
|
13
|
+
|
14
|
+
def to_json
|
15
|
+
PM.logger.warn "PM::PushNotification.to_json not implemented yet."
|
16
|
+
end
|
17
|
+
|
18
|
+
def aps
|
19
|
+
self.notification["aps"]
|
20
|
+
end
|
21
|
+
|
22
|
+
def alert
|
23
|
+
aps["alert"] if aps
|
24
|
+
end
|
25
|
+
|
26
|
+
def badge
|
27
|
+
aps["badge"] if aps
|
28
|
+
end
|
29
|
+
|
30
|
+
def sound
|
31
|
+
aps["sound"] if aps
|
32
|
+
end
|
33
|
+
|
34
|
+
# For testing from the REPL
|
35
|
+
# > PM::PushNotification.simulate alert: "My test message", badge: 4
|
36
|
+
def self.simulate(args = {})
|
37
|
+
UIApplication.sharedApplication.delegate.on_push_notification self.fake_notification(args)
|
38
|
+
end
|
39
|
+
|
40
|
+
def self.fake_notification(args = {})
|
41
|
+
self.new({
|
42
|
+
"aps" => {
|
43
|
+
"alert" => args[:alert] || "Test Push Notification",
|
44
|
+
"badge" => args[:badge] || 2,
|
45
|
+
"sound" => args[:sound] || "default"
|
46
|
+
}
|
47
|
+
})
|
48
|
+
end
|
49
|
+
|
50
|
+
end
|
51
|
+
end
|
@@ -14,13 +14,13 @@ module ProMotion
|
|
14
14
|
end
|
15
15
|
alias :remove_element :remove
|
16
16
|
alias :remove_view :remove
|
17
|
-
|
17
|
+
|
18
18
|
def add_to(parent_element, element, attrs = {})
|
19
|
+
parent_element.addSubview element
|
19
20
|
if attrs && attrs.length > 0
|
20
21
|
set_attributes(element, attrs)
|
21
22
|
set_easy_attributes(parent_element, element, attrs)
|
22
23
|
end
|
23
|
-
parent_element.addSubview element
|
24
24
|
element
|
25
25
|
end
|
26
26
|
|