glimmer-dsl-swt 4.17.2.0 → 4.17.3.0

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.
@@ -27,10 +27,20 @@ module Glimmer
27
27
  #
28
28
  # Follows the Proxy Design Pattern
29
29
  class ImageProxy
30
+ class << self
31
+ def create(*args)
32
+ if args.size == 1 && args.first.is_a?(ImageProxy)
33
+ args.first
34
+ else
35
+ new(*args)
36
+ end
37
+ end
38
+ end
39
+
30
40
  include_package 'org.eclipse.swt.graphics'
31
41
 
32
42
  attr_reader :file_path, :jar_file_path, :image_data, :swt_image
33
-
43
+
34
44
  # Initializes a proxy for an SWT Image object
35
45
  #
36
46
  # Takes the same args as the SWT Image class
@@ -38,28 +48,41 @@ module Glimmer
38
48
  # and returns an image object.
39
49
  def initialize(*args)
40
50
  @args = args
41
- @file_path = @args.first if @args.first.is_a?(String) && @args.size == 1
42
- if @file_path
43
- if @file_path.start_with?('uri:classloader')
44
- @jar_file_path = @file_path
45
- @file_path = @jar_file_path.sub(/^uri\:classloader\:/, '').sub('//', '/') # the latter sub is needed for Mac
46
- object = java.lang.Object.new
47
- file_input_stream = object.java_class.resource_as_stream(file_path)
48
- buffered_file_input_stream = java.io.BufferedInputStream.new(file_input_stream)
49
- end
50
- @image_data = ImageData.new(buffered_file_input_stream || @file_path)
51
+ options = @args.last.is_a?(Hash) ? @args.delete_at(-1) : {}
52
+ options[:swt_image] = @args.first if @args.size == 1 && @args.first.is_a?(Image)
53
+ @file_path = @args.first if @args.size == 1 && @args.first.is_a?(String)
54
+ @args = @args.first if @args.size == 1 && @args.first.is_a?(Array)
55
+ if options&.keys&.include?(:swt_image)
56
+ @swt_image = options[:swt_image]
57
+ @image_data = @swt_image.image_data
58
+ elsif @file_path
59
+ @image_data = ImageData.new(input_stream || @file_path)
51
60
  @swt_image = Image.new(DisplayProxy.instance.swt_display, @image_data)
52
61
  else
53
62
  @swt_image = Image.new(*@args)
54
63
  @image_data = @swt_image.image_data
55
64
  end
56
65
  end
66
+
67
+ def input_stream
68
+ if @file_path.start_with?('uri:classloader')
69
+ @jar_file_path = @file_path
70
+ file_path = @jar_file_path.sub(/^uri\:classloader\:/, '').sub('//', '/') # the latter sub is needed for Mac
71
+ object = java.lang.Object.new
72
+ file_input_stream = object.java_class.resource_as_stream(file_path)
73
+ else
74
+ file_input_stream = java.io.FileInputStream.new(@file_path)
75
+ end
76
+ java.io.BufferedInputStream.new(file_input_stream) if file_input_stream
77
+ end
57
78
 
58
79
  def scale_to(width, height)
59
80
  scaled_image_data = image_data.scaledTo(width, height)
60
81
  device = swt_image.device
61
82
  swt_image.dispose
62
83
  @swt_image = Image.new(device, scaled_image_data)
84
+ @image_data = @swt_image.image_data
85
+ self
63
86
  end
64
87
 
65
88
  def method_missing(method, *args, &block)
@@ -128,7 +128,7 @@ module Glimmer
128
128
  def deconstruct(integer)
129
129
  constant_source_class.constants.reduce([]) do |found, c|
130
130
  constant_value = constant_source_class.const_get(c) rescue -1
131
- is_found = constant_value.is_a?(Integer) && (integer & constant_value) == integer
131
+ is_found = constant_value.is_a?(Integer) && (integer & constant_value) == constant_value
132
132
  is_found ? found += [c] : found
133
133
  end
134
134
  end
@@ -136,6 +136,7 @@ module Glimmer
136
136
  # Reverse engineer a style integer into a symbol
137
137
  # Useful for debugging
