glimmer-dsl-opal 0.1.0 → 0.5.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (97) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +48 -0
  3. data/README.md +948 -169
  4. data/VERSION +1 -1
  5. data/lib/glimmer-dsl-opal.rb +31 -7
  6. data/lib/glimmer-dsl-opal/ext/date.rb +13 -0
  7. data/lib/glimmer-dsl-opal/ext/exception.rb +5 -0
  8. data/lib/{samples → glimmer-dsl-opal/samples}/elaborate/contact_manager.rb +0 -0
  9. data/lib/{samples → glimmer-dsl-opal/samples}/elaborate/contact_manager/contact.rb +0 -0
  10. data/lib/{samples → glimmer-dsl-opal/samples}/elaborate/contact_manager/contact_manager_presenter.rb +0 -0
  11. data/lib/{samples → glimmer-dsl-opal/samples}/elaborate/contact_manager/contact_repository.rb +24 -99
  12. data/lib/{samples → glimmer-dsl-opal/samples}/elaborate/login.rb +0 -0
  13. data/lib/{samples → glimmer-dsl-opal/samples}/elaborate/tic_tac_toe.rb +0 -0
  14. data/lib/{samples → glimmer-dsl-opal/samples}/elaborate/tic_tac_toe/board.rb +0 -0
  15. data/lib/{samples → glimmer-dsl-opal/samples}/elaborate/tic_tac_toe/cell.rb +0 -0
  16. data/lib/{samples → glimmer-dsl-opal/samples}/hello/hello_browser.rb +0 -0
  17. data/lib/glimmer-dsl-opal/samples/hello/hello_checkbox.rb +85 -0
  18. data/lib/glimmer-dsl-opal/samples/hello/hello_checkbox_group.rb +68 -0
  19. data/lib/glimmer-dsl-opal/samples/hello/hello_combo.rb +63 -0
  20. data/lib/{samples → glimmer-dsl-opal/samples}/hello/hello_computed.rb +0 -0
  21. data/lib/{samples → glimmer-dsl-opal/samples}/hello/hello_computed/contact.rb +0 -0
  22. data/lib/glimmer-dsl-opal/samples/hello/hello_custom_shell.rb +155 -0
  23. data/lib/glimmer-dsl-opal/samples/hello/hello_custom_widget.rb +86 -0
  24. data/lib/glimmer-dsl-opal/samples/hello/hello_group.rb +104 -0
  25. data/lib/{samples → glimmer-dsl-opal/samples}/hello/hello_list_multi_selection.rb +0 -0
  26. data/lib/{samples → glimmer-dsl-opal/samples}/hello/hello_list_single_selection.rb +1 -1
  27. data/lib/glimmer-dsl-opal/samples/hello/hello_radio.rb +108 -0
  28. data/lib/glimmer-dsl-opal/samples/hello/hello_radio_group.rb +84 -0
  29. data/lib/glimmer-dsl-opal/samples/hello/hello_tab.rb +50 -0
  30. data/lib/glimmer-dsl-opal/samples/hello/hello_world.rb +29 -0
  31. data/lib/{jquery.js → glimmer-dsl-opal/vendor/jquery.js} +0 -0
  32. data/lib/glimmer-dsl-swt.rb +37 -0
  33. data/lib/glimmer/data_binding/element_binding.rb +2 -1
  34. data/lib/glimmer/data_binding/ext/observable_model.rb +1 -1
  35. data/lib/glimmer/dsl/opal/async_exec_expression.rb +23 -7
  36. data/lib/glimmer/dsl/opal/checkbox_group_selection_data_binding_expression.rb +61 -0
  37. data/lib/glimmer/dsl/opal/color_expression.rb +38 -0
  38. data/lib/glimmer/dsl/opal/custom_widget_expression.rb +94 -0
  39. data/lib/glimmer/dsl/opal/display_expression.rb +40 -0
  40. data/lib/glimmer/dsl/opal/dsl.rb +14 -0
  41. data/lib/glimmer/dsl/opal/exec_expression.rb +55 -0
  42. data/lib/glimmer/dsl/opal/font_expression.rb +47 -0
  43. data/lib/glimmer/dsl/opal/layout_expression.rb +1 -1
  44. data/lib/glimmer/dsl/opal/property_expression.rb +6 -2
  45. data/lib/glimmer/dsl/opal/radio_group_selection_data_binding_expression.rb +61 -0
  46. data/lib/glimmer/dsl/opal/rgb_expression.rb +32 -0
  47. data/lib/glimmer/dsl/opal/rgba_expression.rb +32 -0
  48. data/lib/glimmer/dsl/opal/shell_expression.rb +19 -2
  49. data/lib/glimmer/dsl/opal/swt_expression.rb +46 -0
  50. data/lib/glimmer/dsl/opal/sync_exec_expression.rb +33 -0
  51. data/lib/glimmer/dsl/opal/widget_expression.rb +2 -1
  52. data/lib/glimmer/dsl/opal/widget_listener_expression.rb +16 -3
  53. data/lib/glimmer/swt.rb +499 -0
  54. data/lib/glimmer/swt/browser_proxy.rb +1 -1
  55. data/lib/glimmer/swt/button_proxy.rb +17 -3
  56. data/lib/glimmer/swt/checkbox_proxy.rb +80 -0
  57. data/lib/glimmer/swt/color_proxy.rb +119 -0
  58. data/lib/glimmer/swt/combo_proxy.rb +13 -12
  59. data/lib/glimmer/swt/composite_proxy.rb +8 -8
  60. data/lib/glimmer/swt/custom/checkbox_group.rb +142 -0
  61. data/lib/glimmer/swt/custom/radio_group.rb +143 -0
  62. data/lib/glimmer/swt/display_proxy.rb +79 -0
  63. data/lib/glimmer/swt/fill_layout_proxy.rb +84 -0
  64. data/lib/glimmer/swt/font_proxy.rb +79 -0
  65. data/lib/glimmer/swt/grid_layout_proxy.rb +45 -4
  66. data/lib/glimmer/swt/group_proxy.rb +38 -0
  67. data/lib/glimmer/swt/label_proxy.rb +28 -4
  68. data/lib/glimmer/swt/layout_data_proxy.rb +59 -6
  69. data/lib/glimmer/swt/layout_proxy.rb +17 -14
  70. data/lib/glimmer/swt/list_proxy.rb +19 -14
  71. data/lib/glimmer/swt/make_shift_shell_proxy.rb +38 -0
  72. data/lib/glimmer/swt/message_box_proxy.rb +5 -8
  73. data/lib/glimmer/swt/radio_proxy.rb +81 -0
  74. data/lib/glimmer/swt/row_layout_proxy.rb +128 -0
  75. data/lib/glimmer/swt/scrolled_composite_proxy.rb +20 -0
  76. data/lib/glimmer/swt/shell_proxy.rb +51 -26
  77. data/lib/glimmer/swt/style_constantizable.rb +154 -0
  78. data/lib/glimmer/swt/styled_text_proxy.rb +44 -0
  79. data/lib/glimmer/swt/swt_proxy.rb +53 -0
  80. data/lib/glimmer/swt/tab_folder_proxy.rb +8 -8
  81. data/lib/glimmer/swt/tab_item_proxy.rb +15 -32
  82. data/lib/glimmer/swt/table_proxy.rb +0 -18
  83. data/lib/glimmer/swt/widget_proxy.rb +173 -54
  84. data/lib/glimmer/ui/custom_shell.rb +92 -0
  85. data/lib/glimmer/ui/custom_widget.rb +292 -0
  86. data/lib/glimmer/util/proc_tracker.rb +39 -0
  87. data/lib/net/http.rb +17 -0
  88. data/lib/uri.rb +64 -0
  89. metadata +108 -57
  90. data/lib/glimmer/opal/display_proxy.rb +0 -23
  91. data/lib/glimmer/opal/element_proxy.rb +0 -312
  92. data/lib/samples/elaborate/launch +0 -6
  93. data/lib/samples/hello/hello_combo.rb +0 -34
  94. data/lib/samples/hello/hello_tab.rb +0 -24
  95. data/lib/samples/hello/hello_world.rb +0 -8
  96. data/lib/samples/hello/launch +0 -10
  97. data/lib/samples/launch +0 -4
