ruby_motion_query 0.5.8 → 0.6.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,354 @@
1
+ module RubyMotionQuery
2
+ class RMQ
3
+ def inspector
4
+ existing = rmq(window).find(InspectorView)
5
+ if existing.length > 0
6
+ existing.remove
7
+ end
8
+
9
+ puts 'The currently selected views will be assigned to $q'
10
+
11
+ rmq(window).append(InspectorView).get.update(selected)
12
+ self
13
+ end
14
+ end
15
+
16
+ class InspectorView < UIView
17
+ # A note about this code. InspectorView will be sitting in the Window, not
18
+ # the current controller. So when you do this rmq(UIButton), that is on the
19
+ # current controller. rmq(self).find(UIButton) would be the buttons in the
20
+ # inspector.
21
+
22
+ def rmq_build
23
+ @self_rmq = rmq(self)
24
+
25
+ # Storing the original stylesheet, so I can remove it, use our own, then
26
+ # put it back when we close the inspector, a bit of hackery here
27
+ @puppets_stylesheet = rmq.stylesheet
28
+
29
+ rmq.stylesheet = InspectorStylesheet
30
+ @self_rmq.apply_style(:inspector_view)
31
+
32
+ @hud = @self_rmq.append(InspectorHud, :hud).on(:tap) do |sender, rmq_event|
33
+ select_at rmq_event.location_in(sender)
34
+ end.get
35
+
36
+ root_view = rmq.root_view
37
+
38
+ rmq(root_view).animate(
39
+ animations: ->(q){ q.apply_style :root_view_scaled },
40
+ after: ->(finished, q) do
41
+ @self_rmq.animations.fade_in
42
+ dim_nav
43
+ end
44
+ )
45
+
46
+ @stats = @self_rmq.append! UILabel, :stats
47
+
48
+ @self_rmq.append(UIButton, :close_button).on(:touch) do |sender|
49
+ rmq(root_view).animate(
50
+ animations: ->(q){ q.apply_style(:root_view) },
51
+ after: ->(finished, inner_q){ rmq.stylesheet = @puppets_stylesheet })
52
+
53
+ @self_rmq.animations.drop_and_spin(after: ->(finished, inner_q) do
54
+ inner_q.remove
55
+ end)
56
+
57
+ @self_rmq = nil
58
+ $q = nil
59
+ show_nav_in_all_its_glory
60
+ end
61
+
62
+ @self_rmq.append(UIButton, :grid_button).on(:touch) do |sender|
63
+ @hud.draw_grid = !@hud.draw_grid
64
+ redisplay
65
+ end
66
+
67
+ @self_rmq.append(UIButton, :grid_x_button).on(:touch) do |sender|
68
+ @hud.draw_grid_x = !@hud.draw_grid_x
69
+ redisplay
70
+ end
71
+
72
+ @self_rmq.append(UIButton, :grid_y_button).on(:touch) do |sender|
73
+ @hud.draw_grid_y = !@hud.draw_grid_y
74
+ redisplay
75
+ end
76
+
77
+ @self_rmq.append(UIButton, :dim_button).on(:touch) do |sender|
78
+ @hud.dimmed = !@hud.dimmed
79
+ redisplay
80
+ end
81
+
82
+ @self_rmq.append(UIButton, :outline_button).on(:touch) do |sender|
83
+ @hud.views_outlined = !@hud.views_outlined
84
+ redisplay
85
+ end
86
+
87
+ @self_rmq.find(UIButton).distribute :horizontal, margin: 5
88
+
89
+ @tree_zoomed = false
90
+ @tree_q = @self_rmq.append(UIScrollView, :tree).on(:tap) do |sender|
91
+ zoom_tree
92
+ end
93
+ end
94
+
95
+ def redisplay
96
+ @hud.setNeedsDisplay
97
+ end
98
+
99
+ def update(selected)
100
+ @hud.selected = selected
101
+
102
+ selected.each { |view| create_tree_view(view) }
103
+
104
+ @self_rmq.find(:selected_view).distribute(:vertical, margin: 2)
105
+ if last = @self_rmq.find(:selected_view).last
106
+ #@self_rmq.find(:selected_view).log
107
+ @tree_q.get.contentSize = [40, last.frame.bottom]
108
+ end
109
+
110
+ redisplay
111
+ end
112
+
113
+ def zoom_tree
114
+ rmq.animate do |q|
115
+ if @tree_zoomed
116
+ @tree_q.apply_style(:tree)
117
+ else
118
+ @tree_q.apply_style(:tree_zoomed)
119
+ end
120
+
121
+ @tree_zoomed = !@tree_zoomed
122
+ end
123
+ end
124
+
125
+ def dim_nav
126
+ if nav_controller = rmq.view_controller.navigationController
127
+ rmq(nav_controller.navigationBar).animate do |q|
128
+ q.style{|st| st.opacity = 0.0}
129
+ end
130
+ end
131
+ end
132
+
133
+ def show_nav_in_all_its_glory
134
+ rmq(rmq.view_controller.navigationController.navigationBar).style{|st| st.opacity = 1.0}
135
+ end
136
+
137
+ def select_at(tapped_at = nil)
138
+ #@tree_q.find(:selected_view).remove
139
+ rmq(@stats).hide
140
+
141
+ @hud.selected_views = []
142
+ root_view = rmq.root_view
143
+
144
+ if tapped_at
145
+ @hud.selected.each do |view|
146
+ rect = view.convertRect(view.bounds, toView: root_view)
147
+ if CGRectContainsPoint(rect, tapped_at)
148
+ @hud.selected_views << view
149
+ end
150
+ end
151
+ end
152
+
153
+ set_selected
154
+ end
155
+
156
+ def set_selected
157
+ if @hud.selected_views.length == 0
158
+ #rmq(rmq.root_view).find.each{|view| create_tree_view(view)}
159
+ else
160
+ update_stats @hud.selected_views.first
161
+
162
+ #@hud.selected_views.each do |view|
163
+ #create_tree_view(view)
164
+ #end
165
+ end
166
+
167
+ if @hud.selected_views.length == 0
168
+ rmq(rmq.root_view).log :tree
169
+ elsif @hud.selected_views.length == 1
170
+ Rect.frame_for_view(@hud.selected_views.first).log
171
+ else
172
+ rmq(@hud.selected_views.first).log :tree
173
+ end
174
+
175
+ $q = rmq(@hud.selected_views)
176
+
177
+ #@self_rmq.find(:selected_view).distribute(:vertical, margin: 5)
178
+ #if last = @self_rmq.find(:selected_view).last
179
+ #@self_rmq.find(:selected_view).log
180
+ #@tree_q.get.contentSize = [40, last.frame.bottom]
181
+ #end
182
+ #rmq(rmq.window).find(UIScrollView).style{|st| st.scale = 3.0; st.height = 580}.move t:0, w: 200
183
+
184
+ redisplay
185
+ end
186
+
187
+ def create_tree_view(view)
188
+ @tree_q.append(UIImageView).tag(:selected_view).style do |st|
189
+ if image = rmq.image.from_view(view)
190
+
191
+ ratio = (image.size.height / image.size.width)
192
+ if image.size.height > image.size.width
193
+ h = 30
194
+ w = ratio * h
195
+ else
196
+ w = 30
197
+ h = ratio * w
198
+ end
199
+
200
+ st.view.contentMode = UIViewContentModeScaleAspectFit
201
+ st.image = image
202
+ else
203
+ h = 10
204
+ w = 30
205
+ end
206
+
207
+ left = 0 + ((rmq(view).parents.length - 1) * 5)
208
+
209
+ st.frame = {l: left, w: w, h: h}
210
+
211
+ st.border_color = rmq.color.from_rgba(34,202,250,0.7).CGColor
212
+ st.border_width = 0.5
213
+ st.background_color = rmq.stylesheet.tree_node_background_color
214
+
215
+ end.enable_interaction.on(:tap) do |sender|
216
+ rmq(sender).animations.sink_and_throb
217
+
218
+ @hud.selected_views = [view]
219
+ set_selected
220
+ zoom_tree if @tree_zoomed
221
+ end
222
+ end
223
+
224
+ def update_stats(view)
225
+ out = %(
226
+ style_name: :#{view.rmq_data.style_name || ''}
227
+ #{rmq(view).frame.inspect}
228
+ #{view.class.name} - object_id: #{view.object_id.to_s}
229
+ ).strip
230
+ rmq(@stats).show.get.text = out
231
+ end
232
+ end
233
+
234
+ class InspectorHud < UIView
235
+ attr_accessor :selected, :selected_views, :dimmed, :views_outlined,
236
+ :draw_grid_x, :draw_grid, :draw_grid_y
237
+
238
+ def rmq_build
239
+ # TODO refactor these into the stylesheet
240
+ @outline_color = rmq.color.from_rgba(34,202,250,0.7).CGColor
241
+ @selected_outline_color = rmq.color.from_rgba(202,34,250,0.7).CGColor
242
+ @view_background_color = rmq.color.from_rgba(34,202,250,0.4).CGColor
243
+ @view_selected_background_color = rmq.color.from_rgba(202,34,250,0.4)
244
+ @text_color = rmq.color.from_rgba(0,0,0,0.9).CGColor
245
+ @light_text_color = rmq.color.from_rgba(0,0,0,0.2).CGColor
246
+ @fill_color = rmq.color.from_rgba(34,202,250,0.1).CGColor
247
+ @row_fill_color = rmq.color.from_rgba(187,197,209,0.2).CGColor
248
+ @column_fill_color = rmq.color.from_rgba(213,53,82,0.1).CGColor
249
+ @background_color = rmq.color.from_rgba(255,255,255,0.9)
250
+ @view_scale = 0.85
251
+
252
+ @views_outlined = true
253
+ @dimmed = true
254
+ @selected_views = []
255
+ end
256
+
257
+ def drawRect(rect)
258
+ super
259
+
260
+ return unless @selected
261
+
262
+ context = UIGraphicsGetCurrentContext()
263
+
264
+ screen_height = RMQ.device.screen_height
265
+ screen_width = RMQ.device.screen_width
266
+
267
+ CGContextSetStrokeColorWithColor(context, @outline_color)
268
+ CGContextSetFillColorWithColor(context, @fill_color)
269
+ CGContextSetLineWidth(context, 1.0)
270
+ #CGContextSelectFont(context, 'Courier New', 7, KCGEncodingMacRoman)
271
+ CGContextSelectFont(context, 'Helvetica', 7, KCGEncodingMacRoman)
272
+
273
+ # Fixes upside down issue
274
+ CGContextSetTextMatrix(context, CGAffineTransformMake(1.0,0.0, 0.0, -1.0, 0.0, 0.0))
275
+
276
+ w = rmq.window
277
+ grid = rmq.stylesheet.grid
278
+ root_view = rmq.root_view
279
+
280
+ if @dimmed
281
+ CGContextSetFillColorWithColor(context, @background_color.CGColor)
282
+ CGContextFillRect(context, self.bounds)
283
+ end
284
+
285
+ if @draw_grid_x
286
+ CGContextSetFillColorWithColor(context, @column_fill_color)
287
+
288
+ grid.column_lefts.each do |x|
289
+ CGContextFillRect(context, [[x,0],[grid.column_width, screen_height]])
290
+ CGContextFillRect(context, [[x,0],[1, screen_height]])
291
+ end
292
+ end
293
+
294
+ if @draw_grid_y
295
+ CGContextSetFillColorWithColor(context, @row_fill_color)
296
+
297
+ grid.row_tops.each do |y|
298
+ CGContextFillRect(context, [[0,y],[screen_width, grid.row_height]])
299
+ CGContextFillRect(context, [[0,y],[screen_width, 1]])
300
+ end
301
+ end
302
+
303
+ if @draw_grid
304
+ 0.upto(grid.num_rows - 1) do |r|
305
+ 0.upto(grid.num_columns - 1) do |c|
306
+ rec = grid[[c, r]]
307
+ CGContextSetFillColorWithColor(context, @column_fill_color)
308
+ CGContextFillRect(context, rec.to_cgrect)
309
+ text = "#{(c+97).chr}#{r}"
310
+ CGContextSetFillColorWithColor(context, @light_text_color)
311
+ CGContextShowTextAtPoint(context, rec.origin.x + 1, rec.origin.y + 5, text, text.length)
312
+ end
313
+ end
314
+ end
315
+
316
+ if @views_outlined
317
+
318
+ @selected.each do |view|
319
+ rec = view.frame
320
+ rec.origin = rmq(view).location_in(root_view)
321
+ #rec.origin = view.origin
322
+
323
+ if @selected_views.include?(view)
324
+ CGContextSetFillColorWithColor(context, @view_selected_background_color.CGColor)
325
+ CGContextSetStrokeColorWithColor(context, @selected_outline_color)
326
+ else
327
+ CGContextSetFillColorWithColor(context, @view_background_color)
328
+ CGContextSetStrokeColorWithColor(context, @outline_color)
329
+ end
330
+
331
+ if @dimmed
332
+ CGContextFillRect(context, rec)
333
+ end
334
+
335
+ CGContextStrokeRect(context, rec)
336
+
337
+ CGContextSetFillColorWithColor(context, @text_color)
338
+
339
+ text = ":#{view.rmq_data.style_name}"
340
+ CGContextShowTextAtPoint(context, rec.origin.x + 1, rec.origin.y + 7, text, text.length)
341
+
342
+ text = "l: #{view.frame.origin.x}, t: #{view.frame.origin.y}"
343
+ CGContextShowTextAtPoint(context, rec.origin.x + 1, rec.origin.y + 16, text, text.length)
344
+ end
345
+ end
346
+ end
347
+ end
348
+
349
+ class TreeNodeView < UIView
350
+ def rmq_build
351
+ end
352
+ end
353
+
354
+ end
@@ -0,0 +1,106 @@
1
+ module RubyMotionQuery
2
+ class InspectorStylesheet < Stylesheet
3
+ attr_reader :tree_node_background_color, :selected_border_color
4
+
5
+ def setup
6
+ @view_scale = 0.85
7
+ @tool_box_button_background = color.from_hex('fe5875')
8
+ @tool_box_button_background_alt = color.from_hex('b7d95b')
9
+ @tree_background_color = color.from_rgba(77, 77, 77, 0.9)
10
+ #@tree_node_background_color = color.from_rgba(77, 77, 77, 0.5)
11
+ @tree_node_background_color = rmq.color.from_rgba(34,202,250,0.4)
12
+ @selected_border_color = rmq.color.white
13
+ #@view_background_color = rmq.color.from_rgba(34,202,250,0.4).CGColor
14
+ #@tree_node_background_color = rmq.color.from_rgba(202,34,250,0.7)
15
+ end
16
+
17
+ def inspector_view(st)
18
+ st.hidden = true
19
+ st.frame = :full
20
+ st.background_color = color.clear
21
+ st.z_position = 999
22
+ #st.scale = @view_scale
23
+ end
24
+
25
+ def root_view_scaled(st)
26
+ st.scale = @view_scale
27
+ st.frame = {t: 20, left: 0}
28
+ end
29
+
30
+ def root_view(st)
31
+ st.scale = 1.0
32
+ st.frame = {l: 0, t: 0}
33
+ end
34
+
35
+ def hud(st)
36
+ st.frame = :full
37
+ st.background_color = color.clear
38
+ st.scale = @view_scale
39
+ st.frame = {t: 20, left: 0}
40
+ end
41
+
42
+ def tree(st)
43
+ st.scale = 1.0
44
+ st.frame = {t: 20, fr: 0, w: 45, fb: 0}
45
+ st.background_color = color.black
46
+ st.content_inset = [2,2,2,2]
47
+ #st.border_color = @tree_node_background_color.CGColor
48
+ #st.border_width = 0
49
+ end
50
+
51
+ def tree_zoomed(st)
52
+ st.scale = 2.0
53
+ st.background_color = @tree_background_color
54
+ st.frame = {fr: 0, t: 0, w: 165, fb: 0}
55
+ #st.border_width = 1
56
+ end
57
+
58
+ def stats(st)
59
+ st.frame = {from_bottom: 15, w: screen_width, h: 45}
60
+ st.background_color = color.clear
61
+ st.font = rmq.font.system(8)
62
+ st.color = color.white
63
+ st.number_of_lines = 0
64
+ end
65
+
66
+ def tool_box_button(st)
67
+ st.frame = {from_bottom: 0, w: 30, h: 9}
68
+ st.text = 'close'
69
+ st.font = rmq.font.system(7)
70
+ st.background_color = @tool_box_button_background
71
+ end
72
+
73
+ def close_button(st)
74
+ tool_box_button(st)
75
+ st.text = 'close'
76
+ end
77
+
78
+ def grid_button(st)
79
+ tool_box_button(st)
80
+ st.text = 'grid'
81
+ st.background_color = @tool_box_button_background_alt
82
+ end
83
+ def grid_x_button(st)
84
+ tool_box_button(st)
85
+ st.text = 'grid-x'
86
+ st.background_color = @tool_box_button_background_alt
87
+ end
88
+ def grid_y_button(st)
89
+ tool_box_button(st)
90
+ st.text = 'grid-y'
91
+ st.background_color = @tool_box_button_background_alt
92
+ end
93
+
94
+ def dim_button(st)
95
+ tool_box_button(st)
96
+ st.text = 'dim'
97
+ end
98
+
99
+ def outline_button(st)
100
+ tool_box_button(st)
101
+ st.text = 'outline'
102
+ end
103
+
104
+ end
105
+
106
+ end
@@ -1,25 +1,43 @@
1
1
  module RubyMotionQuery
