motion-prime 0.7.0 → 0.7.1

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 (38) hide show
  1. checksums.yaml +8 -8
  2. data/CHANGELOG.md +6 -0
  3. data/Gemfile +0 -3
  4. data/Gemfile.lock +5 -8
  5. data/ROADMAP.md +1 -1
  6. data/files/Gemfile +2 -4
  7. data/motion-prime.gemspec +2 -2
  8. data/motion-prime/config/base.rb +2 -0
  9. data/motion-prime/config/config.rb +6 -0
  10. data/motion-prime/elements/_content_text_mixin.rb +4 -0
  11. data/motion-prime/elements/_text_mixin.rb +38 -17
  12. data/motion-prime/elements/base_element.rb +2 -1
  13. data/motion-prime/elements/draw/label.rb +3 -1
  14. data/motion-prime/elements/label.rb +15 -2
  15. data/motion-prime/models/model.rb +4 -3
  16. data/motion-prime/screens/extensions/_indicators_mixin.rb +33 -0
  17. data/motion-prime/screens/screen.rb +1 -1
  18. data/motion-prime/sections/_draw_section_mixin.rb +1 -1
  19. data/motion-prime/sections/base_section.rb +1 -4
  20. data/motion-prime/sections/form.rb +0 -6
  21. data/motion-prime/sections/form/date_field_section.rb +1 -0
  22. data/motion-prime/sections/form/password_field_section.rb +0 -4
  23. data/motion-prime/sections/form/select_field_section.rb +0 -4
  24. data/motion-prime/sections/form/string_field_section.rb +0 -4
  25. data/motion-prime/sections/form/submit_field_section.rb +0 -4
  26. data/motion-prime/sections/form/text_field_section.rb +0 -4
  27. data/motion-prime/sections/table.rb +2 -2
  28. data/motion-prime/sections/table/table_delegate.rb +4 -4
  29. data/motion-prime/services/logger.rb +17 -2
  30. data/motion-prime/styles/base.rb +12 -0
  31. data/motion-prime/support/mp_spinner.rb +1 -0
  32. data/motion-prime/support/mp_table_view.rb +4 -4
  33. data/motion-prime/support/tab_bar_controller.rb +7 -1
  34. data/motion-prime/version.rb +1 -1
  35. data/motion-prime/views/styles.rb +7 -5
  36. data/motion-prime/views/view_builder.rb +0 -17
  37. data/motion-prime/views/view_styler.rb +29 -36
  38. metadata +10 -10
checksums.yaml CHANGED
@@ -1,15 +1,15 @@
1
1
  ---
2
2
  !binary "U0hBMQ==":
3
3
  metadata.gz: !binary |-
4
- YmU3NjAzNmZmNTZhOTZmZjczN2Y4MjFiMTcxOTI5ODVhZDdmZTI5OA==
4
+ NDNjNzg4MDdmZGRhMWZjY2M4ZDljZmY0NGYyOTFmOWNmM2E0NjEyNg==
5
5
  data.tar.gz: !binary |-
6
- ZWI3ZDRiMWVkYzE2MmJkNzYzZjRmNTc1MGY2YjE1ZTUyYWJhNDNhNw==
6
+ NDlmNmQ1NDhhY2YwOGQ0OTdkZGE2ZWNmYmU2ZmM1MjQ3YjFjMTE0Nw==
7
7
  !binary "U0hBNTEy":
8
8
  metadata.gz: !binary |-
9
- NDgyODhmMjQyMzhiNTM0OTA1OWE5NTQ0OGM0ZTYwZDkxNjk1NDVmOTU1MmY1
10
- N2RmNzA2NDY1YzA2Yjc1YWNlZjgxY2JmODcyODdmOTBiYzA5ZmQ1ZGVjZTAy
11
- OGI5ZmRiNWRmMTEzNmI4OTYzZjc5ZTZiZGViNWRlMTMzNDliNGM=
9
+ MzIwOWMzMDc3YjNmNjk5MjNiZTUyMzYxZWRmODYyYzVmM2I2ZWFiY2RmOTU4
10
+ NWRjZGI0MjY5NDdjOGYwMTFlYjFjMDJlN2NkZDlmNDk1YWFkZjY5YmM0MTc5
11
+ M2RjMGQwZmM3ZWUzNmUzZWI5NjVmN2M4M2JhMDAyNDViOWY0MDE=
12
12
  data.tar.gz: !binary |-
