glimmer-dsl-swt 4.18.1.0 → 4.18.2.3
Sign up to get free protection for your applications and to get access to all the features.
- 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
|