138
138
  def reverse_lookup(integer)
139
+ # TODO support looking up compound style mixes
139
140
  constant_source_class.constants.reduce([]) do |found, c|
140
141
  constant_value = constant_source_class.const_get(c) rescue -1
141
142
  is_found = constant_value.is_a?(Integer) && integer == constant_value
@@ -23,6 +23,7 @@ require 'glimmer/swt/widget_listener_proxy'
23
23
  require 'glimmer/swt/color_proxy'
24
24
  require 'glimmer/swt/font_proxy'
25
25
  require 'glimmer/swt/swt_proxy'
26
+ require 'glimmer/swt/display_proxy'
26
27
  require 'glimmer/swt/dnd_proxy'
27
28
  require 'glimmer/swt/image_proxy'
28
29
 
@@ -204,7 +205,7 @@ module Glimmer
204
205
  widget_custom_attribute = widget_custom_attribute_mapping[attribute_name.to_s]
205
206
  if widget_custom_attribute
206
207
  widget_custom_attribute[:setter][:invoker].call(@swt_widget, args)
207
- elsif @swt_widget.respond_to?(attribute_setter(attribute_name), args)
208
+ elsif @swt_widget.respond_to?(attribute_setter(attribute_name))
208
209
  apply_property_type_converters(attribute_name, args)
209
210
  @swt_widget.send(attribute_setter(attribute_name), *args) unless @swt_widget.send(attribute_getter(attribute_name)) == args.first
210
211
  else
@@ -678,23 +679,50 @@ module Glimmer
678
679
  end
679
680
  # TODO consider detecting type on widget method and automatically invoking right converter (e.g. :to_s for String, :to_i for Integer)