13
- ZGU5ZDFmMzczNWI5ODVlYjc5OWUyNDIyYjQ2OTdmNjlkNGJmYWQ4MjI3MjZi
14
- MGQwMTg0ZWYwMTYzYTBlNGIwYjc0MzQ1MGQ1NWE3MDlmYzljN2M4NmI0YjRl
15
- NGMzNjA0NjNhZGYxZmY2M2I5NzdkNzU4OGMzOTlmZDdiYThhNGI=
13
+ Zjk5ODM4OTVmMGY3NjliYmM0MjMyZmNmMjUzYzg1YWQwNThmMWI2MGUyZGYx
14
+ ZTQ1YTk4OWRlNDBlNTQ0ZGFiYjQ1MjY3NDNjNmUwZjhiZWVmYjQwYjk4MzAw
15
+ ZGJhYzU3NjZmYjVlNzYwMDA3ZWE4NDljN2FlNDg2YWE3ZTRhZTc=
data/CHANGELOG.md CHANGED
@@ -1,3 +1,9 @@
1
+ === 0.7.1
2
+ * fix memory leaks for UITabbarController
3
+ * Improved logger.
4
+ * Better support for attributed text.
5
+ * Fix default vertical align for draw labels.
6
+
1
7
  === 0.7.0
2
8
  * Added Model.find(1) syntax support where 1 is :id attribute.
3
9
  * Migrate to AFMotion.
data/Gemfile CHANGED
@@ -2,7 +2,4 @@ source 'http://rubygems.org'
2
2
 
3
3
  gem 'motion-cocoapods', '~> 1.4.0'
4
4
  gem 'motion-support', '~> 0.2.4'
5
- gem 'sugarcube', '~> 1.3.7', require: 'sugarcube-classic'
6
- gem 'bubble-wrap', '~> 1.3.0'
7
- gem 'afmotion', '~> 2.0.0'
8
5
  gemspec
data/Gemfile.lock CHANGED
@@ -1,16 +1,16 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- motion-prime (0.7.0)
4
+ motion-prime (0.7.1)
5
5
  afmotion (~> 2.0.0)
6
- bubble-wrap
6
+ bubble-wrap (~> 1.4.0)
7
7
  cocoapods
8
8
  methadone
9
9
  motion-cocoapods
10
10
  motion-require
11
11
  motion-support
12
12
  rm-digest
13
- sugarcube
13
+ sugarcube (~> 1.3.11)
14
14
 
15
15
  GEM
16
16
  remote: http://rubygems.org/
@@ -21,7 +21,7 @@ GEM
21
21
  afmotion (2.0.0)
22
22
  motion-cocoapods (~> 1.4.0)
23
23
  motion-require (~> 0.0.7)
24
- bubble-wrap (1.3.0)
24
+ bubble-wrap (1.4.0)
25
25
  claide (0.4.0)
26
26
  cocoapods (0.28.0)
27
27
  activesupport (>= 3.2.15, < 4)
@@ -59,7 +59,7 @@ GEM
59
59
  open4 (1.3.0)
60
60
  rake (10.1.0)
61
61
  rm-digest (0.0.2)
62
- sugarcube (1.3.7)
62
+ sugarcube (1.3.11)
63
63
  xcodeproj (0.14.1)
64
64
  activesupport (~> 3.0)
65
65
  colored (~> 1.2)
@@ -69,12 +69,9 @@ PLATFORMS
69
69
  ruby
70
70
 
71
71
  DEPENDENCIES
72
- afmotion (~> 2.0.0)
73
- bubble-wrap (~> 1.3.0)
74
72
  motion-cocoapods (~> 1.4.0)
75
73
  motion-prime!
76
74
  motion-redgreen
77
75
  motion-stump
78
76
  motion-support (~> 0.2.4)
79
77
  rake
80
- sugarcube (~> 1.3.7)
data/ROADMAP.md CHANGED
@@ -1,5 +1,5 @@
1
1
  === 0.8.0
2
- * handle and fix memory leaks for UITabbarController
2
+ * add cell preload for reverse scrolling table.
3
3
  * deprecate root level :title option for submit field
4
4
  * rename submit element in submit field to button element
5
5
  * rename date_picker element in date_picker field to input element
data/files/Gemfile CHANGED
@@ -2,13 +2,11 @@ source 'http://rubygems.org'
2
2
 
3
3
  gem 'motion-cocoapods', '~> 1.4.0'
4
4
  gem 'motion-support', '~> 0.2.4'
5
- gem 'sugarcube', '~> 1.3.7', require: 'sugarcube-classic'
6
- gem 'bubble-wrap', '~> 1.4.0'
7
5
 
8
- gem 'motion-prime', '0.7.0'
6
+ gem 'motion-prime', '0.7.1'
9
7
 
10
8
  # add reside menu for sidebar support
11
9
  gem 'prime_reside_menu', '~> 0.1.4'
12
10
 
13
11
  # or add sliding menu for sidebar support