@@ -0,0 +1,128 @@
1
+ require 'glimmer/swt/layout_proxy'
2
+
3
+ module Glimmer
4
+ module SWT
5
+ class RowLayoutProxy < LayoutProxy
6
+ include Glimmer
7
+
8
+ STYLE = <<~CSS
9
+ .row-layout {
10
+ display: flex;
11
+ align-items: flex-start;
12
+ }
13
+
14
+ .row-layout-pack-false {
15
+ align-items: stretch;
16
+ }
17
+
18
+ .row-layout-horizontal {
19
+ flex-direction: row;
20
+ }
21
+
22
+ .row-layout-horizontal.row-layout-pack-false {
23
+ flex-direction: unset;
24
+ }
25
+
26
+ .row-layout-vertical {
27
+ flex-direction: column;
28
+ }
29
+
30
+ .row-layout-vertical.row-layout-pack {
31
+ flex-direction: none;
32
+ }
33
+ CSS
34
+
35
+ attr_reader :type, :margin_width, :margin_height, :margin_top, :margin_right, :margin_bottom, :margin_left, :spacing, :pack
36
+
37
+ def initialize(parent, args)
38
+ super(parent, args)
39
+ @type = @args.first || :horizontal
40
+ @marign_width = 15
41
+ @margin_height = 15
42
+ self.pack = true
43
+ @parent.dom_element.add_class('row-layout')
44
+ @parent.dom_element.add_class(horizontal? ? 'row-layout-horizontal' : 'row-layout-vertical')
45
+ end
46
+
47
+ def horizontal?
48
+ @type == :horizontal
49
+ end
50
+
51
+ def vertical?
52
+ @type == :vertical
53
+ end
54
+
55
+ def dom(widget_dom)
56
+ dom_result = widget_dom
57
+ dom_result += '<br />' if vertical? && @pack
58
+ dom_result
59
+ end
60
+
61
+ def pack=(value)
62
+ @pack = value
63
+ if @pack
64
+ @parent.dom_element.remove_class('row-layout-pack-false')
65
+ else
66
+ @parent.dom_element.add_class('row-layout-pack-false')
67
+ end
68
+ end
69
+
70
+ def margin_width=(pixels)
71
+ @margin_width = pixels
72
+ # Using padding for width since margin-right isn't getting respected with width 100%
73
+ @parent.dom_element.css('padding-left', @margin_width)
74
+ @parent.dom_element.css('padding-right', @margin_width)
75
+ end
76
+
77
+ def margin_height=(pixels)
78
+ @margin_height = pixels
79
+ @parent.dom_element.css('padding-top', @margin_height)
80
+ @parent.dom_element.css('padding-bottom', @margin_height)
81
+ end
82
+
83
+ def margin_top=(pixels)
84
+ @margin_top = pixels
85
+ # Using padding for width since margin-right isn't getting respected with width 100%
86
+ @parent.dom_element.css('padding-top', @margin_top)
87
+ end
88
+
89
+ def margin_right=(pixels)
90
+ @margin_right = pixels
91
+ @parent.dom_element.css('padding-right', @margin_right)
92
+ end
93
+
94
+ def margin_bottom=(pixels)
95
+ @margin_bottom = pixels
96
+ # Using padding for width since margin-right isn't getting respected with width 100%
97
+ @parent.dom_element.css('padding-bottom', @margin_bottom)
98
+ end
99
+
100
+ def margin_left=(pixels)
101
+ @margin_left = pixels
102
+ @parent.dom_element.css('padding-left', @margin_left)
103
+ end
104
+
105
+ def spacing=(spacing)
106
+ @spacing = spacing.to_i
107
+ # TODO implement changes to accomodate layout_data in the future
108
+ @parent.style_element.html css {
109
+ s("##{@parent.id} > *") {
110
+ if horizontal?
111
+ margin_right "#{@spacing}px"
112
+ elsif vertical?
113
+ margin_bottom "#{@spacing}px"
114
+ end
115
+ }
116
+ s("##{@parent.id} > :last-child") {
117
+ if horizontal?
118
+ margin_right 0
119
+ elsif vertical?
120
+ margin_bottom 0
121
+ end
122
+ }
123
+ }.to_s
124
+ end
125
+
126
+ end
127
+ end
128
+ end
@@ -0,0 +1,20 @@
1
+ require 'glimmer/swt/grid_layout_proxy'
2
+ require 'glimmer/swt/widget_proxy'
3
+
4
+ module Glimmer
5
+ module SWT
6
+ class ScrolledCompositeProxy < CompositeProxy
7
+ STYLE = <<~CSS
8
+ .scrolled-composite {
9
+ }
10
+ CSS
11
+
12
+ # TODO set overflow-y and overflow-x based on :v_scroll and :h_scroll styles.... though consider also that it might not be needed in web browsers where scrollbars are always present
13
+ # height: 100px;
14
+ # overflow-y: auto;
15
+
16
+ end
17
+
18
+ end
19
+
20
+ end
@@ -1,19 +1,26 @@
1
- require 'glimmer/swt/widget_proxy'
1
+ require 'glimmer/swt/widget_proxy'
2
+ require 'glimmer/swt/display_proxy'
2
3
  require 'glimmer/swt/point'