680
681
  @property_type_converters ||= {
682
+ alignment: -> (*value) {
683
+ SWTProxy[*value]
684
+ },
681
685
  :background => color_converter,
682
686
  :background_image => lambda do |value|
683
- image_proxy = nil
684
- if value.is_a?(String)
685
- image_proxy = ImageProxy.new(value)
686
- elsif value.is_a?(Array)
687
- image_proxy = ImageProxy.new(*value)
688
- end
689
- if image_proxy
687
+ image_proxy = ImageProxy.create(value)
688
+
689
+ if image_proxy&.file_path&.end_with?('.gif')
690
+ image = image_proxy.swt_image
691
+ width = image.get_bounds.width.to_i
692
+ height = image.get_bounds.height.to_i
693
+ image_number = 0
694
+ loader = ImageLoader.new
695
+ loader.load(image_proxy.input_stream)
696
+ image.dispose
697
+ image = org.eclipse.swt.graphics.Image.new(DisplayProxy.instance.swt_display,loader.data[0].scaledTo(width, height))
698
+ gc = org.eclipse.swt.graphics.GC.new(image)
699
+ on_paint_control { |event|
700
+ image_number = (image_number == loader.data.length - 1) ? 0 : image_number + 1
701
+ next_frame_data = loader.data[image_number]
702
+ image = org.eclipse.swt.graphics.Image.new(DisplayProxy.instance.swt_display, next_frame_data.scaledTo(width, height))
703
+ event.gc.drawImage(image, 0, 0, width, height, 0, 0, width, height)
704
+ image.dispose
705
+ }
706
+ Thread.new {
707
+ last_image_number = -1
708
+ while last_image_number != image_number
709
+ last_image_number = image_number
710
+ sync_exec {
711
+ redraw
712
+ }
713
+ delayTime = loader.data[image_number].delayTime.to_f / 100.0
714
+ sleep(delayTime)
715
+ end
716
+ };
717
+ image_proxy = nil
718
+ else
690
719
  on_swt_Resize do |resize_event|
691
720
  image_proxy.scale_to(@swt_widget.getSize.x, @swt_widget.getSize.y)
692
- @swt_widget.setBackgroundImage(image_proxy.swt_image)
693
- end
694
- image_proxy.swt_image
695
- else
696
- value
697
- end
721
+ @swt_widget.setBackgroundImage(image_proxy.swt_image)
722
+ end
723
+ end
724
+
725
+ image_proxy&.swt_image
698
726
  end,
699
727
  :cursor => lambda do |value|
700
728
  cursor_proxy = nil
@@ -715,34 +743,18 @@ module Glimmer
715
743
  end
716
744
  end,
717
745
  :image => lambda do |value|
718
- if value.is_a?(String)
719
- ImageProxy.new(value).swt_image
720
- elsif value.is_a?(Array)
721
- ImageProxy.new(*value).swt_image
722
- else
723
- value
724
- end
746
+ ImageProxy.create(value).swt_image
725
747
  end,
726
748
  :images => lambda do |array|
727
749
  array.to_a.map do |value|
728
- if value.is_a?(String)
729
- ImageProxy.new(value).swt_image
730
- elsif value.is_a?(Array)
731
- ImageProxy.new(*value).swt_image
732
- else
733
- value
734
- end
750
+ ImageProxy.create(value).swt_image
735
751
  end.to_java(Image)
736
752
  end,
737
753
  :items => lambda do |value|
738
754
  value.to_java :string
739
755
  end,
740
756
  :text => lambda do |value|
741
- if swt_widget.is_a?(Browser)
742
- value.to_s
743
- else
744
- value.to_s
745
- end
757
+ value.to_s
746
758
  end,
747
759
  :transfer => lambda do |value|
748
760
  value = value.first if value.is_a?(Array) && value.size == 1 && value.first.is_a?(Array)
@@ -211,9 +211,9 @@ module Glimmer
211
211
 
212
212
  # This method ensures it has an instance method not coming from Glimmer DSL
213
213
  def has_instance_method?(method_name)
214
- respond_to?(method_name) &&
215
- !swt_widget.respond_to?(method_name) &&
216
- !method(method_name)&.source_location&.first&.include?('glimmer/dsl/engine.rb') &&
214
+ respond_to?(method_name) and
215
+ !swt_widget&.respond_to?(method_name) and
216
+ !method(method_name)&.source_location&.first&.include?('glimmer/dsl/engine.rb') and
217
217
  !method(method_name)&.source_location&.first&.include?('glimmer/swt/widget_proxy.rb')
218
218
  end
219
219
 
@@ -273,7 +273,10 @@ module Glimmer
273
273
 
274
274
  def execute_hooks(hook_name)
275
275
  self.class.instance_variable_get("@#{hook_name}_blocks")&.each do |hook_block|
276
- instance_exec(&hook_block)
276
+ temp_method_name = "#{hook_name}_block_#{hook_block.hash.abs}_#{(Time.now.to_f * 1_000_000).to_i}"
277
+ singleton_class.define_method(temp_method_name, &hook_block)
278
+ send(temp_method_name)
279
+ singleton_class.send(:remove_method, temp_method_name)
277
280
  end
278
281
  end
279
282
  end
@@ -124,105 +124,8 @@ class ContactManager
124
124
  Jason
125
125
  Emma
126
126
  Olivia
127
- Ava
128
- Isabella
129
- Sophia
130
- Charlotte
131
- Mia
132
- Amelia
133
- Harper
134
- Evelyn
135
- Abigail
136
- Emily
137
- Elizabeth
138
- Mila
139
- Ella
140
- Avery
141
- Sofia
142
- Camila
143
- Aria
144
- Scarlett
145
- Victoria
146
- Madison
147
- Luna
148
- Grace
149
- Chloe
150
- Penelope
151
- Layla
152
- Riley
153
- Zoey
154
- Nora
155
- Lily
156
- Eleanor
157
- Hannah
158
- Lillian
159
- Addison
160
- Aubrey
161
- Ellie
162
- Stella
163
- Natalie
164
- Zoe
165
- Leah
166
- Hazel
167
- Violet
168
- Aurora
169
- Savannah
170
- Audrey
171
- Brooklyn
172
- Bella
173
- Claire
174
- Skylar
175
- Lucy
176
- Paisley
177
- Everly
178
- Anna
179
- Caroline
180
- Nova
181
- Genesis
182
- Emilia
183
- Kennedy
184
- Samantha
185
- Maya
186
- Willow
187
- Kinsley
188
- Naomi
189
- Aaliyah
190
- Elena
191
- Sarah
192
- Ariana
193
- Allison
194
- Gabriella
195
- Alice
196
- Madelyn
197
- Cora
198
- Ruby
199
- Eva
200
- Serenity
201
- Autumn
202
- Adeline
203
- Hailey
204
- Gianna
205
- Valentina
206
- Isla
207
- Eliana
208
- Quinn
209
- Nevaeh
210
- Ivy
211
- Sadie
212
- Piper
213
- Lydia
214
- Alexa
215
- Josephine
216
- Emery
217
- Julia
218
- Delilah
219
- Arianna
220
- Vivian
221
- Kaylee
222
- Sophie
223
- Brielle
224
- Madeline
225
127
  ]
