glimmer-dsl-libui 0.7.8 → 0.9.0

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.
@@ -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