3
4
 
4
5
  module Glimmer
5
6
  module SWT
6
- class ShellProxy < WidgetProxy
7
+ class ShellProxy < CompositeProxy
7
8
  # TODO consider renaming to ShellProxy to match SWT API
8
9
  attr_reader :minimum_size
9
10
 
11
+ WIDTH_MIN = 130
12
+ HEIGHT_MIN = 0
13
+
10
14
  def initialize(args)
11
15
  @args = args
12
16
  @children = []
13
- # Document.ready? do
17
+ # Document.ready? do end # TODO consider embedding this jQuery call in so outside consumers don't have to use it
14
18
  Document.find('body').empty unless ENV['RUBY_ENV'] == 'test'
15
- redraw
16
- # end
19
+ render
20
+ @layout = FillLayoutProxy.new(self, [])
21
+ @layout.margin_width = 0
22
+ @layout.margin_height = 0
23
+ self.minimum_size = Point.new(WIDTH_MIN, HEIGHT_MIN)
17
24
  end
18
25
 
19
26
  def element
@@ -29,14 +36,14 @@ module Glimmer
29
36
  end
30
37
 
31
38
  def text=(value)
32
- # Document.ready? do
33
- Document.title = value
34
- # end
39
+ Document.title = value
35
40
  end
36
41
 