128
+
226
129
  NAMES_LAST = %w[
227
130
  Smith
228
131
  Johnson
@@ -235,8 +138,9 @@ class ContactManager
235
138
  Anderson
236
139
  Taylor
237
140
  ]
141
+
238
142
  def initialize(contacts = nil)
239
- @contacts = contacts || 1000.times.map do |n|
143
+ @contacts = contacts || 100.times.map do |n|
240
144
  random_first_name_index = (rand*NAMES_FIRST.size).to_i
241
145
  random_last_name_index = (rand*NAMES_LAST.size).to_i
242
146
  first_name = NAMES_FIRST[random_first_name_index]
@@ -23,30 +23,34 @@ class Person
23
23
  attr_accessor :country, :country_options
24
24
 
25
25
  def initialize
26
- self.country_options=["", "Canada", "US", "Mexico"]
27
- self.country = "Canada"
26
+ self.country_options = ['', 'Canada', 'US', 'Mexico']
27
+ reset_country
28
28
  end
29
29
 
30
30
  def reset_country
31
- self.country = "Canada"
31
+ self.country = 'Canada'
32
32
  end
33
33
  end
34
34
 
35
35
  class HelloCombo
36
36
  include Glimmer
37
+
37
38
  def launch
38
39
  person = Person.new
39
40
 