2
2
  class RMQ
3
3
 
4
+ # Always applied in this order, regardless of the hash order:
5
+ # grid
6
+ # l, t, w, h
7
+ # previous
8
+ # from_right, from_bottom
9
+ # right, bottom
10
+ # left and right applied together (will change width)
11
+ # top and bottom applied together (will change height)
12
+ # centered
13
+ # padding
14
+ #
4
15
  # @example
5
- # rmq.append(UILabel).layout(l: 10, t: 100, w: 100, h: 18)
6
- # rmq(my_view).move(l: 10, t: 100)
7
- # rmq(my_view).resize(h: 10, w: 100)
16
+ # rmq.append(UILabel).layout(l: 10, t: 100, w: 100, h: 18)
17
+ # rmq(my_view).move(l: 10, t: 100)
18
+ # rmq(my_view).resize(h: 10, w: 100)
19
+ # rmq(my_view).layout :full
20
+ # rmq(my_view).layout(l: 10, t: 20, w: 100, h: 150)
21
+ # rmq(my_view).layout(t: 20, h: 150, l: 10, w: 100)
22
+ # rmq(my_view).layout(l: 10, t: 20)
23
+ # rmq(my_view).layout(h: 20)
24
+ # rmq(my_view).layout(l: :prev, t: 20, w: 100, h: 150)
25
+ # rmq(my_view).layout(l: 10, below_prev: 10, w: prev, h: 150)
26
+ # rmq(my_view).layout(left: 10, top: 20, width: 100, height: 150)
27
+ # rmq(my_view).layout(l: 10, t: 10, fr: 10, fb: 10)
28
+ # rmq(my_view).layout(width: 50, height: 20, centered: :both)
29
+ # rmq(my_view).layout("a1:b5").show
30
+ # rmq(my_view, my_other_view).layout grid: "b2", w: 100, h: 200
31
+ # rmq(my_view, my_other_view).layout g: "b2", w: 100, h: 200
32
+ #
33
+ # @example with padding
34
+ # mq(my_view).layout(grid: "b2:d14", padding: 5)
35
+ # mq(my_view).layout(grid: "b2:d14", padding: {l: 5, t: 0, r: 5, b:0})
8
36
  #
