shoes-dsl 4.0.0.pre2

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 (209) hide show
  1. checksums.yaml +7 -0
  2. data/CHANGELOG +84 -0
  3. data/Gemfile +24 -0
  4. data/Guardfile +11 -0
  5. data/LICENSE +31 -0
  6. data/README.md +201 -0
  7. data/ext/install/Rakefile +29 -0
  8. data/ext/install/shoes.bat +9 -0
  9. data/fonts/Coolvetica.ttf +0 -0
  10. data/fonts/Lacuna.ttf +0 -0
  11. data/lib/shoes/animation.rb +56 -0
  12. data/lib/shoes/app.rb +131 -0
  13. data/lib/shoes/arc.rb +25 -0
  14. data/lib/shoes/background.rb +24 -0
  15. data/lib/shoes/border.rb +24 -0
  16. data/lib/shoes/builtin_methods.rb +77 -0
  17. data/lib/shoes/button.rb +30 -0
  18. data/lib/shoes/check_button.rb +44 -0
  19. data/lib/shoes/color.rb +385 -0
  20. data/lib/shoes/common/background_element.rb +9 -0
  21. data/lib/shoes/common/changeable.rb +34 -0
  22. data/lib/shoes/common/clickable.rb +24 -0
  23. data/lib/shoes/common/inspect.rb +14 -0
  24. data/lib/shoes/common/positioning.rb +30 -0
  25. data/lib/shoes/common/registration.rb +33 -0
  26. data/lib/shoes/common/remove.rb +10 -0
  27. data/lib/shoes/common/state.rb +18 -0
  28. data/lib/shoes/common/style.rb +152 -0
  29. data/lib/shoes/common/style_normalizer.rb +16 -0
  30. data/lib/shoes/common/ui_element.rb +11 -0
  31. data/lib/shoes/common/visibility.rb +40 -0
  32. data/lib/shoes/configuration.rb +96 -0
  33. data/lib/shoes/dialog.rb +27 -0
  34. data/lib/shoes/dimension.rb +239 -0
  35. data/lib/shoes/dimensions.rb +209 -0
  36. data/lib/shoes/download.rb +121 -0
  37. data/lib/shoes/dsl.rb +591 -0
  38. data/lib/shoes/font.rb +49 -0
  39. data/lib/shoes/gradient.rb +31 -0
  40. data/lib/shoes/image.rb +29 -0
  41. data/lib/shoes/image_pattern.rb +12 -0
  42. data/lib/shoes/input_box.rb +60 -0
  43. data/lib/shoes/internal_app.rb +219 -0
  44. data/lib/shoes/key_event.rb +17 -0
  45. data/lib/shoes/line.rb +87 -0
  46. data/lib/shoes/link.rb +59 -0
  47. data/lib/shoes/link_hover.rb +5 -0
  48. data/lib/shoes/list_box.rb +50 -0
  49. data/lib/shoes/logger.rb +66 -0
  50. data/lib/shoes/logger/ruby.rb +18 -0
  51. data/lib/shoes/mock.rb +31 -0
  52. data/lib/shoes/mock/animation.rb +8 -0
  53. data/lib/shoes/mock/app.rb +47 -0
  54. data/lib/shoes/mock/arc.rb +9 -0
  55. data/lib/shoes/mock/background.rb +10 -0
  56. data/lib/shoes/mock/border.rb +7 -0
  57. data/lib/shoes/mock/button.rb +10 -0
  58. data/lib/shoes/mock/check.rb +25 -0
  59. data/lib/shoes/mock/clickable.rb +8 -0
  60. data/lib/shoes/mock/common_methods.rb +12 -0
  61. data/lib/shoes/mock/dialog.rb +13 -0
  62. data/lib/shoes/mock/download.rb +18 -0
  63. data/lib/shoes/mock/font.rb +17 -0
  64. data/lib/shoes/mock/image.rb +13 -0
  65. data/lib/shoes/mock/image_pattern.rb +9 -0
  66. data/lib/shoes/mock/input_box.rb +30 -0
  67. data/lib/shoes/mock/keypress.rb +10 -0
  68. data/lib/shoes/mock/keyrelease.rb +10 -0
  69. data/lib/shoes/mock/line.rb +14 -0
  70. data/lib/shoes/mock/link.rb +12 -0
  71. data/lib/shoes/mock/list_box.rb +19 -0
  72. data/lib/shoes/mock/oval.rb +12 -0
  73. data/lib/shoes/mock/progress.rb +10 -0
  74. data/lib/shoes/mock/radio.rb +27 -0
  75. data/lib/shoes/mock/rect.rb +14 -0
  76. data/lib/shoes/mock/shape.rb +20 -0
  77. data/lib/shoes/mock/slot.rb +16 -0
  78. data/lib/shoes/mock/sound.rb +8 -0
  79. data/lib/shoes/mock/star.rb +14 -0
  80. data/lib/shoes/mock/text_block.rb +36 -0
  81. data/lib/shoes/mock/timer.rb +8 -0
  82. data/lib/shoes/not_implemented_error.rb +4 -0
  83. data/lib/shoes/oval.rb +20 -0
  84. data/lib/shoes/point.rb +54 -0
  85. data/lib/shoes/progress.rb +25 -0
  86. data/lib/shoes/radio.rb +16 -0
  87. data/lib/shoes/rect.rb +21 -0
  88. data/lib/shoes/renamed_delegate.rb +15 -0
  89. data/lib/shoes/shape.rb +158 -0
  90. data/lib/shoes/slot.rb +271 -0
  91. data/lib/shoes/slot_contents.rb +50 -0
  92. data/lib/shoes/sound.rb +18 -0
  93. data/lib/shoes/span.rb +16 -0
  94. data/lib/shoes/star.rb +45 -0
  95. data/lib/shoes/text.rb +24 -0
  96. data/lib/shoes/text_block.rb +143 -0
  97. data/lib/shoes/text_block_dimensions.rb +52 -0
  98. data/lib/shoes/timer.rb +12 -0
  99. data/lib/shoes/url.rb +44 -0
  100. data/lib/shoes/version.rb +3 -0
  101. data/lib/shoes/widget.rb +69 -0
  102. data/manifests/common.rb +34 -0
  103. data/manifests/shoes-dsl.rb +34 -0
  104. data/shoes-dsl.gemspec +19 -0
  105. data/spec/code_coverage.rb +14 -0
  106. data/spec/shoes/animation_spec.rb +65 -0
  107. data/spec/shoes/app_spec.rb +484 -0
  108. data/spec/shoes/arc_spec.rb +51 -0
  109. data/spec/shoes/background_spec.rb +53 -0
  110. data/spec/shoes/border_spec.rb +47 -0
  111. data/spec/shoes/builtin_methods_spec.rb +110 -0
  112. data/spec/shoes/button_spec.rb +44 -0
  113. data/spec/shoes/check_spec.rb +35 -0
  114. data/spec/shoes/cli_spec.rb +15 -0
  115. data/spec/shoes/color_spec.rb +408 -0
  116. data/spec/shoes/common/inspect_spec.rb +26 -0
  117. data/spec/shoes/common/remove_spec.rb +38 -0
  118. data/spec/shoes/common/style_normalizer_spec.rb +28 -0
  119. data/spec/shoes/common/style_spec.rb +147 -0
  120. data/spec/shoes/configuration_spec.rb +36 -0
  121. data/spec/shoes/constants_spec.rb +38 -0
  122. data/spec/shoes/dialog_spec.rb +163 -0
  123. data/spec/shoes/dimension_spec.rb +407 -0
  124. data/spec/shoes/dimensions_spec.rb +837 -0
  125. data/spec/shoes/download_spec.rb +142 -0
  126. data/spec/shoes/flow_spec.rb +133 -0
  127. data/spec/shoes/font_spec.rb +37 -0
  128. data/spec/shoes/framework_learning_spec.rb +30 -0
  129. data/spec/shoes/gradient_spec.rb +32 -0
  130. data/spec/shoes/helpers/fake_element.rb +17 -0
  131. data/spec/shoes/helpers/inspect_helpers.rb +5 -0
  132. data/spec/shoes/helpers/sample17_helper.rb +66 -0
  133. data/spec/shoes/image_spec.rb +49 -0
  134. data/spec/shoes/images/shoe.jpg +0 -0
  135. data/spec/shoes/input_box_spec.rb +80 -0
  136. data/spec/shoes/integration_spec.rb +20 -0
  137. data/spec/shoes/internal_app_spec.rb +141 -0
  138. data/spec/shoes/keypress_spec.rb +11 -0
  139. data/spec/shoes/keyrelease_spec.rb +12 -0
  140. data/spec/shoes/line_spec.rb +49 -0
  141. data/spec/shoes/link_spec.rb +105 -0
  142. data/spec/shoes/list_box_spec.rb +74 -0
  143. data/spec/shoes/logger/ruby_spec.rb +8 -0
  144. data/spec/shoes/logger_spec.rb +45 -0
  145. data/spec/shoes/oval_spec.rb +24 -0
  146. data/spec/shoes/point_spec.rb +71 -0
  147. data/spec/shoes/progress_spec.rb +54 -0
  148. data/spec/shoes/radio_spec.rb +32 -0
  149. data/spec/shoes/rect_spec.rb +39 -0
  150. data/spec/shoes/renamed_delegate_spec.rb +70 -0
  151. data/spec/shoes/shape_spec.rb +95 -0
  152. data/spec/shoes/shared_examples/button.rb +6 -0
  153. data/spec/shoes/shared_examples/changeable.rb +26 -0
  154. data/spec/shoes/shared_examples/clickable.rb +5 -0
  155. data/spec/shoes/shared_examples/common_methods.rb +35 -0
  156. data/spec/shoes/shared_examples/dimensions.rb +32 -0
  157. data/spec/shoes/shared_examples/dsl.rb +44 -0
  158. data/spec/shoes/shared_examples/dsl/animate.rb +29 -0
  159. data/spec/shoes/shared_examples/dsl/arc.rb +45 -0
  160. data/spec/shoes/shared_examples/dsl/background.rb +26 -0
  161. data/spec/shoes/shared_examples/dsl/border.rb +10 -0
  162. data/spec/shoes/shared_examples/dsl/button.rb +5 -0
  163. data/spec/shoes/shared_examples/dsl/cap.rb +6 -0
  164. data/spec/shoes/shared_examples/dsl/check.rb +11 -0
  165. data/spec/shoes/shared_examples/dsl/edit_box.rb +8 -0
  166. data/spec/shoes/shared_examples/dsl/edit_line.rb +8 -0
  167. data/spec/shoes/shared_examples/dsl/editable_element.rb +29 -0
  168. data/spec/shoes/shared_examples/dsl/fill.rb +27 -0
  169. data/spec/shoes/shared_examples/dsl/flow.rb +15 -0
  170. data/spec/shoes/shared_examples/dsl/gradient.rb +62 -0
  171. data/spec/shoes/shared_examples/dsl/image.rb +21 -0
  172. data/spec/shoes/shared_examples/dsl/line.rb +9 -0
  173. data/spec/shoes/shared_examples/dsl/nofill.rb +6 -0
  174. data/spec/shoes/shared_examples/dsl/nostroke.rb +6 -0
  175. data/spec/shoes/shared_examples/dsl/oval.rb +88 -0
  176. data/spec/shoes/shared_examples/dsl/pattern.rb +34 -0
  177. data/spec/shoes/shared_examples/dsl/progress.rb +7 -0
  178. data/spec/shoes/shared_examples/dsl/rect.rb +92 -0
  179. data/spec/shoes/shared_examples/dsl/rgb.rb +26 -0
  180. data/spec/shoes/shared_examples/dsl/shape.rb +21 -0
  181. data/spec/shoes/shared_examples/dsl/star.rb +48 -0
  182. data/spec/shoes/shared_examples/dsl/stroke.rb +30 -0
  183. data/spec/shoes/shared_examples/dsl/strokewidth.rb +19 -0
  184. data/spec/shoes/shared_examples/dsl/style.rb +32 -0
  185. data/spec/shoes/shared_examples/dsl/text_elements.rb +81 -0
  186. data/spec/shoes/shared_examples/dsl/video.rb +5 -0
  187. data/spec/shoes/shared_examples/dsl_app_context.rb +8 -0
  188. data/spec/shoes/shared_examples/hover_leave.rb +11 -0
  189. data/spec/shoes/shared_examples/parent.rb +6 -0
  190. data/spec/shoes/shared_examples/scroll.rb +41 -0
  191. data/spec/shoes/shared_examples/shared_element_method.rb +60 -0
  192. data/spec/shoes/shared_examples/slot.rb +331 -0
  193. data/spec/shoes/shared_examples/state.rb +19 -0
  194. data/spec/shoes/shared_examples/style.rb +82 -0
  195. data/spec/shoes/slot_spec.rb +130 -0
  196. data/spec/shoes/sound_spec.rb +15 -0
  197. data/spec/shoes/span_spec.rb +112 -0
  198. data/spec/shoes/spec_helper.rb +24 -0
  199. data/spec/shoes/stack_spec.rb +79 -0
  200. data/spec/shoes/star_spec.rb +31 -0
  201. data/spec/shoes/text_block_dimensions_spec.rb +75 -0
  202. data/spec/shoes/text_block_spec.rb +270 -0
  203. data/spec/shoes/url_spec.rb +68 -0
  204. data/spec/shoes/widget_spec.rb +70 -0
  205. data/spec/shoes_spec.rb +44 -0
  206. data/spec/spec_helper.rb +18 -0
  207. data/static/Shoes.icns +0 -0
  208. data/static/shoes-icon.png +0 -0
  209. metadata +354 -0
