motion-prime 0.4.3 → 0.4.4
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +6 -14
- data/CHANGELOG.md +5 -0
- data/Gemfile.lock +1 -1
- data/ROADMAP.md +9 -4
- data/doc/code/getting_started.rb +1 -2
- data/doc/code/screens.rb +54 -0
- data/doc/docs/getting_started.html +27 -6
- data/doc/docs/screens.html +166 -0
- data/files/Gemfile +1 -1
- data/files/Gemfile.lock +64 -0
- data/files/app/environment.rb +10 -0
- data/files/app/styles/sidebar.rb +3 -10
- data/files/resources/images/menu_button.png +0 -0
- data/files/resources/images/menu_button@2x.png +0 -0
- data/motion-prime/app_delegate.rb +19 -0
- data/motion-prime/core_ext/kernel.rb +4 -0
- data/motion-prime/elements/_content_text_mixin.rb +23 -11
- data/motion-prime/elements/_text_mixin.rb +54 -0
- data/motion-prime/elements/base_element.rb +19 -14
- data/motion-prime/elements/draw.rb +22 -1
- data/motion-prime/elements/draw/_draw_background_mixin.rb +28 -28
- data/motion-prime/elements/draw/image.rb +67 -48
- data/motion-prime/elements/draw/label.rb +59 -49
- data/motion-prime/elements/draw/view.rb +5 -3
- data/motion-prime/helpers/has_style_chain_builder.rb +1 -3
- data/motion-prime/models/association_collection.rb +8 -0
- data/motion-prime/models/finder.rb +8 -0
- data/motion-prime/mp.rb +4 -0
- data/motion-prime/screens/_navigation_mixin.rb +4 -0
- data/motion-prime/screens/base_screen.rb +7 -0
- data/motion-prime/screens/sidebar_container_screen.rb +2 -2
- data/motion-prime/sections/_cell_section_mixin.rb +44 -5
- data/motion-prime/sections/_draw_section_mixin.rb +120 -0
- data/motion-prime/sections/base_section.rb +29 -24
- data/motion-prime/sections/form.rb +48 -65
- data/motion-prime/sections/form/base_field_section.rb +2 -2
- data/motion-prime/sections/table.rb +143 -82
- data/motion-prime/sections/table/table_delegate.rb +48 -0
- data/motion-prime/styles/form.rb +1 -1
- data/motion-prime/support/mp_cell_with_section.rb +6 -2
- data/motion-prime/support/mp_view_with_section.rb +1 -1
- data/motion-prime/version.rb +1 -1
- data/motion-prime/views/_frame_calculator_mixin.rb +4 -8
- data/motion-prime/views/layout.rb +1 -0
- data/motion-prime/views/view_styler.rb +3 -12
- metadata +34 -26
- data/motion-prime/sections/_draw_mixin.rb +0 -66
data/files/app/styles/sidebar.rb
CHANGED
@@ -1,16 +1,16 @@
|
|
1
1
|
Prime::Styles.define :sidebar do
|
2
2
|
style :screen,
|
3
|
-
background_color:
|
3
|
+
background_color: proc { Prime::Config.color.dark }
|
4
4
|
style :table,
|
5
5
|
top: 150,
|
6
6
|
left: 0,
|
7
7
|
width: 320,
|
8
8
|
bottom: 0,
|
9
|
-
background_color:
|
9
|
+
background_color: proc { Prime::Config.color.dark },
|
10
10
|
separator_color: :clear
|
11
11
|
|
12
12
|
style :table_cell,
|
13
|
-
selection_style:
|
13
|
+
selection_style: :none
|
14
14
|
|
15
15
|
style :action_title,
|
16
16
|
text_color: :white,
|
@@ -20,11 +20,4 @@ Prime::Styles.define :sidebar do
|
|
20
20
|
size_to_fit: true,
|
21
21
|
left: 20,
|
22
22
|
text_color: :white
|
23
|
-
|
24
|
-
style :action_arrow,
|
25
|
-
width: 9,
|
26
|
-
height: 14,
|
27
|
-
right: 150,
|
28
|
-
top: 17,
|
29
|
-
image: "images/sidebar/arrow.png"
|
30
23
|
end
|
Binary file
|
Binary file
|
@@ -32,6 +32,7 @@ module MotionPrime
|
|
32
32
|
|
33
33
|
# TODO: move to private methods
|
34
34
|
def open_root_screen(screen)
|
35
|
+
close_current_screens
|
35
36
|
screen.send(:on_screen_load) if screen.respond_to?(:on_screen_load)
|
36
37
|
screen.wrap_in_navigation if screen.respond_to?(:wrap_in_navigation)
|
37
38
|
|
@@ -46,6 +47,7 @@ module MotionPrime
|
|
46
47
|
# TODO: move to private methods
|
47
48
|
def open_content_screen(screen)
|
48
49
|
if sidebar?
|
50
|
+
close_current_screens
|
49
51
|
sidebar_container.content_controller = screen
|
50
52
|
else
|
51
53
|
open_root_screen(screen)
|
@@ -83,7 +85,24 @@ module MotionPrime
|
|
83
85
|
NSNotificationCenter.defaultCenter.postNotificationName(:on_current_user_reset, object: user_was)
|
84
86
|
end
|
85
87
|
|
88
|
+
def close_screens(screens)
|
89
|
+
Array.wrap(screens).each { |screen| screen.on_destroy if screen.respond_to?(:on_destroy) }
|
90
|
+
end
|
91
|
+
|
86
92
|
private
|
93
|
+
def close_current_screens
|
94
|
+
return unless self.window
|
95
|
+
|
96
|
+
screens = if sidebar? && sidebar_container.content_controller.is_a?(UINavigationController)
|
97
|
+
sidebar_container.content_controller.childViewControllers
|
98
|
+
elsif sidebar?
|
99
|
+
sidebar_container.content_controller
|
100
|
+
else
|
101
|
+
window.rootViewController
|
102
|
+
end
|
103
|
+
close_screens(screens)
|
104
|
+
end
|
105
|
+
|
87
106
|
def create_tab_bar(screens)
|
88
107
|
MotionPrime::TabBarController.new(screens)
|
89
108
|
end
|
@@ -1,5 +1,8 @@
|
|
1
|
+
motion_require './_text_mixin.rb'
|
1
2
|
module MotionPrime
|
2
3
|
module ElementContentTextMixin
|
4
|
+
include ElementTextMixin
|
5
|
+
|
3
6
|
def content_text
|
4
7
|
is_a?(ButtonElement) ? button_content_text : input_content_text
|
5
8
|
end
|
@@ -8,6 +11,21 @@ module MotionPrime
|
|
8
11
|
(is_a?(ButtonElement) ? button_content_font : input_content_font) || :system.uifont
|
9
12
|
end
|
10
13
|
|
14
|
+
def content_attributed_text
|
15
|
+
if view.try(:is_a?, UITextView) && view.text.present?
|
16
|
+
text = view.attributedText
|
17
|
+
text += ' ' if text.to_s.end_with?("\n") # does not respect \n at the end by default
|
18
|
+
return text
|
19
|
+
end
|
20
|
+
|
21
|
+
options = {
|
22
|
+
text: content_text,
|
23
|
+
font: content_font,
|
24
|
+
line_spacing: computed_options[:line_spacing]
|
25
|
+
}
|
26
|
+
computed_options[:html].present? ? html_string(options) : attributed_string(options)
|
27
|
+
end
|
28
|
+
|
11
29
|
def content_width
|
12
30
|
min, max = computed_options[:min_width].to_f, computed_options[:max_width]
|
13
31
|
return min if content_text.blank?
|
@@ -23,7 +41,7 @@ module MotionPrime
|
|
23
41
|
def content_height
|
24
42
|
min, max = computed_options[:min_height].to_f, computed_options[:max_height]
|
25
43
|
return min if content_text.blank?
|
26
|
-
rect = get_content_rect(computed_options[:width])
|
44
|
+
rect = get_content_rect(computed_options[:width] - content_padding_width)
|
27
45
|
@content_height = [[rect.size.height.ceil, max].compact.min, min].max.ceil
|
28
46
|
end
|
29
47
|
|
@@ -34,15 +52,9 @@ module MotionPrime
|
|
34
52
|
private
|
35
53
|
def get_content_rect(width)
|
36
54
|
raise "Please set element width for content size calculation" unless width
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
paragrahStyle.setLineSpacing(computed_options[:line_spacing])
|
41
|
-
attributes[NSParagraphStyleAttributeName] = paragrahStyle
|
42
|
-
end
|
43
|
-
attributed_text = NSAttributedString.alloc.initWithString(content_text, attributes: attributes)
|
44
|
-
attributed_text.boundingRectWithSize(
|
45
|
-
[width, Float::MAX], options:NSStringDrawingUsesLineFragmentOrigin, context:nil
|
55
|
+
|
56
|
+
content_attributed_text.boundingRectWithSize(
|
57
|
+
[width, Float::MAX], options: NSStringDrawingUsesLineFragmentOrigin | NSStringDrawingUsesFontLeading | NSStringDrawingTruncatesLastVisibleLine, context:nil
|
46
58
|
)
|
47
59
|
end
|
48
60
|
|
@@ -63,7 +75,7 @@ module MotionPrime
|
|
63
75
|
end
|
64
76
|
|
65
77
|
def input_value_text
|
66
|
-
view && !is_a?(DrawElement) ? view.text : computed_options[:text]
|
78
|
+
view && !is_a?(DrawElement) ? view.text : (computed_options[:html] || computed_options[:text])
|
67
79
|
end
|
68
80
|
|
69
81
|
def input_placeholder_text
|
@@ -0,0 +1,54 @@
|
|
1
|
+
module MotionPrime
|
2
|
+
module ElementTextMixin
|
3
|
+
# Options
|
4
|
+
# text
|
5
|
+
# text_color
|
6
|
+
# font
|
7
|
+
# line_spacing
|
8
|
+
# text_alignment
|
9
|
+
# text_alignment_name
|
10
|
+
# line_break_mode
|
11
|
+
# underline (range)
|
12
|
+
|
13
|
+
def html_string(options)
|
14
|
+
styles = []
|
15
|
+
styles << "color: #{options[:text_color].hex};" if options[:text_color]
|
16
|
+
styles << "line-height: #{options[:line_spacing].to_f + options[:font].pointSize}px;"
|
17
|
+
styles << "font-family: '#{options[:font].familyName}';"
|
18
|
+
styles << "font-size: #{options[:font].pointSize}px;"
|
19
|
+
styles << "text-align: #{options[:text_alignment_name]};" if options[:text_alignment_name]
|
20
|
+
|
21
|
+
html_options = {
|
22
|
+
NSDocumentTypeDocumentAttribute => NSHTMLTextDocumentType,
|
23
|
+
NSCharacterEncodingDocumentAttribute => NSNumber.numberWithInt(NSUTF8StringEncoding)
|
24
|
+
}
|
25
|
+
# DTCoreTextFontDescriptor.setOverrideFontName(Prime::Config.font.light, forFontFamily: 'Calibri', bold: false, italic: false)
|
26
|
+
# DTCoreTextFontDescriptor.setOverrideFontName(Prime::Config.font.bold, forFontFamily: 'Calibri', bold: true, italic: false)
|
27
|
+
# DTCoreTextFontDescriptor.setOverrideFontName(Prime::Config.font.light_italic, forFontFamily: 'Calibri', bold: false, italic: true)
|
28
|
+
# DTCoreTextFontDescriptor.setOverrideFontName(Prime::Config.font.bold_italic, forFontFamily: 'Calibri', bold: true, italic: true)
|
29
|
+
|
30
|
+
text = "#{options[:text]}<style>* { #{styles.join} }</style>"
|
31
|
+
NSAttributedString.alloc.initWithData(text.dataUsingEncoding(NSString.defaultCStringEncoding), options: html_options, documentAttributes: nil, error: nil)
|
32
|
+
end
|
33
|
+
|
34
|
+
def attributed_string(options)
|
35
|
+
paragrahStyle = NSMutableParagraphStyle.alloc.init
|
36
|
+
|
37
|
+
paragrahStyle.setLineSpacing(options[:line_spacing]) if options[:line_spacing]
|
38
|
+
paragrahStyle.setAlignment(options[:text_alignment]) if options[:text_alignment]
|
39
|
+
paragrahStyle.setLineBreakMode(options[:line_break_mode]) if options[:line_break_mode]
|
40
|
+
attributes = {}
|
41
|
+
attributes[NSParagraphStyleAttributeName] = paragrahStyle
|
42
|
+
attributes[NSForegroundColorAttributeName] = options[:text_color]
|
43
|
+
attributes[NSFontAttributeName] = options[:font]
|
44
|
+
|
45
|
+
prepared_text = NSMutableAttributedString.alloc.initWithString(options[:text], attributes: attributes)
|
46
|
+
if underline_range = options[:underline]
|
47
|
+
# FIXME
|
48
|
+
# prepared_text = NSMutableAttributedString.alloc.initWithAttributedString(prepared_text)
|
49
|
+
# prepared_text.addAttributes({NSUnderlineStyleAttributeName => NSUnderlineStyleSingle}, range: underline_range)
|
50
|
+
end
|
51
|
+
prepared_text
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
@@ -21,12 +21,17 @@ module MotionPrime
|
|
21
21
|
@options = options
|
22
22
|
@screen = options[:screen]
|
23
23
|
@section = options[:section]
|
24
|
+
@view_class = options[:view_class] || 'UIView'
|
24
25
|
@name = options[:name]
|
25
26
|
@block = options[:block]
|
26
|
-
@view_class = options[:view_class] || 'UIView'
|
27
27
|
@view_name = self.class_name_without_kvo.demodulize.underscore.gsub(/(_draw)?_element/, '')
|
28
28
|
end
|
29
29
|
|
30
|
+
def dealloc
|
31
|
+
pp 'deallocating elemenet', self.name
|
32
|
+
super
|
33
|
+
end
|
34
|
+
|
30
35
|
def render(options = {}, &block)
|
31
36
|
run_callbacks :render do
|
32
37
|
render!(&block)
|
@@ -46,6 +51,15 @@ module MotionPrime
|
|
46
51
|
@computed_options
|
47
52
|
end
|
48
53
|
|
54
|
+
def compute_options!
|
55
|
+
block_options = compute_block_options || {}
|
56
|
+
raw_options = self.options.except(:screen, :name, :block, :view_class).merge(block_options)
|
57
|
+
compute_style_options(raw_options)
|
58
|
+
raw_options = Styles.for(styles).merge(raw_options)
|
59
|
+
@computed_options = raw_options
|
60
|
+
normalize_options(@computed_options, section, %w[text placeholder font title_label padding padding_left padding_right min_width min_outer_width max_width max_outer_width width left right])
|
61
|
+
end
|
62
|
+
|
49
63
|
def update_with_options(new_options = {})
|
50
64
|
options.merge!(new_options)
|
51
65
|
compute_options!
|
@@ -70,15 +84,6 @@ module MotionPrime
|
|
70
84
|
end
|
71
85
|
|
72
86
|
protected
|
73
|
-
def compute_options!
|
74
|
-
block_options = compute_block_options || {}
|
75
|
-
raw_options = self.options.except(:screen, :name, :block, :view_class).merge(block_options)
|
76
|
-
compute_style_options(raw_options)
|
77
|
-
raw_options = Styles.for(styles).merge(raw_options)
|
78
|
-
|
79
|
-
@computed_options = raw_options
|
80
|
-
normalize_options(@computed_options, section, %w[text placeholder font title_label padding padding_left padding_right min_width min_outer_width max_width max_outer_width width left right])
|
81
|
-
end
|
82
87
|
|
83
88
|
# Compute options sent inside block, e.g.
|
84
89
|
# element :button do
|
@@ -142,23 +147,23 @@ module MotionPrime
|
|
142
147
|
# table element: categories_table_cell_icon, categories_table_title_icon
|
143
148
|
@styles += build_styles_chain(base_styles[:specific], suffixes[:specific])
|
144
149
|
end
|
145
|
-
if section
|
150
|
+
if section && section.name.present? && name.present?
|
146
151
|
# using for base sections
|
147
|
-
@styles << [section.name, name].
|
152
|
+
@styles << [section.name, name].join('_').to_sym
|
148
153
|
end
|
149
154
|
# custom style (from options or block options), using for TableViews as well
|
150
155
|
custom_styles = style_sources.map do |source|
|
151
156
|
normalize_object(source.delete(:styles), section)
|
152
157
|
end.flatten
|
153
158
|
@styles += custom_styles
|
154
|
-
#puts @view_class.to_s + @styles.inspect, ''
|
159
|
+
# puts @view_class.to_s + @styles.inspect, ''
|
155
160
|
end
|
156
161
|
|
157
162
|
class << self
|
158
163
|
def factory(type, options = {})
|
159
164
|
element_class = class_factory("#{type}_element", true) || self
|
160
165
|
view_class_name = camelize_factory("ui_#{type}")
|
161
|
-
|
166
|
+
|
162
167
|
options.merge!(view_class: view_class_name)
|
163
168
|
element_class.new(options)
|
164
169
|
end
|
@@ -7,6 +7,19 @@ module MotionPrime
|
|
7
7
|
include FrameCalculatorMixin
|
8
8
|
include ElementContentPaddingMixin
|
9
9
|
|
10
|
+
def draw_options
|
11
|
+
options = computed_options
|
12
|
+
background_color = options[:background_color].try(:uicolor)
|
13
|
+
{
|
14
|
+
rect: CGRectMake(computed_left, computed_top, computed_outer_width, computed_outer_height),
|
15
|
+
background_color: background_color,
|
16
|
+
masks_to_bounds: options[:layer].try(:[], :masks_to_bounds) || options[:clips_to_bounds],
|
17
|
+
corner_radius: options[:layer].try(:[], :corner_radius).to_f,
|
18
|
+
border_width: options[:layer].try(:[], :border_width).to_f,
|
19
|
+
border_color: options[:layer].try(:[], :border_color).try(:uicolor) || background_color
|
20
|
+
}
|
21
|
+
end
|
22
|
+
|
10
23
|
def render!; end
|
11
24
|
|
12
25
|
def view
|
@@ -14,7 +27,7 @@ module MotionPrime
|
|
14
27
|
end
|
15
28
|
|
16
29
|
def computed_frame
|
17
|
-
@computed_frame ||= calculate_frome_for(view.bounds, computed_options)
|
30
|
+
@computed_frame ||= calculate_frome_for(view.try(:bounds) || section.container_bounds, computed_options)
|
18
31
|
end
|
19
32
|
|
20
33
|
def default_padding_for(side)
|
@@ -61,8 +74,16 @@ module MotionPrime
|
|
61
74
|
view.setNeedsDisplay
|
62
75
|
end
|
63
76
|
|
77
|
+
def update_with_options(new_options = {})
|
78
|
+
options.merge!(new_options)
|
79
|
+
compute_options!
|
80
|
+
view.setNeedsDisplay
|
81
|
+
end
|
82
|
+
|
64
83
|
private
|
65
84
|
def reset_computed_values
|
85
|
+
@content_height = nil
|
86
|
+
@content_width = nil
|
66
87
|
@computed_frame = nil
|
67
88
|
end
|
68
89
|
|
@@ -1,35 +1,35 @@
|
|
1
1
|
module MotionPrime
|
2
2
|
module DrawBackgroundMixin
|
3
|
-
def
|
4
|
-
|
5
|
-
|
6
|
-
border_width = options
|
7
|
-
border_color = options[:layer].try(:[], :border_color) || bg_color || :black
|
3
|
+
def draw_background_in_context(context = nil)
|
4
|
+
context ||= UIGraphicsGetCurrentContext()
|
5
|
+
options = draw_options
|
6
|
+
rect, background_color, border_width, border_color, corner_radius = options.slice(:rect, :background_color, :border_width, :border_color, :corner_radius).values
|
8
7
|
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
CGContextFillRect(context, rect) if bg_color
|
8
|
+
return unless background_color || border_width > 0
|
9
|
+
|
10
|
+
inset = border_width > 0 ? (border_width - 1 )*0.5 : 0
|
11
|
+
rect = CGRectInset(rect, -inset, -inset)
|
12
|
+
if corner_radius > 0
|
13
|
+
bezierPath = UIBezierPath.bezierPathWithRoundedRect rect, cornerRadius: corner_radius
|
14
|
+
UIGraphicsPushContext(context)
|
15
|
+
if border_width > 0
|
16
|
+
bezierPath.lineWidth = border_width
|
17
|
+
border_color.setStroke
|
18
|
+
bezierPath.stroke
|
19
|
+
end
|
20
|
+
if background_color
|
21
|
+
background_color.setFill
|
22
|
+
bezierPath.fill
|
23
|
+
end
|
24
|
+
UIGraphicsPopContext()
|
25
|
+
else
|
26
|
+
if border_width > 0 && border_color
|
27
|
+
CGContextSetLineWidth(context, border_width)
|
28
|
+
CGContextSetStrokeColorWithColor(context, border_color.uicolor.cgcolor)
|
29
|
+
CGContextStrokeRect(context, rect)
|
32
30
|
end
|
31
|
+
CGContextSetFillColorWithColor(context, background_color.uicolor.cgcolor) if background_color
|
32
|
+
CGContextFillRect(context, rect) if background_color
|
33
33
|
end
|
34
34
|
end
|
35
35
|
end
|
@@ -4,67 +4,86 @@ module MotionPrime
|
|
4
4
|
include DrawBackgroundMixin
|
5
5
|
attr_accessor :image_data
|
6
6
|
|
7
|
+
def draw_options
|
8
|
+
image = image_data || computed_options[:image]
|
9
|
+
image ||= computed_options[:default] if computed_options[:url]
|
10
|
+
|
11
|
+
# already initialized image or image from resources or default image
|
12
|
+
super.merge({image: image.try(:uiimage)})
|
13
|
+
end
|
14
|
+
|
7
15
|
def draw_in(rect)
|
8
16
|
return if computed_options[:hidden]
|
9
|
-
options = computed_options
|
10
|
-
image_rect = CGRectMake(
|
11
|
-
computed_left,
|
12
|
-
computed_top,
|
13
|
-
computed_width,
|
14
|
-
computed_height
|
15
|
-
)
|
16
17
|
|
17
|
-
|
18
|
-
|
18
|
+
draw_background_in_context(UIGraphicsGetCurrentContext())
|
19
|
+
computed_options[:draw_in_rect] ? draw_in_context(UIGraphicsGetCurrentContext()) : draw_with_layer
|
20
|
+
load_image
|
21
|
+
end
|
19
22
|
|
20
|
-
|
23
|
+
def draw_in_context(context)
|
24
|
+
return if computed_options[:hidden]
|
21
25
|
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
if type == SDImageCacheTypeNone || type == SDImageCacheTypeDisk
|
43
|
-
# if it's first call, we should redraw view, because it's async
|
44
|
-
section.container_view.setNeedsDisplay
|
45
|
-
else
|
46
|
-
# if it's second call, we should just draw image
|
47
|
-
draw_with_layer(image_data, image_rect)
|
48
|
-
end
|
49
|
-
end
|
50
|
-
} )
|
26
|
+
draw_background_in_context(context)
|
27
|
+
options = draw_options
|
28
|
+
return unless image = options[:image]
|
29
|
+
|
30
|
+
border_width = options[:border_width]
|
31
|
+
inset = border_width > 0 ? (border_width - 1 ).abs*0.5 : 0
|
32
|
+
rect = CGRectInset(options[:rect], inset, inset)
|
33
|
+
radius = options[:corner_radius].to_f if options[:corner_radius] && options[:masks_to_bounds]
|
34
|
+
|
35
|
+
UIGraphicsPushContext(context)
|
36
|
+
if radius
|
37
|
+
CGContextBeginPath(context)
|
38
|
+
CGContextAddArc(context, rect.origin.x + rect.size.width/2, rect.origin.y + rect.size.height/2, radius, 0, 2*Math::PI, 0) # FIXME
|
39
|
+
CGContextClosePath(context)
|
40
|
+
CGContextSaveGState(context)
|
41
|
+
CGContextClip(context)
|
42
|
+
image.drawInRect(rect)
|
43
|
+
CGContextRestoreGState(context)
|
44
|
+
else
|
45
|
+
image.drawInRect(rect)
|
51
46
|
end
|
47
|
+
UIGraphicsPopContext()
|
52
48
|
end
|
53
49
|
|
54
|
-
def draw_with_layer
|
50
|
+
def draw_with_layer
|
51
|
+
options = draw_options
|
52
|
+
return unless image = options[:image]
|
53
|
+
rect = options[:rect]
|
54
|
+
radius = options[:corner_radius].to_f if options[:corner_radius] && options[:masks_to_bounds]
|
55
|
+
|
55
56
|
layer = CALayer.layer
|
56
57
|
layer.contents = image.CGImage
|
57
58
|
layer.frame = rect
|
58
59
|
layer.bounds = rect
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
60
|
+
|
61
|
+
layer.masksToBounds = options[:masks_to_bounds]
|
62
|
+
layer.cornerRadius = radius if radius
|
63
|
+
|
64
|
+
view.layer.addSublayer(layer)
|
65
|
+
end
|
66
|
+
|
67
|
+
def load_image
|
68
|
+
return if image_data || !computed_options[:url]
|
69
|
+
BW::Reactor.schedule do
|
70
|
+
manager = SDWebImageManager.sharedManager
|
71
|
+
manager.downloadWithURL(computed_options[:url],
|
72
|
+
options: 0,
|
73
|
+
progress: lambda{ |r_size, e_size| },
|
74
|
+
completed: lambda{ |image, error, type, finished|
|
75
|
+
break unless image && section
|
76
|
+
self.image_data = image
|
77
|
+
|
78
|
+
section.cached_draw_image = nil
|
79
|
+
if section.respond_to?(:cell_name)
|
80
|
+
section.pending_display!
|
81
|
+
else
|
82
|
+
self.view.performSelectorOnMainThread :setNeedsDisplay, withObject: nil, waitUntilDone: false
|
83
|
+
end
|
84
|
+
}
|
85
|
+
)
|
66
86
|
end
|
67
|
-
view.layer.addSublayer layer
|
68
87
|
end
|
69
88
|
end
|
70
89
|
end
|