9
37
  # @return [RMQ]
10
- def layout(opts)
11
- # TODO, add centered and from_bottom and from_top, and bottom and top
12
- # TODO, add animate option
13
- left = opts[:left] || opts[:l] || opts[:x]
14
- top = opts[:top] || opts[:t] || opts[:y]
15
- width = opts[:width] || opts[:w]
16
- height = opts[:height] || opts[:h]
17
-
38
+ def layout(params)
18
39
  selected.each do |view|
19
- view.frame = [
20
- [left || view.origin.x, top || view.origin.y],
21
- [width || view.size.width, height || view.size.height]
22
- ]
40
+ RubyMotionQuery::Rect.update_view_frame(view, params)
23
41
  end
24
42
 
25
43
  self
@@ -28,11 +46,12 @@ module RubyMotionQuery
28
46
  alias :resize :layout
29
47
 
30
48
  # @return [RMQ]
31
- def nudge(opts)
32
- left = opts[:left] || opts[:l] || 0
33
- right = opts[:right] || opts[:r] || 0
34
- up = opts[:up] || opts[:u] || 0
35
- down = opts[:down] || opts[:d] || 0
49
+ # TODO move nudge implementation into Rect
50
+ def nudge(params)
51
+ left = params[:left] || params[:l] || 0
52
+ right = params[:right] || params[:r] || 0
53
+ up = params[:up] || params[:u] || 0
54
+ down = params[:down] || params[:d] || 0
36
55
 
37
56
  selected.each do |view|
38
57
  f = view.frame