14
- # gem 'prime_sliding_menu', '~> 0.1.3'
12
+ # gem 'prime_sliding_menu', '~> 0.1.5'
data/motion-prime.gemspec CHANGED
@@ -24,8 +24,8 @@ Gem::Specification.new do |spec|
24
24
  spec.add_dependency "motion-cocoapods"
25
25
  spec.add_dependency "motion-require"
26
26
  spec.add_dependency "motion-support"
27
- spec.add_dependency 'bubble-wrap'
28
- spec.add_dependency 'sugarcube'
27
+ spec.add_dependency 'bubble-wrap', '~> 1.4.0'
28
+ spec.add_dependency 'sugarcube', '~> 1.3.11'
29
29
  spec.add_dependency 'afmotion', '~> 2.0.0'
30
30
  spec.add_dependency "methadone"
31
31
  spec.add_dependency "rm-digest"
@@ -21,4 +21,6 @@ MotionPrime::Config.configure do |config|
21
21
  api.allow_queue = false
22
22
  end
23
23
  config.prime.cell_section.mixins = [Prime::CellSectionMixin]
24
+ config.logger.level = :info
25
+ config.logger.dealloc_items = ['screen', 'tab_bar']
24
26
  end
@@ -53,6 +53,7 @@ module MotionPrime
53
53
  end
54
54
  setup_models
55
55
  setup_colors
56
+ setup_logger
56
57
  end
57
58
 
58
59
  def setup_models
@@ -72,6 +73,11 @@ module MotionPrime
72
73
  end
73
74
  Symbol.css_colors.merge!(colors)
74
75
  end
76
+
77
+ def setup_logger
78
+ Prime::Logger.level = @base_config.logger.level
79
+ Prime::Logger.dealloc_items = @base_config.logger.dealloc_items
80
+ end
75
81
  end
76
82
 
77
83
  def method_missing(name, *args, &block)
@@ -50,6 +50,10 @@ module MotionPrime
50
50
  @content_height ||= content_height
51
51
  end
52
52
 
53
+ def attributed_text?
54
+ computed_options.slice(:html, :line_spacing, :line_height, :underline, :fragment_color).any? || computed_options[:attributed_text_options]
55
+ end
56
+
53
57
  private
54
58
  def get_content_rect(width)
55
59
  raise "Please set element width for content size calculation" unless width
@@ -32,25 +32,46 @@ module MotionPrime
32
32
  end
33
33
 
34
34
  def attributed_string(options)
35
- paragrahStyle = NSMutableParagraphStyle.alloc.init
35
+ attributes = {}
36
+ line_height = options[:line_height]
37
+ line_spacing = options[:line_spacing]
38
+ text_alignment = options[:text_alignment]
39
+ line_break_mode = options[:line_break_mode]
36
40
 
37
- if options[:line_height]
38
- paragrahStyle.setMinimumLineHeight(options[:line_height])
39
- elsif options[:line_spacing]
40
- paragrahStyle.setLineSpacing(options[:line_spacing])
41
+ if line_height || line_spacing || text_alignment || line_break_mode
42
+ paragrah_style = NSMutableParagraphStyle.alloc.init
43
+ if line_height
44
+ paragrah_style.setMinimumLineHeight(line_height)
45
+ elsif line_spacing
46
+ paragrah_style.setLineSpacing(line_spacing)
47
+ end
48
+ if text_alignment
49
+ text_alignment = text_alignment.uitextalignment if text_alignment.is_a?(Symbol)
50
+ paragrah_style.setAlignment(text_alignment)
51
+ end
52
+ if line_break_mode
53
+ line_break_mode = line_break_mode.uilinebreakmode if line_break_mode.is_a?(Symbol)
54
+ paragrah_style.setLineBreakMode(line_break_mode)
55
+ end
56
+ attributes[NSParagraphStyleAttributeName] = paragrah_style
41
57
  end
42
- paragrahStyle.setAlignment(options[:text_alignment]) if options[:text_alignment]
43
- paragrahStyle.setLineBreakMode(options[:line_break_mode]) if options[:line_break_mode]
44
- attributes = {}
45
- attributes[NSParagraphStyleAttributeName] = paragrahStyle
46
- attributes[NSForegroundColorAttributeName] = options[:text_color]
47
- attributes[NSFontAttributeName] = options[:font]
48
-
49
- prepared_text = NSMutableAttributedString.alloc.initWithString(options[:text] || '', attributes: attributes)
50
- if underline_range = options[:underline]
51
- # FIXME
52
- # prepared_text = NSMutableAttributedString.alloc.initWithAttributedString(prepared_text)
53
- # prepared_text.addAttributes({NSUnderlineStyleAttributeName => NSUnderlineStyleSingle}, range: underline_range)
58
+
59
+ attributes[NSForegroundColorAttributeName] = options[:text_color].uicolor if options[:text_color]
60
+ attributes[NSFontAttributeName] = options[:font].uifont if options[:font]
61
+
62
+ prepared_text = NSMutableAttributedString.alloc.initWithString(options[:text].to_s, attributes: attributes)
63
+ underline_range = options[:underline]
64
+ fragment_color = options[:fragment_color]
65
+ if paragrah_style && (underline_range || fragment_color) && options.fetch(:number_of_lines, 1) == 1
66
+ Prime.logger.debug "If attributed text has paragraph style and underline - you must set number of lines != 1"
67
+ end
68
+
69
+ if underline_range
70
+ underline_range = [0, options[:text].length] if underline_range === true
71
+ prepared_text.addAttributes({NSUnderlineStyleAttributeName => NSUnderlineStyleSingle}, range: underline_range)
72
+ end
73
+ if fragment_color
74
+ prepared_text.addAttributes({NSForegroundColorAttributeName => fragment_color[:color].uicolor}, range: fragment_color[:range])
54
75
  end
