glimmer-dsl-swt 4.17.9.0 → 4.17.10.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -132,6 +132,69 @@ module Glimmer
132
132
  }
133
133
  end,
134
134
  },
135
+ date: {
136
+ widget_value_property: :date_time,
137
+ editor_gui: lambda do |args, model, property, table_proxy|
138
+ first_time = true
139
+ table_proxy.table_editor.minimumHeight = 25
140
+ date(*args) {
141
+ date_time model.send(property)
142
+ focus true
143
+ on_focus_lost {
144
+ table_proxy.finish_edit!
145
+ }
146
+ on_key_pressed { |key_event|
147
+ if key_event.keyCode == swt(:cr)
148
+ table_proxy.finish_edit!
149
+ elsif key_event.keyCode == swt(:esc)
150
+ table_proxy.cancel_edit!
151
+ end
152
+ }
153
+ }
154
+ end,
155
+ },
156
+ date_drop_down: {
157
+ widget_value_property: :date_time,
158
+ editor_gui: lambda do |args, model, property, table_proxy|
159
+ first_time = true
160
+ table_proxy.table_editor.minimumHeight = 25
161
+ date_drop_down(*args) {
162
+ date_time model.send(property)
163
+ focus true
164
+ on_focus_lost {
165
+ table_proxy.finish_edit!
166
+ }
167
+ on_key_pressed { |key_event|
168
+ if key_event.keyCode == swt(:cr)
169
+ table_proxy.finish_edit!
170
+ elsif key_event.keyCode == swt(:esc)
171
+ table_proxy.cancel_edit!
172
+ end
173
+ }
174
+ }
175
+ end,
176
+ },
177
+ time: {
178
+ widget_value_property: :date_time,
179
+ editor_gui: lambda do |args, model, property, table_proxy|
180
+ first_time = true
181
+ table_proxy.table_editor.minimumHeight = 25
182
+ time(*args) {
183
+ date_time model.send(property)
184
+ focus true
185
+ on_focus_lost {
186
+ table_proxy.finish_edit!
187
+ }
188
+ on_key_pressed { |key_event|
189
+ if key_event.keyCode == swt(:cr)
190
+ table_proxy.finish_edit!
191
+ elsif key_event.keyCode == swt(:esc)
192
+ table_proxy.cancel_edit!
193
+ end
194
+ }
195
+ }
196
+ end,
197
+ },
135
198
  radio: {
136
199
  widget_value_property: :selection,
137
200
  editor_gui: lambda do |args, model, property, table_proxy|
@@ -174,11 +237,6 @@ module Glimmer
174
237
  table_proxy.cancel_edit!
175
238
  end
176
239
  }
177
- # on_widget_selected {
178
- # if !OS.windows? || !first_time || first_time && model.send(property) != table_editor_widget_proxy.swt_widget.text
179
- # table_proxy.finish_edit!
180
- # end
181
- # }
182
240
  }
183
241
  table_editor_widget_proxy
184
242
  end,
@@ -187,7 +245,7 @@ module Glimmer
187
245
  end
188
246
  end
189
247
 
190
- attr_reader :table_editor, :table_editor_widget_proxy, :sort_property, :sort_direction, :sort_block, :sort_type, :sort_by_block, :additional_sort_properties, :editor, :editable
248
+ attr_reader :table_editor, :table_editor_widget_proxy, :sort_property, :sort_direction, :sort_block, :sort_type, :sort_by_block, :additional_sort_properties, :editor, :editable, :initial_sort_property
191
249
  attr_accessor :column_properties
192
250
  alias editable? editable
193
251
 
@@ -211,10 +269,49 @@ module Glimmer
211
269
  swt_widget.data
212
270
  end
213
271
 
