motion-xray 1.0.4

Sign up to get free protection for your applications and to get access to all the features.
Files changed (56) hide show
  1. data/.gitignore +21 -0
  2. data/Gemfile +3 -0
  3. data/Gemfile.lock +28 -0
  4. data/README.md +426 -0
  5. data/Rakefile +11 -0
  6. data/app/app_delegate.rb +44 -0
  7. data/lib/motion-xray.rb +37 -0
  8. data/lib/motion-xray/plugins/accessibility_plugin.rb +129 -0
  9. data/lib/motion-xray/plugins/log_plugin.rb +301 -0
  10. data/lib/motion-xray/plugins/save_ui_plugin.rb +142 -0
  11. data/lib/motion-xray/plugins/ui_plugin.rb +41 -0
  12. data/lib/motion-xray/version.rb +5 -0
  13. data/lib/motion-xray/views/xray_color_swatch.rb +234 -0
  14. data/lib/motion-xray/views/xray_dpad.rb +142 -0
  15. data/lib/motion-xray/views/xray_gradient_view.rb +23 -0
  16. data/lib/motion-xray/views/xray_headers.rb +101 -0
  17. data/lib/motion-xray/views/xray_lock_button.rb +50 -0
  18. data/lib/motion-xray/views/xray_scroll_view.rb +12 -0
  19. data/lib/motion-xray/views/xray_toolbar.rb +173 -0
  20. data/lib/motion-xray/views/xray_window.rb +13 -0
  21. data/lib/motion-xray/xray.rb +56 -0
  22. data/lib/motion-xray/xray_constants.rb +5 -0
  23. data/lib/motion-xray/xray_dummy.rb +8 -0
  24. data/lib/motion-xray/xray_editors.rb +62 -0
  25. data/lib/motion-xray/xray_ext.rb +125 -0
  26. data/lib/motion-xray/xray_plugin.rb +40 -0
  27. data/lib/motion-xray/xray_typewriter.rb +217 -0
  28. data/lib/motion-xray/xray_ui.rb +723 -0
  29. data/lib/motion-xray/z_editors/xray_boolean_editor.rb +24 -0
  30. data/lib/motion-xray/z_editors/xray_color_editor.rb +119 -0
  31. data/lib/motion-xray/z_editors/xray_frame_editor.rb +108 -0
  32. data/lib/motion-xray/z_editors/xray_image_editor.rb +78 -0
  33. data/lib/motion-xray/z_editors/xray_text_editor.rb +94 -0
  34. data/lib/resources/xray_button_bg@2x.png +0 -0
  35. data/lib/resources/xray_choose_button@2x.png +0 -0
  36. data/lib/resources/xray_clear_button@2x.png +0 -0
  37. data/lib/resources/xray_detail_button@2x.png +0 -0
  38. data/lib/resources/xray_dpad@2x.png +0 -0
  39. data/lib/resources/xray_dpad_center@2x.png +0 -0
  40. data/lib/resources/xray_dpad_down@2x.png +0 -0
  41. data/lib/resources/xray_dpad_left@2x.png +0 -0
  42. data/lib/resources/xray_dpad_right@2x.png +0 -0
  43. data/lib/resources/xray_dpad_up@2x.png +0 -0
  44. data/lib/resources/xray_drawer_left@2x.png +0 -0
  45. data/lib/resources/xray_drawer_right@2x.png +0 -0
  46. data/lib/resources/xray_edit_button@2x.png +0 -0
  47. data/lib/resources/xray_email_button@2x.png +0 -0
  48. data/lib/resources/xray_lock_button_horizontal@2x.png +0 -0
  49. data/lib/resources/xray_lock_button_locked@2x.png +0 -0
  50. data/lib/resources/xray_lock_button_unlocked@2x.png +0 -0
  51. data/lib/resources/xray_lock_button_vertical@2x.png +0 -0
  52. data/motion-xray.gemspec +40 -0
  53. data/resources/Default-568h@2x.png +0 -0
  54. data/spec/xray_view_spec.rb +43 -0
  55. data/vendor/Podfile.lock +11 -0
  56. metadata +177 -0