55
76
  prepared_text
56
77
  end
@@ -22,6 +22,7 @@ module MotionPrime
22
22
  @options = options
23
23
  @screen = options[:screen]
24
24
  @section = options[:section]
25
+
25
26
  @view_class = options[:view_class] || 'UIView'
26
27
  @name = options[:name]
27
28
  @block = options[:block]
@@ -29,7 +30,7 @@ module MotionPrime
29
30
  end
30
31
 
31
32
  # def dealloc
32
- # pp 'Deallocating elemenet', self.name, self.to_s, view_class#, view.try(:to_s)
33
+ # pp 'Deallocating elemenet', self.name, self.to_s, computed_options[:text]
33
34
  # super
34
35
  # end
35
36
 
@@ -90,7 +90,9 @@ module MotionPrime
90
90
  def set_text_position
91
91
  if computed_options.slice(:padding_top, :padding_bottom, :padding).values.none?
92
92
  computed_options[:width] ||= computed_width
93
- @padding_top = (computed_outer_height - cached_content_height)/2
93
+ content_height = cached_content_height
94
+ content_height = computed_outer_height if content_height > computed_outer_height
95
+ @padding_top = (computed_outer_height - content_height)/2
94
96
  # @padding_top += 1 unless @padding_top.zero?
95
97
  end
96
98
  end
@@ -1,7 +1,8 @@
1
1
  module MotionPrime
2
2
  class LabelElement < BaseElement
3
- include MotionPrime::ElementContentPaddingMixin
4
- include MotionPrime::ElementContentTextMixin
3
+ include ElementContentPaddingMixin
4
+ include ElementContentTextMixin
5
+ include ElementTextMixin
5
6
 
6
7
  before_render :size_to_fit_if_needed
7
8
  after_render :size_to_fit
@@ -28,5 +29,17 @@ module MotionPrime
28
29
  @computed_options[:height_to_fit] = cached_content_outer_height
29
30
  end
30
31
  end
32
+
33
+ def set_text(value)
34
+ computed_options[:text] = value
35
+ styler = ViewStyler.new(view, CGRectZero, computed_options)
36
+ if styler.options[:attributed_text]
37
+ view.attributedText = styler.options[:attributed_text]
38
+ else
39
+ view.text = value
40
+ end
41
+ @content_height = nil
42
+ size_to_fit
43
+ end
31
44
  end
32
45
  end
@@ -24,8 +24,9 @@ module MotionPrime
24
24
  @errors ||= Errors.new(self.weak_ref)
25
25
  end
26
26
 
27
- # def dealloc
28
- # pp 'deall model'
29
- # end
27
+ def dealloc
28
+ Prime.logger.dealloc_message :model, self
29
+ super
30
+ end
30
31
  end
31
32
  end
@@ -41,5 +41,38 @@ module MotionPrime
41
41
  MBHUDView.hudWithBody message,
42
42
  type: hud_type, hidesAfter: time, show: true
43
43
  end
44
+
45
+ def show_spinner(message = nil)
46
+ if message.present?
47
+ spinner_message_element.set_text(message)
48
+ spinner_message_element.show
49
+ end
50
+ spinner_element.show
51
+ spinner_element.view.init_animation
52
+ end
53
+
54
+ def hide_spinner
55
+ spinner_element.hide
56
+ spinner_message_element.hide
57
+ end
58
+
59
+ private
60
+
61
+ def spinner_element
62
+ @_spinner_element ||= self.spinner({
63
+ styles: base_styles_for('spinner'),
64
+ hidden: true})
65
+ end
66
+
67
+ def spinner_message_element
68
+ @_spinner_message_element ||= self.label({
69
+ styles: base_styles_for('spinner_message'),
70
+ text: '',
71
+ hidden: true})
72
+ end
73
+
74
+ def base_styles_for(name)
75
+ ([:base] + default_styles).map { |base| :"#{base}_#{name}" }
76
+ end
44
77
  end