37
42
  def minimum_size=(width_or_minimum_size, height = nil)
38
43
  @minimum_size = height.nil? ? width_or_minimum_size : Point.new(width_or_minimum_size, height)
39
- redraw
44
+ return if @minimum_size.nil?
45
+ dom_element.css('min-width', "#{@minimum_size.x}px")
46
+ dom_element.css('min-height', "#{@minimum_size.y}px")
40
47
  end
41
48
 
42
49
  def style_dom_css
@@ -47,7 +54,7 @@ module Glimmer
47
54
  .selected, .tabs .tab.selected {
48
55
  background: rgb(80, 116, 211);
49
56
  color: white;
50
- }
57
+ }
51
58
  CSS
52
59
  end
53
60
 
@@ -57,11 +64,15 @@ module Glimmer
57
64
  width: 100%;
58
65
  height: 100%;
59
66
  }
60
- body, .shell {
67
+ body {
61
68
  width: 100%;
62
69
  height: 100%;
63
70
  margin: 0;
64
71
  }
72
+ .shell {
73
+ height: 100%;
74
+ margin: 0;
75
+ }
65
76
  .shell iframe {
66
77
  width: 100%;
67
78
  height: 100%;
@@ -111,11 +122,11 @@ module Glimmer
111
122
  /* Create an selected/current tablink class */
112
123
  .tabs .tab.selected {
113
124
  background-color: #ccc;
114
- }
125
+ }
115
126
  /* Change background color of buttons on hover */
116
127
  .tabs .tab:hover {
117
128
  background-color: #ddd;
118
- }
129
+ }
119
130
  /* Style the tab content */
