ProMotion 0.7.8 → 1.0.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.
Files changed (91) hide show
  1. data/.gitignore +2 -1
  2. data/.travis.yml +1 -1
  3. data/ProMotion.gemspec +2 -0
  4. data/README.md +51 -449
  5. data/Rakefile +11 -1
  6. data/app/screens/basic_screen.rb +0 -24
  7. data/lib/ProMotion/cocoatouch/{NavigationController.rb → navigation_controller.rb} +0 -0
  8. data/lib/ProMotion/cocoatouch/split_view_controller.rb +29 -0
  9. data/lib/ProMotion/cocoatouch/tab_bar_controller.rb +43 -0
  10. data/lib/ProMotion/cocoatouch/{TableViewCell.rb → table_view_cell.rb} +0 -1
  11. data/lib/ProMotion/cocoatouch/{TableViewController.rb → table_view_controller.rb} +0 -0
  12. data/lib/ProMotion/cocoatouch/{ViewController.rb → view_controller.rb} +6 -1
  13. data/lib/ProMotion/{screen_helpers → containers}/split_screen.rb +0 -2
  14. data/lib/ProMotion/containers/tabs.rb +95 -0
  15. data/lib/ProMotion/delegate/delegate.rb +2 -13
  16. data/lib/ProMotion/delegate/{delegate_helper.rb → delegate_module.rb} +29 -16
  17. data/lib/ProMotion/delegate/delegate_notifications.rb +17 -8
  18. data/lib/ProMotion/delegate/delegate_parent.rb +11 -0
  19. data/lib/ProMotion/extensions/conversions.rb +20 -0
  20. data/lib/ProMotion/{helpers/logger.rb → logger.rb} +0 -0
  21. data/lib/ProMotion/map/map_screen.rb +6 -0
  22. data/lib/ProMotion/map/map_screen_annotation.rb +56 -0
  23. data/lib/ProMotion/map/map_screen_module.rb +207 -0
  24. data/lib/ProMotion/{push_notifications → push_notification}/push_notification.rb +13 -6
  25. data/lib/ProMotion/{screens → screen}/screen.rb +1 -1
  26. data/lib/ProMotion/{screens/_screen_module.rb → screen/screen_module.rb} +76 -51
  27. data/lib/ProMotion/{screen_helpers → screen}/screen_navigation.rb +8 -12
  28. data/lib/ProMotion/{screens/_tables → table/cell}/table_view_cell_module.rb +18 -27
  29. data/lib/ProMotion/table/data/table_data.rb +98 -0
  30. data/lib/ProMotion/table/extensions/indexable.rb +9 -0
  31. data/lib/ProMotion/table/extensions/refreshable.rb +45 -0
  32. data/lib/ProMotion/table/extensions/searchable.rb +61 -0
  33. data/lib/ProMotion/table/grouped_table.rb +9 -0
  34. data/lib/ProMotion/table/grouped_table_screen.rb +6 -0
  35. data/lib/ProMotion/table/table.rb +312 -0
  36. data/lib/ProMotion/table/table_screen.rb +6 -0
  37. data/lib/ProMotion/{screens/_compatibility → thirdparty}/formotion_screen.rb +18 -5
  38. data/lib/ProMotion/version.rb +1 -1
  39. data/lib/ProMotion/view/styling.rb +137 -0
  40. data/lib/ProMotion/web/web_screen.rb +6 -0
  41. data/lib/ProMotion/web/web_screen_module.rb +155 -0
  42. data/resources/WebScreen.html +6 -0
  43. data/resources/test.jpeg +0 -0
  44. data/spec/functional/func_map_screen_spec.rb +105 -0
  45. data/spec/functional/func_screen_spec.rb +54 -7
  46. data/spec/functional/func_searchable_table_spec.rb +1 -1
  47. data/spec/functional/func_tab_bar_spec.rb +78 -0
  48. data/spec/functional/func_table_screen_spec.rb +61 -14
  49. data/spec/functional/func_web_screen_spec.rb +51 -0
  50. data/spec/helpers/map_screen.rb +51 -0
  51. data/spec/helpers/present_screen.rb +26 -0
  52. data/spec/helpers/tab_screen.rb +4 -0
  53. data/spec/helpers/table_screen.rb +12 -3
  54. data/spec/helpers/table_screen_formotion.rb +25 -0
  55. data/spec/helpers/table_screen_indexable.rb +13 -0
  56. data/spec/helpers/test_delegate.rb +28 -0
  57. data/spec/helpers/web_screen.rb +22 -0
  58. data/spec/unit/delegate_spec.rb +53 -4
  59. data/spec/unit/map_spec.rb +48 -0
  60. data/spec/unit/screen_helpers_spec.rb +24 -16
  61. data/spec/unit/screen_spec.rb +22 -18
  62. data/spec/unit/split_screen_in_tab_bar_spec.rb +2 -2
  63. data/spec/unit/split_screen_open_screen_spec.rb +15 -10
  64. data/spec/unit/split_screen_spec.rb +2 -2
  65. data/spec/unit/tab_spec.rb +41 -0
  66. data/spec/unit/tables/formotion_screen_spec.rb +16 -0
  67. data/spec/unit/tables/table_indexable_spec.rb +12 -0
  68. data/spec/unit/tables/table_module_spec.rb +24 -9
  69. data/spec/unit/tables/table_screen_spec.rb +1 -1
  70. data/spec/unit/tables/table_view_cell_spec.rb +9 -8
  71. data/spec/unit/view_helper_spec.rb +2 -2
  72. data/spec/unit/web_spec.rb +106 -0
  73. metadata +96 -35
  74. data/lib/ProMotion/cocoatouch/SplitViewController.rb +0 -23
  75. data/lib/ProMotion/helpers/console.rb +0 -29
  76. data/lib/ProMotion/helpers/measure_helper.rb +0 -20
  77. data/lib/ProMotion/helpers/system_helper.rb +0 -29
  78. data/lib/ProMotion/helpers/view_helper.rb +0 -82
  79. data/lib/ProMotion/screen_helpers/screen_elements.rb +0 -36
  80. data/lib/ProMotion/screen_helpers/screen_tabs.rb +0 -95
  81. data/lib/ProMotion/screens/_table_screen_module.rb +0 -47
  82. data/lib/ProMotion/screens/_tables/_refreshable_table.rb +0 -45
  83. data/lib/ProMotion/screens/_tables/_searchable_table.rb +0 -60
  84. data/lib/ProMotion/screens/_tables/_sectioned_table.rb +0 -5
  85. data/lib/ProMotion/screens/_tables/_table.rb +0 -169
  86. data/lib/ProMotion/screens/_tables/grouped_table.rb +0 -16
  87. data/lib/ProMotion/screens/_tables/plain_table.rb +0 -17
  88. data/lib/ProMotion/screens/_tables/table_data.rb +0 -175
  89. data/lib/ProMotion/screens/behaves_like_screen.rb +0 -10
  90. data/lib/ProMotion/screens/table_screen.rb +0 -16
  91. data/spec/unit/ios_version_spec.rb +0 -28
