motion-xray 1.0.4
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.
- data/.gitignore +21 -0
- data/Gemfile +3 -0
- data/Gemfile.lock +28 -0
- data/README.md +426 -0
- data/Rakefile +11 -0
- data/app/app_delegate.rb +44 -0
- data/lib/motion-xray.rb +37 -0
- data/lib/motion-xray/plugins/accessibility_plugin.rb +129 -0
- data/lib/motion-xray/plugins/log_plugin.rb +301 -0
- data/lib/motion-xray/plugins/save_ui_plugin.rb +142 -0
- data/lib/motion-xray/plugins/ui_plugin.rb +41 -0
- data/lib/motion-xray/version.rb +5 -0
- data/lib/motion-xray/views/xray_color_swatch.rb +234 -0
- data/lib/motion-xray/views/xray_dpad.rb +142 -0
- data/lib/motion-xray/views/xray_gradient_view.rb +23 -0
- data/lib/motion-xray/views/xray_headers.rb +101 -0
- data/lib/motion-xray/views/xray_lock_button.rb +50 -0
- data/lib/motion-xray/views/xray_scroll_view.rb +12 -0
- data/lib/motion-xray/views/xray_toolbar.rb +173 -0
- data/lib/motion-xray/views/xray_window.rb +13 -0
- data/lib/motion-xray/xray.rb +56 -0
- data/lib/motion-xray/xray_constants.rb +5 -0
- data/lib/motion-xray/xray_dummy.rb +8 -0
- data/lib/motion-xray/xray_editors.rb +62 -0
- data/lib/motion-xray/xray_ext.rb +125 -0
- data/lib/motion-xray/xray_plugin.rb +40 -0
- data/lib/motion-xray/xray_typewriter.rb +217 -0
- data/lib/motion-xray/xray_ui.rb +723 -0
- data/lib/motion-xray/z_editors/xray_boolean_editor.rb +24 -0
- data/lib/motion-xray/z_editors/xray_color_editor.rb +119 -0
- data/lib/motion-xray/z_editors/xray_frame_editor.rb +108 -0
- data/lib/motion-xray/z_editors/xray_image_editor.rb +78 -0
- data/lib/motion-xray/z_editors/xray_text_editor.rb +94 -0
- data/lib/resources/xray_button_bg@2x.png +0 -0
- data/lib/resources/xray_choose_button@2x.png +0 -0
- data/lib/resources/xray_clear_button@2x.png +0 -0
- data/lib/resources/xray_detail_button@2x.png +0 -0
- data/lib/resources/xray_dpad@2x.png +0 -0
- data/lib/resources/xray_dpad_center@2x.png +0 -0
- data/lib/resources/xray_dpad_down@2x.png +0 -0
- data/lib/resources/xray_dpad_left@2x.png +0 -0
- data/lib/resources/xray_dpad_right@2x.png +0 -0
- data/lib/resources/xray_dpad_up@2x.png +0 -0
- data/lib/resources/xray_drawer_left@2x.png +0 -0
- data/lib/resources/xray_drawer_right@2x.png +0 -0
- data/lib/resources/xray_edit_button@2x.png +0 -0
- data/lib/resources/xray_email_button@2x.png +0 -0
- data/lib/resources/xray_lock_button_horizontal@2x.png +0 -0
- data/lib/resources/xray_lock_button_locked@2x.png +0 -0
- data/lib/resources/xray_lock_button_unlocked@2x.png +0 -0
- data/lib/resources/xray_lock_button_vertical@2x.png +0 -0
- data/motion-xray.gemspec +40 -0
- data/resources/Default-568h@2x.png +0 -0
- data/spec/xray_view_spec.rb +43 -0
- data/vendor/Podfile.lock +11 -0
- 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,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,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'
|