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,131 @@
1
+ class Shoes
2
+ ICON = File.join(DIR, 'static/shoes-icon.png').freeze
3
+
4
+ # Instantiates a new Shoes app.
5
+ #
6
+ # @param opts [Hash] A hash of options used instantiate the Shoes::App object with.
7
+ # @param blk [Proc] The block containing the DSL instructions for the actual app.
8
+ #
9
+ # @example
10
+ # Shoes.app(title: "Chunky") do
11
+ # para "Bacon is awesome!"
12
+ # end
13
+ #
14
+ # @return A new instance of Shoes::App
15
+ #
16
+ # @see Shoes::App#initialize
17
+
18
+ def self.app(opts={}, &blk)
19
+ Shoes::App.new(opts, &blk)
20
+ end
21
+
22
+ # This is the user-facing App object. It is `self` inside of a Shoes.app
23
+ # block, and is the context in which a Shoes app is evaled. It delegates most
24
+ # of its functionality to an InternalApp object, which interacts with other
25
+ # Shoes objects. There should be no unnecessary instance variables or methods
26
+ # in this class, so users are free to use whatever names they choose for
27
+ # their own code.
28
+ class App
29
+ include DSL
30
+ include BuiltinMethods
31
+ include Common::Inspect
32
+
33
+ # Instantiates a new Shoes app.
34
+ #
35
+ # @param opts [Hash] The options to initialize the app with.
36
+ # @param blk [Proc] The block containing the DSL instructions to be executed within the app.
37
+ #
38
+ # @option opts [String] :title ("Shoes 4") The title of the window
39
+ # @option opts [Boolean] :resizable (true) Whether the window is resizable
40
+ # @option opts [Boolean] :fullscreen (false) Whether the app should start in fullscreen
41
+ # @option opts [Fixnum] :width (600) The width of the app window
42
+ # @option opts [Fixnum] :height (500) The height of the app window
43
+ #
44
+ # @see Dimension#initialize
45
+ def initialize(opts={}, &blk)
46
+ @__app__ = Shoes::InternalApp.new(self, opts, &blk)
47
+ @__app__.setup_gui
48
+ Shoes.register self
49
+ @__app__.open_gui
50
+ end
51
+
52
+ # Shoes 3 exposes the app object like this, so we keep it for
53
+ # compatibility
54
+ def app
55
+ self
56
+ end
57
+
58
+ def window(options={}, &block)
59
+ options.merge! owner: self
60
+ self.class.new(options, &block)
61
+ end
62
+
63
+ def close
64
+ quit
65
+ end
66
+
67
+ def quit
68
+ Shoes.unregister self
69
+ @__app__.quit
70
+ end
71
+
72
+ def parent
73
+ @__app__.current_slot.parent
74
+ end
75
+
76
+ %w(
77
+ width height owner started? location left top absolute_left
78
+ absolute_top click release clear fullscreen fullscreen=
79
+ contents
80
+ ).each do |method|
81
+ define_method method do |*args, &block|
82
+ @__app__.public_send method, *args, &block
83
+ end
84
+ end
85
+
86
+ alias_method :fullscreen?, :fullscreen
87
+
88
+ def to_s
89
+ super.insert(-2, " \"#{@__app__.app_title}\"")
90
+ end
91
+
92
+ def inspect
93
+ super.insert(-2, " \"#{@__app__.app_title}\")")
94
+ end
95
+
96
+ def eval_with_additional_context(context, &blk)
97
+ @__additional_context__ = context
98
+ instance_eval(&blk) if blk
99
+ ensure
100
+ @__additional_context__ = nil
101
+ end
102
+
103
+ def method_missing(name, *args, &blk)
104
+ if @__additional_context__
105
+ @__additional_context__.public_send(name, *args, &blk)
106
+ else
107
+ super
108
+ end
109
+ end
110
+
111
+ DELEGATE_BLACKLIST = [:parent, :app]
112
+
113
+ # class definitions are evaluated top to bottom, want to have all of them
114
+ # so define at bottom
115
+ DELEGATE_METHODS = ((Shoes::App.public_instance_methods(false) +
116
+ Shoes::DSL.public_instance_methods) - DELEGATE_BLACKLIST).freeze
117
+
118
+ def self.subscribe_to_dsl_methods(klazz)
119
+ klazz.extend Forwardable unless klazz.is_a? Forwardable
120
+ klazz.def_delegators :app, *DELEGATE_METHODS
121
+ @method_subscribers ||= []
122
+ @method_subscribers << klazz
123
+ end
124
+
125
+ def self.new_dsl_method(name, &blk)
126
+ define_method name, blk
127
+ @method_subscribers.each {|klazz| klazz.def_delegator :app, name}
128
+ end
129
+ end
130
+
131
+ end
@@ -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,24 @@
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
+
20
+ def needs_to_be_positioned?
21
+ absolutely_positioned?
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,24 @@
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
+
20
+ def needs_to_be_positioned?
21
+ false
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,77 @@
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
+ extend BuiltinMethods
72
+ end
73
+
74
+ # including the module into the main object (monkey patch)
75
+ class << self
76
+ include Shoes::BuiltinMethods
77
+ end
@@ -0,0 +1,30 @@
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
+
29
+ end
30
+ end
@@ -0,0 +1,44 @@
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
+
37
+ end
38
+
39
+ class Check < CheckButton
40
+ style_with :checked, :click, :common_styles, :dimensions, :state
41
+ end
42
+
43
+
44
+ end
@@ -0,0 +1,385 @@
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
+ raise 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, " #{to_s} alpha:#{@alpha}")
84
+ end
85
+
86
+ private
87
+ def normalize_rgb(value)
88
+ rgb = value.is_a?(Fixnum) ? value : (255 * value).round
89
+ return 255 if rgb > 255
90
+ return 0 if rgb < 0
91
+ rgb
92
+ end
93
+
94
+ def raise_class_mismatch_error other
95
+ raise ArgumentError,
96
+ "can't compare #{self.class.name} with #{other.class.name}"
97
+ end
98
+
99
+ def same_base_color? other
100
+ @red == other.red && @green == other.green && @blue == other.blue
101
+ end
102
+
103
+ def less_or_greater_than(other)
104
+ own_sum = @red + @green + @blue
105
+ other_sum = other.red + other.green + other.blue
106
+ if own_sum > other_sum
107
+ 1
108
+ else
109
+ -1
110
+ end
111
+ end
112
+
113
+ class HexConverter
114
+ def initialize(hex)
115
+ @hex = validate(hex) || raise(ArgumentError, "Bad hex color: #{hex}")
116
+ @red, @green, @blue = hex_to_rgb(pad_if_necessary @hex)
117
+ end
118
+
119
+ def to_rgb
120
+ [@red, @green, @blue]
121
+ end
122
+
123
+ private
124
+ def hex_to_rgb(hex)
125
+ hex.chars.each_slice(2).map { |a| a.join.to_i(16) }
126
+ end
127
+
128
+ def pad_if_necessary(hex)
129
+ return hex unless hex.length == 3
130
+ hex.chars.map { |c| "#{c}#{c}" }.join
131
+ end
132
+
133
+ # Returns a 3- or 6-char hex string for valid input, or nil
134
+ # for invalid input.
135
+ def validate(hex)
136
+ match = /^#?(([0-9a-f]{3}){1,2})$/i.match(hex)
137
+ match && match[1]
138
+ end
139
+ end
140
+
141
+ module DSLHelpers
142
+ def pattern(*args)
143
+ if args.length == 1
144
+ arg = args.first
145
+ case arg
146
+ when String
147
+ image_file?(arg) ? image_pattern(arg) : color(arg)
148
+ when Shoes::Color
149
+ color arg
150
+ when Range, Shoes::Gradient
151
+ gradient(arg)
152
+ when Shoes::ImagePattern
153
+ arg
154
+ else
155
+ raise ArgumentError, "Bad pattern: #{arg.inspect}"
156
+ end
157
+ else
158
+ gradient(*args)
159
+ end
160
+ end
161
+
162
+ def color(arg)
163
+ Shoes::Color.create(arg)
164
+ end
165
+
166
+ def rgb(red, green, blue, alpha = Shoes::Color::OPAQUE)
167
+ Shoes::Color.new(red, green, blue, alpha)
168
+ end
169
+
170
+ # Creates a new Shoes::Gradient
171
+ #
172
+ # @overload gradient(from, to)
173
+ # @param [Shoes::Color] from the starting color
174
+ # @param [Shoes::Color] to the ending color
175
+ #
176
+ # @overload gradient(from, to)
177
+ # @param [String] from a hex string representing the starting color
178
+ # @param [String] to a hex string representing the ending color
179
+ #
180
+ # @overload gradient(range)
181
+ # @param [Range<Shoes::Color>] range min color to max color
182
+ #
183
+ # @overload gradient(range)
184
+ # @param [Range<String>] range min color to max color
185
+ def gradient(*args)
186
+ case args.length
187
+ when 1
188
+ arg = args[0]
189
+ case arg
190
+ when Gradient
191
+ min, max = arg.color1, arg.color2
192
+ when Range
193
+ min, max = arg.first, arg.last
194
+ else
195
+ raise ArgumentError, "Can't make gradient out of #{arg.inspect}"
196
+ end
197
+ when 2
198
+ min, max = args[0], args[1]
199
+ else
200
+ raise ArgumentError, "Wrong number of arguments (#{args.length} for 1 or 2)"
201
+ end
202
+ Shoes::Gradient.new(color(min), color(max))
203
+ end
204
+
205
+ def gray(level = 128, alpha = Shoes::Color::OPAQUE)
206
+ Shoes::Color.new(level, level, level, alpha)
207
+ end
208
+
209
+ alias_method :grey, :gray
210
+
211
+ private
212
+ def image_file?(arg)
213
+ arg =~ /\.gif|jpg|jpeg|png$/
214
+ end
215
+
216
+ def image_pattern(path)
217
+ Shoes::ImagePattern.new path if File.exist?(path)
218
+ end
219
+ end
220
+
221
+ end
222
+
223
+ # Create all of the built-in Shoes colors
224
+ COLORS = {}
225
+
226
+ module DSL
227
+ colors = [
228
+ [:aliceblue, 240, 248, 255],
229
+ [:antiquewhite, 250, 235, 215],
230
+ [:aqua, 0, 255, 255],
231
+ [:aquamarine, 127, 255, 212],
232
+ [:azure, 240, 255, 255],
233
+ [:beige, 245, 245, 220],
234
+ [:bisque, 255, 228, 196],
235
+ [:black, 0, 0, 0],
236
+ [:blanchedalmond, 255, 235, 205],
237
+ [:blue, 0, 0, 255],
238
+ [:blueviolet, 138, 43, 226],
239
+ [:brown, 165, 42, 42],
240
+ [:burlywood, 222, 184, 135],
241
+ [:cadetblue, 95, 158, 160],
242
+ [:chartreuse, 127, 255, 0],
243
+ [:chocolate, 210, 105, 30],
244
+ [:coral, 255, 127, 80],
245
+ [:cornflowerblue, 100, 149, 237],
246
+ [:cornsilk, 255, 248, 220],
247
+ [:crimson, 220, 20, 60],
248
+ [:cyan, 0, 255, 255],
249
+ [:darkblue, 0, 0, 139],
250
+ [:darkcyan, 0, 139, 139],
251
+ [:darkgoldenrod, 184, 134, 11],
252
+ [:darkgray, 169, 169, 169],
253
+ [:darkgrey, 169, 169, 169],
254
+ [:darkgreen, 0, 100, 0],
255
+ [:darkkhaki, 189, 183, 107],
256
+ [:darkmagenta, 139, 0, 139],
257
+ [:darkolivegreen, 85, 107, 47],
258
+ [:darkorange, 255, 140, 0],
259
+ [:darkorchid, 153, 50, 204],
260
+ [:darkred, 139, 0, 0],
261
+ [:darksalmon, 233, 150, 122],
262
+ [:darkseagreen, 143, 188, 143],
263
+ [:darkslateblue, 72, 61, 139],
264
+ [:darkslategray, 47, 79, 79],
265
+ [:darkslategrey, 47, 79, 79],
266
+ [:darkturquoise, 0, 206, 209],
267
+ [:darkviolet, 148, 0, 211],
268
+ [:deeppink, 255, 20, 147],
269
+ [:deepskyblue, 0, 191, 255],
270
+ [:dimgray, 105, 105, 105],
271
+ [:dimgrey, 105, 105, 105],
272
+ [:dodgerblue, 30, 144, 255],
273
+ [:firebrick, 178, 34, 34],
274
+ [:floralwhite, 255, 250, 240],
275
+ [:forestgreen, 34, 139, 34],
276
+ [:fuchsia, 255, 0, 255],
277
+ [:gainsboro, 220, 220, 220],
278
+ [:ghostwhite, 248, 248, 255],
279
+ [:gold, 255, 215, 0],
280
+ [:goldenrod, 218, 165, 32],
281
+ [:green, 0, 128, 0],
282
+ [:greenyellow, 173, 255, 47],
283
+ [:honeydew, 240, 255, 240],
284
+ [:hotpink, 255, 105, 180],
285
+ [:indianred, 205, 92, 92],
286
+ [:indigo, 75, 0, 130],
287
+ [:ivory, 255, 255, 240],
288
+ [:khaki, 240, 230, 140],
289
+ [:lavender, 230, 230, 250],
290
+ [:lavenderblush, 255, 240, 245],
291
+ [:lawngreen, 124, 252, 0],
292
+ [:lemonchiffon, 255, 250, 205],
293
+ [:lightblue, 173, 216, 230],
294
+ [:lightcoral, 240, 128, 128],
295
+ [:lightcyan, 224, 255, 255],
296
+ [:lightgoldenrodyellow, 250, 250, 210],
297
+ [:lightgreen, 144, 238, 144],
298
+ [:lightgray, 211, 211, 211],
299
+ [:lightgrey, 211, 211, 211],
300
+ [:lightpink, 255, 182, 193],
301
+ [:lightsalmon, 255, 160, 122],
302
+ [:lightseagreen, 32, 178, 170],
303
+ [:lightskyblue, 135, 206, 250],
304
+ [:lightslategray, 119, 136, 153],
305
+ [:lightslategrey, 119, 136, 153],
306
+ [:lightsteelblue, 176, 196, 222],
307
+ [:lightyellow, 255, 255, 224],
308
+ [:lime, 0, 255, 0],
309
+ [:limegreen, 50, 205, 50],
310
+ [:linen, 250, 240, 230],
311
+ [:magenta, 255, 0, 255],
312
+ [:maroon, 128, 0, 0],
313
+ [:mediumaquamarine, 102, 205, 170],
314
+ [:mediumblue, 0, 0, 205],
315
+ [:mediumorchid, 186, 85, 211],
316
+ [:mediumpurple, 147, 112, 219],
317
+ [:mediumseagreen, 60, 179, 113],
318
+ [:mediumslateblue, 123, 104, 238],
319
+ [:mediumspringgreen, 0, 250, 154],
320
+ [:mediumturquoise, 72, 209, 204],
321
+ [:mediumvioletred, 199, 21, 133],
322
+ [:midnightblue, 25, 25, 112],
323
+ [:mintcream, 245, 255, 250],
324
+ [:mistyrose, 255, 228, 225],
325
+ [:moccasin, 255, 228, 181],
326
+ [:navajowhite, 255, 222, 173],
327
+ [:navy, 0, 0, 128],
328
+ [:oldlace, 253, 245, 230],
329
+ [:olive, 128, 128, 0],
330
+ [:olivedrab, 107, 142, 35],
331
+ [:orange, 255, 165, 0],
332
+ [:orangered, 255, 69, 0],
333
+ [:orchid, 218, 112, 214],
334
+ [:palegoldenrod, 238, 232, 170],
335
+ [:palegreen, 152, 251, 152],
336
+ [:paleturquoise, 175, 238, 238],
337
+ [:palevioletred, 219, 112, 147],
338
+ [:papayawhip, 255, 239, 213],
339
+ [:peachpuff, 255, 218, 185],
340
+ [:peru, 205, 133, 63],
341
+ [:pink, 255, 192, 203],
342
+ [:plum, 221, 160, 221],
343
+ [:powderblue, 176, 224, 230],
344
+ [:purple, 128, 0, 128],
345
+ [:red, 255, 0, 0],
346
+ [:rosybrown, 188, 143, 143],
347
+ [:royalblue, 65, 105, 225],
348
+ [:saddlebrown, 139, 69, 19],
349
+ [:salmon, 250, 128, 114],
350
+ [:sandybrown, 244, 164, 96],
351
+ [:seagreen, 46, 139, 87],
352
+ [:seashell, 255, 245, 238],
353
+ [:sienna, 160, 82, 45],
354
+ [:silver, 192, 192, 192],
355
+ [:skyblue, 135, 206, 235],
356
+ [:slateblue, 106, 90, 205],
357
+ [:slategray, 112, 128, 144],
358
+ [:slategrey, 112, 128, 144],
359
+ [:snow, 255, 250, 250],
360
+ [:springgreen, 0, 255, 127],
361
+ [:steelblue, 70, 130, 180],
362
+ [:tan, 210, 180, 140],
363
+ [:teal, 0, 128, 128],
364
+ [:thistle, 216, 191, 216],
365
+ [:tomato, 255, 99, 71],
366
+ [:turquoise, 64, 224, 208],
367
+ [:violet, 238, 130, 238],
368
+ [:wheat, 245, 222, 179],
369
+ [:white, 255, 255, 255],
370
+ [:whitesmoke, 245, 245, 245],
371
+ [:yellow, 255, 255, 0],
372
+ [:yellowgreen, 154, 205, 50],
373
+ [:shoes_background, 237, 237, 237],
374
+ ]
375
+
376
+ colors.each do |color_name, r, g, b|
377
+ Shoes::COLORS[color_name] = Shoes::Color.new(r, g, b)
378
+ define_method(color_name) do |alpha = Shoes::Color::OPAQUE|
379
+ color = Shoes::COLORS.fetch(color_name)
380
+ return color if alpha == Shoes::Color::OPAQUE
381
+ Shoes::Color.new(color.red, color.green, color.blue, alpha)
382
+ end
383
+ end
384
+ end
385
+ end