glimmer-dsl-libui 0.7.8 → 0.9.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -62,13 +62,17 @@ module Glimmer
62
62
  end
63
63
 
64
64
  def perfect_shape
65
- perfect_shape_dependencies = [x, y, c1_x, c1_y, c2_x, c2_y, end_x, end_y]
66
- if perfect_shape_dependencies != @perfect_shape_dependencies
67
- x, y, c1_x, c1_y, c2_x, c2_y, end_x, end_y = @perfect_shape_dependencies = perfect_shape_dependencies
68
- @perfect_shape = PerfectShape::CubicBezierCurve.new(points: [x, y, c1_x, c1_y, c2_x, c2_y, end_x, end_y].compact)
65
+ the_perfect_shape_dependencies = perfect_shape_dependencies
66
+ if the_perfect_shape_dependencies != @perfect_shape_dependencies
67
+ absolute_x, absolute_y, absolute_c1_x, absolute_c1_y, absolute_c2_x, absolute_c2_y, absolute_end_x, absolute_end_y = @perfect_shape_dependencies = the_perfect_shape_dependencies
68
+ @perfect_shape = PerfectShape::CubicBezierCurve.new(points: [absolute_x, absolute_y, absolute_c1_x, absolute_c1_y, absolute_c2_x, absolute_c2_y, absolute_end_x, absolute_end_y].compact)
69
69
  end
70
70
  @perfect_shape
71
71
  end
72
+
73
+ def perfect_shape_dependencies
74
+ [absolute_x, absolute_y, absolute_c1_x, absolute_c1_y, absolute_c2_x, absolute_c2_y, absolute_end_x, absolute_end_y]
75
+ end
72
76
  end
73
77
  end
74
78
  end
@@ -51,13 +51,17 @@ module Glimmer
51
51
  end
52
52
 
53
53
  def perfect_shape
54
- perfect_shape_dependencies = [x_center, y_center, radius]
55
- if perfect_shape_dependencies != @perfect_shape_dependencies
56
- x_center, y_center, radius = @perfect_shape_dependencies = perfect_shape_dependencies
57
- @perfect_shape = PerfectShape::Circle.new(center_x: x_center, center_y: y_center, radius: radius)
54
+ the_perfect_shape_dependencies = perfect_shape_dependencies
55
+ if the_perfect_shape_dependencies != @perfect_shape_dependencies
56
+ absolute_x_center, absolute_y_center, radius = @perfect_shape_dependencies = the_perfect_shape_dependencies
57
+ @perfect_shape = PerfectShape::Circle.new(center_x: absolute_x_center, center_y: absolute_y_center, radius: radius)
58
58
  end
59
59
  @perfect_shape
60
60
  end
61
+
62
+ def perfect_shape_dependencies
63
+ [absolute_x_center, absolute_y_center, radius]
64
+ end
61
65
  end
62
66
  end
63
67
  end