214
- def sort_by_column(table_column_proxy)
215
- index = swt_widget.columns.to_a.index(table_column_proxy.swt_widget)
216
- new_sort_property = table_column_proxy.sort_property || [column_properties[index]]
217
- if new_sort_property.size == 1 && !additional_sort_properties.to_a.empty?
272
+ def sort_block=(comparator)
273
+ @sort_block = comparator
274
+ end
275
+
276
+ def sort_by_block=(property_picker)
277
+ @sort_by_block = property_picker
278
+ end
279
+
280
+ def sort_property=(new_sort_property)
281
+ @sort_property = [new_sort_property].flatten.compact
282
+ end
283
+
284
+ def detect_sort_type
285
+ @sort_type = sort_property.size.times.map { String }
286
+ array = model_binding.evaluate_property
287
+ sort_property.each_with_index do |a_sort_property, i|
288
+ values = array.map { |object| object.send(a_sort_property) }
289
+ value_classes = values.map(&:class).uniq
290
+ if value_classes.size == 1
291
+ @sort_type[i] = value_classes.first
292
+ elsif value_classes.include?(Integer)
293
+ @sort_type[i] = Integer
294
+ elsif value_classes.include?(Float)
295
+ @sort_type[i] = Float
296
+ end
297
+ end
298
+ end
299
+
300
+ def column_sort_properties
301
+ column_properties.zip(table_column_proxies.map(&:sort_property)).map do |pair|
302
+ [pair.compact.last].flatten.compact
303
+ end
304
+ end
305
+
306
+ # Sorts by specified TableColumnProxy object. If nil, it uses the table default sort instead.
307
+ def sort_by_column!(table_column_proxy=nil)
308
+ index = swt_widget.columns.to_a.index(table_column_proxy.swt_widget) unless table_column_proxy.nil?
309
+ new_sort_property = table_column_proxy.nil? ? @sort_property : table_column_proxy.sort_property || [column_properties[index]]
310
+ return if table_column_proxy.nil? && new_sort_property.nil? && @sort_block.nil? && @sort_by_block.nil?
311
+ if new_sort_property && table_column_proxy.nil? && new_sort_property.size == 1 && (index = column_sort_properties.index(new_sort_property))
312
+ table_column_proxy = table_column_proxies[index]
313
+ end
314
+ if new_sort_property && new_sort_property.size == 1 && !additional_sort_properties.to_a.empty?
218
315
  selected_additional_sort_properties = additional_sort_properties.clone
219
316
  if selected_additional_sort_properties.include?(new_sort_property.first)
220
317
  selected_additional_sort_properties.delete(new_sort_property.first)
@@ -224,39 +321,32 @@ module Glimmer
224
321
  end
225
322
  end
226
323
 
227
- @sort_direction = @sort_direction.nil? || @sort_property != new_sort_property || @sort_direction == :descending ? :ascending : :descending
324
+ @sort_direction = @sort_direction.nil? || @sort_property.first != new_sort_property.first || @sort_direction == :descending ? :ascending : :descending
228
325
  swt_widget.sort_direction = @sort_direction == :ascending ? SWTProxy[:up] : SWTProxy[:down]
229
326
 
230
- @sort_property = new_sort_property
231
- swt_widget.sort_column = table_column_proxy.swt_widget
232
-
233
- @sort_by_block = nil
234
- @sort_block = nil
327
+ @sort_property = [new_sort_property].flatten.compact
328
+ table_column_index = column_properties.index(new_sort_property.to_s.to_sym)
329
+ table_column_proxy ||= table_column_proxies[table_column_index] if table_column_index
330
+ swt_widget.sort_column = table_column_proxy.swt_widget if table_column_proxy
331
+
332
+ if table_column_proxy
333
+ @sort_by_block = nil
334
+ @sort_block = nil
335
+ end
235
336
  @sort_type = nil
236
- if table_column_proxy.sort_by_block
337
+ if table_column_proxy&.sort_by_block
237
338
  @sort_by_block = table_column_proxy.sort_by_block
238
- elsif table_column_proxy.sort_block
339
+ elsif table_column_proxy&.sort_block
239
340
  @sort_block = table_column_proxy.sort_block
240
341
  else
241
342
  detect_sort_type
242
343
  end
243
- sort
344
+
345
+ sort!
244
346
  end
245
347
 