45
78
  end
@@ -45,7 +45,7 @@ module MotionPrime
45
45
  end
46
46
 
47
47
  def dealloc
48
- pp 'Deallocating Screen', self.object_id, self.to_s
48
+ Prime.logger.dealloc_message :screen, self
49
49
  # FIXME: calling instance_eval in title method (_base_screen_mixin) instance variables need to be cleared manually
50
50
  clear_instance_variables(except: [:_search_bar])
51
51
  super
@@ -78,7 +78,7 @@ module MotionPrime
78
78
  end
79
79
 
80
80
  def strong_references
81
- [self, screen].map(&:strong_ref)
81
+ [self, screen.main_controller].map(&:strong_ref)
82
82
  end
83
83
 
84
84
  private
@@ -37,7 +37,7 @@ module MotionPrime
37
37
  end
38
38
 
39
39
  def dealloc
40
- # pp 'Deallocating section', self.name, self.to_s, self.object_id
40
+ Prime.logger.dealloc_message :section, self, self.name
41
41
  NSNotificationCenter.defaultCenter.removeObserver self # unbinding events created in bind_keyboard_events
42
42
  super
43
43
  end
@@ -281,9 +281,6 @@ module MotionPrime
281
281
  self.elements.select { |key, element| element.is_a?(BaseElement) }
282
282
  end
283
283
 
284
- def events_off
285
- end
286
-
287
284
  protected
288
285
  def bind_keyboard_close
289
286
  bindings = self.class.keyboard_close_bindings
@@ -209,12 +209,6 @@ module MotionPrime
209
209
  section.container_height
210
210
  end
211
211
 
212
- def events_off
213
- fields.values.each do |section|
214
- section.events_off
215
- end
216
- end
217
-
218
212
  class << self
219
213
  def field(name, options = {}, &block)
220
214
  options[:name] = name
@@ -22,6 +22,7 @@ module MotionPrime
22
22
  end
23
23
 
24
24
  def dealloc
25
+ picker = view(:date_picker)
25
26
  picker.setDelegate nil
26
27
  super
27
28
  end
@@ -8,9 +8,5 @@ module MotionPrime
8
8
  end
9
9
  element :error_message, type: :error_message, text: proc { all_errors.join("\n") if observing_errors? }
10
10
  after_render :bind_text_input
11
-
12
- def events_off
13
- view(:input).off :change
14
- end
15
11
  end
16
12
  end
@@ -18,9 +18,5 @@ module MotionPrime
18
18
  form.send(options[:action]) if options[:action]
19
19
  end
20
20
  end
21
-
22
- def events_off
23
- view(:button).off :touch_down
24
- end
25
21
  end
26
22
  end
@@ -10,9 +10,5 @@ module MotionPrime
10
10
 
11
11
  element :error_message, type: :error_message, text: proc { all_errors.join("\n") if observing_errors? }
12
12
  after_render :bind_text_input
13
-
14
- def events_off
15
- view(:input).off :change
16
- end
17
13
  end
18
14
  end
@@ -12,9 +12,5 @@ module MotionPrime
12
12
  form.send(options[:action]) if options[:action]
13
13
  end
14
14
  end
15
-
16
- def events_off
17
- view(:submit).off :touch
18
- end
19
15
  end
20
16
  end
@@ -9,9 +9,5 @@ module MotionPrime
9
9
 
10
10
  element :error_message, type: :error_message, text: proc { observing_errors? and all_errors.join("\n") }
11
11
  after_render :bind_text_input
12
-
13
- def events_off
14
- view(:input).off :change
15
- end
16
12
  end
17
13
  end
@@ -20,7 +20,7 @@ module MotionPrime
20
20
  end
21
21
 
22
22
  def dealloc
23
- pp 'Deallocating table', self.to_s, self.table_view.to_s
23
+ Prime.logger.dealloc_message :table, self, self.table_view.to_s
24
24
  table_delegate.clear_delegated
25
25
  table_view.setDataSource nil
26
26
  super
@@ -390,7 +390,7 @@ module MotionPrime
390
390
  # TODO: do not release parent_objcets unless finished
391
391
  BW::Reactor.schedule(@preloader_queue.count) do |queue_id|
392
392
  @preloader_queue[queue_id] = :in_progress
393
- @strong_refs[queue_id] = screen.strong_ref
393
+ @strong_refs[queue_id] = screen.main_controller.strong_ref
394
394
  result = load_count.times do |offset|
395
395
  if @preloader_queue[queue_id] == :cancelled
396
396
  @strong_refs[queue_id] = nil
@@ -15,10 +15,10 @@ module MotionPrime
15
15
  Array.wrap(@delegated_views).each { |view| view.setDelegate(nil) }