@@ -0,0 +1,101 @@
1
+ # Copyright (c) 2021-2022 Andy Maleh
2
+ #
3
+ # Permission is hereby granted, free of charge, to any person obtaining
4
+ # a copy of this software and associated documentation files (the
5
+ # "Software"), to deal in the Software without restriction, including
6
+ # without limitation the rights to use, copy, modify, merge, publish,
7
+ # distribute, sublicense, and/or sell copies of the Software, and to
8
+ # permit persons to whom the Software is furnished to do so, subject to
9
+ # the following conditions:
10
+ #
11
+ # The above copyright notice and this permission notice shall be
12
+ # included in all copies or substantial portions of the Software.
13
+ #
14
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
21
+
22
+ require 'glimmer/libui/shape'
23
+
24
+ module Glimmer
25
+ module LibUI
26
+ class Shape
27
+ class CompositeShape < Glimmer::LibUI::Shape
28
+ # TODO support nested shape properties that apply to all children
29
+ parameters :x, :y
30
+ parameter_defaults 0, 0
31
+
32
+ def draw(area_draw_params)
33
+ children.each do |child|
34
+ child_fill = child.fill
35
+ child_stroke = child.stroke
36
+ child_transform = child.transform
37
+ child.fill = fill if Glimmer::LibUI.blank_color?(child.fill)
38
+ child.stroke = stroke if Glimmer::LibUI.blank_color?(child.stroke)
39
+ child.transform = transform if child.transform.nil?
40
+ child.move_by(x, y)
41
+ begin
42
+ child.draw(area_draw_params)
43
+ rescue Exception => e
44
+ raise e
45
+ ensure
46
+ # restore original child attributes
47
+ child.move_by(-x, -y)
48
+ child.transform = child_transform
49
+ child.stroke = Glimmer::LibUI.blank_color?(child_stroke) ? Glimmer::LibUI.blank_color : child_stroke
50
+ child.fill = Glimmer::LibUI.blank_color?(child_fill) ? Glimmer::LibUI.blank_color : child_fill
51
+ end
52
+ end
53
+ super
54
+ end
55
+
56
+ def transform(matrix = nil)
57
+ if matrix.nil?
58
+ @matrix
59
+ else
60
+ @matrix = matrix
61
+ end
62
+ end
63
+
64
+ def move_by(x_delta, y_delta)
65
+ self.x += x_delta
66
+ self.y += y_delta
67
+ end
68
+
69
+ def contain?(*point, outline: false, distance_tolerance: 0)
70
+ children.any? { |child| child.contain?(*point, outline: outline, distance_tolerance: distance_tolerance) }
71
+ end
72
+
73
+ def include?(*point)
74
+ children.any? { |child| child.include?(*point) }
75
+ end
76
+
77
+ def relative_x(x)
78
+ self.x + x
79
+ end
80
+
81
+ def relative_y(y)
82
+ self.y + y
83
+ end
84
+
85
+ def relative_point(*point)
86
+ [relative_x(point.first), relative_y(point.last)]
87
+ end
88
+
89
+ def perfect_shape
90
+ perfect_shape_dependencies = [x, y, children.map(&:perfect_shape_dependencies)]
91
+ if perfect_shape_dependencies != @perfect_shape_dependencies
92
+ x, y, _ = @perfect_shape_dependencies = perfect_shape_dependencies
93
+ shapes = children.map(&:perfect_shape)
94
+ @perfect_shape = PerfectShape::CompositeShape.new(shapes: shapes)
95
+ end
96
+ @perfect_shape
97
+ end
98
+ end
99
+ end
100
+ end
101
+ end
@@ -58,10 +58,10 @@ module Glimmer
58
58
  end
59
59
 
60
60
  def perfect_shape
61
- perfect_shape_dependencies = [x, y, closed, parent.draw_fill_mode, children]
62
- if perfect_shape_dependencies != @perfect_shape_dependencies
63
- x, y, closed, draw_fill_mode, children = @perfect_shape_dependencies = perfect_shape_dependencies
64
- path_shapes = [[x, y]]
61
+ the_perfect_shape_dependencies = perfect_shape_dependencies
62
+ if the_perfect_shape_dependencies != @perfect_shape_dependencies
63
+ absolute_x, absolute_y, closed, draw_fill_mode, children = @perfect_shape_dependencies = the_perfect_shape_dependencies
64
+ path_shapes = [[absolute_x, absolute_y]]
65
65
  path_shapes += children.map(&:perfect_shape)
66
66
  winding_rule = draw_fill_mode == :winding ? :wind_non_zero : :wind_even_odd