120
131
  .tab-item {
121
132
  padding: 6px 12px;
@@ -186,22 +197,16 @@ module Glimmer
186
197
 
187
198
  table tr th,td {
188
199
  cursor: default;
189
- }
200
+ }
190
201
  CSS
191
202
  end
192
203
 
193
204
  def dom
194
205
  i = 0
195
206
  body_id = id
196
- body_class = name
197
- body_style = '' # a start for more styling further along
198
- if @minimum_size
199
- body_style += "min-width: #{@minimum_size.x}px; min-height: #{@minimum_size.y}px;" if @minimum_size
200
- Document.find('body').css('min-width', "#{@minimum_size.x}px")
201
- Document.find('body').css('min-height', "#{@minimum_size.y}px")
202
- end
207
+ body_class = ([name] + css_classes.to_a).join(' ')
203
208
  @dom ||= html {
204
- div(id: body_id, class: body_class, style: body_style) {
209
+ div(id: body_id, class: body_class) {
205
210
  style(class: 'common-style') {
206
211
  style_dom_css
207
212
  }
@@ -213,22 +218,42 @@ module Glimmer
213
218
  }
214
219
  style(class: 'tab-style') {
215
220
  style_dom_tab_css
216
- }
221
+ }
217
222
  # style(class: 'tab-item-style') {
218
223
  # style_dom_tab_item_css
219
- # }
224
+ # }
220
225
  # style(class: 'modal-style') {
221
226
  # style_dom_modal_css
222
- # }
227
+ # }
223
228
  style(class: 'table-style') {
224
229
  style_dom_table_css
225
- }
230
+ }
231
+ style(class: 'fill-layout-style') {
232
+ Glimmer::SWT::FillLayoutProxy::STYLE
233
+ }
234
+ style(class: 'row-layout-style') {
235
+ Glimmer::SWT::RowLayoutProxy::STYLE
236
+ }
237
+ style(class: 'grid-layout-style') {
238
+ Glimmer::SWT::GridLayoutProxy::STYLE
239
+ }
240
+ style(class: 'checkbox-style') {
241
+ Glimmer::SWT::CheckboxProxy::STYLE
242
+ }
243
+ style(class: 'radio-style') {
244
+ Glimmer::SWT::RadioProxy::STYLE
245
+ }
246
+ style(class: 'scrolled-composite-style') {
247
+ Glimmer::SWT::ScrolledCompositeProxy::STYLE
248
+ }
226
249
  }
227
250
  }.to_s
228
251
  end
229
252
 
230
253
  def open
254
+ # TODO consider the idea of delaying rendering till the open method
231
255
  # TODO make it start as hidden and show shell upon open
256
+ Glimmer::SWT::DisplayProxy.instance.shells << self
232
257
  end
233
258
  end
234
259
  end