@@ -0,0 +1,121 @@
1
+ class Shoes
2
+ class HttpResponse
3
+ # Struct might be better?
4
+ attr_accessor :headers, :body, :status
5
+ def initalize
6
+ @headers = {}
7
+ @body = ''
8
+ @status = []
9
+ end
10
+ end
11
+
12
+ class Download
13
+
14
+ attr_reader :progress, :response, :content_length, :gui, :transferred
15
+ UPDATE_STEPS = 100
16
+
17
+ def initialize(app, parent, url, opts = {}, &blk)
18
+ @url = url
19
+ @opts = opts
20
+ @blk = blk
21
+ @gui = Shoes.configuration.backend_for(self)
22
+
23
+ @response = HttpResponse.new
24
+ @finished = false
25
+ @transferred = 0
26
+ @content_length = 1 # non zero initialized to avoid Zero Div Errors
27
+ end
28
+
29
+ def start
30
+ start_download
31
+ end
32
+
33
+ def started?
34
+ @started
35
+ end
36
+
37
+ def finished?
38
+ @finished
39
+ end
40
+
41
+ # needed for the specs (jay multi threading and specs)
42
+ def join_thread
43
+ @thread.join unless @thread.nil?
44
+ end
45
+
46
+ def percent
47
+ @transferred * 100 / @content_length
48
+ end
49
+
50
+ def abort
51
+ @thread.exit if @thread
52
+ end
53
+
54
+ # shoes 3 compatibility
55
+ def length
56
+ @content_length
57
+ end
58
+
59
+ private
60
+ def start_download
61
+ require 'open-uri'
62
+ @thread = Thread.new do
63
+ uri_opts = {}
64
+ uri_opts[:content_length_proc] = content_length_proc
65
+ uri_opts[:progress_proc] = progress_proc if @opts[:progress]
66
+
67
+ open @url, uri_opts do |download_data|
68
+ @response.body = download_data.read
69
+ @response.status = download_data.status
70
+ @response.headers = download_data.meta
71
+ save_to_file(@opts[:save]) if @opts[:save]
72
+ finish_download download_data
73
+ end
74
+ end
75
+ end
76
+
77
+ def content_length_proc
78
+ lambda do |content_length|
79
+ download_started(content_length)
80
+ eval_block(@opts[:progress], self) if @opts[:progress]
81
+ end
82
+ end
83
+
84
+ def progress_proc
85
+ lambda do |size|
86
+ if !content_length.nil? &&
87
+ (size - self.transferred) > (content_length / UPDATE_STEPS) &&
88
+ !@gui.busy?
89
+ @gui.busy = true
90
+ eval_block(@opts[:progress], self)
91
+ @transferred = size
92
+ end
93
+ end
94
+ end
95
+
96
+ def finish_download(download_data)
97
+ @finished = true
98
+
99
+ #In case backend didn't catch the 100%
100
+ @transferred = @content_length
101
+ eval_block(@opts[:progress], self) if @opts[:progress]
102
+
103
+ #:finish and block are the same
104
+ eval_block(@blk, self) if @blk
105
+ eval_block(@opts[:finish], self) if @opts[:finish]
106
+ end
107
+
108
+ def eval_block(blk, result)
109
+ @gui.eval_block(blk, result)
110
+ end
111
+
112
+ def save_to_file(file_path)
113
+ open(file_path, 'wb') { |fw| fw.print @response.body }
114
+ end
115
+
116
+ def download_started(content_length)
117
+ @content_length = content_length
118
+ @started = true
119
+ end
120
+ end
121
+ end
@@ -0,0 +1,591 @@
1
+ require 'forwardable'
2
+ require 'pathname'
3
+ require 'shoes/common/registration'
4
+
5
+ class Shoes
6
+ PI = Math::PI
7
+ TWO_PI = 2 * PI
8
+ HALF_PI = 0.5 * PI
9
+ DIR = Pathname.new(__FILE__).parent.parent.parent.to_s
10
+ LOG = []
11
+ LEFT_MOUSE_BUTTON = 1
12
+ MIDDLE_MOUSE_BUTTON = 2
13
+ RIGHT_MOUSE_BUTTON = 3
14
+
15
+ extend Common::Registration
16
+
17
+ class << self
18
+
19
+ def logger
20
+ Shoes.configuration.logger_instance
21
+ end
22
+
23
+ # To ease the upgrade path from Shoes 3 we warn users they need to install
24
+ # and require gems themselves.
25
+ #
26
+ # @example
27
+ # Shoes.setup do
28
+ # gem 'bluecloth =2.0.6'
29
+ # gem 'metaid'
30
+ # end
31
+ #
32
+ # @param block [Proc] The block that describes the gems that are needed
33
+ # @deprecated
34
+ def setup(&block)
35
+ $stderr.puts "WARN: The Shoes.setup method is deprecated, you need to install gems yourself." +
36
+ "You can do this using the 'gem install' command or bundler and a Gemfile."
37
+ DeprecatedShoesGemSetup.new.instance_eval(&block)
38
+ end
39
+
40
+ # Load the backend in memory. This does not set any configuration.
41
+ #
42
+ # @param name [String|Symbol] The name, such as :swt or :mock
43
+ # @return The backend
44
+ def load_backend(name)
45
+ begin
46
+ require "shoes/#{name.to_s.downcase}"
47
+ Shoes.const_get(name.to_s.capitalize)
48
+ rescue LoadError => e
49
+ raise LoadError, "Couldn't load backend Shoes::#{name.capitalize}'. Error: #{e.message}\n#{e.backtrace.join("\n")}"
50
+ end
51
+ end
52
+ end
53
+
54
+ class DeprecatedShoesGemSetup
55
+ def gem(name)
56
+ name, version = name.split()
57
+ install_cmd = 'gem install ' + name
58
+ install_cmd += " --version \"#{version}\"" if version
59
+ $stderr.puts "WARN: To use the '#{name}' gem, install it with '#{install_cmd}', and put 'require \"#{name}\"' at the top of your Shoes program."
60
+ end
61
+ end
62
+ end
63
+
64
+ require 'shoes/version'
65
+ require 'shoes/renamed_delegate'
66
+ require 'shoes/common/inspect'
67
+ require 'shoes/dimension'
68
+ require 'shoes/dimensions'
69
+ require 'shoes/not_implemented_error'
70
+ require 'shoes/text_block_dimensions'
71
+
72
+ require 'shoes/color'
73
+
74
+ require 'shoes/common/background_element'
75
+ require 'shoes/common/changeable'
76
+ require 'shoes/common/clickable'
77
+ require 'shoes/common/positioning'
78
+ require 'shoes/common/remove'
79
+ require 'shoes/common/state'
80
+ require 'shoes/common/style'
81
+ require 'shoes/common/style_normalizer'
82
+ require 'shoes/common/visibility'
83
+
84
+ require 'shoes/common/ui_element'
85
+
86
+ require 'shoes/builtin_methods'
87
+ require 'shoes/check_button'
88
+ require 'shoes/text'
89
+ require 'shoes/span'
90
+ require 'shoes/input_box'
91
+
92
+ # please keep this list tidy and alphabetically sorted
93
+ require 'shoes/animation'
94
+ require 'shoes/arc'
95
+ require 'shoes/background'
96
+ require 'shoes/border'
97
+ require 'shoes/button'
98
+ require 'shoes/configuration'
99
+ require 'shoes/color'
100
+ require 'shoes/dialog'
101
+ require 'shoes/download'
102
+ require 'shoes/font'
103
+ require 'shoes/gradient'
104
+ require 'shoes/image'
105
+ require 'shoes/image_pattern'
106
+ require 'shoes/key_event'
107
+ require 'shoes/line'
108
+ require 'shoes/link'
109
+ require 'shoes/link_hover'
110
+ require 'shoes/list_box'
111
+ require 'shoes/logger'
112
+ require 'shoes/oval'
113
+ require 'shoes/point'
114
+ require 'shoes/progress'
115
+ require 'shoes/radio'
116
+ require 'shoes/rect'
117
+ require 'shoes/shape'
118
+ require 'shoes/slot_contents'
119
+ require 'shoes/slot'
120
+ require 'shoes/star'
121
+ require 'shoes/sound'
122
+ require 'shoes/text_block'
123
+ require 'shoes/timer'
124
+
125
+ class Shoes
126
+ # Methods for creating and manipulating Shoes elements
127
+ #
128
+ # Requirements
129
+ #
130
+ # Including classes must provide:
131
+ #
132
+ # @__app__
133
+ #
134
+ # which provides
135
+ # #style: a hash of styles
136
+ # #element_styles: a hash of {Class => styles}, where styles is
137
+ # a hash of default styles for elements of Class,
138
+ module DSL
139
+ include Common::Style
140
+ include Color::DSLHelpers
141
+
142
+ # Set default style for elements of a particular class, or for all
143
+ # elements, or return the current defaults for all elements
144
+ #
145
+ # @overload style(klass, styles)
146
+ # Set default style for elements of a particular class
147
+ # @param [Class] klass a Shoes element class
148
+ # @param [Hash] styles default styles for elements of klass
149
+ # @example
150
+ # style Para, :text_size => 42, :stroke => green
151
+ #
152
+ # @overload style(styles)
153
+ # Set default style for all elements
154
+ # @param [Hash] styles default style for all elements
155
+ # @example
156
+ # style :stroke => alicewhite, :fill => black
157
+ #
158
+ # @overload style()
159
+ # @return [Hash] the default style for all elements
160
+ def style(klass_or_styles = nil, styles = {})
161
+ if klass_or_styles.kind_of? Class
162
+ klass = klass_or_styles
163
+ @__app__.element_styles[klass] = styles
164
+ else
165
+ @__app__.style(klass_or_styles)
166
+ end
167
+ end
168
+
169
+ private
170
+
171
+ def style_normalizer
172
+ @style_normalizer ||= Common::StyleNormalizer.new
173
+ end
174
+
175
+ def pop_style(opts)
176
+ opts.last.class == Hash ? opts.pop : {}
177
+ end
178
+
179
+ # Default styles for elements of klass
180
+ def style_for_element(klass, styles = {})
181
+ @__app__.element_styles.fetch(klass, {}).merge(styles)
182
+ end
183
+
184
+ def normalize_style_for_element(clazz, texts)
185
+ style = style_normalizer.normalize(pop_style(texts))
186
+ style_for_element(clazz, style)
187
+ end
188
+
189
+ def create(element, *args, &blk)
190
+ element.new(@__app__, @__app__.current_slot, *args, &blk)
191
+ end
192
+
193
+ public
194
+
195
+ def image(path, styles = {}, &blk)
196
+ create Shoes::Image, path, styles, blk
197
+ end
198
+
199
+ def border(color, styles = {})
200
+ create Shoes::Border, pattern(color), styles
201
+ end
202
+
203
+ def background(color, styles = {})
204
+ create Shoes::Background, pattern(color), style_normalizer.normalize(styles)
205
+ end
206
+
207
+ def edit_line(*args, &blk)
208
+ style = pop_style(args)
209
+ text = args.first || ''
210
+ create Shoes::EditLine, text, style, blk
211
+ end
212
+
213
+ def edit_box(*args, &blk)
214
+ style = pop_style(args)
215
+ text = args.first || ''
216
+ create Shoes::EditBox, text, style, blk
217
+ end
218
+
219
+ def progress(opts = {}, &blk)
220
+ create Shoes::Progress, opts, blk
221
+ end
222
+
223
+ def check(opts = {}, &blk)
224
+ create Shoes::Check, opts, blk
225
+ end
226
+
227
+ def radio(*args, &blk)
228
+ style = pop_style(args)
229
+ group = args.first
230
+ create Shoes::Radio, group, style, blk
231
+ end
232
+
233
+ def list_box(opts = {}, &blk)
234
+ create Shoes::ListBox, opts, blk
235
+ end
236
+
237
+ def flow(opts = {}, &blk)
238
+ create Shoes::Flow, opts, blk
239
+ end
240
+
241
+ def stack(opts = {}, &blk)
242
+ create Shoes::Stack, opts, blk
243
+ end
244
+
245
+ def button(text = 'Button', opts={}, &blk)
246
+ create Shoes::Button, text, opts, blk
247
+ end
248
+
249
+ # Creates an animation that runs the given block of code.
250
+ #
251
+ # @overload animate &blk
252
+ # @param [Proc] blk Code to run for each animation frame
253
+ # @return [Shoes::Animation]
254
+ # Defaults to framerate of 24 frames per second
255
+ # @example
256
+ # # 24 frames per second
257
+ # animate do
258
+ # # animation code
259
+ # end
260
+ # @overload animate(framerate, &blk)
261
+ # @param [Integer] framerate Frames per second
262
+ # @param [Proc] blk Code to run for each animation frame
263
+ # @return [Shoes::Animation]
264
+ # @example
265
+ # # 10 frames per second
266
+ # animate 10 do
267
+ # # animation code
268
+ # end
269
+ # @overload animate(opts = {}, &blk)
270
+ # @param [Hash] opts Animation options
271
+ # @param [Proc] blk Code to run for each animation frame
272
+ # @option opts [Integer] :framerate Frames per second
273
+ # @return [Shoes::Animation]
274
+ # @example
275
+ # # 10 frames per second
276
+ # animate :framerate => 10 do
277
+ # # animation code
278
+ # end
279
+ #
280
+ def animate(opts = {}, &blk)
281
+ opts = {:framerate => opts} unless opts.is_a? Hash
282
+ Shoes::Animation.new @__app__, opts, blk
283
+ end
284
+
285
+ def every(n=1, &blk)
286
+ animate 1.0/n, &blk
287
+ end
288
+
289
+ def timer(n=1, &blk)
290
+ n *= 1000
291
+ Timer.new @__app__, n, &blk
292
+ end
293
+
294
+ # similar controls as Shoes::Video (#video)
295
+ def sound(soundfile, opts = {}, &blk)
296
+ Shoes::Sound.new @__app__, soundfile, opts, &blk
297
+ end
298
+
299
+ # Creates an arc at (left, top)
300
+ #
301
+ # @param [Integer] left the x-coordinate of the top-left corner
302
+ # @param [Integer] top the y-coordinate of the top-left corner
303
+ # @param [Integer] width width of the arc's ellipse
304
+ # @param [Integer] height height of the arc's ellipse
305
+ # @param [Float] angle1 angle in radians marking the beginning of the arc segment
306
+ # @param [Float] angle2 angle in radians marking the end of the arc segment
307
+ # @param [Hash] opts Arc style options
308
+ # @option opts [Boolean] wedge (false)
309
+ # @option opts [Boolean] center (false) is (left, top) the center of the rectangle?
310
+ def arc(left, top, width, height, angle1, angle2, styles = {}, &blk)
311
+ create Shoes::Arc, left, top, width, height, angle1, angle2, styles, blk
312
+ end
313
+
314
+ # Draws a line from point A (x1,y1) to point B (x2,y2)
315
+ #
316
+ # @param [Integer] x1 The x-value of point A
317
+ # @param [Integer] y1 The y-value of point A
318
+ # @param [Integer] x2 The x-value of point B
319
+ # @param [Integer] y2 The y-value of point B
320
+ # @param [Hash] opts Style options
321
+ def line(x1, y1, x2, y2, styles = {}, &blk)
322
+ create Shoes::Line, Shoes::Point.new(x1, y1), Shoes::Point.new(x2, y2), styles, blk
323
+ end
324
+
325
+ # Creates an oval at (left, top)
326
+ #
327
+ # @overload oval(left, top, diameter)
328
+ # Creates a circle at (left, top), with the given diameter
329
+ # @param [Integer] left the x-coordinate of the top-left corner
330
+ # @param [Integer] top the y-coordinate of the top-left corner
331
+ # @param [Integer] diameter the diameter
332
+ # @overload oval(left, top, width, height)
333
+ # Creates an oval at (left, top), with the given width and height
334
+ # @param [Integer] left the x-coordinate of the top-left corner
335
+ # @param [Integer] top the y-coordinate of the top-left corner
336
+ # @param [Integer] width the width
337
+ # @param [Integer] height the height
338
+ # @overload oval(styles)
339
+ # Creates an oval using values from the styles Hash.
340
+ # @param [Hash] styles
341
+ # @option styles [Integer] left (0) the x-coordinate of the top-left corner
342
+ # @option styles [Integer] top (0) the y-coordinate of the top-left corner
343
+ # @option styles [Integer] width (0) the width
344
+ # @option styles [Integer] height (0) the height
345
+ # @option styles [Integer] top (0) the y-coordinate of the top-left corner
346
+ # @option styles [Boolean] center (false) is (left, top) the center of the oval
347
+ def oval(*opts, &blk)
348
+ oval_style = pop_style(opts)
349
+ oval_style = style_normalizer.normalize(oval_style)
350
+ case opts.length
351
+ when 3
352
+ left, top, width = opts
353
+ height = width
354
+ when 4
355
+ left, top, width, height = opts
356
+ when 0
357
+ left = oval_style[:left] || 0
358
+ top = oval_style[:top] || 0
359
+ width = oval_style[:diameter] || oval_style[:width] ||
360
+ (oval_style[:radius] || 0) * 2
361
+ height = oval_style[:height] || width
362
+ else
363
+ message = <<EOS
364
+ Wrong number of arguments. Must be one of:
365
+ - oval(left, top, diameter, [opts])
366
+ - oval(left, top, width, height, [opts])
367
+ - oval(styles)
368
+ EOS
369
+ raise ArgumentError, message
370
+ end
371
+ create Shoes::Oval, left, top, width, height, oval_style, blk
372
+ end
373
+
374
+ # Creates a rectangle
375
+ #
376
+ # @overload rect(left, top, side, styles)
377
+ # Creates a square at (left, top), with sides of the given length
378
+ # @param [Integer] left the x-coordinate of the top-left corner
379
+ # @param [Integer] top the y-coordinate of the top-left corner
380
+ # @param [Integer] side the length of a side
381
+ # @overload rect(left, top, width, height, rounded = 0, styles)
382
+ # Creates a rectangle at (left, top), with the given width and height
383
+ # @param [Integer] left the x-coordinate of the top-left corner
384
+ # @param [Integer] top the y-coordinate of the top-left corner
385
+ # @param [Integer] width the width
386
+ # @param [Integer] height the height
387
+ # @overload rect(styles)
388
+ # Creates a rectangle using values from the styles Hash.
389
+ # @param [Hash] styles
390
+ # @option styles [Integer] left (0) the x-coordinate of the top-left corner
391
+ # @option styles [Integer] top (0) the y-coordinate of the top-left corner
392
+ # @option styles [Integer] width (0) the width
393
+ # @option styles [Integer] height (0) the height
394
+ # @option styles [Integer] top (0) the y-coordinate of the top-left corner
395
+ # @option styles [Boolean] center (false) is (left, top) the center of the rectangle?
396
+ def rect(*args, &blk)
397
+ opts = style_normalizer.normalize pop_style(args)
398
+ case args.length
399
+ when 3
400
+ left, top, width = args
401
+ height = width
402
+ opts[:curve] ||= 0
403
+ when 4
404
+ left, top, width, height = args
405
+ opts[:curve] ||= 0
406
+ when 5
407
+ left, top, width, height, opts[:curve] = args
408
+ when 0
409
+ left = opts[:left] || 0
410
+ top = opts[:top] || 0
411
+ width = opts[:width] || 0
412
+ height = opts[:height] || width
413
+ opts[:curve] ||= 0
414
+ else
415
+ message = <<EOS
416
+ Wrong number of arguments. Must be one of:
417
+ - rect(left, top, side, [opts])
418
+ - rect(left, top, width, height, [opts])
419
+ - rect(left, top, width, height, curve, [opts])
420
+ - rect(styles)
421
+ EOS
422
+ raise ArgumentError, message
423
+ end
424
+ create Shoes::Rect, left, top, width, height, style.merge(opts), blk
425
+ end
426
+
427
+ def star(left, top, points = 10, outer = 100.0, inner = 50.0, styles = {}, &blk)
428
+ styles = style_normalizer.normalize styles
429
+ create Shoes::Star, left, top, points, outer, inner, styles, blk
430
+ end
431
+
432
+ # Creates a new Shoes::Shape object
433
+ def shape(styles = {}, &blk)
434
+ create Shoes::Shape, styles, blk
435
+ end
436
+
437
+ # Define app-level setter methods
438
+ PATTERN_APP_STYLES = [:fill, :stroke]
439
+ OTHER_APP_STYLES = [:cap, :rotate, :strokewidth, :transform, :translate]
440
+
441
+ PATTERN_APP_STYLES.each do |style|
442
+ define_method style.to_s do |val|
443
+ @__app__.style[style] = pattern(val)
444
+ end
445
+ end
446
+
447
+ OTHER_APP_STYLES.each do |style|
448
+ define_method style.to_s do |val|
449
+ @__app__.style[style] = val
450
+ end
451
+ end
452
+
453
+ def nostroke
454
+ @__app__.style[:stroke] = nil
455
+ end
456
+
457
+ def nofill
458
+ @__app__.style[:fill] = nil
459
+ end
460
+
461
+ %w[banner title subtitle tagline caption para inscription].each do |method|
462
+ define_method method do |*texts|
463
+ styles = pop_style(texts)
464
+ klass = Shoes.const_get(method.capitalize)
465
+ create klass, texts, styles
466
+ end
467
+ end
468
+
469
+ TEXT_STYLES = {
470
+ code: { font: "Lucida Console" },
471
+ del: { strikethrough: true },
472
+ em: { emphasis: true },
473
+ ins: { underline: true },
474
+ sub: { rise: -10, size_modifier: 0.8 },
475
+ sup: { rise: 10, size_modifier: 0.8 },
476
+ strong: { weight: true },
477
+ }
478
+
479
+ TEXT_STYLES.keys.each do |method|
480
+ define_method method do |*texts|
481
+ styles = style_normalizer.normalize(pop_style(texts))
482
+ styles = TEXT_STYLES[method].merge(styles)
483
+ Shoes::Span.new texts, styles
484
+ end
485
+ end
486
+
487
+ def fg(*texts, color)
488
+ Shoes::Span.new texts, { stroke: pattern(color) }
489
+ end
490
+
491
+ def bg(*texts, color)
492
+ Shoes::Span.new texts, { fill: pattern(color) }
493
+ end
494
+
495
+ def link(*texts, &blk)
496
+ opts = normalize_style_for_element(Shoes::Link, texts)
497
+ create Shoes::Link, texts, opts, blk
498
+ end
499
+
500
+ def span(*texts)
501
+ opts = normalize_style_for_element(Shoes::Span, texts)
502
+ Shoes::Span.new texts, opts
503
+ end
504
+
505
+ def mouse
506
+ [@__app__.mouse_button, @__app__.mouse_pos[0], @__app__.mouse_pos[1]]
507
+ end
508
+
509
+ def motion(&blk)
510
+ @__app__.mouse_motion << blk
511
+ end
512
+
513
+ def resize(&blk)
514
+ @__app__.add_resize_callback blk
515
+ end
516
+
517
+ # hover and leave just delegate to the current slot as hover and leave
518
+ # are just defined for slots but self is always the app.
519
+ def hover(&blk)
520
+ @__app__.current_slot.hover(blk)
521
+ end
522
+
523
+ def leave(&blk)
524
+ @__app__.current_slot.leave(blk)
525
+ end
526
+
527
+ def keypress(&blk)
528
+ Shoes::Keypress.new @__app__, &blk
529
+ end
530
+
531
+ def keyrelease(&blk)
532
+ Shoes::Keyrelease.new @__app__, &blk
533
+ end
534
+
535
+ def append(&blk)
536
+ blk.call if blk
537
+ end
538
+
539
+ def visit(url)
540
+ match_data = nil
541
+ url_data = Shoes::URL.urls.find {|page, _| match_data = page.match url}
542
+ if url_data
543
+ action_proc = url_data[1]
544
+ url_argument = match_data[1]
545
+ clear do
546
+ @__app__.location = url
547
+ action_proc.call self, url_argument
548
+ end
549
+ end
550
+ end
551
+
552
+ def scroll_top
553
+ @__app__.scroll_top
554
+ end
555
+
556
+ def scroll_top=(n)
557
+ @__app__.scroll_top = n
558
+ end
559
+
560
+ def clipboard
561
+ @__app__.clipboard
562
+ end
563
+
564
+ def clipboard=(str)
565
+ @__app__.clipboard = str
566
+ end
567
+
568
+ def download(name, args={}, &blk)
569
+ create(Shoes::Download, name, args, &blk).tap do |download|
570
+ download.start
571
+ end
572
+ end
573
+
574
+ def gutter
575
+ @__app__.gutter
576
+ end
577
+
578
+ def video(*args)
579
+ raise Shoes::NotImplementedError,
580
+ 'Sorry video support has been cut from shoes 4!' +
581
+ ' Check out github issue #113 for any changes/updates or if you' +
582
+ ' want to help :)'
583
+ end
584
+
585
+ end
586
+ end
587
+
588
+ require 'shoes/internal_app'
589
+ require 'shoes/app'
590
+ require 'shoes/widget'
591
+ require 'shoes/url'