@@ -0,0 +1,23 @@
1
+ module Motion ; module Xray
2
+
3
+ class XrayGradientView < UIView
4
+ attr_accessor :start_color
5
+ attr_accessor :final_color
6
+
7
+ def drawRect(rect)
8
+ context = UIGraphicsGetCurrentContext()
9
+ color_space = CGColorSpaceCreateDeviceRGB()
10
+ cgcolors = [
11
+ (start_color || :white).uicolor.CGColor,
12
+ (final_color || :lightgray).uicolor.CGColor,
13
+ ]
14
+
15
+ points = [0, 1]
16
+
17
+ gradient = CGGradientCreateWithColors(color_space, cgcolors, points.to_pointer(:float))
18
+ CGContextDrawLinearGradient(context, gradient, self.bounds.top_left, self.bounds.bottom_left, 0)
19
+ end
20
+
21
+ end
22
+
23
+ end end
@@ -0,0 +1,101 @@
1
+ module Motion ; module Xray
2
+
3
+ class XrayHeaderBackground < UIView
4
+ attr_accessor :label
5
+
6
+ def initWithFrame(frame)
7
+ super.tap do
8
+ self.layer.borderWidth = 1
9
+ self.layer.borderColor = :xray_dashboard_label_border.uicolor.CGColor
10
+ self.layer.backgroundColor = :xray_dashboard_label_bg.uicolor.CGColor
11
+ end
12
+ end
13
+
14
+ def label=(lbl)
15
+ if @label
16
+ @label.removeFromSuperview
17
+ end
18
+ @label = lbl
19
+ self << @label
20
+ end
21
+
22
+ def text=(str)
23
+ label.text = str
24
+ end
25
+
26
+ end
27
+
28
+ class XrayHeaderLabel < UILabel
29
+
30
+ def initWithFrame(frame)
31
+ super.tap do
32
+ self.font = 'Futura'.uifont(12)
33
+ self.textAlignment = :left.uitextalignment
34
+ self.textColor = :xray_dashboard_label_text.uicolor
35
+ self.backgroundColor = :clear.uicolor
36
+ end
37
+ end
38
+
39
+ end
40
+
41
+ class XraySectionHeader < UIControl
42
+ attr_accessor :text
43
+ attr :tracking_view
44
+
45
+ def initWithFrame(frame)
46
+ super.tap do
47
+ @exposed = true
48
+ @pressed = false
49
+ @tracking_view = XrayTypewriterView.alloc.initWithFrame([[0, 0], [self.frame.size.width, 0]])
50
+ end
51
+ end
52
+
53
+ def exposed?
54
+ @exposed
55
+ end
56
+
57
+ def exposed=(value)
58
+ @exposed = !! value
59
+ end
60
+
61
+ def drawRect(rect)
62
+ context = UIGraphicsGetCurrentContext()
63
+ color_space = CGColorSpaceCreateDeviceRGB()
64
+ if @pressed
65
+ else
66
+ cgcolors = [
67
+ :white.uicolor.CGColor,
68
+ :lightgray.uicolor.CGColor,
69
+ ]
70
+ end
71
+
72
+ points = [0, 1]
73
+
74
+ gradient = CGGradientCreateWithColors(color_space, cgcolors, points.to_pointer(:float))
75
+ CGContextDrawLinearGradient(context, gradient, self.bounds.top_left, self.bounds.bottom_left, 0)
76
+
77
+ text.drawAtPoint([17, 3], withFont: :bold.uifont(11))
78
+
79
+ CGContextSaveGState(context)
80
+ triangle_bounds = CGRect.new([0, 0], [20, 20]).shrink(6)
81
+ :clear.uicolor.setStroke
82
+ :lightgray.uicolor.setFill
83
+
84
+ if false
85
+ if @exposed
86
+ CGContextMoveToPoint(context, triangle_bounds.top_right(true).x, triangle_bounds.top_right(true).y)
87
+ CGContextAddLineToPoint(context, triangle_bounds.bottom_center(true).x, triangle_bounds.bottom_center(true).y)
88
+ CGContextAddLineToPoint(context, triangle_bounds.top_left(true).x, triangle_bounds.top_left(true).y)
89
+ else
90
+ CGContextMoveToPoint(context, triangle_bounds.top_left(true).x, triangle_bounds.top_left(true).y)
91
+ CGContextAddLineToPoint(context, triangle_bounds.center_right(true).x, triangle_bounds.center_right(true).y)
92
+ CGContextAddLineToPoint(context, triangle_bounds.bottom_left(true).x, triangle_bounds.bottom_left(true).y)
93
+ end
94
+ end
95
+ CGContextDrawPath(context, KCGPathFillStroke)
96
+ CGContextRestoreGState(context)
97
+ end
98
+
99
+ end
100
+
101
+ end end
@@ -0,0 +1,50 @@
1
+ module Motion ; module Xray
2
+
3
+ class XrayLockButton < UIButton
4
+ States = 4
5
+ LockedState = 0
6
+ UnlockedState = 1
7
+ LockedVerticalState = 2
8
+ LockedHorizontalState = 3
9
+ InitialState = LockedState
10
+
11
+ UnlockedImage = 'xray_lock_button_unlocked'.uiimage
12
+ LockedHorizontalImage = 'xray_lock_button_horizontal'.uiimage
13
+ LockedVerticalImage = 'xray_lock_button_vertical'.uiimage
14
+ LockedImage = 'xray_lock_button_locked'.uiimage
15
+
16
+ attr :lock_state
17
+
18
+ def init
19
+ frame = [[0, 0], UnlockedImage.size]
20
+ initWithFrame(frame)
21
+ end
22
+
23
+ def initWithFrame(frame)
24
+ super.tap do
25
+ @lock_state = InitialState
26
+ update_state
27
+ self.on :touch do
28
+ @lock_state += 1
29
+ @lock_state = @lock_state % States
30
+ update_state
31
+ end
32
+ end
33
+ end
34
+
35
+ def update_state
36
+ case @lock_state
37
+ when UnlockedState
38
+ self.setImage(UnlockedImage, forState: :normal.uicontrolstate)
39
+ when LockedVerticalState
40
+ self.setImage(LockedVerticalImage, forState: :normal.uicontrolstate)
41
+ when LockedHorizontalState
42
+ self.setImage(LockedHorizontalImage, forState: :normal.uicontrolstate)
43
+ when LockedState
44
+ self.setImage(LockedImage, forState: :normal.uicontrolstate)
45
+ end
46
+ end
47
+
48
+ end
49
+
50
+ end end
@@ -0,0 +1,12 @@
1
+ module Motion ; module Xray
2
+
3
+ class XrayScrollView < UIScrollView
4
+
5
+ def touchesShouldCancelInContentView(view)
6
+ return false if view.is_a?(XrayDpad)
7
+ return super
8
+ end
9
+
10
+ end
11
+
12
+ end end
@@ -0,0 +1,173 @@
1
+ module Motion ; module Xray
2
+
3
+ # Toolbar is a terrible name. It's more of a "tab bar", but that name was
4
+ # taken. Plus, I dunno, maybe I'll add other tools to it!
5
+ class XrayToolbar < UIView
6
+ attr_accessor :canvas
7
+ attr_accessor :selected
8
+ attr_accessor :delegate
9
+
10
+ def initWithFrame(frame)
11
+ super.tap do
12
+ self.backgroundColor = :white.uicolor
13
+ self.layer.borderColor = :black.uicolor.cgcolor
14
+ self.layer.borderWidth = 1
15
+ grad_layer = CAGradientLayer.layer
16
+ grad_layer.frame = self.layer.bounds
17
+ grad_layer.colors = [0x526691.uicolor.cgcolor, 0x27386e.uicolor.cgcolor]
18
+ self.layer << grad_layer
19
+
20
+ @scroll_view = UIScrollView.alloc.initWithFrame(bounds)
21
+ self << @scroll_view
22
+ @selected_view = XraySelectedToolbarItem.new
23
+ @scroll_view << @selected_view
24
+
25
+ @index = nil
26
+ @toolbar_items = []
27
+ @views = []
28
+ @item_x = margin
29
+
30
+ recognizer = UITapGestureRecognizer.alloc.initWithTarget(self, action:'tapped:')
31
+ recognizer.numberOfTapsRequired = 1
32
+ recognizer.numberOfTouchesRequired = 1
33
+ self.addGestureRecognizer(recognizer)
34
+ end
35
+ end
36
+
37
+ def tapped(event)
38
+ touched_x = event.locationInView(self).x + @scroll_view.contentOffset.x
39
+ touched_index = nil
40
+ @toolbar_items.each_with_index do |item, index|
41
+ if touched_x < item.frame.max_x
42
+ touched_index = index
43
+ break
44
+ end
45
+ end
46
+ select(touched_index) if touched_index
47
+ end
48
+
49
+ def margin
50
+ 10
51
+ end
52
+
53
+ def add(name, plugin_view)
54
+ toolbar_item = XrayToolbarItem.alloc.initWithText(name)
55
+ toolbar_item.frame = toolbar_item.frame.right(@item_x).down(5)
56
+ @item_x += toolbar_item.frame.width
57
+ @item_x += margin
58
+ @scroll_view << toolbar_item
59
+ @scroll_view.contentSize = [@item_x, self.bounds.height]
60
+ @toolbar_items << toolbar_item
61
+ @views << plugin_view
62
+
63
+ unless @index
64
+ select(0)
65
+ end
66
+ end
67
+
68
+ def select(index)
69
+ toolbar_item = @toolbar_items[index]
70
+ will_hide
71
+ @index = index
72
+ self.canvas.subviews.each &:removeFromSuperview
73
+ UIView.animate {
74
+ @selected_view.item = toolbar_item
75
+ }
76
+ will_show
77
+
78
+ plugin_view = @views[@index]
79
+ self.canvas << plugin_view
80
+
81
+ if self.canvas.is_a?(UIScrollView)
82
+ self.canvas.contentSize = plugin_view.frame.size
83
+ self.canvas.setContentOffset([0, 0], animated: false)
84
+ end
85
+ end
86
+
87
+ def show
88
+ will_show
89
+ end
90
+
91
+ def will_hide
92
+ end
93
+
94
+ def will_show
95
+ end
96
+
97
+ end
98
+
99
+ class PluginToolbar < XrayToolbar
100
+
101
+ def initWithFrame(frame)
102
+ super.tap do
103
+ @plugin_items = []
104
+ @selected = nil
105
+ end
106
+ end
107
+
108
+ def add(plugin)
109
+ name = plugin.xray_name
110
+ plugin_view = plugin.get_plugin_view(@canvas)
111
+ @plugin_items << plugin
112
+ super(name, plugin_view)
113
+ end
114
+
115
+ def will_hide
116
+ @selected.hide if @selected
117
+ end
118
+
119
+ def will_show
120
+ @selected = @plugin_items[@index]
121
+ @selected.show if @selected
122
+ end
123
+
124
+ end
125
+
126
+ class XraySelectedToolbarItem < UIView
127
+ attr :item
128
+
129
+ def initWithFrame(frame)
130
+ super.tap do
131
+ self.backgroundColor = :clear.uicolor
132
+ @item = nil
133
+ end
134
+ end
135
+
136
+ def item=(item)
137
+ @item = item
138
+ f = item.frame
139
+ f.origin.x -= corner_radius
140
+ f.origin.y -= corner_radius / 2
141
+ f.size = item.size
142
+ f.size.width += corner_radius * 2
143
+ f.size.height += corner_radius
144
+ self.frame = f
145
+ setNeedsDisplay
146
+ end
147
+
148
+ def corner_radius
149
+ 5
150
+ end
151
+
152
+ def drawRect(rect)
153
+ :white.uicolor.setFill
154
+ UIBezierPath.bezierPathWithRoundedRect(bounds, cornerRadius:corner_radius).fill
155
+ end
156
+
157
+ end
158
+
159
+ class XrayToolbarItem < UILabel
160
+ attr :name
161
+
162
+ def initWithText(text)
163
+ initWithFrame(CGRect.empty).tap do
164
+ self.backgroundColor = :clear.uicolor
165
+ self.font = :label.uifont(12)
166
+ self.text = text
167
+ sizeToFit
168
+ end
169
+ end
170
+
171
+ end
172
+
173
+ end end
@@ -0,0 +1,13 @@
1
+ module Motion ; module Xray
2
+
3
+ class XrayWindow < UIWindow
4
+
5
+ def motionEnded(motion, withEvent:event)
6
+ if event.type == UIEventSubtypeMotionShake
7
+ Xray.toggle
8
+ end
9
+ end
10
+
11
+ end
12
+
13
+ end end
@@ -0,0 +1,56 @@
1
+ module Motion ; module Xray
2
+
3
+ module_function
4
+ def ui
5
+ unless @xray_ui
6
+ @xray_ui ||= UI.new
7
+
8
+ # register default plugins if this is the first time xray_ui has been
9
+ # accessed. AKA "startup". Default plugins get pushed to the front,
10
+ # so they will appear in reverse order than they are here.
11
+ [LogPlugin, AccessibilityPlugin, UIPlugin].each do |plugin_class|
12
+ unless Xray.plugins.any? { |plugin| plugin_class === plugin }
13
+ Xray.plugins.unshift(plugin_class.new)
14
+ end
15
+ end
16
+ end
17
+ return @xray_ui
18
+ end
19
+
20
+ def controller
21
+ @xray_controller ||= XrayViewController.new
22
+ end
23
+
24
+ def toggle
25
+ Xray.ui.toggle
26
+ end
27
+
28
+ def fire_up
29
+ Xray.ui.fire_up
30
+ end
31
+
32
+ def cool_down
33
+ Xray.ui.cool_down
34
+ end
35
+
36
+ def window
37
+ UIApplication.sharedApplication.keyWindow || UIApplication.sharedApplication.windows[0]
38
+ end
39
+
40
+ def app_shared
41
+ UIApplication.sharedApplication
42
+ end
43
+
44
+ def app_bounds
45
+ UIScreen.mainScreen.bounds
46
+ end
47
+
48
+ def plugins
49
+ @plugins ||= []
50
+ end
51
+
52
+ def register(plugin)
53
+ Xray.plugins << plugin
54
+ end
55
+
56
+ end end
@@ -0,0 +1,5 @@
1
+ Symbol.css_colors[:xray_dashboard_label_text] = :darkblue.uicolor
2
+ Symbol.css_colors[:xray_dashboard_label_border] = :lightblue.uicolor
3
+ Symbol.css_colors[:xray_dashboard_label_bg] = :ghostwhite.uicolor
4
+
5
+ XrayTargetDidChangeNotification = 'Motion::Xray::TargetDidChangeNotification'
@@ -0,0 +1,8 @@
1
+ module Motion ; module Xray
2
+ module_function
3
+ def dummy
4
+ view.userInteractionEnabled = true
5
+ view.userInteractionEnabled?
6
+ view.isUserInteractionEnabled
7
+ end
8
+ end end