glimmer-dsl-swt 4.18.1.0 → 4.18.2.3
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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +45 -0
- data/README.md +136 -46
- data/VERSION +1 -1
- data/glimmer-dsl-swt.gemspec +10 -4
- data/lib/glimmer/dsl/swt/display_expression.rb +3 -3
- data/lib/glimmer/dsl/swt/property_expression.rb +2 -1
- data/lib/glimmer/dsl/swt/shape_expression.rb +1 -1
- data/lib/glimmer/rake_task/list.rb +5 -5
- data/lib/glimmer/rake_task/package.rb +9 -9
- data/lib/glimmer/rake_task/scaffold.rb +36 -36
- data/lib/glimmer/swt/custom/animation.rb +163 -36
- data/lib/glimmer/swt/custom/code_text.rb +2 -1
- data/lib/glimmer/swt/custom/shape.rb +83 -18
- data/lib/glimmer/swt/display_proxy.rb +2 -1
- data/lib/glimmer/swt/widget_proxy.rb +4 -6
- data/lib/glimmer/ui/custom_shell.rb +13 -0
- data/samples/elaborate/meta_sample.rb +22 -1
- data/samples/elaborate/tetris.rb +102 -0
- data/samples/elaborate/tetris/model/block.rb +48 -0
- data/samples/elaborate/tetris/model/game.rb +116 -0
- data/samples/elaborate/tetris/model/tetromino.rb +228 -0
- data/samples/elaborate/tetris/view/block.rb +45 -0
- data/samples/elaborate/tetris/view/playfield.rb +49 -0
- data/samples/hello/hello_canvas.rb +7 -6
- data/samples/hello/hello_canvas_animation.rb +1 -1
- metadata +22 -14
@@ -1,5 +1,5 @@
|
|
1
1
|
# Copyright (c) 2007-2021 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
|
@@ -30,7 +30,8 @@ module Glimmer
|
|
30
30
|
args.size > 0 and
|
31
31
|
parent.respond_to?(:set_attribute) and
|
32
32
|
parent.respond_to?(:has_attribute?) and
|
33
|
-
parent.has_attribute?(keyword, *args)
|
33
|
+
parent.has_attribute?(keyword, *args) and
|
34
|
+
!(parent.respond_to?(:swt_widget) && parent.swt_widget.class == org.eclipse.swt.widgets.Canvas && keyword == 'image')
|
34
35
|
end
|
35
36
|
|
36
37
|
def interpret(parent, keyword, *args, &block)
|
@@ -1,5 +1,5 @@
|
|
1
1
|
# Copyright (c) 2007-2021 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
|
@@ -57,11 +57,11 @@ module Glimmer
|
|
57
57
|
lines = `gem search -d #{gem_prefix}`.split("\n")
|
58
58
|
gems = lines.slice_before {|l| l.match(REGEX_GEM_LINE) }.to_a
|
59
59
|
gems = gems.map do |gem|
|
60
|
-
{
|
60
|
+
{
|
61
61
|
name: gem[0].match(REGEX_GEM_LINE)[1],
|
62
62
|
version: gem[0].match(REGEX_GEM_LINE)[2],
|
63
63
|
author: gem[1].strip,
|
64
|
-
description: gem[4..-1]
|
64
|
+
description: gem[4..-1]&.map(&:strip)&.join(' ').to_s
|
65
65
|
}
|
66
66
|
end.select do |gem|
|
67
67
|
query.nil? || "#{gem[:name]} #{gem[:author]} #{gem[:description]}".downcase.include?(query.to_s.downcase)
|
@@ -1,5 +1,5 @@
|
|
1
1
|
# Copyright (c) 2007-2021 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
|
@@ -27,7 +27,7 @@ module Glimmer
|
|
27
27
|
module Package
|
28
28
|
class << self
|
29
29
|
attr_accessor :javapackager_extra_args
|
30
|
-
alias jpackage_extra_args
|
30
|
+
alias jpackage_extra_args javapackager_extra_args
|
31
31
|
|
32
32
|
def clean
|
33
33
|
require 'fileutils'
|
@@ -48,7 +48,7 @@ module Glimmer
|
|
48
48
|
FileUtils.mkdir_p('vendor/jars')
|
49
49
|
command = "lock_jars --vendor-dir vendor/jars"
|
50
50
|
puts command
|
51
|
-
system command
|
51
|
+
system command
|
52
52
|
end
|
53
53
|
|
54
54
|
def config
|
@@ -78,18 +78,18 @@ module Glimmer
|
|
78
78
|
else
|
79
79
|
puts 'Warbler executable "warble" is missing!'
|
80
80
|
end
|
81
|
-
end
|
81
|
+
end
|
82
82
|
end
|
83
83
|
|
84
84
|
def jar
|
85
85
|
FileUtils.mkdir_p('dist')
|
86
86
|
puts "Generating JAR with Warbler..."
|
87
87
|
system "jruby -S gem install warbler -v2.0.5 --no-document" unless warbler_exists?
|
88
|
-
system('warble')
|
88
|
+
system('warble')
|
89
89
|
end
|
90
90
|
|
91
91
|
def native(native_type=nil, native_extra_args)
|
92
|
-
puts "Generating native executable with javapackager/jpackage..."
|
92
|
+
puts "Generating native executable with javapackager/jpackage..."
|
93
93
|
java_version = `java -version`
|
94
94
|
puts "WARNING! Glimmer Packaging Pre-Requisite Java Version 1.8.0_241 Is Not Found!" unless java_version.include?('1.8.0_241')
|
95
95
|
require 'facets/string/titlecase'
|
@@ -125,7 +125,7 @@ module Glimmer
|
|
125
125
|
command += " #{ENV['JAVAPACKAGER_EXTRA_ARGS']} " if ENV['JAVAPACKAGER_EXTRA_ARGS']
|
126
126
|
command += " #{native_extra_args} " if native_extra_args
|
127
127
|
puts command
|
128
|
-
system command
|
128
|
+
system command
|
129
129
|
end
|
130
130
|
|
131
131
|
private
|
@@ -1,5 +1,5 @@
|
|
1
1
|
# Copyright (c) 2007-2021 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
|
@@ -42,6 +42,7 @@ module Glimmer
|
|
42
42
|
*.gem
|
43
43
|
*.rbc
|
44
44
|
/.config
|
45
|
+
/.mvn/
|
45
46
|
/coverage/
|
46
47
|
/InstalledFiles
|
47
48
|
/pkg/
|
@@ -97,9 +98,9 @@ module Glimmer
|
|
97
98
|
.gladiator
|
98
99
|
|
99
100
|
# Glimmer
|
100
|
-
dist
|
101
|
-
packages
|
102
|
-
vendor/jars
|
101
|
+
/dist/
|
102
|
+
/packages/
|
103
|
+
/vendor/jars/
|
103
104
|
MULTI_LINE_STRING
|
104
105
|
|
105
106
|
GEMFILE = <<~MULTI_LINE_STRING
|
@@ -113,7 +114,6 @@ module Glimmer
|
|
113
114
|
|
114
115
|
group :development do
|
115
116
|
gem 'rspec', '~> 3.5.0'
|
116
|
-
gem 'git-glimmer', '1.7.0'
|
117
117
|
gem 'juwelier', '2.4.9'
|
118
118
|
gem 'warbler', '2.0.5'
|
119
119
|
gem 'simplecov', '>= 0'
|
@@ -133,12 +133,12 @@ module Glimmer
|
|
133
133
|
gem_summary = human_name(app_name)
|
134
134
|
return puts("The directory '#{gem_name}' already exists. Please either remove or pick a different name.") if Dir.exist?(gem_name)
|
135
135
|
system "jruby -S gem install juwelier -v2.4.9 --no-document" unless juwelier_exists?
|
136
|
-
system "jruby -
|
136
|
+
system "jruby -S juwelier --markdown --rspec --summary '#{gem_summary}' --description '#{gem_summary}' #{gem_name}"
|
137
137
|
return puts('Your Git user.name and/or github.user are missing! Please add in for Juwelier to help Glimmer with Scaffolding.') if `git config --get github.user`.strip.empty? && `git config --get user.name`.strip.empty?
|
138
138
|
cd gem_name
|
139
139
|
rm_rf 'lib'
|
140
140
|
write '.gitignore', GITIGNORE
|
141
|
-
write '.ruby-version', RUBY_VERSION
|
141
|
+
write '.ruby-version', RUBY_VERSION
|
142
142
|
write '.ruby-gemset', app_name
|
143
143
|
write 'VERSION', '1.0.0'
|
144
144
|
write 'LICENSE.txt', "Copyright (c) #{Time.now.year} #{app_name}"
|
@@ -178,7 +178,7 @@ module Glimmer
|
|
178
178
|
system "bundle"
|
179
179
|
system "rspec --init"
|
180
180
|
else
|
181
|
-
system "bash -c '#{RVM_FUNCTION}\n cd .\n bundle\n rspec --init\n'"
|
181
|
+
system "bash -c '#{RVM_FUNCTION}\n cd .\n bundle\n rspec --init\n'"
|
182
182
|
end
|
183
183
|
write 'spec/spec_helper.rb', spec_helper_file
|
184
184
|
if OS.windows?
|
@@ -191,7 +191,7 @@ module Glimmer
|
|
191
191
|
else
|
192
192
|
system "glimmer run"
|
193
193
|
end
|
194
|
-
end
|
194
|
+
end
|
195
195
|
end
|
196
196
|
|
197
197
|
def custom_shell(custom_shell_name, namespace, shell_type = nil, shell_options = {})
|
@@ -231,11 +231,11 @@ module Glimmer
|
|
231
231
|
end
|
232
232
|
return puts("The directory '#{gem_name}' already exists. Please either remove or pick a different name.") if Dir.exist?(gem_name)
|
233
233
|
system "jruby -S gem install juwelier -v2.4.9 --no-document" unless juwelier_exists?
|
234
|
-
system "jruby -
|
234
|
+
system "jruby -S juwelier --markdown --rspec --summary '#{gem_summary}' --description '#{gem_summary}' #{gem_name}"
|
235
235
|
return puts('Your Git user.name and/or github.user are missing! Please add in for Juwelier to help Glimmer with Scaffolding.') if `git config --get github.user`.strip.empty? && `git config --get user.name`.strip.empty?
|
236
236
|
cd gem_name
|
237
237
|
write '.gitignore', GITIGNORE
|
238
|
-
write '.ruby-version', RUBY_VERSION
|
238
|
+
write '.ruby-version', RUBY_VERSION
|
239
239
|
write '.ruby-gemset', gem_name
|
240
240
|
write 'VERSION', '1.0.0'
|
241
241
|
write 'Gemfile', GEMFILE
|
@@ -256,7 +256,7 @@ module Glimmer
|
|
256
256
|
system "rspec --init"
|
257
257
|
else
|
258
258
|
system "bash -c '#{RVM_FUNCTION}\n cd .\n bundle\n rspec --init\n'"
|
259
|
-
end
|
259
|
+
end
|
260
260
|
write 'spec/spec_helper.rb', spec_helper_file
|
261
261
|
|
262
262
|
mkdir_p 'package/windows'
|
@@ -283,7 +283,7 @@ module Glimmer
|
|
283
283
|
system "open packages/bundles/#{human_name(custom_shell_name).gsub(' ', '\ ')}.app" if OS.mac?
|
284
284
|
else
|
285
285
|
system "glimmer run"
|
286
|
-
end
|
286
|
+
end
|
287
287
|
end
|
288
288
|
puts "Finished creating #{gem_name} Ruby gem."
|
289
289
|
puts 'Edit Rakefile to configure gem details.'
|
@@ -305,11 +305,11 @@ module Glimmer
|
|
305
305
|
|
306
306
|
return puts("The directory '#{gem_name}' already exists. Please either remove or pick a different name.") if Dir.exist?(gem_name)
|
307
307
|
system "jruby -S gem install juwelier -v2.4.9 --no-document" unless juwelier_exists?
|
308
|
-
system "jruby -
|
308
|
+
system "jruby -S juwelier --markdown --rspec --summary '#{gem_summary}' --description '#{gem_summary}' #{gem_name}"
|
309
309
|
return puts('Your Git user.name and/or github.user are missing! Please add in for Juwelier to help Glimmer with Scaffolding.') if `git config --get github.user`.strip.empty? && `git config --get user.name`.strip.empty?
|
310
310
|
cd gem_name
|
311
311
|
write '.gitignore', GITIGNORE
|
312
|
-
write '.ruby-version', RUBY_VERSION
|
312
|
+
write '.ruby-version', RUBY_VERSION
|
313
313
|
write '.ruby-gemset', gem_name
|
314
314
|
write 'VERSION', '1.0.0'
|
315
315
|
write 'Gemfile', GEMFILE
|
@@ -397,9 +397,9 @@ module Glimmer
|
|
397
397
|
class #{class_name(app_name)}
|
398
398
|
include Glimmer
|
399
399
|
|
400
|
-
APP_ROOT = File.expand_path('../..', __FILE__)
|
400
|
+
APP_ROOT = File.expand_path('../..', __FILE__)
|
401
401
|
VERSION = File.read(File.join(APP_ROOT, 'VERSION'))
|
402
|
-
LICENSE = File.read(File.join(APP_ROOT, 'LICENSE.txt'))
|
402
|
+
LICENSE = File.read(File.join(APP_ROOT, 'LICENSE.txt'))
|
403
403
|
|
404
404
|
def open
|
405
405
|
app_view.open
|
@@ -443,7 +443,7 @@ module Glimmer
|
|
443
443
|
|
444
444
|
launcher = Glimmer::Launcher.new([runner] + ARGV)
|
445
445
|
launcher.launch
|
446
|
-
end
|
446
|
+
end
|
447
447
|
MULTI_LINE_STRING
|
448
448
|
end
|
449
449
|
|
@@ -482,7 +482,7 @@ module Glimmer
|
|
482
482
|
|
483
483
|
launcher = Glimmer::Launcher.new([runner] + ARGV)
|
484
484
|
launcher.launch
|
485
|
-
end
|
485
|
+
end
|
486
486
|
MULTI_LINE_STRING
|
487
487
|
end
|
488
488
|
|
@@ -502,15 +502,15 @@ module Glimmer
|
|
502
502
|
end
|
503
503
|
spec_pattern_line_index = lines.index(lines.detect {|l| l.include?('spec.pattern =') })
|
504
504
|
lines.insert(spec_pattern_line_index+1, " spec.ruby_opts = [Glimmer::Launcher.jruby_os_specific_options]")
|
505
|
-
lines << "\nrequire 'glimmer/rake_task'\n"
|
505
|
+
lines << "\nrequire 'glimmer/rake_task'\n"
|
506
506
|
file_content = lines.join("\n")
|
507
507
|
if custom_shell_name
|
508
|
-
file_content << <<~MULTI_LINE_STRING
|
508
|
+
file_content << <<~MULTI_LINE_STRING
|
509
509
|
Glimmer::RakeTask::Package.javapackager_extra_args =
|
510
510
|
" -name '#{human_name(custom_shell_name)}'" +
|
511
511
|
" -title '#{human_name(custom_shell_name)}'" +
|
512
512
|
" -Bmac.CFBundleName='#{human_name(custom_shell_name)}'" +
|
513
|
-
" -Bmac.CFBundleIdentifier='org.#{namespace ? compact_name(namespace) : compact_name(custom_shell_name)}.application.#{compact_name(custom_shell_name).camelcase(:upper)}'"
|
513
|
+
" -Bmac.CFBundleIdentifier='org.#{namespace ? compact_name(namespace) : compact_name(custom_shell_name)}.application.#{compact_name(custom_shell_name).camelcase(:upper)}'"
|
514
514
|
# " -BlicenseType=" +
|
515
515
|
# " -Bmac.category=" +
|
516
516
|
# " -Bmac.signing-key-developer-id-app="
|
@@ -575,8 +575,8 @@ module Glimmer
|
|
575
575
|
if %i[gem app desktopify].include?(shell_type)
|
576
576
|
custom_shell_file_content += <<-MULTI_LINE_STRING
|
577
577
|
before_body {
|
578
|
-
Display.
|
579
|
-
Display.
|
578
|
+
Display.app_name = '#{shell_type == :gem ? human_name(custom_shell_name) : human_name(namespace)}'
|
579
|
+
Display.app_version = VERSION
|
580
580
|
@display = display {
|
581
581
|
on_about {
|
582
582
|
display_about_dialog
|
@@ -600,7 +600,7 @@ module Glimmer
|
|
600
600
|
## Use after_body block to setup observers for widgets in body
|
601
601
|
#
|
602
602
|
# after_body {
|
603
|
-
#
|
603
|
+
#
|
604
604
|
# }
|
605
605
|
|
606
606
|
## Add widget content inside custom shell body
|
@@ -616,10 +616,10 @@ module Glimmer
|
|
616
616
|
MULTI_LINE_STRING
|
617
617
|
|
618
618
|
if shell_type == :desktopify
|
619
|
-
custom_shell_file_content += <<-MULTI_LINE_STRING
|
619
|
+
custom_shell_file_content += <<-MULTI_LINE_STRING
|
620
620
|
browser {
|
621
|
-
url "#{shell_options[:website]}"
|
622
|
-
}
|
621
|
+
url "#{shell_options[:website]}"
|
622
|
+
}
|
623
623
|
MULTI_LINE_STRING
|
624
624
|
else
|
625
625
|
custom_shell_file_content += <<-MULTI_LINE_STRING
|
@@ -628,7 +628,7 @@ module Glimmer
|
|
628
628
|
text bind(self, :greeting)
|
629
629
|
font height: 40
|
630
630
|
layout_data :fill, :center, true, true
|
631
|
-
}
|
631
|
+
}
|
632
632
|
MULTI_LINE_STRING
|
633
633
|
end
|
634
634
|
|
@@ -690,7 +690,7 @@ module Glimmer
|
|
690
690
|
text 'Greeting'
|
691
691
|
font style: :bold
|
692
692
|
[
|
693
|
-
'Hello, World!',
|
693
|
+
'Hello, World!',
|
694
694
|
'Howdy, Partner!'
|
695
695
|
].each do |greeting_text|
|
696
696
|
button(:radio) {
|
@@ -733,19 +733,19 @@ module Glimmer
|
|
733
733
|
#
|
734
734
|
#
|
735
735
|
# before_body {
|
736
|
-
#
|
736
|
+
#
|
737
737
|
# }
|
738
738
|
|
739
739
|
## Use after_body block to setup observers for widgets in body
|
740
740
|
#
|
741
741
|
# after_body {
|
742
|
-
#
|
742
|
+
#
|
743
743
|
# }
|
744
744
|
|
745
745
|
## Add widget content under custom widget body
|
746
746
|
##
|
747
|
-
## If you want to add a shell as the top-most widget,
|
748
|
-
## consider creating a custom shell instead
|
747
|
+
## If you want to add a shell as the top-most widget,
|
748
|
+
## consider creating a custom shell instead
|
749
749
|
## (Glimmer::UI::CustomShell offers shell convenience methods, like show and hide)
|
750
750
|
#
|
751
751
|
body {
|
@@ -28,68 +28,127 @@ module Glimmer
|
|
28
28
|
class Animation
|
29
29
|
include Properties # TODO rename to Properties
|
30
30
|
|
31
|
-
|
31
|
+
class << self
|
32
|
+
def schedule_frame_animation(animation, &frame_animation_block)
|
33
|
+
frame_animation_queue(animation).prepend(frame_animation_block)
|
34
|
+
swt_display.async_exec do
|
35
|
+
frame_animation_queue(next_animation)&.pop&.call
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
def next_animation
|
40
|
+
animation = nil
|
41
|
+
while frame_animation_queues.values.reduce(:+)&.any? && (animation.nil? || frame_animation_queue(animation).last.nil?)
|
42
|
+
animation = frame_animation_queues.keys[next_animation_index]
|
43
|
+
frame_animation_queues.delete(animation) if frame_animation_queues.values.reduce(:+)&.any? && !animation.nil? && frame_animation_queue(animation).empty?
|
44
|
+
end
|
45
|
+
animation
|
46
|
+
end
|
47
|
+
|
48
|
+
def next_animation_index
|
49
|
+
next_schedule_index % frame_animation_queues.keys.size
|
50
|
+
end
|
51
|
+
|
52
|
+
def next_schedule_index
|
53
|
+
unless defined? @@next_schedule_index
|
54
|
+
@@next_schedule_index = 0
|
55
|
+
else
|
56
|
+
@@next_schedule_index += 1
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
def frame_animation_queues
|
61
|
+
unless defined? @@frame_animation_queues
|
62
|
+
@@frame_animation_queues = {}
|
63
|
+
end
|
64
|
+
@@frame_animation_queues
|
65
|
+
end
|
66
|
+
|
67
|
+
def frame_animation_queue(animation)
|
68
|
+
frame_animation_queues[animation] ||= []
|
69
|
+
end
|
70
|
+
|
71
|
+
def swt_display
|
72
|
+
unless defined? @@swt_display
|
73
|
+
@@swt_display = DisplayProxy.instance.swt_display
|
74
|
+
end
|
75
|
+
@@swt_display
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
attr_reader :parent, :options, :frame_index, :cycle
|
32
80
|
alias current_frame_index frame_index
|
33
|
-
attr_accessor :frame_block, :every, :
|
81
|
+
attr_accessor :frame_block, :every, :cycle_count, :frame_count, :started, :duration_limit
|
82
|
+
alias started? started
|
34
83
|
# TODO consider supporting an async: false option
|
35
84
|
|
36
85
|
def initialize(parent)
|
37
86
|
@parent = parent
|
38
87
|
@started = true
|
39
88
|
@frame_index = 0
|
89
|
+
@cycle_count_index = 0
|
90
|
+
@start_number = 0 # denotes the number of starts (increments on every start)
|
91
|
+
self.class.swt_display # ensures initializing variable to set from GUI thread
|
40
92
|
end
|
41
93
|
|
42
94
|
def post_add_content
|
43
95
|
@parent.on_widget_disposed { stop }
|
44
|
-
start if
|
96
|
+
start if started?
|
45
97
|
end
|
46
|
-
|
98
|
+
|
99
|
+
# Starts an animation that is indefinite or has never been started before (i.e. having `started: false` option).
|
100
|
+
# Otherwise, resumes a stopped animation that has not been completed.
|
47
101
|
def start
|
48
|
-
|
49
|
-
|
102
|
+
return if @start_number > 0 && started?
|
103
|
+
@start_number += 1
|
104
|
+
@started = true
|
105
|
+
@start_time = Time.now
|
106
|
+
@original_start_time = @start_time if @duration.nil?
|
107
|
+
# TODO track when finished in a variable for finite animations (whether by frame count, cycle count, or duration limit)
|
50
108
|
Thread.new do
|
51
|
-
|
52
|
-
block_args = [@frame_index]
|
53
|
-
block_args << @cycle[@frame_index % @cycle.length] if @cycle.is_a?(Array)
|
54
|
-
swt_display.async_exec do
|
55
|
-
@parent.clear_shapes
|
56
|
-
@parent.content {
|
57
|
-
frame_block.call(*block_args)
|
58
|
-
}
|
59
|
-
end
|
60
|
-
@frame_index += 1
|
61
|
-
sleep(every) if every.is_a?(Numeric)
|
62
|
-
end
|
63
|
-
|
109
|
+
start_number = @start_number
|
64
110
|
if cycle_count.is_a?(Integer) && cycle.is_a?(Array)
|
65
111
|
(cycle_count * cycle.length).times do
|
66
|
-
break
|
67
|
-
begin
|
68
|
-
frame_rendering_block.call
|
69
|
-
rescue => e
|
70
|
-
Glimmer::Config.logger.error {e}
|
71
|
-
break
|
72
|
-
end
|
112
|
+
break unless draw_frame(start_number)
|
73
113
|
end
|
74
114
|
else
|
75
115
|
loop do
|
76
|
-
break
|
77
|
-
|
78
|
-
frame_rendering_block.call
|
79
|
-
rescue => e
|
80
|
-
Glimmer::Config.logger.error {e}
|
81
|
-
break
|
82
|
-
end
|
116
|
+
# this code has to be duplicated to break from a loop (break keyword only works when literally in a loop block)
|
117
|
+
break unless draw_frame(start_number)
|
83
118
|
end
|
84
119
|
end
|
85
|
-
@started = false
|
86
120
|
end
|
87
121
|
end
|
88
122
|
|
89
123
|
def stop
|
124
|
+
return if stopped?
|
90
125
|
@started = false
|
126
|
+
@duration = (Time.now - @start_time) + @duration.to_f if duration_limited? && !@start_time.nil?
|
127
|
+
end
|
128
|
+
|
129
|
+
# Restarts an animation (whether indefinite or not and whether stopped or not)
|
130
|
+
def restart
|
131
|
+
@original_start_time = @start_time = nil
|
132
|
+
@duration = nil
|
133
|
+
@frame_index = 0
|
134
|
+
@cycle_count_index = 0
|
135
|
+
stop
|
136
|
+
start
|
137
|
+
end
|
138
|
+
|
139
|
+
def stopped?
|
140
|
+
!started?
|
91
141
|
end
|
92
142
|
|
143
|
+
def finite?
|
144
|
+
frame_count_limited? || cycle_limited? || duration_limited?
|
145
|
+
end
|
146
|
+
|
147
|
+
def infinite?
|
148
|
+
!finite?
|
149
|
+
end
|
150
|
+
alias indefinite? infinite?
|
151
|
+
|
93
152
|
def has_attribute?(attribute_name, *args)
|
94
153
|
respond_to?(ruby_attribute_setter(attribute_name)) && respond_to?(ruby_attribute_getter(attribute_name))
|
95
154
|
end
|
@@ -102,11 +161,79 @@ module Glimmer
|
|
102
161
|
send(ruby_attribute_getter(attribute_name))
|
103
162
|
end
|
104
163
|
|
164
|
+
def cycle=(*args)
|
165
|
+
if args.size == 1
|
166
|
+
if args.first.is_a?(Array)
|
167
|
+
@cycle = args.first
|
168
|
+
else
|
169
|
+
@cycle = [args.first]
|
170
|
+
end
|
171
|
+
elsif args.size > 1
|
172
|
+
@cycle = args
|
173
|
+
end
|
174
|
+
end
|
175
|
+
|
176
|
+
def cycle_enabled?
|
177
|
+
@cycle.is_a?(Array)
|
178
|
+
end
|
179
|
+
|
180
|
+
def cycle_limited?
|
181
|
+
cycle_enabled? && @cycle_count.is_a?(Integer)
|
182
|
+
end
|
183
|
+
|
184
|
+
def duration_limited?
|
185
|
+
@duration_limit.is_a?(Integer)
|
186
|
+
end
|
187
|
+
|
188
|
+
def frame_count_limited?
|
189
|
+
@frame_count.is_a?(Integer)
|
190
|
+
end
|
191
|
+
|
192
|
+
def surpassed_duration_limit?
|
193
|
+
duration_limited? && ((Time.now - @start_time) > (@duration_limit - @duration.to_f))
|
194
|
+
end
|
195
|
+
|
196
|
+
def within_duration_limit?
|
197
|
+
!surpassed_duration_limit?
|
198
|
+
end
|
199
|
+
|
105
200
|
private
|
106
201
|
|
107
|
-
|
108
|
-
|
202
|
+
# Returns true on success of painting a frame and false otherwise
|
203
|
+
def draw_frame(start_number)
|
204
|
+
return false if stopped? ||
|
205
|
+
start_number != @start_number ||
|
206
|
+
(frame_count_limited? && @frame_index == @frame_count) ||
|
207
|
+
(cycle_limited? && @cycle_count_index == @cycle_count) ||
|
208
|
+
surpassed_duration_limit?
|
209
|
+
block_args = [@frame_index]
|
210
|
+
block_args << @cycle[@frame_index % @cycle.length] if cycle_enabled?
|
211
|
+
current_frame_index = @frame_index
|
212
|
+
current_cycle_count_index = @cycle_count_index
|
213
|
+
self.class.schedule_frame_animation(self) do
|
214
|
+
if started? && start_number == @start_number && within_duration_limit?
|
215
|
+
@parent.clear_shapes
|
216
|
+
@parent.content {
|
217
|
+
frame_block.call(*block_args)
|
218
|
+
}
|
219
|
+
@parent.redraw
|
220
|
+
else
|
221
|
+
if stopped? && @frame_index > current_frame_index
|
222
|
+
@started = false
|
223
|
+
@frame_index = current_frame_index
|
224
|
+
@cycle_count_index = current_cycle_count_index
|
225
|
+
end
|
226
|
+
end
|
227
|
+
end
|
228
|
+
@frame_index += 1
|
229
|
+
@cycle_count_index += 1 if cycle_limited? && (@frame_index % @cycle&.length&.to_i) == 0
|
230
|
+
sleep(every) if every.is_a?(Numeric)
|
231
|
+
true
|
232
|
+
rescue => e
|
233
|
+
Glimmer::Config.logger.error {e}
|
234
|
+
false
|
109
235
|
end
|
236
|
+
|
110
237
|
end
|
111
238
|
|
112
239
|
end
|