shoes-core 4.0.0.pre3

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.
Files changed (219) hide show
  1. checksums.yaml +7 -0
  2. data/LICENSE +31 -0
  3. data/README.md +8 -0
  4. data/Rakefile +1 -0
  5. data/bin/shoes +62 -0
  6. data/bin/shoes-guard +8 -0
  7. data/bin/shoes-picker +6 -0
  8. data/bin/shoes-stub +62 -0
  9. data/ext/install/Rakefile +29 -0
  10. data/ext/install/shoes.bat +15 -0
  11. data/fonts/Coolvetica.ttf +0 -0
  12. data/fonts/Lacuna.ttf +0 -0
  13. data/lib/rubygems_plugin.rb +24 -0
  14. data/lib/shoes.rb +1 -0
  15. data/lib/shoes/animation.rb +56 -0
  16. data/lib/shoes/app.rb +130 -0
  17. data/lib/shoes/arc.rb +25 -0
  18. data/lib/shoes/background.rb +20 -0
  19. data/lib/shoes/border.rb +20 -0
  20. data/lib/shoes/builtin_methods.rb +76 -0
  21. data/lib/shoes/button.rb +29 -0
  22. data/lib/shoes/check_button.rb +41 -0
  23. data/lib/shoes/color.rb +387 -0
  24. data/lib/shoes/common/background_element.rb +9 -0
  25. data/lib/shoes/common/changeable.rb +34 -0
  26. data/lib/shoes/common/clickable.rb +24 -0
  27. data/lib/shoes/common/inspect.rb +14 -0
  28. data/lib/shoes/common/positioning.rb +30 -0
  29. data/lib/shoes/common/registration.rb +31 -0
  30. data/lib/shoes/common/remove.rb +10 -0
  31. data/lib/shoes/common/state.rb +16 -0
  32. data/lib/shoes/common/style.rb +160 -0
  33. data/lib/shoes/common/style_normalizer.rb +16 -0
  34. data/lib/shoes/common/ui_element.rb +11 -0
  35. data/lib/shoes/common/visibility.rb +41 -0
  36. data/lib/shoes/configuration.rb +96 -0
  37. data/lib/shoes/core.rb +1 -0
  38. data/lib/shoes/core/version.rb +5 -0
  39. data/lib/shoes/dialog.rb +56 -0
  40. data/lib/shoes/dimension.rb +269 -0
  41. data/lib/shoes/dimensions.rb +203 -0
  42. data/lib/shoes/download.rb +130 -0
  43. data/lib/shoes/dsl.rb +656 -0
  44. data/lib/shoes/file_not_found_error.rb +4 -0
  45. data/lib/shoes/font.rb +50 -0
  46. data/lib/shoes/gradient.rb +31 -0
  47. data/lib/shoes/image.rb +53 -0
  48. data/lib/shoes/image_pattern.rb +12 -0
  49. data/lib/shoes/input_box.rb +59 -0
  50. data/lib/shoes/internal_app.rb +230 -0
  51. data/lib/shoes/key_event.rb +17 -0
  52. data/lib/shoes/line.rb +84 -0
  53. data/lib/shoes/link.rb +57 -0
  54. data/lib/shoes/link_hover.rb +5 -0
  55. data/lib/shoes/list_box.rb +50 -0
  56. data/lib/shoes/logger.rb +65 -0
  57. data/lib/shoes/logger/ruby.rb +16 -0
  58. data/lib/shoes/mock.rb +33 -0
  59. data/lib/shoes/mock/animation.rb +8 -0
  60. data/lib/shoes/mock/app.rb +49 -0
  61. data/lib/shoes/mock/arc.rb +9 -0
  62. data/lib/shoes/mock/background.rb +10 -0
  63. data/lib/shoes/mock/border.rb +7 -0
  64. data/lib/shoes/mock/button.rb +22 -0
  65. data/lib/shoes/mock/check.rb +24 -0
  66. data/lib/shoes/mock/clickable.rb +8 -0
  67. data/lib/shoes/mock/common_methods.rb +12 -0
  68. data/lib/shoes/mock/dialog.rb +13 -0
  69. data/lib/shoes/mock/download.rb +16 -0
  70. data/lib/shoes/mock/font.rb +15 -0
  71. data/lib/shoes/mock/image.rb +13 -0
  72. data/lib/shoes/mock/image_pattern.rb +8 -0
  73. data/lib/shoes/mock/input_box.rb +30 -0
  74. data/lib/shoes/mock/keypress.rb +11 -0
  75. data/lib/shoes/mock/keyrelease.rb +11 -0
  76. data/lib/shoes/mock/line.rb +14 -0
  77. data/lib/shoes/mock/link.rb +11 -0
  78. data/lib/shoes/mock/list_box.rb +19 -0
  79. data/lib/shoes/mock/oval.rb +11 -0
  80. data/lib/shoes/mock/packager.rb +13 -0
  81. data/lib/shoes/mock/progress.rb +10 -0
  82. data/lib/shoes/mock/radio.rb +27 -0
  83. data/lib/shoes/mock/rect.rb +14 -0
  84. data/lib/shoes/mock/shape.rb +20 -0
  85. data/lib/shoes/mock/slot.rb +16 -0
  86. data/lib/shoes/mock/sound.rb +8 -0
  87. data/lib/shoes/mock/star.rb +14 -0
  88. data/lib/shoes/mock/text_block.rb +36 -0
  89. data/lib/shoes/mock/timer.rb +8 -0
  90. data/lib/shoes/not_implemented_error.rb +4 -0
  91. data/lib/shoes/oval.rb +20 -0
  92. data/lib/shoes/packager.rb +26 -0
  93. data/lib/shoes/point.rb +54 -0
  94. data/lib/shoes/progress.rb +25 -0
  95. data/lib/shoes/radio.rb +15 -0
  96. data/lib/shoes/rect.rb +21 -0
  97. data/lib/shoes/renamed_delegate.rb +15 -0
  98. data/lib/shoes/shape.rb +159 -0
  99. data/lib/shoes/slot.rb +276 -0
  100. data/lib/shoes/slot_contents.rb +51 -0
  101. data/lib/shoes/sound.rb +18 -0
  102. data/lib/shoes/span.rb +16 -0
  103. data/lib/shoes/star.rb +50 -0
  104. data/lib/shoes/text.rb +24 -0
  105. data/lib/shoes/text_block.rb +142 -0
  106. data/lib/shoes/text_block_dimensions.rb +51 -0
  107. data/lib/shoes/timer.rb +14 -0
  108. data/lib/shoes/ui/cli.rb +67 -0
  109. data/lib/shoes/ui/picker.rb +47 -0
  110. data/lib/shoes/url.rb +44 -0
  111. data/lib/shoes/version.rb +3 -0
  112. data/lib/shoes/widget.rb +67 -0
  113. data/shoes-core.gemspec +22 -0
  114. data/spec/shoes/animation_spec.rb +71 -0
  115. data/spec/shoes/app_spec.rb +484 -0
  116. data/spec/shoes/arc_spec.rb +51 -0
  117. data/spec/shoes/background_spec.rb +47 -0
  118. data/spec/shoes/border_spec.rb +46 -0
  119. data/spec/shoes/builtin_methods_spec.rb +110 -0
  120. data/spec/shoes/button_spec.rb +44 -0
  121. data/spec/shoes/check_spec.rb +35 -0
  122. data/spec/shoes/color_spec.rb +408 -0
  123. data/spec/shoes/common/inspect_spec.rb +26 -0
  124. data/spec/shoes/common/remove_spec.rb +38 -0
  125. data/spec/shoes/common/style_normalizer_spec.rb +28 -0
  126. data/spec/shoes/common/style_spec.rb +147 -0
  127. data/spec/shoes/configuration_spec.rb +36 -0
  128. data/spec/shoes/constants_spec.rb +38 -0
  129. data/spec/shoes/dialog_spec.rb +171 -0
  130. data/spec/shoes/dimension_spec.rb +433 -0
  131. data/spec/shoes/dimensions_spec.rb +837 -0
  132. data/spec/shoes/download_spec.rb +146 -0
  133. data/spec/shoes/flow_spec.rb +133 -0
  134. data/spec/shoes/font_spec.rb +37 -0
  135. data/spec/shoes/framework_learning_spec.rb +30 -0
  136. data/spec/shoes/gradient_spec.rb +32 -0
  137. data/spec/shoes/helpers/fake_element.rb +17 -0
  138. data/spec/shoes/helpers/inspect_helpers.rb +5 -0
  139. data/spec/shoes/helpers/sample17_helper.rb +66 -0
  140. data/spec/shoes/image_spec.rb +68 -0
  141. data/spec/shoes/images/shoe.jpg +0 -0
  142. data/spec/shoes/input_box_spec.rb +80 -0
  143. data/spec/shoes/integration_spec.rb +20 -0
  144. data/spec/shoes/internal_app_spec.rb +141 -0
  145. data/spec/shoes/keypress_spec.rb +11 -0
  146. data/spec/shoes/keyrelease_spec.rb +12 -0
  147. data/spec/shoes/line_spec.rb +87 -0
  148. data/spec/shoes/link_spec.rb +118 -0
  149. data/spec/shoes/list_box_spec.rb +74 -0
  150. data/spec/shoes/logger/ruby_spec.rb +8 -0
  151. data/spec/shoes/logger_spec.rb +45 -0
  152. data/spec/shoes/oval_spec.rb +24 -0
  153. data/spec/shoes/packager_spec.rb +25 -0
  154. data/spec/shoes/point_spec.rb +71 -0
  155. data/spec/shoes/progress_spec.rb +54 -0
  156. data/spec/shoes/radio_spec.rb +32 -0
  157. data/spec/shoes/rect_spec.rb +39 -0
  158. data/spec/shoes/renamed_delegate_spec.rb +70 -0
  159. data/spec/shoes/shape_spec.rb +106 -0
  160. data/spec/shoes/shared_examples/button.rb +6 -0
  161. data/spec/shoes/shared_examples/changeable.rb +26 -0
  162. data/spec/shoes/shared_examples/clickable.rb +5 -0
  163. data/spec/shoes/shared_examples/common_methods.rb +35 -0
  164. data/spec/shoes/shared_examples/dimensions.rb +32 -0
  165. data/spec/shoes/shared_examples/dsl.rb +44 -0
  166. data/spec/shoes/shared_examples/dsl/animate.rb +29 -0
  167. data/spec/shoes/shared_examples/dsl/arc.rb +45 -0
  168. data/spec/shoes/shared_examples/dsl/background.rb +26 -0
  169. data/spec/shoes/shared_examples/dsl/border.rb +10 -0
  170. data/spec/shoes/shared_examples/dsl/button.rb +5 -0
  171. data/spec/shoes/shared_examples/dsl/cap.rb +6 -0
  172. data/spec/shoes/shared_examples/dsl/check.rb +11 -0
  173. data/spec/shoes/shared_examples/dsl/edit_box.rb +8 -0
  174. data/spec/shoes/shared_examples/dsl/edit_line.rb +8 -0
  175. data/spec/shoes/shared_examples/dsl/editable_element.rb +29 -0
  176. data/spec/shoes/shared_examples/dsl/fill.rb +27 -0
  177. data/spec/shoes/shared_examples/dsl/flow.rb +15 -0
  178. data/spec/shoes/shared_examples/dsl/gradient.rb +62 -0
  179. data/spec/shoes/shared_examples/dsl/image.rb +21 -0
  180. data/spec/shoes/shared_examples/dsl/line.rb +9 -0
  181. data/spec/shoes/shared_examples/dsl/nofill.rb +6 -0
  182. data/spec/shoes/shared_examples/dsl/nostroke.rb +6 -0
  183. data/spec/shoes/shared_examples/dsl/oval.rb +88 -0
  184. data/spec/shoes/shared_examples/dsl/pattern.rb +34 -0
  185. data/spec/shoes/shared_examples/dsl/progress.rb +7 -0
  186. data/spec/shoes/shared_examples/dsl/rect.rb +92 -0
  187. data/spec/shoes/shared_examples/dsl/rgb.rb +26 -0
  188. data/spec/shoes/shared_examples/dsl/shape.rb +57 -0
  189. data/spec/shoes/shared_examples/dsl/star.rb +111 -0
  190. data/spec/shoes/shared_examples/dsl/stroke.rb +30 -0
  191. data/spec/shoes/shared_examples/dsl/strokewidth.rb +19 -0
  192. data/spec/shoes/shared_examples/dsl/style.rb +32 -0
  193. data/spec/shoes/shared_examples/dsl/text_elements.rb +81 -0
  194. data/spec/shoes/shared_examples/dsl/video.rb +5 -0
  195. data/spec/shoes/shared_examples/dsl_app_context.rb +8 -0
  196. data/spec/shoes/shared_examples/hover_leave.rb +11 -0
  197. data/spec/shoes/shared_examples/parent.rb +6 -0
  198. data/spec/shoes/shared_examples/scroll.rb +41 -0
  199. data/spec/shoes/shared_examples/shared_element_method.rb +60 -0
  200. data/spec/shoes/shared_examples/slot.rb +394 -0
  201. data/spec/shoes/shared_examples/state.rb +19 -0
  202. data/spec/shoes/shared_examples/style.rb +82 -0
  203. data/spec/shoes/slot_spec.rb +186 -0
  204. data/spec/shoes/sound_spec.rb +15 -0
  205. data/spec/shoes/span_spec.rb +112 -0
  206. data/spec/shoes/spec_helper.rb +24 -0
  207. data/spec/shoes/stack_spec.rb +79 -0
  208. data/spec/shoes/star_spec.rb +48 -0
  209. data/spec/shoes/text_block_dimensions_spec.rb +75 -0
  210. data/spec/shoes/text_block_spec.rb +270 -0
  211. data/spec/shoes/url_spec.rb +68 -0
  212. data/spec/shoes/widget_spec.rb +70 -0
  213. data/spec/shoes_spec.rb +44 -0
  214. data/spec/spec_helper.rb +19 -0
  215. data/static/downloading.png +0 -0
  216. data/static/shoes-icon-blue.png +0 -0
  217. data/static/shoes-icon-brown.png +0 -0
  218. data/static/shoes-icon.png +0 -0
  219. metadata +366 -0