246
- def detect_sort_type
247
- @sort_type = sort_property.size.times.map { String }
248
- array = model_binding.evaluate_property
249
- sort_property.each_with_index do |a_sort_property, i|
250
- values = array.map { |object| object.send(a_sort_property) }
251
- value_classes = values.map(&:class).uniq
252
- if value_classes.size == 1
253
- @sort_type[i] = value_classes.first
254
- elsif value_classes.include?(Integer)
255
- @sort_type[i] = Integer
256
- elsif value_classes.include?(Float)
257
- @sort_type[i] = Float
258
- end
259
- end
348
+ def initial_sort!
349
+ sort_by_column!
260
350
  end
261
351
 
262
352
  def additional_sort_properties=(args)
@@ -276,7 +366,7 @@ module Glimmer
276
366
  swt_widget.items.map {|item| column_count.times.map {|i| item.get_text(i)} }
277
367
  end
278
368
 
279
- def sort
369
+ def sort!
280
370
  return unless sort_property && (sort_type || sort_block || sort_by_block)
281
371
  array = model_binding.evaluate_property
282
372
  array = array.sort_by(&:hash) # this ensures consistent subsequent sorting in case there are equivalent sorts to avoid an infinite loop
@@ -317,22 +407,16 @@ module Glimmer
317
407
  search
318
408
  end
319
409
 
320
- def widget_property_listener_installers
321
- super.merge({
322
- Java::OrgEclipseSwtWidgets::Table => {
323
- selection: lambda do |observer|
324
- on_widget_selected { |selection_event|
325
- observer.call(@swt_widget.getSelection)
326
- }
327
- end
328
- },
329
- })
330
- end
331
-
332
410
  def post_initialize_child(table_column_proxy)
333
411
  table_column_proxies << table_column_proxy
334
412
  end
335
413
 
414
+ def post_add_content
415
+ return if @initially_sorted
416
+ initial_sort!
417
+ @initially_sorted = true
418
+ end
419
+
336
420
  def table_column_proxies
337
421
  @table_column_proxies ||= []
338
422
  end
@@ -365,7 +449,8 @@ module Glimmer
365
449
  return if table_item.nil?
366
450
  model = table_item.data
367
451
  property = column_properties[column_index]
368
- @cancel_edit&.call if @edit_mode
452
+ cancel_edit!
453
+ return unless table_column_proxies[column_index].editable?
369
454
  action_taken = false
370
455
  @edit_mode = true
371
456
 
@@ -390,7 +475,7 @@ module Glimmer
390
475
  end
391
476
 
392
477
  @finish_edit = lambda do |event=nil|
393
- new_value = @table_editor_widget_proxy&.swt_widget&.send(widget_value_property)
478
+ new_value = @table_editor_widget_proxy&.send(widget_value_property)
394
479
  if table_item.isDisposed
395
480
  @cancel_edit.call
396
481
  elsif !new_value.nil? && !action_taken && !@edit_in_progress && !@cancel_in_progress
@@ -234,7 +234,6 @@ module Glimmer
234
234
  elsif @swt_widget.respond_to?(attribute_getter(attribute_name))
235
235
  @swt_widget.send(attribute_getter(attribute_name))
236
236
  else
237
- pd attribute_name
238
237
  send(attribute_name)
239
238
  end
240
239
  end
@@ -282,6 +281,17 @@ module Glimmer
282
281
  }
283
282
  end,
284
283
  },