16
16
  end
17
17
 
18
- def dealloc
19
- pp 'Deallocating table_delegate for ', @section_instance
20
- super
21
- end
18
+ # def dealloc
19
+ # pp 'Deallocating table_delegate for ', @section_instance
20
+ # super
21
+ # end
22
22
 
23
23
  def init_pull_to_refresh
24
24
  return unless block = table_section.class.pull_to_refresh_block
@@ -3,8 +3,9 @@ module MotionPrime
3
3
  LOGGER_ERROR_LEVEL = 0
4
4
  LOGGER_INFO_LEVEL = 1
5
5
  LOGGER_DEBUG_LEVEL = 2
6
+ LOGGER_DEALLOC_LEVEL = 3
6
7
 
7
- class_attribute :level
8
+ class_attribute :level, :dealloc_items
8
9
 
9
10
  def initialize
10
11
  @default_level = Config.logger.level.nil? ? :info : Config.logger.level
@@ -22,6 +23,18 @@ module MotionPrime
22
23
  pp(*args) if LOGGER_DEBUG_LEVEL <= current_level
23
24
  end
24
25
 
26
+ def dealloc_message(type, object, *args)
27
+ if LOGGER_DEALLOC_LEVEL <= current_level
28
+ if dealloc_items.include?(type.to_s)
29
+ pp "Deallocating #{type}", object.object_id, object.to_s, *args
30
+ end
31
+ end
32
+ end
33
+
34
+ def dealloc_items
35
+ self.class.dealloc_items || []
36
+ end
37
+
25
38
  def current_level
26
39
  current_level = self.class.level || @default_level
27
40
  case current_level.to_s
@@ -30,7 +43,9 @@ module MotionPrime
30
43
  when 'info'
31
44
  LOGGER_INFO_LEVEL
32
45
  when 'debug'
33
- LOGGER_DEBUG_LEVE
46
+ LOGGER_DEBUG_LEVEL
47
+ when 'dealloc'
48
+ LOGGER_DEALLOC_LEVEL
34
49
  else
35
50
  2
36
51
  end
@@ -50,4 +50,16 @@ MotionPrime::Styles.define :base do
50
50
  width: 300,
51
51
  height: 150,
52
52
  top: 30, left: 0
53
+
54
+ style :spinner,
55
+ annular: true,
56
+ center: proc { screen.view.center }, width: 37, height: 37,
57
+ progress_tint_color: proc { :app_base.uicolor },
58
+ background_tint_color: proc { :black.uicolor(0.05) },
59
+ progress: 0.25
60
+
61
+ style :spinner_message, mixins: [:multiline],
62
+ top: proc { screen.view.center.y + 38 }, left: 50, width: 220, text_alignment: :center,
63
+ font: proc { MotionPrime::Config.font.name.uifont(18) },
64
+ line_spacing: 6
53
65
  end
@@ -1,5 +1,6 @@
1
1
  class MPSpinner < MBRoundProgressView
2
2
  def init_animation
3
+ return if @firstTimestamp
3
4
  displayLink = CADisplayLink.displayLinkWithTarget(self, selector: :"handleDisplayLink:")
4
5
  displayLink.addToRunLoop(NSRunLoop.currentRunLoop, forMode:NSDefaultRunLoopMode)
5
6
  end
@@ -1,6 +1,6 @@
1
1
  class MPTableView < UITableView
2
- def dealloc
3
- pp 'Deallocating table view', self.to_s
4
- super
5
- end
2
+ # def dealloc
3
+ # pp 'Deallocating table view', self.to_s
4
+ # super
5
+ # end
6
6
  end
@@ -15,7 +15,7 @@ module MotionPrime
15
15
 
16
16
  screen.send(:on_screen_load) if screen.respond_to?(:on_screen_load)
17
17
  screen.wrap_in_navigation if screen.respond_to?(:wrap_in_navigation)
18
- screen.tab_bar = controller if screen.respond_to?(:tab_bar=)
18
+ screen.tab_bar = controller.weak_ref if screen.respond_to?(:tab_bar=)
19
19
  view_controllers << screen.main_controller.strong_ref
20
20
  end
21
21
 
@@ -31,6 +31,12 @@ module MotionPrime
31
31
  controller
32
32
  end
33
33
 
34
+ def dealloc
35
+ Prime.logger.dealloc_message :tab_bar, self
36
+ clear_instance_variables
37
+ super
38
+ end
39
+
34
40
  protected
35
41
  def self.init_screen_with_options(options, tag: tag)
36
42
  screen, title = options.delete(:screen), options.delete(:title)
@@ -1,3 +1,3 @@
1
1
  module MotionPrime
2
- VERSION = "0.7.0"
2
+ VERSION = "0.7.1"
3
3
  end
