glimmer-dsl-swt 4.18.4.2 → 4.18.4.7
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +33 -0
- data/README.md +84 -5072
- data/VERSION +1 -1
- data/docs/reference/GLIMMER_COMMAND.md +591 -0
- data/docs/reference/GLIMMER_CONFIGURATION.md +183 -0
- data/docs/reference/GLIMMER_GIRB.md +30 -0
- data/docs/reference/GLIMMER_GUI_DSL_SYNTAX.md +3276 -0
- data/docs/reference/GLIMMER_PACKAGING_AND_DISTRIBUTION.md +202 -0
- data/docs/reference/GLIMMER_SAMPLES.md +676 -0
- data/docs/reference/GLIMMER_STYLE_GUIDE.md +14 -0
- data/glimmer-dsl-swt.gemspec +16 -8
- data/lib/glimmer/dsl/swt/custom_widget_expression.rb +3 -3
- data/lib/glimmer/dsl/swt/exec_expression.rb +1 -1
- data/lib/glimmer/dsl/swt/observe_expression.rb +8 -5
- data/lib/glimmer/dsl/swt/pixel_expression.rb +38 -0
- data/lib/glimmer/dsl/swt/timer_exec_expression.rb +35 -0
- data/lib/glimmer/dsl/swt/widget_expression.rb +1 -0
- data/lib/glimmer/swt/custom/animation.rb +9 -8
- data/lib/glimmer/swt/custom/code_text.rb +24 -20
- data/lib/glimmer/swt/custom/drawable.rb +21 -5
- data/lib/glimmer/swt/custom/shape.rb +62 -57
- data/lib/glimmer/swt/display_proxy.rb +11 -10
- data/lib/glimmer/swt/properties.rb +35 -10
- data/lib/glimmer/swt/shell_proxy.rb +1 -1
- data/lib/glimmer/swt/widget_proxy.rb +16 -3
- data/lib/glimmer/ui/custom_widget.rb +17 -0
- data/samples/elaborate/mandelbrot_fractal.rb +103 -0
- data/samples/elaborate/meta_sample.rb +1 -1
- data/samples/elaborate/tetris.rb +20 -21
- data/samples/elaborate/tetris/view/playfield.rb +1 -1
- data/samples/elaborate/tetris/view/tetris_menu_bar.rb +13 -11
- data/samples/hello/hello_canvas_transform.rb +1 -1
- metadata +14 -6
- data/samples/elaborate/meta_sample/meta_sample_logo.png +0 -0
- data/samples/hello/hello_canvas_transform/hello_canvas_transform_image.png +0 -0
@@ -0,0 +1,14 @@
|
|
1
|
+
## Glimmer Style Guide
|
2
|
+
|
3
|
+
- Widgets are declared with underscored lowercase versions of their SWT names minus the SWT package name.
|
4
|
+
- Widget declarations may optionally have arguments and be followed by a block (to contain properties and content)
|
5
|
+
- Widget blocks are always declared with curly braces
|
6
|
+
- Widget arguments are always wrapped inside parentheses
|
7
|
+
- Widget properties are declared with underscored lowercase versions of the SWT properties
|
8
|
+
- Widget property declarations always have arguments and never take a block
|
9
|
+
- Widget property arguments are never wrapped inside parentheses
|
10
|
+
- Widget listeners are always declared starting with `on_` prefix and affixing listener event method name afterwards in underscored lowercase form
|
11
|
+
- Widget listeners are always followed by a block using curly braces (Only when declared in DSL. When invoked on widget object directly outside of GUI declarations, standard Ruby conventions apply)
|
12
|
+
- Data-binding is done via `bind` keyword, which always takes arguments wrapped in parentheses
|
13
|
+
- Custom widget body, before_body, and after_body blocks open their blocks and close them with curly braces.
|
14
|
+
- Custom widgets receive additional arguments to SWT style called options. These are passed as the last argument inside the parentheses, a hash of option names pointing to values.
|
data/glimmer-dsl-swt.gemspec
CHANGED
@@ -2,16 +2,16 @@
|
|
2
2
|
# DO NOT EDIT THIS FILE DIRECTLY
|
3
3
|
# Instead, edit Juwelier::Tasks in Rakefile, and run 'rake gemspec'
|
4
4
|
# -*- encoding: utf-8 -*-
|
5
|
-
# stub: glimmer-dsl-swt 4.18.4.
|
5
|
+
# stub: glimmer-dsl-swt 4.18.4.7 ruby lib
|
6
6
|
|
7
7
|
Gem::Specification.new do |s|
|
8
8
|
s.name = "glimmer-dsl-swt".freeze
|
9
|
-
s.version = "4.18.4.
|
9
|
+
s.version = "4.18.4.7"
|
10
10
|
|
11
11
|
s.required_rubygems_version = Gem::Requirement.new(">= 0".freeze) if s.respond_to? :required_rubygems_version=
|
12
12
|
s.require_paths = ["lib".freeze]
|
13
13
|
s.authors = ["AndyMaleh".freeze]
|
14
|
-
s.date = "2021-02-
|
14
|
+
s.date = "2021-02-11"
|
15
15
|
s.description = "Glimmer DSL for SWT (JRuby Desktop Development GUI Framework) is a native-GUI cross-platform desktop development library written in JRuby, an OS-threaded faster JVM version of Ruby. Glimmer's main innovation is a declarative Ruby DSL that enables productive and efficient authoring of desktop application user-interfaces by relying on the robust Eclipse SWT library. Glimmer additionally innovates by having built-in data-binding support, which greatly facilitates synchronizing the GUI with domain models, thus achieving true decoupling of object oriented components and enabling developers to solve business problems (test-first) without worrying about GUI concerns, or alternatively drive development GUI-first, and then write clean business models (test-first) afterwards. Not only does Glimmer provide a large set of GUI widgets, but it also supports drawing Canvas Graphics like Shapes and Animations. To get started quickly, Glimmer offers scaffolding options for Apps, Gems, and Custom Widgets. Glimmer also includes native-executable packaging support, sorely lacking in other libraries, thus enabling the delivery of desktop apps written in Ruby as truly native DMG/PKG/APP files on the Mac + App Store, MSI/EXE files on Windows, and Gem Packaged Shell Scripts on Linux.".freeze
|
16
16
|
s.email = "andy.am@gmail.com".freeze
|
17
17
|
s.executables = ["glimmer".freeze, "girb".freeze]
|
@@ -28,6 +28,13 @@ Gem::Specification.new do |s|
|
|
28
28
|
"bin/girb",
|
29
29
|
"bin/girb_runner.rb",
|
30
30
|
"bin/glimmer",
|
31
|
+
"docs/reference/GLIMMER_COMMAND.md",
|
32
|
+
"docs/reference/GLIMMER_CONFIGURATION.md",
|
33
|
+
"docs/reference/GLIMMER_GIRB.md",
|
34
|
+
"docs/reference/GLIMMER_GUI_DSL_SYNTAX.md",
|
35
|
+
"docs/reference/GLIMMER_PACKAGING_AND_DISTRIBUTION.md",
|
36
|
+
"docs/reference/GLIMMER_SAMPLES.md",
|
37
|
+
"docs/reference/GLIMMER_STYLE_GUIDE.md",
|
31
38
|
"glimmer-dsl-swt.gemspec",
|
32
39
|
"icons/scaffold_app.icns",
|
33
40
|
"icons/scaffold_app.ico",
|
@@ -72,6 +79,7 @@ Gem::Specification.new do |s|
|
|
72
79
|
"lib/glimmer/dsl/swt/message_box_expression.rb",
|
73
80
|
"lib/glimmer/dsl/swt/multiply_expression.rb",
|
74
81
|
"lib/glimmer/dsl/swt/observe_expression.rb",
|
82
|
+
"lib/glimmer/dsl/swt/pixel_expression.rb",
|
75
83
|
"lib/glimmer/dsl/swt/property_expression.rb",
|
76
84
|
"lib/glimmer/dsl/swt/radio_group_selection_data_binding_expression.rb",
|
77
85
|
"lib/glimmer/dsl/swt/rgb_expression.rb",
|
@@ -82,6 +90,7 @@ Gem::Specification.new do |s|
|
|
82
90
|
"lib/glimmer/dsl/swt/sync_exec_expression.rb",
|
83
91
|
"lib/glimmer/dsl/swt/tab_item_expression.rb",
|
84
92
|
"lib/glimmer/dsl/swt/table_items_data_binding_expression.rb",
|
93
|
+
"lib/glimmer/dsl/swt/timer_exec_expression.rb",
|
85
94
|
"lib/glimmer/dsl/swt/transform_expression.rb",
|
86
95
|
"lib/glimmer/dsl/swt/tree_items_data_binding_expression.rb",
|
87
96
|
"lib/glimmer/dsl/swt/tree_properties_expression.rb",
|
@@ -135,8 +144,8 @@ Gem::Specification.new do |s|
|
|
135
144
|
"samples/elaborate/contact_manager/contact_manager_presenter.rb",
|
136
145
|
"samples/elaborate/contact_manager/contact_repository.rb",
|
137
146
|
"samples/elaborate/login.rb",
|
147
|
+
"samples/elaborate/mandelbrot_fractal.rb",
|
138
148
|
"samples/elaborate/meta_sample.rb",
|
139
|
-
"samples/elaborate/meta_sample/meta_sample_logo.png",
|
140
149
|
"samples/elaborate/tetris.rb",
|
141
150
|
"samples/elaborate/tetris/model/block.rb",
|
142
151
|
"samples/elaborate/tetris/model/game.rb",
|
@@ -156,7 +165,6 @@ Gem::Specification.new do |s|
|
|
156
165
|
"samples/hello/hello_canvas.rb",
|
157
166
|
"samples/hello/hello_canvas_animation.rb",
|
158
167
|
"samples/hello/hello_canvas_transform.rb",
|
159
|
-
"samples/hello/hello_canvas_transform/hello_canvas_transform_image.png",
|
160
168
|
"samples/hello/hello_checkbox.rb",
|
161
169
|
"samples/hello/hello_checkbox_group.rb",
|
162
170
|
"samples/hello/hello_code_text.rb",
|
@@ -201,7 +209,7 @@ Gem::Specification.new do |s|
|
|
201
209
|
s.specification_version = 4
|
202
210
|
|
203
211
|
if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
|
204
|
-
s.add_runtime_dependency(%q<glimmer>.freeze, ["~> 1.
|
212
|
+
s.add_runtime_dependency(%q<glimmer>.freeze, ["~> 1.1.1"])
|
205
213
|
s.add_runtime_dependency(%q<super_module>.freeze, [">= 1.4.1", "< 2.0.0"])
|
206
214
|
s.add_runtime_dependency(%q<nested_inherited_jruby_include_package>.freeze, [">= 0.3.0", "< 2.0.0"])
|
207
215
|
s.add_runtime_dependency(%q<puts_debuggerer>.freeze, [">= 0.11.0", "< 2.0.0"])
|
@@ -220,7 +228,7 @@ Gem::Specification.new do |s|
|
|
220
228
|
s.add_development_dependency(%q<simplecov>.freeze, ["~> 0.16.1"])
|
221
229
|
s.add_development_dependency(%q<simplecov-lcov>.freeze, ["~> 0.7.0"])
|
222
230
|
else
|
223
|
-
s.add_dependency(%q<glimmer>.freeze, ["~> 1.
|
231
|
+
s.add_dependency(%q<glimmer>.freeze, ["~> 1.1.1"])
|
224
232
|
s.add_dependency(%q<super_module>.freeze, [">= 1.4.1", "< 2.0.0"])
|
225
233
|
s.add_dependency(%q<nested_inherited_jruby_include_package>.freeze, [">= 0.3.0", "< 2.0.0"])
|
226
234
|
s.add_dependency(%q<puts_debuggerer>.freeze, [">= 0.11.0", "< 2.0.0"])
|
@@ -240,7 +248,7 @@ Gem::Specification.new do |s|
|
|
240
248
|
s.add_dependency(%q<simplecov-lcov>.freeze, ["~> 0.7.0"])
|
241
249
|
end
|
242
250
|
else
|
243
|
-
s.add_dependency(%q<glimmer>.freeze, ["~> 1.
|
251
|
+
s.add_dependency(%q<glimmer>.freeze, ["~> 1.1.1"])
|
244
252
|
s.add_dependency(%q<super_module>.freeze, [">= 1.4.1", "< 2.0.0"])
|
245
253
|
s.add_dependency(%q<nested_inherited_jruby_include_package>.freeze, [">= 0.3.0", "< 2.0.0"])
|
246
254
|
s.add_dependency(%q<puts_debuggerer>.freeze, [">= 0.11.0", "< 2.0.0"])
|
@@ -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
|
@@ -41,7 +41,7 @@ module Glimmer
|
|
41
41
|
end
|
42
42
|
|
43
43
|
def interpret(parent, keyword, *args, &block)
|
44
|
-
Glimmer::SWT::DisplayProxy.instance.swt_display.send(exec_operation) do |*args|
|
44
|
+
Glimmer::SWT::DisplayProxy.instance.swt_display.send(exec_operation, *args) do |*args|
|
45
45
|
begin
|
46
46
|
block.call(*args)
|
47
47
|
rescue => e
|
@@ -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
|
@@ -23,6 +23,7 @@ require 'glimmer/dsl/static_expression'
|
|
23
23
|
require 'glimmer/dsl/top_level_expression'
|
24
24
|
require 'glimmer/data_binding/observer'
|
25
25
|
require 'glimmer/data_binding/model_binding'
|
26
|
+
require 'glimmer/ui/custom_widget'
|
26
27
|
|
27
28
|
module Glimmer
|
28
29
|
module DSL
|
@@ -42,10 +43,12 @@ module Glimmer
|
|
42
43
|
def interpret(parent, keyword, *args, &block)
|
43
44
|
observer = DataBinding::Observer.proc(&block)
|
44
45
|
if args[1].to_s.match(REGEX_NESTED_OR_INDEXED_PROPERTY)
|
45
|
-
observer.observe(DataBinding::ModelBinding.new(args[0], args[1]))
|
46
|
+
observer_registration = observer.observe(DataBinding::ModelBinding.new(args[0], args[1]))
|
46
47
|
else
|
47
|
-
observer.observe(args[0], args[1])
|
48
|
+
observer_registration = observer.observe(args[0], args[1])
|
48
49
|
end
|
50
|
+
Glimmer::UI::CustomWidget.current_custom_widgets.last&.observer_registrations&.push(observer_registration)
|
51
|
+
observer_registration
|
49
52
|
end
|
50
53
|
end
|
51
54
|
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
# Copyright (c) 2007-2021 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/dsl/static_expression'
|
23
|
+
require 'glimmer/swt/swt_proxy'
|
24
|
+
require 'glimmer/swt/custom/shape'
|
25
|
+
require 'glimmer/swt/custom/drawable'
|
26
|
+
|
27
|
+
module Glimmer
|
28
|
+
module DSL
|
29
|
+
module SWT
|
30
|
+
class PixelExpression < StaticExpression
|
31
|
+
|
32
|
+
def interpret(parent, keyword, *args, &block)
|
33
|
+
Glimmer::SWT::Custom::Shape.new(parent, 'point', *args, &block)
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
# Copyright (c) 2007-2021 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/dsl/static_expression'
|
23
|
+
require 'glimmer/dsl/swt/exec_expression'
|
24
|
+
|
25
|
+
module Glimmer
|
26
|
+
module DSL
|
27
|
+
module SWT
|
28
|
+
# Asynchronously executes code block against the SWT Event Loop
|
29
|
+
# after a certain time elapsed
|
30
|
+
class TimerExecExpression < StaticExpression
|
31
|
+
include ExecExpression
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
@@ -26,7 +26,7 @@ module Glimmer
|
|
26
26
|
module Custom
|
27
27
|
# Represents an animation declaratively
|
28
28
|
class Animation
|
29
|
-
include Properties
|
29
|
+
include Properties
|
30
30
|
|
31
31
|
class << self
|
32
32
|
def schedule_frame_animation(animation, &frame_animation_block)
|
@@ -92,8 +92,10 @@ module Glimmer
|
|
92
92
|
end
|
93
93
|
|
94
94
|
def post_add_content
|
95
|
-
@
|
96
|
-
|
95
|
+
if @dispose_listener_registration.nil?
|
96
|
+
@dispose_listener_registration = @parent.on_widget_disposed { stop }
|
97
|
+
start if started?
|
98
|
+
end
|
97
99
|
end
|
98
100
|
|
99
101
|
# Starts an animation that is indefinite or has never been started before (i.e. having `started: false` option).
|
@@ -212,11 +214,10 @@ module Glimmer
|
|
212
214
|
current_cycle_count_index = @cycle_count_index
|
213
215
|
self.class.schedule_frame_animation(self) do
|
214
216
|
if started? && start_number == @start_number && within_duration_limit?
|
215
|
-
@parent.
|
216
|
-
|
217
|
-
frame_block.call(*block_args)
|
218
|
-
|
219
|
-
@parent.redraw
|
217
|
+
unless @parent.isDisposed
|
218
|
+
@parent.clear_shapes # TODO adjust this to clear only the shapes of this animation (not all shapes) to allow simultaneous animations to occur on the same parent
|
219
|
+
@parent.content { frame_block.call(*block_args) }
|
220
|
+
end
|
220
221
|
else
|
221
222
|
if stopped? && @frame_index > current_frame_index
|
222
223
|
@started = false
|
@@ -22,8 +22,6 @@ module Glimmer
|
|
22
22
|
REGEX_COLOR_HEX6 = /^#([0-9a-f]{2})([0-9a-f]{2})([0-9a-f]{2})$/
|
23
23
|
|
24
24
|
# TODO support auto language detection
|
25
|
-
# TODO support end of line via CMD+E and beginning of line via CMD+A
|
26
|
-
# TODO support select all via CMD+A
|
27
25
|
|
28
26
|
option :language, default: 'ruby'
|
29
27
|
# TODO consider supporting data-binding of language
|
@@ -31,6 +29,9 @@ module Glimmer
|
|
31
29
|
# TODO support method for redrawing the syntax highlighting
|
32
30
|
option :theme, default: 'glimmer'
|
33
31
|
option :lines, default: false
|
32
|
+
|
33
|
+
# This option indicates if default keyboard handlers/menus should be activated
|
34
|
+
option :default_behavior, default: true
|
34
35
|
|
35
36
|
alias lines? lines
|
36
37
|
attr_accessor :styled_text_proxy_text, :styled_text_proxy_top_pixel
|
@@ -42,6 +43,7 @@ module Glimmer
|
|
42
43
|
args.pop if args.last.is_a?(Hash) && args.last[:dsl]
|
43
44
|
super(method_name, *args, &block)
|
44
45
|
elsif @styled_text_proxy&.respond_to?(method_name, *args, &block)
|
46
|
+
@line_numbers_styled_text_proxy&.send(method_name, *args, &block) if method_name.to_s == 'font='
|
45
47
|
@styled_text_proxy&.send(method_name, *args, &block)
|
46
48
|
else
|
47
49
|
super
|
@@ -88,28 +90,29 @@ module Glimmer
|
|
88
90
|
}
|
89
91
|
|
90
92
|
body {
|
91
|
-
# TODO enable this once fully implemented
|
92
93
|
if lines
|
93
94
|
composite {
|
94
95
|
grid_layout(2, false)
|
95
96
|
|
96
97
|
@line_numbers_styled_text_proxy = styled_text(swt(swt(swt_style), :h_scroll!, :v_scroll!)) {
|
97
98
|
layout_data(:right, :fill, false, true)
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
@lines_width
|
107
|
-
|
108
|
-
|
99
|
+
top_pixel_before_read = nil
|
100
|
+
text bind(self,
|
101
|
+
:styled_text_proxy_text,
|
102
|
+
read_only: true,
|
103
|
+
on_read: lambda { |text_value|
|
104
|
+
line_count = "#{text_value} ".split("\n").count
|
105
|
+
line_count = 1 if line_count == 0
|
106
|
+
lines_text_size = [line_count.to_s.size, @lines_width].max
|
107
|
+
if lines_text_size > @lines_width
|
108
|
+
@lines_width = lines_text_size
|
109
|
+
end
|
110
|
+
line_count.times.map {|n| (' ' * (lines_text_size - (n+1).to_s.size)) + (n+1).to_s }.join("\n") + "\n"
|
111
|
+
},
|
112
|
+
after_read: lambda {
|
109
113
|
@line_numbers_styled_text_proxy&.top_pixel = styled_text_proxy_top_pixel
|
110
114
|
}
|
111
|
-
|
112
|
-
}
|
115
|
+
)
|
113
116
|
top_pixel bind(self, :styled_text_proxy_top_pixel, read_only: true)
|
114
117
|
font name: @font_name, height: OS.mac? ? 15 : 12
|
115
118
|
background color(:widget_background)
|
@@ -144,22 +147,22 @@ module Glimmer
|
|
144
147
|
layout_data :fill, :fill, true, true if lines
|
145
148
|
text bind(self, :styled_text_proxy_text) if lines
|
146
149
|
top_pixel bind(self, :styled_text_proxy_top_pixel) if lines
|
147
|
-
font name: @font_name, height: 15
|
150
|
+
font name: @font_name, height: OS.mac? ? 15 : 12
|
148
151
|
foreground rgb(75, 75, 75)
|
149
152
|
left_margin 5
|
150
153
|
top_margin 5
|
151
154
|
right_margin 5
|
152
155
|
bottom_margin 5
|
153
156
|
|
154
|
-
if
|
157
|
+
if default_behavior
|
155
158
|
on_key_pressed { |event|
|
156
159
|
character = event.keyCode.chr rescue nil
|
157
160
|
case [event.stateMask, character]
|
158
161
|
when [(OS.mac? ? swt(:command) : swt(:ctrl)), 'a']
|
159
162
|
@styled_text_proxy.swt_widget.selectAll
|
160
|
-
when [(swt(:ctrl)
|
163
|
+
when [(swt(:ctrl) if OS.mac?), 'a']
|
161
164
|
jump_to_beginning_of_line
|
162
|
-
when [(swt(:ctrl)
|
165
|
+
when [(swt(:ctrl) if OS.mac?), 'e']
|
163
166
|
jump_to_end_of_line
|
164
167
|
end
|
165
168
|
}
|
@@ -228,6 +231,7 @@ module Glimmer
|
|
228
231
|
@lexer ||= Rouge::Lexer.find_fancy('ruby') # default to Ruby if no lexer is found
|
229
232
|
end
|
230
233
|
|
234
|
+
# TODO extract this to ColorProxy
|
231
235
|
def hex_color_to_swt_color(color_data, default_color)
|
232
236
|
color_data = "##{color_data.chars.drop(1).map {|c| c*2}.join}" if color_data.is_a?(String) && color_data.start_with?('#') && color_data&.size == 4
|
233
237
|
color_data = color_data.match(REGEX_COLOR_HEX6).to_a.drop(1).map {|c| "0x#{c}".hex}.to_a if color_data.is_a?(String) && color_data.start_with?('#')
|
@@ -32,14 +32,30 @@ module Glimmer
|
|
32
32
|
shapes.dup.each(&:dispose)
|
33
33
|
end
|
34
34
|
|
35
|
-
def
|
35
|
+
def deregister_shape_painting
|
36
|
+
@paint_listener_proxy&.deregister
|
37
|
+
end
|
38
|
+
|
39
|
+
def setup_shape_painting
|
36
40
|
# TODO consider performance optimization relating to order of shape rendering (affecting only further shapes not previous ones)
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
+
if @paint_listener_proxy.nil?
|
42
|
+
shape_painter = lambda do |paint_event|
|
43
|
+
shapes.each do |shape|
|
44
|
+
shape.paint(paint_event)
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
# TODO consider making this logic polymorphic (image vs other)
|
49
|
+
if respond_to?(:swt_image)
|
50
|
+
shape_painter.call(self) # treat self as paint event since image has its own gc and doesn't do repaints (it's a one time deal for now though could be adjusted in the future.)
|
51
|
+
else
|
52
|
+
@paint_listener_proxy = on_swt_paint(&shape_painter)
|
53
|
+
end
|
54
|
+
else
|
55
|
+
redraw if @finished_add_content && !is_disposed
|
41
56
|
end
|
42
57
|
end
|
58
|
+
alias resetup_shape_painting setup_shape_painting
|
43
59
|
end
|
44
60
|
|
45
61
|
end
|
@@ -39,7 +39,7 @@ module Glimmer
|
|
39
39
|
|
40
40
|
class << self
|
41
41
|
def valid?(parent, keyword, *args, &block)
|
42
|
-
gc_instance_methods.include?(method_name(keyword, args))
|
42
|
+
gc_instance_methods.include?(method_name(keyword, arg_options(args)))
|
43
43
|
end
|
44
44
|
|
45
45
|
def gc_instance_methods
|
@@ -62,14 +62,14 @@ module Glimmer
|
|
62
62
|
options.nil? ? {} : options.symbolize_keys
|
63
63
|
end
|
64
64
|
|
65
|
-
def method_name(keyword,
|
66
|
-
|
65
|
+
def method_name(keyword, method_arg_options)
|
66
|
+
keyword = keyword.to_s
|
67
|
+
method_arg_options = method_arg_options.select {|key, value| %w[fill gradient round].include?(key.to_s)}
|
67
68
|
unless flyweight_method_names.keys.include?([keyword, method_arg_options])
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
flyweight_method_names[[keyword, method_arg_options]] = "#{gc_instance_method_name_prefix}#{gradient}#{round}#{keyword}"
|
69
|
+
gradient = 'Gradient' if method_arg_options[:gradient]
|
70
|
+
round = 'Round' if method_arg_options[:round]
|
71
|
+
gc_instance_method_name_prefix = !['polyline', 'point', 'image', 'focus'].include?(keyword) && (method_arg_options[:fill] || method_arg_options[:gradient]) ? 'fill' : 'draw'
|
72
|
+
flyweight_method_names[[keyword, method_arg_options]] = "#{gc_instance_method_name_prefix}#{gradient}#{round}#{keyword.capitalize}"
|
73
73
|
end
|
74
74
|
flyweight_method_names[[keyword, method_arg_options]]
|
75
75
|
end
|
@@ -91,15 +91,18 @@ module Glimmer
|
|
91
91
|
end
|
92
92
|
end
|
93
93
|
|
94
|
-
attr_reader :parent, :name, :args, :options
|
94
|
+
attr_reader :parent, :name, :args, :options
|
95
95
|
|
96
96
|
def initialize(parent, keyword, *args, &property_block)
|
97
97
|
@parent = parent
|
98
98
|
@name = keyword
|
99
|
-
@method_name = self.class.method_name(keyword, args)
|
100
99
|
@options = self.class.arg_options(args, extract: true)
|
100
|
+
@method_name = self.class.method_name(keyword, @options)
|
101
101
|
@args = args
|
102
102
|
@properties = {}
|
103
|
+
@options.reject {|key, value| %w[fill gradient round].include?(key.to_s)}.each do |property, property_args|
|
104
|
+
@properties[property] = property_args
|
105
|
+
end
|
103
106
|
@parent.shapes << self
|
104
107
|
post_add_content if property_block.nil?
|
105
108
|
end
|
@@ -129,9 +132,11 @@ module Glimmer
|
|
129
132
|
end
|
130
133
|
|
131
134
|
def post_add_content
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
+
unless @content_added
|
136
|
+
amend_method_name_options_based_on_properties!
|
137
|
+
@parent.setup_shape_painting
|
138
|
+
@content_added = true
|
139
|
+
end
|
135
140
|
end
|
136
141
|
|
137
142
|
def apply_property_arg_conversions(method_name, property, args)
|
@@ -172,41 +177,42 @@ module Glimmer
|
|
172
177
|
args
|
173
178
|
end
|
174
179
|
|
175
|
-
def apply_shape_arg_conversions
|
176
|
-
if args.size > 1 && (
|
177
|
-
args[0] = args.dup
|
178
|
-
args[1..-1] = []
|
180
|
+
def apply_shape_arg_conversions!
|
181
|
+
if @args.size > 1 && (['polygon', 'polyline'].include?(@name))
|
182
|
+
@args[0] = @args.dup
|
183
|
+
@args[1..-1] = []
|
179
184
|
end
|
180
185
|
end
|
181
186
|
|
182
|
-
def apply_shape_arg_defaults
|
183
|
-
if
|
184
|
-
(6 - args.size).times {args << 60}
|
185
|
-
elsif
|
186
|
-
args << true
|
187
|
-
elsif (
|
188
|
-
args << true
|
187
|
+
def apply_shape_arg_defaults!
|
188
|
+
if @name.include?('rectangle') && round? && @args.size.between?(4, 5)
|
189
|
+
(6 - @args.size).times {@args << 60}
|
190
|
+
elsif @name.include?('rectangle') && gradient? && @args.size == 4
|
191
|
+
@args << true
|
192
|
+
elsif (@name.include?('text') || @name.include?('String')) && !@properties.keys.map(&:to_s).include?('background') && @args.size == 3
|
193
|
+
@args << true
|
189
194
|
end
|
190
|
-
if
|
191
|
-
args[0] = ImageProxy.new(args[0])
|
195
|
+
if @name.include?('image') && @args.first.is_a?(String)
|
196
|
+
@args[0] = ImageProxy.new(@args[0])
|
192
197
|
end
|
193
|
-
if
|
194
|
-
@image = args[0] = args[0].swt_image
|
198
|
+
if @name.include?('image') && @args.first.is_a?(ImageProxy)
|
199
|
+
@image = @args[0] = @args[0].swt_image
|
195
200
|
end
|
196
201
|
end
|
197
202
|
|
198
203
|
# Tolerates shape extra args added by user by mistake
|
199
204
|
# (e.g. happens when switching from round rectangle to a standard one without removing all extra args)
|
200
|
-
def tolerate_shape_extra_args
|
205
|
+
def tolerate_shape_extra_args!
|
201
206
|
the_java_method_arg_count = org.eclipse.swt.graphics.GC.java_class.declared_instance_methods.select do |m|
|
202
|
-
m.name == method_name.camelcase(:lower)
|
207
|
+
m.name == @method_name.camelcase(:lower)
|
203
208
|
end.map(&:parameter_types).map(&:size).max
|
204
|
-
if args.size > the_java_method_arg_count
|
205
|
-
args[the_java_method_arg_count..-1] = []
|
209
|
+
if @args.size > the_java_method_arg_count
|
210
|
+
@args[the_java_method_arg_count..-1] = []
|
206
211
|
end
|
207
212
|
end
|
208
213
|
|
209
|
-
def amend_method_name_options_based_on_properties
|
214
|
+
def amend_method_name_options_based_on_properties!
|
215
|
+
return if @name == 'point'
|
210
216
|
if has_some_background? && !has_some_foreground?
|
211
217
|
@options[:fill] = true
|
212
218
|
elsif !has_some_background? && has_some_foreground?
|
@@ -218,7 +224,7 @@ module Glimmer
|
|
218
224
|
if @name == 'rectangle' && @args.size > 4 && @args.last.is_a?(Numeric)
|
219
225
|
@options[:round] = true
|
220
226
|
end
|
221
|
-
@method_name = self.class.method_name(@name, @
|
227
|
+
@method_name = self.class.method_name(@name, @options)
|
222
228
|
end
|
223
229
|
|
224
230
|
def has_attribute?(attribute_name, *args)
|
@@ -228,7 +234,7 @@ module Glimmer
|
|
228
234
|
def set_attribute(attribute_name, *args)
|
229
235
|
@properties[attribute_name] = args
|
230
236
|
if @content_added && !@parent.is_disposed
|
231
|
-
@
|
237
|
+
@calculated_paint_args = false
|
232
238
|
@parent.redraw
|
233
239
|
end
|
234
240
|
end
|
@@ -247,7 +253,6 @@ module Glimmer
|
|
247
253
|
end
|
248
254
|
|
249
255
|
def dispose
|
250
|
-
paint_listener_proxy&.unregister
|
251
256
|
@background_pattern&.dispose
|
252
257
|
@background_pattern = nil
|
253
258
|
@foreground_pattern&.dispose
|
@@ -257,36 +262,36 @@ module Glimmer
|
|
257
262
|
@parent.shapes.delete(self)
|
258
263
|
end
|
259
264
|
|
260
|
-
def setup_painting
|
261
|
-
# TODO consider moving this method to parent (making the logic polymorphic)
|
262
|
-
return if @parent.is_disposed
|
263
|
-
if parent.respond_to?(:swt_display)
|
264
|
-
@paint_listener_proxy = @parent.on_swt_paint(&method(:paint))
|
265
|
-
elsif parent.respond_to?(:swt_image)
|
266
|
-
paint(parent) # treat parent as paint event since you don't do repaints with images, it's a one time deal.
|
267
|
-
elsif parent.respond_to?(:swt_widget)
|
268
|
-
@paint_listener_proxy = @parent.on_paint_control(&method(:paint))
|
269
|
-
end
|
270
|
-
end
|
271
|
-
|
272
265
|
def paint(paint_event)
|
273
|
-
|
274
|
-
@properties['foreground'] = [@parent.foreground] if @parent.respond_to?(:foreground) && draw? && !has_some_foreground?
|
275
|
-
@properties['font'] = [@parent.font] if @parent.respond_to?(:font) && draw? && !@properties.keys.map(&:to_s).include?('font')
|
276
|
-
@properties['transform'] = [nil] if @parent.respond_to?(:transform) && !@properties.keys.map(&:to_s).include?('transform')
|
266
|
+
calculate_paint_args!
|
277
267
|
@properties.each do |property, args|
|
278
268
|
method_name = attribute_setter(property)
|
279
|
-
|
280
|
-
paint_event.gc.send(method_name, *
|
269
|
+
# TODO consider optimization of not setting a background/foreground/font if it didn't change from last shape
|
270
|
+
paint_event.gc.send(method_name, *args)
|
281
271
|
if property == 'transform' && args.first.is_a?(TransformProxy)
|
282
272
|
args.first.swt_transform.dispose
|
283
273
|
end
|
284
274
|
end
|
285
|
-
apply_shape_arg_conversions(@method_name, @args)
|
286
|
-
apply_shape_arg_defaults(@method_name, @args)
|
287
|
-
tolerate_shape_extra_args(@method_name, @args)
|
288
275
|
paint_event.gc.send(@method_name, *@args)
|
289
276
|
end
|
277
|
+
|
278
|
+
def calculate_paint_args!
|
279
|
+
unless @name == 'point' || @calculated_paint_args
|
280
|
+
@properties['background'] = [@parent.background] if fill? && !has_some_background?
|
281
|
+
@properties['foreground'] = [@parent.foreground] if @parent.respond_to?(:foreground) && draw? && !has_some_foreground?
|
282
|
+
@properties['font'] = [@parent.font] if @parent.respond_to?(:font) && draw? && !@properties.keys.map(&:to_s).include?('font')
|
283
|
+
@properties['transform'] = [nil] if @parent.respond_to?(:transform) && !@properties.keys.map(&:to_s).include?('transform')
|
284
|
+
@properties.each do |property, args|
|
285
|
+
method_name = attribute_setter(property)
|
286
|
+
converted_args = apply_property_arg_conversions(method_name, property, args)
|
287
|
+
@properties[property] = converted_args
|
288
|
+
end
|
289
|
+
apply_shape_arg_conversions!
|
290
|
+
apply_shape_arg_defaults!
|
291
|
+
tolerate_shape_extra_args!
|
292
|
+
@calculated_paint_args = true
|
293
|
+
end
|
294
|
+
end
|
290
295
|
|
291
296
|
end
|
292
297
|
|