@@ -0,0 +1,154 @@
1
+ # Copyright (c) 2020 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/error'
23
+
24
+ module Glimmer
25
+ module SWT
26
+ # Mixin for all proxy classes that manage style constants (e.g. SWT, DND, etc...)
27
+ module StyleConstantizable
28
+ module ClassMethods
29
+ REGEX_SYMBOL_NEGATIVITY = /^([^!]+)(!)?$/
30
+
31
+ def constant_source_class
32
+ raise 'Not implemented! Mixer must implement!'
33
+ end
34
+
35
+ def constant_value_none
36
+ # TODO instead of raising error try a convention instead like CLASSNAME::NONE by default
37
+ raise 'Not implemented! Mixer must implement!'
38
+ end
39
+
40
+ # hash of extra styles (i.e. new style combinations)
41
+ def extra_styles
42
+ raise 'Not implemented! Mixer must implement!'
43
+ end
44
+
45
+ def error_message_invalid_style
46
+ " is an invalid #{constant_source_class.name.split(':').last} style! Please choose a style from #{constant_source_class.name} class constants." # TODO parameterize
47
+ end
48
+
49
+ # Gets constants (e.g. SWT::CONSTANT) where constant is
50
+ # passed in as a lower case symbol
51
+ def [](*symbols)
52
+ symbols = symbols.first if symbols.size == 1 && symbols.first.is_a?(Array)
53
+ result = symbols.compact.map do |symbol|
54
+ constant(symbol).tap do |constant_value|
55
+ raise Glimmer::Error, symbol.to_s + error_message_invalid_style unless constant_value.is_a?(Integer)
56
+ end
57
+ end.reduce do |output, constant_value|
58
+ if constant_value < 0
59
+ output & constant_value
60
+ else
61
+ output | constant_value
62
+ end
63
+ end
64
+ result.nil? ? constant_value_none : result
65
+ end
66
+
67
+ # Returns style integer value for passed in symbol or allows
68
+ # passed in object to pass through (e.g. Integer). This makes is convenient
69
+ # to use symbols or actual style integers in Glimmer
70
+ # Does not raise error for invalid values. Just lets them pass as is.
71
+ # (look into [] operator if you want an error raised on invalid values)
72
+ def constant(symbol)
73
+ return symbol unless symbol.is_a?(Symbol) || symbol.is_a?(String)
74
+ symbol_string, negative = extract_symbol_string_negativity(symbol)
75
+ swt_constant_symbol = symbol_string.downcase == symbol_string ? symbol_string.upcase.to_sym : symbol_string.to_sym
76
+ bit_value = constant_source_class.const_get(swt_constant_symbol)
77
+ negative ? ~bit_value : bit_value
78
+ rescue => e
79
+ begin
80
+ # Glimmer::Config.logger.debug {e.full_message}
81
+ alternative_swt_constant_symbol = constant_source_class.constants.find {|c| c.to_s.upcase == swt_constant_symbol.to_s.upcase}
82
+ bit_value = constant_source_class.const_get(alternative_swt_constant_symbol)
83
+ negative ? ~bit_value : bit_value
84
+ rescue => e
85
+ # Glimmer::Config.logger.debug {e.full_message}
86
+ bit_value = extra_styles[swt_constant_symbol]
87
+ if bit_value
88
+ negative ? ~bit_value : bit_value
89
+ else
90
+ symbol
91
+ end
92
+ end
93
+ end
94
+
95
+ def extract_symbol_string_negativity(symbol)
96
+ if symbol.is_a?(Symbol) || symbol.is_a?(String)
97
+ symbol_negativity_match = symbol.to_s.match(REGEX_SYMBOL_NEGATIVITY)
98
+ symbol = symbol_negativity_match[1]
99
+ negative = !!symbol_negativity_match[2]
100
+ [symbol, negative]
101
+ else
102
+ negative = symbol < 0
103
+ [symbol, negative]
104
+ end
105
+ end
106
+
107
+ def negative?(symbol)
108
+ extract_symbol_string_negativity(symbol)[1]
109
+ end
110
+
111
+ def has_constant?(symbol)
112
+ return false unless symbol.is_a?(Symbol) || symbol.is_a?(String)
113
+ constant(symbol).is_a?(Integer)
114
+ end
115
+
116
+ def constantify_args(args)
117
+ args.map {|arg| constant(arg)}
118
+ end
119
+
120
+ # Deconstructs a style integer into symbols
121
+ # Useful for debugging
122
+ def deconstruct(integer)
123
+ constant_source_class.constants.reduce([]) do |found, c|
124
+ constant_value = constant_source_class.const_get(c) rescue -1
125
+ is_found = constant_value.is_a?(Integer) && (integer & constant_value) == integer
126
+ is_found ? found += [c] : found
127
+ end
128
+ end
129
+
130
+ # Reverse engineer a style integer into a symbol
131
+ # Useful for debugging
132
+ def reverse_lookup(integer)
133
+ constant_source_class.constants.reduce([]) do |found, c|
134
+ constant_value = constant_source_class.const_get(c) rescue -1
135
+ is_found = constant_value.is_a?(Integer) && integer == constant_value
136
+ is_found ? found += [c] : found
137
+ end
138
+ end
139
+
140
+ def include?(swt_constant, *symbols)
141
+ swt_constant & self[symbols] == self[symbols]
142
+ end
143
+
144
+ end
145
+
146
+ def self.included(klass)
147
+ klass.extend(ClassMethods)
148
+ end
149
+
150
+ end
151
+
152
+ end
153
+
154
+ end