@@ -13,7 +13,7 @@ module MotionPrime
13
13
 
14
14
  if options.present?
15
15
  parent = options.delete(:parent)
16
- if parent_namespace = options.delete(:parent_namespace) || @namespace
16
+ if parent && (parent_namespace = options.delete(:parent_namespace) || @namespace)
17
17
  parent ="#{parent_namespace}_#{parent}".to_sym
18
18
  end
19
19
  mixins = Array.wrap(options.delete(:mixins)).map { |mixin_name| :"_mixin_#{mixin_name}" }
@@ -21,8 +21,8 @@ module MotionPrime
21
21
  names.each do |name|
22
22
  name = "#{@namespace}_#{name}".to_sym if @namespace
23
23
  @@repo[name] ||= {}
24
- @@repo[name].deep_merge!(self.class.for(parent)) if parent
25
- @@repo[name].deep_merge!(self.class.for(mixins)) if mixins.present?
24
+ @@repo[name].deep_merge!(self.class.for(parent, debug_missing: true, type: :parent, name: name)) if parent
25
+ @@repo[name].deep_merge!(self.class.for(mixins, debug_missing: true, type: :mixin, name: name)) if mixins.present?
26
26
  @@repo[name].deep_merge! options
27
27
  end
28
28
  elsif !block_given?
@@ -57,10 +57,12 @@ module MotionPrime
57
57
  end
58
58
  end
59
59
 
60
- def for(style_names)
60
+ def for(style_names, options = {})
61
61
  style_options = {}
62
62
  Array.wrap(style_names).each do |name|
63
- style_options.deep_merge!(@@repo[name] || {})
63
+ styles = @@repo[name]
64
+ Prime.logger.debug "No styles found for `#{name}` (element: `#{options[:name]}`, type: #{options.fetch(:type, 'general')})" if options[:debug_missing] && styles.blank?
65
+ style_options.deep_merge!(styles || {})
64
66
  end
65
67
  style_options
66
68
  end
@@ -31,23 +31,6 @@ module MotionPrime
31
31
  def default_views_map