284
+ Java::OrgEclipseSwtWidgets::Table => {
285
+ :selection => lambda do |observer|
286
+ on_widget_selected { |selection_event|
287
+ if has_style?(:multi)
288
+ observer.call(@swt_widget.getSelection.map(&:get_data))
289
+ else
290
+ observer.call(@swt_widget.getSelection.first&.get_data)
291
+ end
292
+ }
293
+ end,
294
+ },
285
295
  Java::OrgEclipseSwtWidgets::Text => {
286
296
  :text => lambda do |observer|
287
297
  on_modify_text { |modify_event|
@@ -447,6 +457,7 @@ module Glimmer
447
457
  underscored_widget_name = KEYWORD_ALIASES[underscored_widget_name] if KEYWORD_ALIASES[underscored_widget_name]
448
458
  swt_widget_name = underscored_widget_name.camelcase(:upper)
449
459
  swt_widget_class = eval(swt_widget_name)
460
+ # TODO fix issue with not detecting DateTime because it's conflicting with the Ruby DateTime
450
461
  unless swt_widget_class.ancestors.include?(org.eclipse.swt.widgets.Widget)
451
462
  swt_widget_class = swt_widget_class_manual_entries[underscored_widget_name]
452
463
  if swt_widget_class.nil?
@@ -822,6 +833,9 @@ module Glimmer
822
833
  end
823
834
  cursor_proxy ? cursor_proxy.swt_cursor : value
824
835
  end,
836
+ :enabled => lambda do |value|
837
+ !!value
838
+ end,
825
839
  :foreground => color_converter,
826
840
  :font => lambda do |value|
827
841
  if value.is_a?(Hash)
@@ -8,7 +8,7 @@ class Sample
8
8
 
9
9
  def name
10
10
  if @name.nil?
11
- @name = File.basename(file, '.rb').split('_').map(&:capitalize).join(' ')
11
+ @name = File.basename(file, '.rb').split('_').map(&:capitalize).join(' ')
12
12
  if @name.start_with?('Hello')
13
13
  name_parts = @name.split
14
14
  name_parts[0] = name_parts.first + ','
@@ -38,11 +38,11 @@ class SampleDirectory
38
38
  select { |file| File.directory?(file) }.
39
39
  map { |file| SampleDirectory.new(file) }
40
40
  glimmer_gems = Gem.find_latest_files("glimmer-*-*")
41
- sample_directories = glimmer_gems.map do |lib|
41
+ sample_directories = glimmer_gems.map do |lib|
42
42
  File.dirname(File.dirname(lib))
43
- end.select do |gem|
43
+ end.select do |gem|
44
44
  Dir.exist?(File.join(gem, 'samples'))
45
- end.map do |gem|
45
+ end.map do |gem|
46
46
  Dir.glob(File.join(gem, 'samples', '*')).select {|file_or_dir| Dir.exist?(file_or_dir)}
47
47
  end.flatten.uniq.reverse
48
48
  if Dir.exist?('samples')
@@ -51,14 +51,14 @@ class SampleDirectory
51
51
  end
52
52
  end
53
53
  sample_directories = sample_directories.uniq {|dir| File.basename(dir)}
54
- @sample_directories = sample_directories.map { |file| SampleDirectory.new(file) }
54
+ @sample_directories = sample_directories.map { |file| SampleDirectory.new(file) }
55
55
  end
56
56
  @sample_directories
57
57
  end
58
58
 
59
59
  def all_samples
60
60
  @all_samples ||= sample_directories.map(&:samples).reduce(:+)
61
- end
61
+ end
62
62
  end
63
63
 
64
64
  include Glimmer # used for observe syntax
@@ -117,7 +117,7 @@ class MetaSampleApplication
117
117
  text 'Glimmer Meta-Sample (The Sample of Samples)'
118
118
 
119
119
  on_swt_show {
120
- SampleDirectory.selected_sample = SampleDirectory.all_samples.first
120
+ SampleDirectory.selected_sample = SampleDirectory.all_samples.first
121
121
  }
122
122
 
123
123
  sash_form {
@@ -153,7 +153,7 @@ class MetaSampleApplication
153
153
  on_widget_selected {
154
154
  SampleDirectory.selected_sample.launch
155
155
  }
156
- }
156
+ }
157
157
  }
158
158
 
159
159
  code_text {
@@ -163,7 +163,7 @@ class MetaSampleApplication
163
163
  }
164
164
 
165
165
  weights 4, 9
166
- }
166
+ }
167
167
  }.open
168
168
  end
169
169
  end
@@ -19,6 +19,9 @@
19
19
  # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
20
  # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
21
21
 