@@ -0,0 +1,25 @@
1
+ class Shoes
2
+ class Arc
3
+ include Common::UIElement
4
+ include Common::Style
5
+ include Common::Clickable
6
+
7
+ attr_reader :app, :parent, :dimensions, :gui
8
+ style_with :angle1, :angle2, :art_styles, :center, :common_styles, :dimensions, :radius, :wedge
9
+ STYLES = { wedge: false }
10
+
11
+ def initialize(app, parent, left, top, width, height, angle1, angle2, styles = {}, blk = nil)
12
+ @app = app
13
+ @parent = parent
14
+ style_init styles, angle1: angle1, angle2: angle2
15
+ @dimensions = Dimensions.new parent, left, top, width, height, @style
16
+ @parent.add_child self
17
+ @gui = Shoes.backend_for self
18
+ register_click blk
19
+ end
20
+
21
+ def wedge?
22
+ wedge
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,20 @@
1
+ class Shoes
2
+ class Background
3
+ include Common::UIElement
4
+ include Common::BackgroundElement
5
+ include Common::Style
6
+
7
+ attr_reader :app, :parent, :dimensions, :gui
8
+ style_with :angle, :common_styles, :curve, :dimensions, :fill
9
+ STYLES = { angle: 0, curve: 0 }
10
+
11
+ def initialize(app, parent, color, styles = {})
12
+ @app = app
13
+ @parent = parent
14
+ style_init styles, fill: color
15
+ @dimensions = ParentDimensions.new parent, @style
16
+ @parent.add_child self
17
+ @gui = Shoes.backend_for self
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,20 @@
1
+ class Shoes
2
+ class Border
3
+ include Common::UIElement
4
+ include Common::BackgroundElement
5
+ include Common::Style
6
+
7
+ attr_reader :app, :parent, :dimensions, :gui
8
+ style_with :angle, :common_styles, :curve, :dimensions, :stroke, :strokewidth
9
+ STYLES = { angle: 0, curve: 0 }
10
+
11
+ def initialize(app, parent, color, styles = {})
12
+ @app = app
13
+ @parent = parent
14
+ style_init styles, stroke: color
15
+ @dimensions = ParentDimensions.new parent, @style
16
+ @parent.add_child self
17
+ @gui = Shoes.backend_for self
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,76 @@
1
+ # The methods defined in this module/file are also available outside of the
2
+ # Shoes.app block. So they are monkey patched onto the main object.
3
+ # However they can also be used from the normal Shoes.app block.
4
+ class Shoes
5
+ def self.p(message)
6
+ Shoes::LOG << ['debug', message.inspect]
7
+ end
8
+
9
+ module BuiltinMethods
10
+ include Color::DSLHelpers
11
+
12
+ def alert(message = '')
13
+ Shoes::Dialog.new.alert message
14
+ end
15
+
16
+ def confirm(message = '')
17
+ Shoes::Dialog.new.confirm(message)
18
+ end
19
+
20
+ def info(message = '')
21
+ Shoes::LOG << ['info', message]
22
+ Shoes.logger.info message
23
+ end
24
+
25
+ def debug(message = '')
26
+ Shoes::LOG << ['debug', message]
27
+ Shoes.logger.debug message
28
+ end
29
+
30
+ def warn(message = '')
31
+ Shoes::LOG << ['warn', message]
32
+ Shoes.logger.warn message
33
+ end
34
+
35
+ def error(message = '')
36
+ Shoes::LOG << ['error', message]
37
+ Shoes.logger.error message
38
+ end
39
+
40
+ alias_method :confirm?, :confirm
41
+
42
+ def ask_open_file
43
+ Shoes::Dialog.new.dialog_chooser 'Open File...'
44
+ end
45
+
46
+ def ask_save_file
47
+ Shoes::Dialog.new.dialog_chooser 'Save File...'
48
+ end
49
+
50
+ def ask_open_folder
51
+ Shoes::Dialog.new.dialog_chooser 'Open Folder...', :folder
52
+ end
53
+
54
+ def ask_save_folder
55
+ Shoes::Dialog.new.dialog_chooser 'Save Folder...', :folder
56
+ end
57
+
58
+ def ask(msg, args = {})
59
+ Shoes::Dialog.new.ask msg, args
60
+ end
61
+
62
+ def ask_color(title = 'Pick a color...')
63
+ Shoes::Dialog.new.ask_color title
64
+ end
65
+
66
+ def font(path = DEFAULT_TEXTBLOCK_FONT)
67
+ Shoes::Font.add_font(path)
68
+ end
69
+ end
70
+
71
+ # make the builtin methods available on the Shoes class
72
+ extend BuiltinMethods
73
+ end
74
+
75
+ # including the module into the main object for availability on the top level
76
+ extend Shoes::BuiltinMethods
@@ -0,0 +1,29 @@
1
+ class Shoes
2
+ class Button
3
+ include Common::UIElement
4
+ include Common::Style
5
+ include Common::Clickable
6
+
7
+ attr_reader :app, :parent, :dimensions, :gui
8
+ style_with :click, :common_styles, :dimensions, :state, :text
9
+
10
+ def initialize(app, parent, text, styles = {}, blk = nil)
11
+ @app = app
12
+ @parent = parent
13
+ style_init styles, text: text
14
+ @dimensions = Dimensions.new parent, @style
15
+ @parent.add_child self
16
+ @gui = Shoes.configuration.backend_for self, @parent.gui
17
+ register_click blk
18
+ end
19
+
20
+ def focus
21
+ @gui.focus
22
+ end
23
+
24
+ def state=(value)
25
+ style(state: value)
26
+ @gui.enabled value.nil?
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,41 @@
1
+ class Shoes
2
+ class CheckButton
3
+ include Common::UIElement
4
+ include Common::Style
5
+ include Common::Clickable
6
+
7
+ attr_reader :app, :parent, :dimensions, :gui
8
+
9
+ def initialize(app, parent, styles = {}, blk = nil)
10
+ @app = app
11
+ @parent = parent
12
+ style_init styles
13
+ @dimensions = Dimensions.new parent, @style
14
+ @parent.add_child self
15
+ @gui = Shoes.configuration.backend_for self, @parent.gui
16
+ register_click blk
17
+ end
18
+
19
+ def checked?
20
+ @gui.checked?
21
+ end
22
+
23
+ def checked=(value)
24
+ style(checked: value)
25
+ @gui.checked = value
26
+ end
27
+
28
+ def focus
29
+ @gui.focus
30
+ end
31
+
32
+ def state=(value)
33
+ style(state: value)
34
+ @gui.enabled value.nil?
35
+ end
36
+ end
37
+
38
+ class Check < CheckButton
39
+ style_with :checked, :click, :common_styles, :dimensions, :state
40
+ end
41
+ end
@@ -0,0 +1,387 @@
1
+ class Shoes
2
+ class Color
3
+ include Common::Inspect
4
+ include Comparable
5
+
6
+ OPAQUE = 255
7
+ TRANSPARENT = 0
8
+
9
+ def self.create(color)
10
+ color.is_a?(Color) ? color : new(color)
11
+ end
12
+
13
+ def initialize(*args) # red, green, blue, alpha = OPAQUE)
14
+ case args.length
15
+ when 1
16
+ red, green, blue, alpha = HexConverter.new(args.first).to_rgb
17
+ when 3, 4
18
+ red, green, blue, alpha = *args
19
+ else
20
+ message = <<EOS
21
+ Wrong number of arguments (#{args.length} for 1, 3, or 4).
22
+ Must be one of:
23
+ - #{self.class}.new(hex_string)
24
+ - #{self.class}.new(red, green, blue)
25
+ - #{self.class}.new(red, green, blue, alpha)
26
+ EOS
27
+ fail ArgumentError, message
28
+ end
29
+ alpha ||= OPAQUE
30
+ @red = normalize_rgb(red)
31
+ @green = normalize_rgb(green)
32
+ @blue = normalize_rgb(blue)
33
+ @alpha = normalize_rgb(alpha)
34
+ end
35
+
36
+ attr_reader :red, :green, :blue, :alpha
37
+
38
+ def light?
39
+ @red + @green + @blue > 510 # 0xaa * 3
40
+ end
41
+
42
+ def dark?
43
+ @red + @green + @blue < 255 # 0x55 * 3
44
+ end
45
+
46
+ def transparent?
47
+ @alpha == TRANSPARENT
48
+ end
49
+
50
+ def opaque?
51
+ @alpha == OPAQUE
52
+ end
53
+
54
+ def white?
55
+ @red == 255 && @green == 255 && @blue == 255
56
+ end
57
+
58
+ def black?
59
+ @red == 0 && @green == 0 && @blue == 0
60
+ end
61
+
62
+ def <=>(other)
63
+ raise_class_mismatch_error(other) unless other.is_a?(self.class)
64
+ if same_base_color?(other)
65
+ @alpha <=> other.alpha
66
+ else
67
+ less_or_greater_than other
68
+ end
69
+ end
70
+
71
+ # @return [String] a hex represenation of this color
72
+ # @example
73
+ # Shoes::Color.new(255, 0, 255).hex # => "#ff00ff"
74
+ def hex
75
+ format "#%02x%02x%02x", @red, @green, @blue
76
+ end
77
+
78
+ def to_s
79
+ "rgb(#{red}, #{green}, #{blue})"
80
+ end
81
+
82
+ def inspect
83
+ super.insert(-2, " #{self} alpha:#{@alpha}")
84
+ end
85
+
86
+ private
87
+
88
+ def normalize_rgb(value)
89
+ rgb = value.is_a?(Fixnum) ? value : (255 * value).round
90
+ return 255 if rgb > 255
91
+ return 0 if rgb < 0
92
+ rgb
93
+ end
94
+
95
+ def raise_class_mismatch_error(other)
96
+ fail ArgumentError,
97
+ "can't compare #{self.class.name} with #{other.class.name}"
98
+ end
99
+
100
+ def same_base_color?(other)
101
+ @red == other.red && @green == other.green && @blue == other.blue
102
+ end
103
+
104
+ def less_or_greater_than(other)
105
+ own_sum = @red + @green + @blue
106
+ other_sum = other.red + other.green + other.blue
107
+ if own_sum > other_sum
108
+ 1
109
+ else
110
+ -1
111
+ end
112
+ end
113
+
114
+ class HexConverter
115
+ def initialize(hex)
116
+ @hex = validate(hex) || fail(ArgumentError, "Bad hex color: #{hex}")
117
+ @red, @green, @blue = hex_to_rgb(pad_if_necessary @hex)
118
+ end
119
+
120
+ def to_rgb
121
+ [@red, @green, @blue]
122
+ end
123
+
124
+ private
125
+
126
+ def hex_to_rgb(hex)
127
+ hex.chars.each_slice(2).map { |a| a.join.to_i(16) }
128
+ end
129
+
130
+ def pad_if_necessary(hex)
131
+ return hex unless hex.length == 3
132
+ hex.chars.map { |c| "#{c}#{c}" }.join
133
+ end
134
+
135
+ # Returns a 3- or 6-char hex string for valid input, or nil
136
+ # for invalid input.
137
+ def validate(hex)
138
+ match = /^#?(([0-9a-f]{3}){1,2})$/i.match(hex)
139
+ match && match[1]
140
+ end
141
+ end
142
+
143
+ module DSLHelpers
144
+ def pattern(*args)
145
+ if args.length == 1
146
+ arg = args.first
147
+ case arg
148
+ when String
149
+ image_file?(arg) ? image_pattern(arg) : color(arg)
150
+ when Shoes::Color
151
+ color arg
152
+ when Range, Shoes::Gradient
153
+ gradient(arg)
154
+ when Shoes::ImagePattern
155
+ arg
156
+ else
157
+ fail ArgumentError, "Bad pattern: #{arg.inspect}"
158
+ end
159
+ else
160
+ gradient(*args)
161
+ end
162
+ end
163
+
164
+ def color(arg)
165
+ Shoes::Color.create(arg)
166
+ end
167
+
168
+ def rgb(red, green, blue, alpha = Shoes::Color::OPAQUE)
169
+ Shoes::Color.new(red, green, blue, alpha)
170
+ end
171
+
172
+ # Creates a new Shoes::Gradient
173
+ #
174
+ # @overload gradient(from, to)
175
+ # @param [Shoes::Color] from the starting color
176
+ # @param [Shoes::Color] to the ending color
177
+ #
178
+ # @overload gradient(from, to)
179
+ # @param [String] from a hex string representing the starting color
180
+ # @param [String] to a hex string representing the ending color
181
+ #
182
+ # @overload gradient(range)
183
+ # @param [Range<Shoes::Color>] range min color to max color
184
+ #
185
+ # @overload gradient(range)
186
+ # @param [Range<String>] range min color to max color
187
+ def gradient(*args)
188
+ case args.length
189
+ when 1
190
+ arg = args[0]
191
+ case arg
192
+ when Gradient
193
+ min, max = arg.color1, arg.color2
194
+ when Range
195
+ min, max = arg.first, arg.last
196
+ else
197
+ fail ArgumentError, "Can't make gradient out of #{arg.inspect}"
198
+ end
199
+ when 2
200
+ min, max = args[0], args[1]
201
+ else
202
+ fail ArgumentError, "Wrong number of arguments (#{args.length} for 1 or 2)"
203
+ end
204
+ Shoes::Gradient.new(color(min), color(max))
205
+ end
206
+
207
+ def gray(level = 128, alpha = Shoes::Color::OPAQUE)
208
+ Shoes::Color.new(level, level, level, alpha)
209
+ end
210
+
211
+ alias_method :grey, :gray
212
+
213
+ private
214
+
215
+ def image_file?(arg)
216
+ arg =~ /\.gif|jpg|jpeg|png$/
217
+ end
218
+
219
+ def image_pattern(path)
220
+ Shoes::ImagePattern.new path if File.exist?(path)
221
+ end
222
+ end
223
+ end
224
+
225
+ # Create all of the built-in Shoes colors
226
+ COLORS = {}
227
+
228
+ module DSL
229
+ colors = [
230
+ [:aliceblue, 240, 248, 255],
231
+ [:antiquewhite, 250, 235, 215],
232
+ [:aqua, 0, 255, 255],
233
+ [:aquamarine, 127, 255, 212],
234
+ [:azure, 240, 255, 255],
235
+ [:beige, 245, 245, 220],
236
+ [:bisque, 255, 228, 196],
237
+ [:black, 0, 0, 0],
238
+ [:blanchedalmond, 255, 235, 205],
239
+ [:blue, 0, 0, 255],
240
+ [:blueviolet, 138, 43, 226],
241
+ [:brown, 165, 42, 42],
242
+ [:burlywood, 222, 184, 135],
243
+ [:cadetblue, 95, 158, 160],
244
+ [:chartreuse, 127, 255, 0],
245
+ [:chocolate, 210, 105, 30],
246
+ [:coral, 255, 127, 80],
247
+ [:cornflowerblue, 100, 149, 237],
248
+ [:cornsilk, 255, 248, 220],
249
+ [:crimson, 220, 20, 60],
250
+ [:cyan, 0, 255, 255],
251
+ [:darkblue, 0, 0, 139],
252
+ [:darkcyan, 0, 139, 139],
253
+ [:darkgoldenrod, 184, 134, 11],
254
+ [:darkgray, 169, 169, 169],
255
+ [:darkgrey, 169, 169, 169],
256
+ [:darkgreen, 0, 100, 0],
257
+ [:darkkhaki, 189, 183, 107],
258
+ [:darkmagenta, 139, 0, 139],
259
+ [:darkolivegreen, 85, 107, 47],
260
+ [:darkorange, 255, 140, 0],
261
+ [:darkorchid, 153, 50, 204],
262
+ [:darkred, 139, 0, 0],
263
+ [:darksalmon, 233, 150, 122],
264
+ [:darkseagreen, 143, 188, 143],
265
+ [:darkslateblue, 72, 61, 139],
266
+ [:darkslategray, 47, 79, 79],
267
+ [:darkslategrey, 47, 79, 79],
268
+ [:darkturquoise, 0, 206, 209],
269
+ [:darkviolet, 148, 0, 211],
270
+ [:deeppink, 255, 20, 147],
271
+ [:deepskyblue, 0, 191, 255],
272
+ [:dimgray, 105, 105, 105],
273
+ [:dimgrey, 105, 105, 105],
274
+ [:dodgerblue, 30, 144, 255],
275
+ [:firebrick, 178, 34, 34],
276
+ [:floralwhite, 255, 250, 240],
277
+ [:forestgreen, 34, 139, 34],
278
+ [:fuchsia, 255, 0, 255],
279
+ [:gainsboro, 220, 220, 220],
280
+ [:ghostwhite, 248, 248, 255],
281
+ [:gold, 255, 215, 0],
282
+ [:goldenrod, 218, 165, 32],
283
+ [:green, 0, 128, 0],
284
+ [:greenyellow, 173, 255, 47],
285
+ [:honeydew, 240, 255, 240],
286
+ [:hotpink, 255, 105, 180],
287
+ [:indianred, 205, 92, 92],
288
+ [:indigo, 75, 0, 130],
289
+ [:ivory, 255, 255, 240],
290
+ [:khaki, 240, 230, 140],
291
+ [:lavender, 230, 230, 250],
292
+ [:lavenderblush, 255, 240, 245],
293
+ [:lawngreen, 124, 252, 0],
294
+ [:lemonchiffon, 255, 250, 205],
295
+ [:lightblue, 173, 216, 230],
296
+ [:lightcoral, 240, 128, 128],
297
+ [:lightcyan, 224, 255, 255],
298
+ [:lightgoldenrodyellow, 250, 250, 210],
299
+ [:lightgreen, 144, 238, 144],
300
+ [:lightgray, 211, 211, 211],
301
+ [:lightgrey, 211, 211, 211],
302
+ [:lightpink, 255, 182, 193],
303
+ [:lightsalmon, 255, 160, 122],
304
+ [:lightseagreen, 32, 178, 170],
305
+ [:lightskyblue, 135, 206, 250],
306
+ [:lightslategray, 119, 136, 153],
307
+ [:lightslategrey, 119, 136, 153],
308
+ [:lightsteelblue, 176, 196, 222],
309
+ [:lightyellow, 255, 255, 224],
310
+ [:lime, 0, 255, 0],
311
+ [:limegreen, 50, 205, 50],
312
+ [:linen, 250, 240, 230],
313
+ [:magenta, 255, 0, 255],
314
+ [:maroon, 128, 0, 0],
315
+ [:mediumaquamarine, 102, 205, 170],
316
+ [:mediumblue, 0, 0, 205],
317
+ [:mediumorchid, 186, 85, 211],
318
+ [:mediumpurple, 147, 112, 219],
319
+ [:mediumseagreen, 60, 179, 113],
320
+ [:mediumslateblue, 123, 104, 238],
321
+ [:mediumspringgreen, 0, 250, 154],
322
+ [:mediumturquoise, 72, 209, 204],
323
+ [:mediumvioletred, 199, 21, 133],
324
+ [:midnightblue, 25, 25, 112],
325
+ [:mintcream, 245, 255, 250],
326
+ [:mistyrose, 255, 228, 225],
327
+ [:moccasin, 255, 228, 181],
328
+ [:navajowhite, 255, 222, 173],
329
+ [:navy, 0, 0, 128],
330
+ [:oldlace, 253, 245, 230],
331
+ [:olive, 128, 128, 0],
332
+ [:olivedrab, 107, 142, 35],
333
+ [:orange, 255, 165, 0],
334
+ [:orangered, 255, 69, 0],
335
+ [:orchid, 218, 112, 214],
336
+ [:palegoldenrod, 238, 232, 170],
337
+ [:palegreen, 152, 251, 152],
338
+ [:paleturquoise, 175, 238, 238],
339
+ [:palevioletred, 219, 112, 147],
340
+ [:papayawhip, 255, 239, 213],
341
+ [:peachpuff, 255, 218, 185],
342
+ [:peru, 205, 133, 63],
343
+ [:pink, 255, 192, 203],
344
+ [:plum, 221, 160, 221],
345
+ [:powderblue, 176, 224, 230],
346
+ [:purple, 128, 0, 128],
347
+ [:red, 255, 0, 0],
348
+ [:rosybrown, 188, 143, 143],
349
+ [:royalblue, 65, 105, 225],
350
+ [:saddlebrown, 139, 69, 19],
351
+ [:salmon, 250, 128, 114],
352
+ [:sandybrown, 244, 164, 96],
353
+ [:seagreen, 46, 139, 87],
354
+ [:seashell, 255, 245, 238],
355
+ [:sienna, 160, 82, 45],
356
+ [:silver, 192, 192, 192],
357
+ [:skyblue, 135, 206, 235],
358
+ [:slateblue, 106, 90, 205],
359
+ [:slategray, 112, 128, 144],
360
+ [:slategrey, 112, 128, 144],
361
+ [:snow, 255, 250, 250],
362
+ [:springgreen, 0, 255, 127],
363
+ [:steelblue, 70, 130, 180],
364
+ [:tan, 210, 180, 140],
365
+ [:teal, 0, 128, 128],
366
+ [:thistle, 216, 191, 216],
367
+ [:tomato, 255, 99, 71],
368
+ [:turquoise, 64, 224, 208],
369
+ [:violet, 238, 130, 238],
370
+ [:wheat, 245, 222, 179],
371
+ [:white, 255, 255, 255],
372
+ [:whitesmoke, 245, 245, 245],
373
+ [:yellow, 255, 255, 0],
374
+ [:yellowgreen, 154, 205, 50],
375
+ [:shoes_background, 237, 237, 237],
376
+ ]
377
+
378
+ colors.each do |color_name, r, g, b|
379
+ Shoes::COLORS[color_name] = Shoes::Color.new(r, g, b)
380
+ define_method(color_name) do |alpha = Shoes::Color::OPAQUE|
381
+ color = Shoes::COLORS.fetch(color_name)
382
+ return color if alpha == Shoes::Color::OPAQUE
383
+ Shoes::Color.new(color.red, color.green, color.blue, alpha)
384
+ end
385
+ end
386
+ end
387
+ end