32
32
  {
33
33
  'UIView' => Proc.new {|klass, options| klass.alloc.initWithFrame CGRectZero },
34
- 'UILabel' => Proc.new {|klass, options|
35
- if options.slice(:line_spacing, :line_height, :underline, :fragment_color).any?
36
- options[:attributed_text_options] = {
37
- text: options.delete(:text),
38
- html: options.delete(:html),
39
- line_spacing: options.delete(:line_spacing),
40
- line_height: options.delete(:line_height),
41
- fragment_color: options.delete(:fragment_color),
42
- underline: options.delete(:underline)
43
- }
44
- [:text_alignment].each do |key|# add keys which must follow after attributed text here
45
- value = options.delete(key)
46
- options[key] = value unless value.nil?
47
- end
48
- end
49
- klass.alloc.initWithFrame CGRectZero
50
- },
51
34
  'UIControl' => Proc.new {|klass, options| klass.alloc.init },
52
35
  'UISwitch' => Proc.new {|klass, options|
53
36
  view = klass.alloc.init
@@ -3,6 +3,7 @@ module MotionPrime
3
3
  include FrameCalculatorMixin
4
4
  include HasStyles
5
5
  include HasClassFactory
6
+ include ElementTextMixin
6
7
 
7
8
  attr_reader :view, :options
8
9
 
@@ -10,6 +11,7 @@ module MotionPrime
10
11
  @options = Styles.extend_and_normalize_options options
11
12
  @view = view
12
13
  prepare_frame_for(bounds) if @options.delete(:calculate_frame)
14
+ prepare_options!
13
15
  end
14
16
 
15
17
  def apply
@@ -41,6 +43,29 @@ module MotionPrime
41
43
  end
42
44
  end
43
45
 
46
+ def prepare_options!
47
+ if options.slice(:html, :line_spacing, :line_height, :underline, :fragment_color).any?
48
+ text_options = extract_attributed_text_options(options)
49
+
50
+ html = text_options.delete(:html)
51
+ text_options[:text] = html if html
52
+ options[:attributed_text] = html ? html_string(text_options) : attributed_string(text_options)
53
+
54
+ # ios 7 bug fix when text is invisible
55
+ options[:number_of_lines] = 0 if text_options.slice(:line_height, :line_spacing, :text_alignment, :line_break_mode).any? && options.fetch(:number_of_lines, 1) == 1
56
+ end
57
+ end
58
+
59
+ def extract_attributed_text_options(options)
60
+ text_attributes = [
61
+ :text, :html, :line_spacing, :line_height, :underline, :fragment_color,
62
+ :text_alignment, :font, :line_break_mode, :number_of_lines
63
+ ]
64
+ attributed_text_options = options.slice(*text_attributes)
65
+ options.except!(*text_attributes)
66
+ attributed_text_options
67
+ end
68
+
44
69
  def set_option(key, value)
45
70
  # return if value.nil?
46
71
  # ignore options
@@ -104,43 +129,11 @@ module MotionPrime
104
129
  mask_layer.frame = bounds
105
130
  mask_layer.path = mask_path.CGPath
106
131
  view.mask = mask_layer
107
- elsif key == 'attributed_text_options'
108
- attributes = {}
109
- if value[:html] # TODO: use _text_mixin
110
- styles = []
111
- styles << "color: #{options[:text_color].hex};" if options[:text_color]
112
- styles << "line-height: #{options[:line_height] || (options[:line_spacing].to_f + options[:font].pointSize)}px;"
113
- styles << "font-family: '#{options[:font].familyName}';"
114
- styles << "font-size: #{options[:font].pointSize}px;"
115
-
116
- html_options = {
117
- NSDocumentTypeDocumentAttribute => NSHTMLTextDocumentType,
118
- NSCharacterEncodingDocumentAttribute => NSNumber.numberWithInt(NSUTF8StringEncoding)
119
- }
120
- text = "#{value[:html]}<style>* { #{styles.join} }</style>"
121
- view.attributedText = NSAttributedString.alloc.initWithData(text.dataUsingEncoding(NSUTF8StringEncoding), options: html_options, documentAttributes: nil, error: nil)
132
+ elsif key == 'attributed_text'
133
+ if view.is_a?(UIButton)
134
+ view.setAttributedTitle value, forState: UIControlStateNormal
122
135
  else
123
- if line_spacing = value[:line_spacing] || line_height = value[:line_height]
124
- paragrahStyle = NSMutableParagraphStyle.alloc.init
125
- line_height ? paragrahStyle.setMinimumLineHeight(line_height) : paragrahStyle.setLineSpacing(line_spacing)
126
- attributes[NSParagraphStyleAttributeName] = paragrahStyle
127
- end
128
-
129
- attributedString = NSAttributedString.alloc.initWithString(value[:text].to_s, attributes: attributes)
130
- if underline_range = value[:underline]
131
- underline_range = [0, value[:text].length] if underline_range === true
132
- attributedString = NSMutableAttributedString.alloc.initWithAttributedString(attributedString)
133
- attributedString.addAttributes({NSUnderlineStyleAttributeName => NSUnderlineStyleSingle}, range: underline_range)
134
- end
135
- if fragment_color = value[:fragment_color]
136
- attributedString = NSMutableAttributedString.alloc.initWithAttributedString(attributedString)
137
- attributedString.addAttributes({NSForegroundColorAttributeName => fragment_color[:color].uicolor}, range: fragment_color[:range])
138
- end
139
- if view.is_a?(UIButton)
140
- view.setAttributedTitle attributedString, forState: UIControlStateNormal
141
- else
142
- view.attributedText = attributedString
143
- end
136
+ view.attributedText = value
144
137
  end
145
138
  elsif key == 'gradient'
146
139
  gradient = prepare_gradient(value)
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: motion-prime
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.7.0
4
+ version: 0.7.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Iskander Haziev
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2014-02-02 00:00:00.000000000 Z
12
+ date: 2014-02-04 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: rake
@@ -113,30 +113,30 @@ dependencies:
113
113
  name: bubble-wrap
114
114
  requirement: !ruby/object:Gem::Requirement
115
115
  requirements:
116
- - - ! '>='
116
+ - - ~>
117
117
  - !ruby/object:Gem::Version
118
- version: '0'
118
+ version: 1.4.0
119
119
  type: :runtime
120
120
  prerelease: false
121
121
  version_requirements: !ruby/object:Gem::Requirement
122
122
  requirements:
123
- - - ! '>='
123
+ - - ~>
124
124
  - !ruby/object:Gem::Version
125
- version: '0'
125
+ version: 1.4.0
126
126
  - !ruby/object:Gem::Dependency
127
127
  name: sugarcube
128
128
  requirement: !ruby/object:Gem::Requirement
129
129
  requirements:
130
- - - ! '>='
130
+ - - ~>
131
131
  - !ruby/object:Gem::Version
132
- version: '0'
132
+ version: 1.3.11
133
133
  type: :runtime
134
134
  prerelease: false
135
135
  version_requirements: !ruby/object:Gem::Requirement
136
136
  requirements:
137
- - - ! '>='
137
+ - - ~>
138
138
  - !ruby/object:Gem::Version
139
- version: '0'
139
+ version: 1.3.11
140
140
  - !ruby/object:Gem::Dependency
141
141
  name: afmotion
142
142
  requirement: !ruby/object:Gem::Requirement