67
67
  @perfect_shape = PerfectShape::Path.new(
@@ -73,6 +73,10 @@ module Glimmer
73
73
  end
74
74
  @perfect_shape
75
75
  end
76
+
77
+ def perfect_shape_dependencies
78
+ [absolute_x, absolute_y, closed, parent.draw_fill_mode, children]
79
+ end
76
80
  end
77
81
  end
78
82
  end
@@ -61,13 +61,17 @@ module Glimmer
61
61
  end
62
62
 
63
63
  def perfect_shape
64
- perfect_shape_dependencies = [x, y, end_x, end_y]
65
- if perfect_shape_dependencies != @perfect_shape_dependencies
66
- x, y, end_x, end_y = @perfect_shape_dependencies = perfect_shape_dependencies
67
- @perfect_shape = PerfectShape::Line.new(points: [x, y, end_x, end_y].compact)
64
+ the_perfect_shape_dependencies = perfect_shape_dependencies
65
+ if the_perfect_shape_dependencies != @perfect_shape_dependencies
66
+ absolute_x, absolute_y, absolute_end_x, absolute_end_y = @perfect_shape_dependencies = the_perfect_shape_dependencies
67
+ @perfect_shape = PerfectShape::Line.new(points: [absolute_x, absolute_y, absolute_end_x, absolute_end_y].compact)
68
68
  end
69
69
  @perfect_shape
70
70
  end
71
+
72
+ def perfect_shape_dependencies
73
+ [absolute_x, absolute_y, absolute_end_x, absolute_end_y]
74
+ end
71
75
  end
72
76
  end
73
77
  end
@@ -45,16 +45,20 @@ module Glimmer
45
45
  end
46
46
 
47
47
  def perfect_shape
48
- perfect_shape_dependencies = PerfectShape::MultiPoint.normalize_point_array(point_array)
49
- if perfect_shape_dependencies != @perfect_shape_dependencies
50
- point_array = @perfect_shape_dependencies = perfect_shape_dependencies
51
- path_shapes = [point_array.first]
52
- bezier_shape_points = point_array.drop(1).each.with_index.to_a.group_by {|pair| pair.last/3}.values.map {|arr| arr.map(&:first)}
48
+ the_perfect_shape_dependencies = perfect_shape_dependencies
49
+ if the_perfect_shape_dependencies != @perfect_shape_dependencies
50
+ absolute_point_array = @perfect_shape_dependencies = the_perfect_shape_dependencies
51
+ path_shapes = [absolute_point_array.first]
52
+ bezier_shape_points = absolute_point_array.drop(1).each.with_index.to_a.group_by {|pair| pair.last/3}.values.map {|arr| arr.map(&:first)}
53
53
  path_shapes += bezier_shape_points.map { |points| PerfectShape::CubicBezierCurve.new(points: points) }
54
54
  @perfect_shape = PerfectShape::Path.new(closed: false, shapes: path_shapes)
55
55
  end
56
56
  @perfect_shape
57
57
  end
58
+
59
+ def perfect_shape_dependencies
60
+ absolute_point_array
61
+ end
58
62
  end
59
63
  end
60
64
  end
@@ -46,15 +46,19 @@ module Glimmer
46
46
  end
47
47
 
48
48
  def perfect_shape
49
- perfect_shape_dependencies = PerfectShape::MultiPoint.normalize_point_array(point_array)
50
- if perfect_shape_dependencies != @perfect_shape_dependencies
51
- point_array = @perfect_shape_dependencies = perfect_shape_dependencies
52
- path_shapes = [point_array.first]
53
- path_shapes += point_array.drop(1).map { |point| PerfectShape::Line.new(points: [point]) }
49
+ the_perfect_shape_dependencies = perfect_shape_dependencies
50
+ if the_perfect_shape_dependencies != @perfect_shape_dependencies
51
+ absolute_point_array = @perfect_shape_dependencies = the_perfect_shape_dependencies
52
+ path_shapes = [absolute_point_array.first]
53
+ path_shapes += absolute_point_array.drop(1).map { |point| PerfectShape::Line.new(points: [point]) }
54
54
  @perfect_shape = PerfectShape::Path.new(closed: true, shapes: path_shapes)
55
55
  end
56
56
  @perfect_shape
57
57
  end
58
+
59
+ def perfect_shape_dependencies
60
+ absolute_point_array
61
+ end
58
62
  end
59
63
  end
60
64
  end
@@ -45,15 +45,19 @@ module Glimmer
45
45
  end
46
46
 
47
47
  def perfect_shape
48
- perfect_shape_dependencies = PerfectShape::MultiPoint.normalize_point_array(point_array)
49
- if perfect_shape_dependencies != @perfect_shape_dependencies
50
- point_array = @perfect_shape_dependencies = perfect_shape_dependencies
51
- path_shapes = [point_array.first]
52
- path_shapes += point_array.drop(1).map { |point| PerfectShape::Line.new(points: [point]) }
48
+ the_perfect_shape_dependencies = perfect_shape_dependencies
49
+ if the_perfect_shape_dependencies != @perfect_shape_dependencies
50
+ absolute_point_array = @perfect_shape_dependencies = the_perfect_shape_dependencies
51
+ path_shapes = [absolute_point_array.first]
52
+ path_shapes += absolute_point_array.drop(1).map { |point| PerfectShape::Line.new(points: [point]) }
53
53
  @perfect_shape = PerfectShape::Path.new(closed: false, shapes: path_shapes)
54
54
  end
55
55
  @perfect_shape
56
56
  end
57
+
58
+ def perfect_shape_dependencies
59
+ absolute_point_array
60
+ end
57
61
  end
58
62
  end
59
63
  end
@@ -39,13 +39,17 @@ module Glimmer
39
39
  end
40
40
 
41
41
  def perfect_shape
42
- perfect_shape_dependencies = [x, y, width, height]
43
- if perfect_shape_dependencies != @perfect_shape_dependencies
44
- x, y, width, height = @perfect_shape_dependencies = perfect_shape_dependencies
45
- @perfect_shape = PerfectShape::Rectangle.new(x: x, y: y, width: width, height: height)
42
+ the_perfect_shape_dependencies = perfect_shape_dependencies
43
+ if the_perfect_shape_dependencies != @perfect_shape_dependencies
44
+ absolute_x, absolute_y, width, height = @perfect_shape_dependencies = the_perfect_shape_dependencies
45
+ @perfect_shape = PerfectShape::Rectangle.new(x: absolute_x, y: absolute_y, width: width, height: height)
46
46
  end
47
47
  @perfect_shape
48
48
  end
49
+
50
+ def perfect_shape_dependencies
51
+ [absolute_x, absolute_y, width, height]
52
+ end
49
53
  end
50
54
  end
51
55
  end
@@ -41,13 +41,17 @@ module Glimmer
41
41
  end
42
42
 
43
43
  def perfect_shape
44
- perfect_shape_dependencies = [x, y, length]
45
- if perfect_shape_dependencies != @perfect_shape_dependencies
46
- @perfect_shape_dependencies = perfect_shape_dependencies
44
+ the_perfect_shape_dependencies = perfect_shape_dependencies
45
+ if the_perfect_shape_dependencies != @perfect_shape_dependencies
46
+ @perfect_shape_dependencies = the_perfect_shape_dependencies
47
47
  @perfect_shape = PerfectShape::Square.new(x: @perfect_shape_dependencies[0], y: @perfect_shape_dependencies[1], length: @perfect_shape_dependencies[2])
48
48
  end
49
49
  @perfect_shape
50
50
  end
51
+
52
+ def perfect_shape_dependencies
53
+ [absolute_x, absolute_y, length]
54
+ end
51
55
  end
52
56
  end
53
57
  end
@@ -31,16 +31,19 @@ module Glimmer
31
31
  class Shape
32
32
  class << self
33
33
  def exists?(keyword)
34
+ keyword = KEYWORD_ALIASES[keyword] || keyword
34
35
  Shape.constants.include?(constant_symbol(keyword)) and
35
36
  shape_class(keyword).respond_to?(:ancestors) and
36
37
  shape_class(keyword).ancestors.include?(Shape)
37
38
  end
38
39
 
39
40
  def create(keyword, parent, args, &block)
41
+ keyword = KEYWORD_ALIASES[keyword] || keyword
40
42
  shape_class(keyword).new(keyword, parent, args, &block)
41
43
  end
42
44
 
43
45
  def shape_class(keyword)
46
+ keyword = KEYWORD_ALIASES[keyword] || keyword
44
47
  Shape.const_get(constant_symbol(keyword))
45
48
  end
46
49
 
@@ -61,6 +64,7 @@ module Glimmer
61
64
  end
62
65
 
63
66
  def constant_symbol(keyword)
67
+ keyword = KEYWORD_ALIASES[keyword] || keyword
64
68
  "#{keyword.camelcase(:upper)}".to_sym
65
69
  end
66
70
  end
@@ -69,10 +73,15 @@ module Glimmer
69
73
  include PerfectShaped
70
74
  include DataBindable
71
75
 
76
+ KEYWORD_ALIASES = {
77
+ 'shape' => 'composite_shape',
78
+ }
79
+
72
80
  attr_reader :parent, :args, :keyword, :block, :content_added
73
81
  alias content_added? content_added
74
82
 
75
83
  def initialize(keyword, parent, args, &block)
84
+ keyword = KEYWORD_ALIASES[keyword] || keyword
76
85
  @keyword = keyword
77
86
  @parent = parent
78
87
  @args = args
@@ -129,6 +138,10 @@ module Glimmer
129
138
  def path_proxy
130
139
  find_parent_in_ancestors { |parent| parent.nil? || parent.is_a?(ControlProxy::PathProxy) }
131
140
  end
141
+
142
+ def composite_shape
143
+ find_parent_in_ancestors { |parent| parent.nil? || parent.is_a?(CompositeShape) }
144
+ end
132
145
 
133
146
  def fill(*args)
134
147
  path_proxy.fill(*args)
@@ -148,6 +161,125 @@ module Glimmer
148
161
  alias transform= transform
149
162
  alias set_transform transform
150
163
 
164
+ def absolute_x
165
+ if composite_shape
166
+ composite_shape.relative_x(x)
167
+ else
168
+ x
169
+ end
170
+ end
171
+
172
+ def absolute_y
173
+ if composite_shape
174
+ composite_shape.relative_y(y)
175
+ else
176
+ y
177
+ end
178
+ end
179
+
180
+ def absolute_point_array
181
+ # TODO Consider moving this method into a module mixed into all shapes having point_array
182
+ return unless respond_to?(:point_array)
183
+
184
+ point_array = self.point_array || []
185
+ point_array = PerfectShape::MultiPoint.normalize_point_array(point_array)
186
+ point_array.map do |point|
187
+ if composite_shape
188
+ composite_shape.relative_point(*point)
189
+ else
190
+ point
191
+ end
192
+ end
193
+ end
194
+
195
+ def absolute_x_center
196
+ # TODO Consider moving this method into a module mixed into all shapes having x_center
197
+ return unless respond_to?(:x_center)
198
+
199
+ if composite_shape
200
+ composite_shape.relative_x(x_center)
201
+ else
202
+ x_center
203
+ end
204
+ end
205
+
206
+ def absolute_y_center
207
+ # TODO Consider moving this method into a module mixed into all shapes having y_center
208
+ return unless respond_to?(:y_center)
209
+
210
+ if composite_shape
211
+ composite_shape.relative_y(y_center)
212
+ else
213
+ y_center
214
+ end
215
+ end
216
+
217
+ def absolute_c1_x
218
+ # TODO Consider moving this method into a module mixed into all shapes having c1_x
219
+ return unless respond_to?(:c1_x)
220
+
221
+ if composite_shape
222
+ composite_shape.relative_x(c1_x)
223
+ else
224
+ c1_x
225
+ end
226
+ end
227
+
228
+ def absolute_c1_y
229
+ # TODO Consider moving this method into a module mixed into all shapes having c1_y
230
+ return unless respond_to?(:c1_y)
231
+
232
+ if composite_shape
233
+ composite_shape.relative_x(c1_y)
234
+ else
235
+ c1_y
236
+ end
237
+ end
238
+
239
+ def absolute_c2_x
240
+ # TODO Consider moving this method into a module mixed into all shapes having c2_x
241
+ return unless respond_to?(:c2_x)
242
+
243
+ if composite_shape
244
+ composite_shape.relative_x(c2_x)
245
+ else
246
+ c2_x
247
+ end
248
+ end
249
+
250
+ def absolute_c2_y
251
+ # TODO Consider moving this method into a module mixed into all shapes having c2_y
252
+ return unless respond_to?(:c2_y)
253
+
254
+ if composite_shape
255
+ composite_shape.relative_x(c2_y)
256
+ else
257
+ c2_y
258
+ end
259
+ end
260
+
261
+ def absolute_end_x
262
+ # TODO Consider moving this method into a module mixed into all shapes having end_x
263
+ return unless respond_to?(:end_x)
264
+
265
+ if composite_shape
266
+ composite_shape.relative_x(end_x)
267
+ else
268
+ end_x
269
+ end
270
+ end
271
+
272
+ def absolute_end_y
273
+ # TODO Consider moving this method into a module mixed into all shapes having end_y
274
+ return unless respond_to?(:end_y)
275
+
276
+ if composite_shape
277
+ composite_shape.relative_x(end_y)
278
+ else
279
+ end_y
280
+ end
281
+ end
282
+
151
283
  def can_handle_listener?(listener_name)
152
284
  area_proxy.can_handle_listener?(listener_name)
153
285
  end
@@ -181,7 +313,16 @@ module Glimmer
181
313
  super
182
314
  end
183
315
  end
184
-
316
+
317
+ # indicates if nested directly under area or on_draw event (having an implicit path not an explicit path parent)
318
+ def implicit_path?
319
+ @implicit_path ||= !!(
320
+ @parent.is_a?(Glimmer::LibUI::ControlProxy::AreaProxy) ||
321
+ @parent.is_a?(Glimmer::LibUI::Shape::CompositeShape) ||
322
+ (@parent.nil? && Glimmer::LibUI::ControlProxy::AreaProxy.current_area_draw_params)
323
+ )
324
+ end
325
+
185
326
  private
186
327
 
187
328
  def build_control
@@ -189,11 +330,6 @@ module Glimmer
189
330
  @parent = Glimmer::LibUI::ControlProxy::PathProxy.new('path', @parent, [], &block)
190
331
  end
191
332
 
192
- # indicates if nested directly under area or on_draw event (having an implicit path not an explicit path parent)
193
- def implicit_path?
194
- @implicit_path ||= !!(@parent.is_a?(Glimmer::LibUI::ControlProxy::AreaProxy) || (@parent.nil? && Glimmer::LibUI::ControlProxy::AreaProxy.current_area_draw_params))
195
- end
196
-
197
333
  def dynamic?
198
334
  ((@parent.nil? || (@parent.is_a?(ControlProxy::PathProxy) && @parent.parent_proxy.nil?)) && Glimmer::LibUI::ControlProxy::AreaProxy.current_area_draw_params)
199
335
  end
data/lib/glimmer/libui.rb CHANGED
@@ -104,6 +104,21 @@ module Glimmer
104
104
  result.merge!(options) if options
105
105
  result
106
106
  end
107
+
108
+ # returns whether the value represents no color (blank) or a present color
109
+ # when a path is first built, it has a blank color
110
+ def blank_color?(value)
111
+ value.nil? ||
112
+ (value.respond_to?(:empty?) && value.empty?) ||
113
+ (value.is_a?(Array) && value.compact.empty?) ||
114
+ (value.is_a?(Hash) && value.values.compact.empty?)
115
+ end
116
+
117
+ # returns a representation of a blank color
118
+ # when a path is first built, it has a blank color
119
+ def blank_color
120
+ [{}]
121
+ end
107
122
 
108
123
  def hex_to_rgb(value)
109
124
  if value.is_a?(String)
@@ -0,0 +1,105 @@
1
+ # Copyright (c) 2007-2023 Andy Maleh
2
+ #
3
+ # Permission is hereby granted, free of charge, to any person obtaining
4
+ # a copy of this software and associated documentation files (the
5
+ # "Software"), to deal in the Software without restriction, including
6
+ # without limitation the rights to use, copy, modify, merge, publish,
7
+ # distribute, sublicense, and/or sell copies of the Software, and to
8
+ # permit persons to whom the Software is furnished to do so, subject to
9
+ # the following conditions:
10
+ #
11
+ # The above copyright notice and this permission notice shall be
12
+ # included in all copies or substantial portions of the Software.
13
+ #
14
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
21
+
22
+ require 'facets'
23
+ require 'text-table'
24
+
25
+ module Glimmer
26
+ module RakeTask
27
+ # Lists Glimmer related gems to use in rake_task.rb
28
+ class List
29
+ class << self
30
+ REGEX_GEM_LINE = /^([^\(]+) \(([^\)]+)\)$/
31
+
32
+ def custom_control_gems(query=nil)
33
+ list_gems('glimmer-cw-', query) do |result|
34
+ puts
35
+ puts " Glimmer Custom Control Gems#{" matching [#{query}]" if query} at rubygems.org:"
36
+ puts result
37
+ end
38
+ end
39
+
40
+ def custom_window_gems(query=nil)
41
+ list_gems('glimmer-cs-', query) do |result|
42
+ puts
43
+ puts " Glimmer Custom Window Gems#{" matching [#{query}]" if query} at rubygems.org:"
44
+ puts result
45
+ end
46
+ end
47
+
48
+ def custom_shape_gems(query=nil)
49
+ list_gems('glimmer-cp-', query) do |result|
50
+ puts
51
+ puts " Glimmer Custom Shape Gems#{" matching [#{query}]" if query} at rubygems.org:"
52
+ puts result
53
+ end
54
+ end
55
+
56
+ def dsl_gems(query=nil)
57
+ list_gems('glimmer-dsl-', query) do |result|
58
+ puts
59
+ puts " Glimmer DSL Gems#{" matching [#{query}]" if query} at rubygems.org:"
60
+ puts result
61
+ end
62
+ end
63
+
64
+ def list_gems(gem_prefix, query=nil, &printer)
65
+ lines = `gem search -d #{gem_prefix}`.split("\n")
66
+ gems = lines.slice_before {|l| l.match(REGEX_GEM_LINE) }.to_a
67
+ gems = gems.map do |gem|
68
+ {
69
+ name: gem[0].match(REGEX_GEM_LINE)[1],
70
+ version: gem[0].match(REGEX_GEM_LINE)[2],
71
+ author: gem[1].strip,
72
+ description: gem[4..-1]&.map(&:strip)&.join(' ').to_s
73
+ }
74
+ end.select do |gem|
75
+ query.nil? || "#{gem[:name]} #{gem[:author]} #{gem[:description]}".downcase.include?(query.to_s.downcase)
76
+ end
77
+ printer.call(tablify(gem_prefix, gems))
78
+ end
79
+
80
+ def tablify(gem_prefix, gems)
81
+ array_of_arrays = gems.map do |gem|
82
+ name, namespace = gem[:name].sub(gem_prefix, '').underscore.titlecase.split
83
+ human_name = name
84
+ human_name += " (#{namespace})" unless namespace.nil?
85
+ [
86
+ human_name,
87
+ gem[:name],
88
+ gem[:version],
89
+ gem[:author].sub('Author: ', ''),
90
+ gem[:description],
91
+ ]
92
+ end
93
+ Text::Table.new(
94
+ :head => %w[Name Gem Version Author Description],
95
+ :rows => array_of_arrays,
96
+ :horizontal_padding => 1,
97
+ :vertical_boundary => ' ',
98
+ :horizontal_boundary => ' ',
99
+ :boundary_intersection => ' '
100
+ )
101
+ end
102
+ end
103
+ end
104
+ end
105
+ end