22
+ # This sample demonstrates the use of a `checkbox_group` (aka `check_group`) in Glimmer, which provides terser syntax
23
+ # than HelloCheckbox for representing multiple checkbox buttons (`button(:check)`) by relying on data-binding to
24
+ # automatically spawn the `checkbox` widgets (`button(:check)`) based on available options on the model.
22
25
  class HelloCheckboxGroup
23
26
  class Person
24
27
  attr_accessor :activities
@@ -1,5 +1,5 @@
1
1
  # Copyright (c) 2007-2020 Andy Maleh
2
- #
2
+ #
3
3
  # Permission is hereby granted, free of charge, to any person obtaining
4
4
  # a copy of this software and associated documentation files (the
5
5
  # "Software"), to deal in the Software without restriction, including
@@ -7,10 +7,10 @@
7
7
  # distribute, sublicense, and/or sell copies of the Software, and to
8
8
  # permit persons to whom the Software is furnished to do so, subject to
9
9
  # the following conditions:
10
- #
10
+ #
11
11
  # The above copyright notice and this permission notice shall be
12
12
  # included in all copies or substantial portions of the Software.
13
- #
13
+ #
14
14
  # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
15
  # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
16
  # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
@@ -41,9 +41,9 @@ class HelloCombo
41
41
  shell {
42
42
  row_layout(:vertical) {
43
43
  pack false
44
- }
44
+ }
45
45
 
46
- text 'Hello, Combo!'
46
+ text 'Hello, Combo!'
47
47
 
48
48
  combo(:read_only) {
49
49
  selection bind(person, :country)
@@ -19,6 +19,9 @@
19
19
  # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
20
  # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
21
21
 
22
+ # This sample demonstrates the use of a `radio_group` in Glimmer, which provides terser syntax
23
+ # than HelloRadio for representing multiple radio buttons by relying on data-binding to
24
+ # automatically spawn the `radio` widgets based on available options on the model.
22
25
  class HelloRadioGroup
23
26
  class Person
24
27
  attr_accessor :gender, :age_group
@@ -1,5 +1,5 @@
1
1
  # Copyright (c) 2007-2020 Andy Maleh
2
- #
2
+ #
3
3
  # Permission is hereby granted, free of charge, to any person obtaining
4
4
  # a copy of this software and associated documentation files (the
5
5
  # "Software"), to deal in the Software without restriction, including
@@ -7,10 +7,10 @@
7
7
  # distribute, sublicense, and/or sell copies of the Software, and to
8
8
  # permit persons to whom the Software is furnished to do so, subject to
9
9
  # the following conditions:
10
- #
10
+ #
11
11
  # The above copyright notice and this permission notice shall be
12
12
  # included in all copies or substantial portions of the Software.
13
- #
13
+ #
14
14
  # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
15
  # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
16
  # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
@@ -0,0 +1,69 @@
1
+ # Copyright (c) 2007-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
+ class HelloSpinner
23
+ class Person
24
+ attr_accessor :donation
25
+ end
26
+
27
+ include Glimmer
28
+
29
+ def initialize
30
+ @person = Person.new
31
+ @person.donation = 500
32
+ end
33
+
34
+ def launch
35
+ shell {
36
+ grid_layout
37
+
38
+ text 'Hello, Spinner!'
39
+
40
+ label {
41
+ text 'Please select the amount you would like to donate to the poor:'
42
+ }
43
+
44
+ composite {
45
+ grid_layout 3, false
46
+
47
+ label {
48
+ text 'Amount:'
49
+ font style: :bold
50
+ }
51
+
52
+ label {
53
+ text '$'
54
+ }
55
+
56
+ spinner {
57
+ digits 2 # digits after the decimal point
58
+ minimum 500 # minimum value (including digits after the decimal point)
59
+ maximum 15000 # maximum value (including digits after the decimal point)
60
+ increment 500 # increment on up and down (including digits after the decimal point)
61
+ page_increment 5000 # page increment on page up and page down (including digits after the decimal point)
62
+ selection bind(@person, :donation) # selection must be set last if other properties are configured to ensure value is within bounds
63
+ }
64
+ }
65
+ }.open
66
+ end
67
+ end
68
+
69
+ HelloSpinner.new.launch