40
41
  shell {
41
- fill_layout :vertical
42
- text 'Hello, Combo!'
42
+ row_layout(:vertical) {
43
+ pack false
44
+ }
45
+
46
+ text 'Hello, Combo!'
43
47
 
44
48
  combo(:read_only) {
45
49
  selection bind(person, :country)
46
50
  }
47
51
 
48
52
  button {
49
- text "Reset Selection"
53
+ text 'Reset Selection'
50
54
 
51
55
  on_widget_selected do
52
56
  person.reset_country
@@ -0,0 +1,155 @@
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
+ require 'date'
23
+
24
+ # This class declares an `email_shell` custom shell, aka custom window (by convention)
25
+ # Used to view an email message
26
+ class EmailShell
27
+ include Glimmer::UI::CustomShell
28
+
29
+ # multiple options without default values
30
+ options :date, :subject, :from, :message
31
+
32
+ # single option with default value
33
+ option :to, default: '"John Irwin" <john.irwin@example.com>'
34
+
35
+ before_body {
36
+ @swt_style |= swt(:shell_trim, :modeless)
37
+ }
38
+
39
+ body {
40
+ # pass received swt_style through to shell to customize it (e.g. :dialog_trim for a blocking shell)
41
+ shell(swt_style) {
42
+ grid_layout(2, false)
43
+
44
+ text subject
45
+
46
+ label {
47
+ text 'Date:'
48
+ }
49
+ label {
50
+ text date
51
+ }
52
+
53
+ label {
54
+ text 'From:'
55
+ }
56
+ label {
57
+ text from
58
+ }
59
+
60
+ label {
61
+ text 'To:'
62
+ }
63
+ label {
64
+ text to
65
+ }
66
+
67
+ label {
68
+ text 'Subject:'
69
+ }
70
+ label {
71
+ text subject
72
+ }
73
+
74
+ label {
75
+ layout_data(:fill, :fill, true, true) {
76
+ horizontal_span 2
77
+ vertical_indent 10
78
+ }
79
+
80
+ background :white
81
+ text message
82
+ }
83
+ }
84
+ }
85
+
86
+ end
87
+
88
+ class HelloCustomShell
89
+ # including Glimmer enables the Glimmer DSL syntax, including auto-discovery of the `email_shell` custom widget
90
+ include Glimmer
91
+
92
+ Email = Struct.new(:date, :subject, :from, :message, keyword_init: true)
93
+ EmailSystem = Struct.new(:emails, keyword_init: true)
94
+
95
+ def initialize
96
+ @email_system = EmailSystem.new(
97
+ emails: [
98
+ Email.new(date: DateTime.new(2029, 10, 22, 11, 3, 0).strftime('%F %I:%M %p'), subject: '3rd Week Report', from: '"Dianne Tux" <dianne.tux@example.com>', message: "Hello,\n\nI was wondering if you'd like to go over the weekly report sometime this afternoon.\n\nDianne"),
99
+ Email.new(date: DateTime.new(2029, 10, 21, 8, 1, 0).strftime('%F %I:%M %p'), subject: 'Glimmer Upgrade v100.0', from: '"Robert McGabbins" <robert.mcgabbins@example.com>', message: "Team,\n\nWe are upgrading to Glimmer version 100.0.\n\nEveryone pull the latest code!\n\nRegards,\n\nRobert McGabbins"),
100
+ Email.new(date: DateTime.new(2029, 10, 19, 16, 58, 0).strftime('%F %I:%M %p'), subject: 'Christmas Party', from: '"Lisa Ferreira" <lisa.ferreira@example.com>', message: "Merry Christmas,\n\nAll office Christmas Party arrangements have been set\n\nMake sure to bring a Secret Santa gift\n\nBest regards,\n\nLisa Ferreira"),
101
+ Email.new(date: DateTime.new(2029, 10, 16, 9, 43, 0).strftime('%F %I:%M %p'), subject: 'Glimmer Upgrade v99.0', from: '"Robert McGabbins" <robert.mcgabbins@example.com>', message: "Team,\n\nWe are upgrading to Glimmer version 99.0.\n\nEveryone pull the latest code!\n\nRegards,\n\nRobert McGabbins"),
102
+ Email.new(date: DateTime.new(2029, 10, 15, 11, 2, 0).strftime('%F %I:%M %p'), subject: '2nd Week Report', from: '"Dianne Tux" <dianne.tux@example.com>', message: "Hello,\n\nI was wondering if you'd like to go over the weekly report sometime this afternoon.\n\nDianne"),
103
+ Email.new(date: DateTime.new(2029, 10, 2, 10, 34, 0).strftime('%F %I:%M %p'), subject: 'Glimmer Upgrade v98.0', from: '"Robert McGabbins" <robert.mcgabbins@example.com>', message: "Team,\n\nWe are upgrading to Glimmer version 98.0.\n\nEveryone pull the latest code!\n\nRegards,\n\nRobert McGabbins"),
104
+ ]
105
+ )
106
+ end
107
+
108
+ def launch
109
+ shell {
110
+ grid_layout
111
+
112
+ text 'Hello, Custom Shell!'
113
+
114
+ label {
115
+ font height: 24, style: :bold
116
+ text 'Emails:'
117
+ }
118
+
119
+ label {
120
+ font height: 18
121
+ text 'Click an email to view its message'
122
+ }
123
+
124
+ table {
125
+ layout_data :fill, :fill, true, true
126
+
127
+ table_column {
128
+ text 'Date:'
129
+ width 180
130
+ }
131
+ table_column {
132
+ text 'Subject:'
133
+ width 180
134
+ }
135
+ table_column {
136
+ text 'From:'
137
+ width 360
138
+ }
139
+
140
+ items bind(@email_system, :emails), column_properties(:date, :subject, :from)
141
+
142
+ on_mouse_up { |event|
143
+ email = event.table_item.get_data
144
+ Thread.new do
145
+ async_exec {
146
+ email_shell(date: email.date, subject: email.subject, from: email.from, message: email.message).open
147
+ }
148
+ end
149
+ }
150
+ }
151
+ }.open
152
+ end
153
+ end
154
+
155
+ HelloCustomShell.new.launch