ProMotion 0.7.8 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
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