@@ -1,5 +0,0 @@
1
- module ProMotion
2
- module SectionedTable
3
- include Table
4
- end
5
- end
@@ -1,169 +0,0 @@
1
- module ProMotion
2
- module Table
3
- include ProMotion::ViewHelper
4
-
5
- def table_setup
6
- check_table_data
7
- set_up_table_view
8
- set_up_searchable
9
- set_up_refreshable
10
- end
11
-
12
- def check_table_data
13
- PM.logger.error "Missing #table_data method in TableScreen #{self.class.to_s}." unless self.respond_to?(:table_data)
14
- end
15
-
16
- def set_up_table_view
17
- self.view = self.create_table_view_from_data(self.table_data)
18
- end
19
-
20
- def set_up_searchable
21
- if self.class.respond_to?(:get_searchable) && self.class.get_searchable
22
- self.make_searchable(content_controller: self, search_bar: self.class.get_searchable_params)
23
- end
24
- end
25
-
26
- def set_up_refreshable
27
- if self.class.respond_to?(:get_refreshable) && self.class.get_refreshable
28
- if defined?(UIRefreshControl)
29
- self.make_refreshable(self.class.get_refreshable_params)
30
- else
31
- PM.logger.warn "To use the refresh control on < iOS 6, you need to include the CocoaPod 'CKRefreshControl'."
32
- end
33
- end
34
- end
35
-
36
- def create_table_view_from_data(data)
37
- @promotion_table_data = TableData.new(data, table_view)
38
- table_view
39
- end
40
-
41
- def update_table_view_data(data)
42
- @promotion_table_data.data = data
43
- table_view.reloadData
44
- end
45
-
46
- # Methods to retrieve data
47
-
48
- def section_at_index(index)
49
- @promotion_table_data.section(index)
50
- end
51
-
52
- def cell_at_section_and_index(section, index)
53
- @promotion_table_data.cell(section: section, index: index)
54
- end
55
-
56
- def trigger_action(action, arguments)
57
- if self.respond_to?(action)
58
- expected_arguments = self.method(action).arity
59
- if expected_arguments == 0
60
- self.send(action)
61
- elsif expected_arguments == 1 || expected_arguments == -1
62
- self.send(action, arguments)
63
- else
64
- PM.logger.warn "#{action} expects #{expected_arguments} arguments. Maximum number of required arguments for an action is 1."
65
- end
66
- else
67
- PM.logger.info "Action not implemented: #{action.to_s}"
68
- end
69
- end
70
-
71
- def accessory_toggled_switch(switch)
72
- # table_cell = switch.superview
73
- table_cell = closest_parent(UITableViewCell, switch)
74
- # index_path = table_cell.superview.indexPathForCell(table_cell)
75
- index_path = closest_parent(UITableView, table_cell).indexPathForCell(table_cell)
76
-
77
- data_cell = cell_at_section_and_index(index_path.section, index_path.row)
78
- data_cell[:accessory][:arguments] = {} unless data_cell[:accessory][:arguments]
79
- data_cell[:accessory][:arguments][:value] = switch.isOn if data_cell[:accessory][:arguments].is_a? Hash
80
-
81
- trigger_action(data_cell[:accessory][:action], data_cell[:accessory][:arguments]) if data_cell[:accessory][:action]
82
- end
83
-
84
- def delete_row(index_paths, animation = nil)
85
- animation ||= UITableViewRowAnimationAutomatic
86
- index_paths = Array(index_paths)
87
-
88
- index_paths.each do |index_path|
89
- @promotion_table_data.delete_cell(index_path: index_path)
90
- end
91
- table_view.deleteRowsAtIndexPaths(index_paths, withRowAnimation:animation)
92
- end
93
-
94
- ########## Cocoa touch methods #################
95
- def numberOfSectionsInTableView(table_view)
96
- return Array(@promotion_table_data.data).length
97
- end
98
-
99
- # Number of cells
100
- def tableView(table_view, numberOfRowsInSection:section)
101
- return @promotion_table_data.section_length(section)
102
- 0
103
- end
104
-
105
- def tableView(table_view, titleForHeaderInSection:section)
106
- return section_at_index(section)[:title] if section_at_index(section) && section_at_index(section)[:title]
107
- end
108
-
109
- # Set table_data_index if you want the right hand index column (jumplist)
110
- def sectionIndexTitlesForTableView(table_view)
111
- if @promotion_table_data.filtered
112
- nil
113
- else
114
- self.table_data_index if self.respond_to?(:table_data_index)
115
- end
116
- end
117
-
118
- def tableView(table_view, cellForRowAtIndexPath:index_path)
119
- @promotion_table_data.table_view_cell(index_path: index_path)
120
- end
121
-
122
- def tableView(table_view, heightForRowAtIndexPath:index_path)
123
- (@promotion_table_data.cell(index_path: index_path)[:height] || table_view.rowHeight).to_f
124
- end
125
-
126
- def tableView(table_view, didSelectRowAtIndexPath:index_path)
127
- cell = @promotion_table_data.cell(index_path: index_path)
128
- table_view.deselectRowAtIndexPath(index_path, animated: true)
129
-
130
- cell[:arguments] ||= {}
131
- cell[:arguments][:cell] = cell if cell[:arguments].is_a?(Hash) # TODO: Should we really do this?
132
-
133
- trigger_action(cell[:action], cell[:arguments]) if cell[:action]
134
- end
135
-
136
- def tableView(table_view, editingStyleForRowAtIndexPath: index_path)
137
- UITableViewCellEditingStyleNone
138
- end
139
-
140
- def tableView(tableView, commitEditingStyle:editing_style, forRowAtIndexPath:index_path)
141
- if editing_style == UITableViewCellEditingStyleDelete
142
- delete_cell(index_path)
143
- end
144
- end
145
-
146
- def tableView(tableView, sectionForSectionIndexTitle:title, atIndex:index)
147
- return index unless ["{search}", UITableViewIndexSearch].include?(self.table_data_index[0])
148
-
149
- if index == 0
150
- tableView.setContentOffset(CGPointZero, animated:false)
151
- NSNotFound
152
- else
153
- index-1
154
- end
155
- end
156
-
157
- def deleteRowsAtIndexPaths(indexPaths, withRowAnimation:animation)
158
- PM.logger.warn "ProMotion expects you to use 'delete_cell(index_paths, animation)'' instead of 'deleteRowsAtIndexPaths(indexPaths, withRowAnimation:animation)'."
159
- delete_cell(indexPaths, animation)
160
- end
161
-
162
-
163
- # Old aliases, deprecated, will be removed
164
- alias :createTableViewFromData :create_table_view_from_data
165
- alias :updateTableViewData :update_table_view_data
166
- alias :cellAtSectionAndIndex :cell_at_section_and_index
167
-
168
- end
169
- end
@@ -1,16 +0,0 @@
1
- module ProMotion
2
- module GroupedTable
3
- include Table
4
- include RefreshableTable
5
-
6
- def table_view
7
- @table_view ||= begin
8
- t = UITableView.alloc.initWithFrame(self.view.frame, style:UITableViewStyleGrouped)
9
- t.dataSource = self
10
- t.delegate = self
11
- t
12
- end
13
- end
14
- alias :tableView :table_view
15
- end
16
- end
@@ -1,17 +0,0 @@
1
- module ProMotion
2
- module PlainTable
3
- include Table
4
- include SearchableTable
5
- include RefreshableTable
6
-
7
- def table_view
8
- @table_view ||= begin
9
- t = UITableView.alloc.initWithFrame(self.view.frame, style:UITableViewStylePlain)
10
- t.dataSource = self
11
- t.delegate = self
12
- t
13
- end
14
- end
15
- alias :tableView :table_view
16
- end
17
- end
@@ -1,175 +0,0 @@
1
- module ProMotion
2
- class TableData
3
- attr_accessor :data, :filtered_data, :filtered, :table_view
4
-
5
- def initialize(data, table_view)
6
- self.data = data
7
- self.table_view = table_view
8
- end
9
-
10
- def section(index)
11
- s = sections.at(index)
12
- s || { title: nil, cells: [] }
13
- end
14
-
15
- def sections
16
- self.filtered ? self.filtered_data : self.data
17
- end
18
-
19
- def section_length(index)
20
- section(index)[:cells].length
21
- end
22
-
23
- def cell(params={})
24
- if params[:index_path]
25
- params[:section] = params[:index_path].section
26
- params[:index] = params[:index_path].row
27
- end
28
-
29
- table_section = self.section(params[:section])
30
- table_section[:cells].at(params[:index].to_i)
31
- end
32
-
33
- def delete_cell(params={})
34
- if params[:index_path]
35
- params[:section] = params[:index_path].section
36
- params[:index] = params[:index_path].row
37
- end
38
-
39
- table_section = self.section(params[:section])
40
- table_section[:cells].delete_at(params[:index].to_i)
41
- end
42
-
43
- def search(search_string)
44
- self.filtered_data = []
45
- self.filtered = true
46
-
47
- search_string = search_string.downcase.strip
48
-
49
- self.data.each do |section|
50
- new_section = {}
51
- new_section[:cells] = []
52
-
53
- new_section[:cells] = section[:cells].map do |cell|
54
- cell[:searchable] != false && "#{cell[:title]}\n#{cell[:search_text]}".downcase.strip.include?(search_string) ? cell : nil
55
- end.compact
56
-
57
- if new_section[:cells] && new_section[:cells].length > 0
58
- new_section[:title] = section[:title]
59
- self.filtered_data << new_section
60
- end
61
- end
62
-
63
- self.filtered_data
64
- end
65
-
66
- def stop_searching
67
- self.filtered_data = []
68
- self.filtered = false
69
- end
70
-
71
- def table_view_cell(params={})
72
- if params[:index_path]
73
- params[:section] = params[:index_path].section
74
- params[:index] = params[:index_path].row
75
- end
76
-
77
- data_cell = self.cell(section: params[:section], index: params[:index])
78
- return UITableViewCell.alloc.init unless data_cell # No data?
79
-
80
- data_cell = self.remap_data_cell(data_cell) # TODO: Deprecated, remove in version 1.0
81
- data_cell = self.set_data_cell_defaults(data_cell)
82
-
83
- table_cell = self.create_table_cell(data_cell)
84
-
85
- table_cell
86
- end
87
-
88
- def set_data_cell_defaults(data_cell)
89
- data_cell[:cell_style] ||= UITableViewCellStyleDefault
90
- data_cell[:cell_identifier] ||= build_cell_identifier(data_cell)
91
- data_cell[:cell_class] ||= ProMotion::TableViewCell
92
- data_cell
93
- end
94
-
95
- def remap_data_cell(data_cell)
96
- # Re-maps legacy data cell calls
97
- mappings = {
98
- cell_style: :cellStyle,
99
- cell_identifier: :cellIdentifier,
100
- cell_class: :cellClass,
101
- masks_to_bounds: :masksToBounds,
102
- background_color: :backgroundColor,
103
- selection_style: :selectionStyle,
104
- cell_class_attributes: :cellClassAttributes,
105
- accessory: :accessoryView,
106
- accessory: :accessory_view,
107
- accessory_type: :accessoryType,
108
- accessory_action: :accessoryAction,
109
- accessory_checked: :accessoryDefault,
110
- remote_image: :remoteImage,
111
- subviews: :subViews
112
- }
113
-
114
- if data_cell[:masks_to_bounds]
115
- PM.logger.deprecated "masks_to_bounds: (value) is deprecated. Use layer: { masks_to_bounds: (value) } instead."
116
- data_cell[:layer] ||= {}
117
- data_cell[:layer][:masks_to_bounds] = data_cell[:masks_to_bounds] # TODO: Deprecate and then remove this.
118
- end
119
-
120
- mappings.each_pair do |n, old|
121
- if data_cell[old]
122
- PM.logger.deprecated "`:#{old}` is deprecated in TableScreens. Use `:#{n}`"
123
- data_cell[n] = data_cell[old]
124
- end
125
- end
126
-
127
- if data_cell[:styles] && data_cell[:styles][:textLabel]
128
- PM.logger.deprecated "`:textLabel` is deprecated in TableScreens. Use `:label`"
129
- data_cell[:styles][:label] = data_cell[:styles][:textLabel]
130
- end
131
-
132
- # Fix the accessory view if needed
133
- # Legacy Support < 0.7.4
134
- data_cell[:accessory] ||= data_cell[:accessory_view]
135
- data_cell[:accessory] = {
136
- view: data_cell[:accessory],
137
- value: data_cell[:accessory_value],
138
- action: data_cell[:accessory_action],
139
- arguments: data_cell[:accessory_arguments]
140
- } unless data_cell[:accessory].is_a? Hash
141
-
142
- data_cell
143
- end
144
-
145
- def create_table_cell(data_cell)
146
- table_cell = table_view.dequeueReusableCellWithIdentifier(data_cell[:cell_identifier])
147
-
148
- unless table_cell
149
- table_cell = data_cell[:cell_class].alloc.initWithStyle(data_cell[:cell_style], reuseIdentifier:data_cell[:cell_identifier])
150
- table_cell.extend ProMotion::TableViewCellModule unless table_cell.is_a?(ProMotion::TableViewCellModule)
151
- table_cell.autoresizingMask = UIViewAutoresizingFlexibleWidth|UIViewAutoresizingFlexibleLeftMargin|UIViewAutoresizingFlexibleRightMargin
152
- end
153
-
154
- table_cell.setup(data_cell)
155
-
156
- table_cell
157
- end
158
-
159
- def build_cell_identifier(data_cell)
160
- ident = "Cell"
161
- unless data_cell[:accessory].nil?
162
- if data_cell[:accessory][:view] == :switch
163
- ident << "-switch"
164
- elsif !data_cell[:accessory][:view].nil?
165
- ident << "-accessory"
166
- end
167
- end
168
- ident << "-subtitle" if data_cell[:subtitle]
169
- ident << "-remoteimage" if data_cell[:remote_image]
170
- ident << "-image" if data_cell[:image]
171
- ident
172
- end
173
-
174
- end
175
- end
@@ -1,10 +0,0 @@
1
- module ProMotion
2
- module BehavesLikeScreen
3
- def pm_main_controller
4
- navigationController || self
5
- end
6
- alias_method :main_controller, :pm_main_controller
7
- end
8
- end
9
-
10
- UIViewController.send :include, ProMotion::BehavesLikeScreen
@@ -1,16 +0,0 @@
1
- module ProMotion
2
- # You can inherit a table screen from any UITableViewController if you include TableScreenModule
3
- # Just make sure to implement the Obj-C methods in cocoatouch/TableViewController.rb.
4
- class TableScreen < TableViewController
5
- include ProMotion::TableScreenModule
6
- # Includes PM::PlainTable already
7
- end
8
-
9
- class GroupedTableScreen < TableScreen
10
- include ProMotion::GroupedTable
11
- end
12
-
13
- class SectionedTableScreen < TableScreen
14
- include ProMotion::SectionedTable
15
- end
16
- end
@@ -1,28 +0,0 @@
1
- describe "ios version" do
2
-
3
- before do
4
- @dummy = DummyClass.new
5
- @dummy.extend ProMotion::SystemHelper
6
- end
7
-
8
- it "#ios_version_is?" do
9
- @dummy.ios_version_is?(@dummy.ios_version).should.be.true
10
- end
11
-
12
- it "#ios_version_greater?" do
13
- @dummy.ios_version_greater?('1.0').should.be.true
14
- end
15
-
16
- it "#ios_version_greater_eq?" do
17
- @dummy.ios_version_greater_eq?(@dummy.ios_version).should.be.true
18
- end
19
-
20
- it "#ios_version_less?" do
21
- @dummy.ios_version_less?('9.0').should.be.true
22
- end
23
-
24
- it "#ios_version_less_eq?" do
25
- @dummy.ios_version_less_eq?(@dummy.ios_version).should.be.true
26
- end
27
-
28
- end