glimmer-dsl-swing 0.0.1 → 0.0.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +7 -0
- data/README.md +243 -4
- data/VERSION +1 -1
- data/bin/girb +0 -0
- data/glimmer-dsl-swing.gemspec +0 -0
- data/lib/glimmer/dsl/swing/component_expression.rb +2 -2
- data/lib/glimmer/dsl/swing/dsl.rb +1 -0
- data/lib/glimmer/dsl/swing/property_expression.rb +5 -2
- data/lib/glimmer/dsl/swing/shape_expression.rb +48 -0
- data/lib/glimmer/swing/component_proxy/j_frame_proxy.rb +12 -2
- data/lib/glimmer/swing/component_proxy.rb +39 -10
- data/lib/glimmer/swing/shape_proxy.rb +167 -0
- data/lib/glimmer-dsl-swing.rb +0 -2
- data/samples/hello/hello_button.rb +3 -3
- data/samples/hello/hello_shapes.rb +49 -0
- metadata +6 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: d91f9d5241c9f9414d4f4c343568a71f19657560b72713a4fbfe4711af0e120f
|
4
|
+
data.tar.gz: 25079ddbf4e8b83a899b4857e88aa9dacfbde3f67147c7708047113654e42df7
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 23641076d917e3223517cfabfd82c72973360b4bff14032567e67e6352b4dd40e6e628d920833786401a8b0d65b3959d6303e6721cd2fd95254ff365e8bc64ee
|
7
|
+
data.tar.gz: f1b4f292413767713e88bf115e0b16cb4df5644f72cfb79c80f5043dbc4bfe639e6e3fb5ec79ec515b3e526e094c4be9aed3a48ed2a3ba7d402978517643770c
|
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,12 @@
|
|
1
1
|
# Change Log
|
2
2
|
|
3
|
+
## 0.0.2
|
4
|
+
|
5
|
+
- General Java 2D shape support by nesting under any component
|
6
|
+
- Support setting `jframe` `minimum_size width, height` without building `Dimension` object manually
|
7
|
+
- Hello, Shapes! sample
|
8
|
+
- Improve Hello, Button! sample
|
9
|
+
|
3
10
|
## 0.0.1
|
4
11
|
|
5
12
|
- Initial version of Glimmer DSL for Swing
|
data/README.md
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
# [<img src="https://raw.githubusercontent.com/AndyObtiva/glimmer/master/images/glimmer-logo-hi-res.png" height=85 />](https://github.com/AndyObtiva/glimmer) Glimmer DSL for Swing 0.0.
|
1
|
+
# [<img src="https://raw.githubusercontent.com/AndyObtiva/glimmer/master/images/glimmer-logo-hi-res.png" height=85 />](https://github.com/AndyObtiva/glimmer) Glimmer DSL for Swing 0.0.2
|
2
2
|
## JRuby Swing Desktop Development GUI Library
|
3
3
|
[![Gem Version](https://badge.fury.io/rb/glimmer-dsl-swing.svg)](http://badge.fury.io/rb/glimmer-dsl-swing)
|
4
4
|
[![Join the chat at https://gitter.im/AndyObtiva/glimmer](https://badges.gitter.im/AndyObtiva/glimmer.svg)](https://gitter.im/AndyObtiva/glimmer?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
|
@@ -64,7 +64,7 @@ gem install glimmer-dsl-swing
|
|
64
64
|
|
65
65
|
Add the following to `Gemfile`:
|
66
66
|
```
|
67
|
-
gem 'glimmer-dsl-swing', '~> 0.0.
|
67
|
+
gem 'glimmer-dsl-swing', '~> 0.0.2'
|
68
68
|
```
|
69
69
|
|
70
70
|
And, then run:
|
@@ -86,6 +86,153 @@ jframe('Hello, World!') {
|
|
86
86
|
}.show
|
87
87
|
```
|
88
88
|
|
89
|
+
## Glimmer GUI DSL
|
90
|
+
|
91
|
+
The Glimmer GUI DSL enables development of desktop graphical user interfaces in a manner similar to HTML, but in one language, Ruby, thus avoiding the multi-language separation dissonance encountered on the web, especially given that Ruby looping/conditional constructs do not need scriptlets to be added around View code. This makes desktop development extremely productive.
|
92
|
+
|
93
|
+
1 - Keywords
|
94
|
+
|
95
|
+
You may declare any swing/awt component with its keyword, which is the underscored version of the class name. For example, `jframe` is the keyword for `javax.swing.JFrame` (`j_frame` is acceptable too)
|
96
|
+
|
97
|
+
Examples:
|
98
|
+
|
99
|
+
```ruby
|
100
|
+
jframe
|
101
|
+
jbutton
|
102
|
+
jlabel
|
103
|
+
```
|
104
|
+
|
105
|
+
2 - Arguments
|
106
|
+
|
107
|
+
You may pass any arguments that a [swing](https://docs.oracle.com/javase/8/docs/api/javax/swing/package-summary.html)/[awt](https://docs.oracle.com/javase/8/docs/api/java/awt/package-summary.html) component constructor accepts to its Glimmer keyword.
|
108
|
+
|
109
|
+
Example `JFrame`, `JLabel`, and `JButton` have a constructor signature that accepts a string representing title or text:
|
110
|
+
|
111
|
+
```ruby
|
112
|
+
jframe('Hello, World!')
|
113
|
+
jbutton('Push Me')
|
114
|
+
jlabel('Name')
|
115
|
+
```
|
116
|
+
|
117
|
+
The recommended style is to always wrap arguments with parentheses for component keywords.
|
118
|
+
|
119
|
+
3 - Content Block
|
120
|
+
|
121
|
+
You may pass a content block to any [swing](https://docs.oracle.com/javase/8/docs/api/javax/swing/package-summary.html)/[awt](https://docs.oracle.com/javase/8/docs/api/java/awt/package-summary.html) component keyword, which contains properties and/or nested components.
|
122
|
+
|
123
|
+
Example:
|
124
|
+
|
125
|
+
```ruby
|
126
|
+
jframe('Hello, World!') {
|
127
|
+
minimum_size 320, 240
|
128
|
+
|
129
|
+
jlabel('Hello, World!')
|
130
|
+
}
|
131
|
+
```
|
132
|
+
|
133
|
+
The recommended style for the content block is to always be curly braces to denote as View nesting code different from the logic in looping/conditional constructs that utilize `do;end` instead.
|
134
|
+
|
135
|
+
Property arguments never have parentheses.
|
136
|
+
|
137
|
+
4 - Listeners
|
138
|
+
|
139
|
+
You may declare listeners with their event method name on the [swing](https://docs.oracle.com/javase/8/docs/api/javax/swing/package-summary.html)/[awt](https://docs.oracle.com/javase/8/docs/api/java/awt/package-summary.html) listener class (these are the classes in the signatures of `AddXYZListener` methods on [swing](https://docs.oracle.com/javase/8/docs/api/javax/swing/package-summary.html)/[awt](https://docs.oracle.com/javase/8/docs/api/java/awt/package-summary.html) component classes).
|
140
|
+
|
141
|
+
For example, `JButton` has an `AddXYZListener` method called `AddActionListener`, which accepts an `ActionListener` class. That class has one event method: `actionPerformed`. In Glimmer, you simply underscore that and prefix with `on_`:
|
142
|
+
|
143
|
+
```ruby
|
144
|
+
jframe('Hello, Button!') {
|
145
|
+
jbutton('Click') {
|
146
|
+
on_action_performed do
|
147
|
+
puts 'Clicked!'
|
148
|
+
end
|
149
|
+
}
|
150
|
+
}
|
151
|
+
```
|
152
|
+
|
153
|
+
The recommended style for listeners is always a `do; end` block.
|
154
|
+
|
155
|
+
5 - Component Proxy & Methods
|
156
|
+
|
157
|
+
When utilizing the Glimmer GUI DSL, you get back proxy objects that wrap [swing](https://docs.oracle.com/javase/8/docs/api/javax/swing/package-summary.html)/[awt](https://docs.oracle.com/javase/8/docs/api/java/awt/package-summary.html) components. To access the original component wrapped by the proxy object, you may call the `#original` method.
|
158
|
+
|
159
|
+
Furthermore, you may invoke any method available on the component on the proxy object, like the `#show` method on `JFrame`.
|
160
|
+
|
161
|
+
```ruby
|
162
|
+
frame1 = jframe('Hello, World!') {
|
163
|
+
# ...
|
164
|
+
}
|
165
|
+
frame1.show
|
166
|
+
```
|
167
|
+
|
168
|
+
### Shape DSL
|
169
|
+
|
170
|
+
[Glimmer DSL for Swing](https://rubygems.org/gems/glimmer-dsl-swing) might be the only Ruby Swing DSL out there that supports an additional Shape DSL.
|
171
|
+
|
172
|
+
This enables declarative painting of arbitrary shapes using Java 2D, which is similar to how SVG works on the web.
|
173
|
+
|
174
|
+
Simply utilize underscored shape names from the `java.awt.geom` [package classes](https://docs.oracle.com/javase/8/docs/api/java/awt/geom/package-summary.html) minus the `2D` suffix, following the same general rules of the [Glimmer GUI DSL](#glimmer-gui-dsl).
|
175
|
+
|
176
|
+
For example, `Arc2D` becomes simply `arc`.
|
177
|
+
|
178
|
+
Additionally, you can set `draw_color` or `fill_color` property as an rgb/rgba hash (e.g. `r: 255, g: 0, b: 0`)
|
179
|
+
|
180
|
+
Example:
|
181
|
+
|
182
|
+
```ruby
|
183
|
+
require 'glimmer-dsl-swing'
|
184
|
+
|
185
|
+
include Glimmer
|
186
|
+
|
187
|
+
jframe('Hello, Shapes!') {
|
188
|
+
minimum_size 400, 400
|
189
|
+
|
190
|
+
arc(40, 40, 90, 90, 30, 230, 0) {
|
191
|
+
fill_color r: 255, g: 0, b: 0
|
192
|
+
draw_color r: 0, g: 255, b: 255
|
193
|
+
}
|
194
|
+
|
195
|
+
arc(40, 140, 90, 90, 30, 230, 1) {
|
196
|
+
fill_color r: 255, g: 0, b: 0
|
197
|
+
draw_color r: 0, g: 255, b: 255
|
198
|
+
}
|
199
|
+
|
200
|
+
arc(40, 240, 90, 90, 30, 230, 2) {
|
201
|
+
fill_color r: 255, g: 0, b: 0
|
202
|
+
draw_color r: 0, g: 255, b: 255
|
203
|
+
}
|
204
|
+
|
205
|
+
ellipse(140, 40, 180, 90) {
|
206
|
+
fill_color r: 0, g: 255, b: 255
|
207
|
+
draw_color r: 255, g: 0, b: 0
|
208
|
+
}
|
209
|
+
|
210
|
+
rectangle(140, 140, 180, 90) {
|
211
|
+
fill_color r: 0, g: 255, b: 255
|
212
|
+
draw_color r: 255, g: 0, b: 0
|
213
|
+
}
|
214
|
+
|
215
|
+
round_rectangle(140, 240, 180, 90, 60, 40) {
|
216
|
+
fill_color r: 0, g: 255, b: 255
|
217
|
+
draw_color r: 255, g: 0, b: 0
|
218
|
+
}
|
219
|
+
|
220
|
+
line(180, 60, 280, 110) {
|
221
|
+
draw_color r: 0, g: 0, b: 0
|
222
|
+
}
|
223
|
+
|
224
|
+
quad_curve(170, 60, 180, 90, 220, 100) {
|
225
|
+
draw_color r: 0, g: 0, b: 0
|
226
|
+
}
|
227
|
+
|
228
|
+
cubic_curve(190, 60, 240, 40, 220, 80, 260, 70) {
|
229
|
+
draw_color r: 0, g: 0, b: 0
|
230
|
+
}
|
231
|
+
}.show
|
232
|
+
```
|
233
|
+
|
234
|
+
![screenshots/glimmer-dsl-swing-mac-hello-shapes.png](screenshots/glimmer-dsl-swing-mac-hello-shapes.png)
|
235
|
+
|
89
236
|
## Girb (Glimmer IRB)
|
90
237
|
|
91
238
|
You can run the `girb` command (`bin/girb` if you cloned the project locally):
|
@@ -102,6 +249,18 @@ This gives you `irb` with the `glimmer-dsl-gtk` gem loaded and the `Glimmer` mod
|
|
102
249
|
|
103
250
|
#### Hello, World!
|
104
251
|
|
252
|
+
Run with gem installed:
|
253
|
+
|
254
|
+
```
|
255
|
+
jruby -r glimmer-dsl-swing -e "require 'samples/hello/hello_world'"
|
256
|
+
```
|
257
|
+
|
258
|
+
Or run from locally cloned project directory:
|
259
|
+
|
260
|
+
```
|
261
|
+
jruby -r ./lib/glimmer-dsl-swing samples/hello/hello_world.rb
|
262
|
+
```
|
263
|
+
|
105
264
|
![screenshots/glimmer-dsl-swing-mac-hello-world.png](screenshots/glimmer-dsl-swing-mac-hello-world.png)
|
106
265
|
|
107
266
|
```ruby
|
@@ -116,6 +275,18 @@ jframe('Hello, World!') {
|
|
116
275
|
|
117
276
|
#### Hello, Button!
|
118
277
|
|
278
|
+
Run with gem installed:
|
279
|
+
|
280
|
+
```
|
281
|
+
jruby -r glimmer-dsl-swing -e "require 'samples/hello/hello_button'"
|
282
|
+
```
|
283
|
+
|
284
|
+
Or run from locally cloned project directory:
|
285
|
+
|
286
|
+
```
|
287
|
+
jruby -r ./lib/glimmer-dsl-swing samples/hello/hello_button.rb
|
288
|
+
```
|
289
|
+
|
119
290
|
![screenshots/glimmer-dsl-swing-mac-hello-button.png](screenshots/glimmer-dsl-swing-mac-hello-button.png)
|
120
291
|
|
121
292
|
```ruby
|
@@ -125,11 +296,79 @@ include Glimmer
|
|
125
296
|
|
126
297
|
jframe('Hello, Button!') {
|
127
298
|
@button = jbutton('Click To Increment: 0') {
|
128
|
-
on_action_performed
|
299
|
+
on_action_performed do
|
129
300
|
button_text_match = @button.text.match(/(.*)(\d+)$/)
|
130
301
|
count = button_text_match[2].to_i + 1
|
131
302
|
@button.text = "#{button_text_match[1]}#{count}"
|
132
|
-
|
303
|
+
end
|
304
|
+
}
|
305
|
+
}.show
|
306
|
+
```
|
307
|
+
|
308
|
+
#### Hello, Shapes!
|
309
|
+
|
310
|
+
Run with gem installed:
|
311
|
+
|
312
|
+
```
|
313
|
+
jruby -r glimmer-dsl-swing -e "require 'samples/hello/hello_shapes'"
|
314
|
+
```
|
315
|
+
|
316
|
+
Or run from locally cloned project directory:
|
317
|
+
|
318
|
+
```
|
319
|
+
jruby -r ./lib/glimmer-dsl-swing samples/hello/hello_shapes.rb
|
320
|
+
```
|
321
|
+
|
322
|
+
![screenshots/glimmer-dsl-swing-mac-hello-shapes.png](screenshots/glimmer-dsl-swing-mac-hello-shapes.png)
|
323
|
+
|
324
|
+
```ruby
|
325
|
+
require 'glimmer-dsl-swing'
|
326
|
+
|
327
|
+
include Glimmer
|
328
|
+
|
329
|
+
jframe('Hello, Shapes!') {
|
330
|
+
minimum_size 400, 400
|
331
|
+
|
332
|
+
arc(40, 40, 90, 90, 30, 230, 0) {
|
333
|
+
fill_color r: 255, g: 0, b: 0
|
334
|
+
draw_color r: 0, g: 255, b: 255
|
335
|
+
}
|
336
|
+
|
337
|
+
arc(40, 140, 90, 90, 30, 230, 1) {
|
338
|
+
fill_color r: 255, g: 0, b: 0
|
339
|
+
draw_color r: 0, g: 255, b: 255
|
340
|
+
}
|
341
|
+
|
342
|
+
arc(40, 240, 90, 90, 30, 230, 2) {
|
343
|
+
fill_color r: 255, g: 0, b: 0
|
344
|
+
draw_color r: 0, g: 255, b: 255
|
345
|
+
}
|
346
|
+
|
347
|
+
ellipse(140, 40, 180, 90) {
|
348
|
+
fill_color r: 0, g: 255, b: 255
|
349
|
+
draw_color r: 255, g: 0, b: 0
|
350
|
+
}
|
351
|
+
|
352
|
+
rectangle(140, 140, 180, 90) {
|
353
|
+
fill_color r: 0, g: 255, b: 255
|
354
|
+
draw_color r: 255, g: 0, b: 0
|
355
|
+
}
|
356
|
+
|
357
|
+
round_rectangle(140, 240, 180, 90, 60, 40) {
|
358
|
+
fill_color r: 0, g: 255, b: 255
|
359
|
+
draw_color r: 255, g: 0, b: 0
|
360
|
+
}
|
361
|
+
|
362
|
+
line(180, 60, 280, 110) {
|
363
|
+
draw_color r: 0, g: 0, b: 0
|
364
|
+
}
|
365
|
+
|
366
|
+
quad_curve(170, 60, 180, 90, 220, 100) {
|
367
|
+
draw_color r: 0, g: 0, b: 0
|
368
|
+
}
|
369
|
+
|
370
|
+
cubic_curve(190, 60, 240, 40, 220, 80, 260, 70) {
|
371
|
+
draw_color r: 0, g: 0, b: 0
|
133
372
|
}
|
134
373
|
}.show
|
135
374
|
```
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.0.
|
1
|
+
0.0.2
|
data/bin/girb
CHANGED
File without changes
|
data/glimmer-dsl-swing.gemspec
CHANGED
Binary file
|
@@ -29,12 +29,12 @@ module Glimmer
|
|
29
29
|
include ParentExpression
|
30
30
|
|
31
31
|
def can_interpret?(parent, keyword, *args, &block)
|
32
|
-
keyword = "j_#{keyword[1..-1]}" if keyword.match(/j[a-z]/)
|
32
|
+
keyword = "j_#{keyword[1..-1]}" if keyword.match(/j[a-z]/) # TODO move this logic to ComponentProxy
|
33
33
|
Glimmer::Swing::ComponentProxy.exist?(keyword)
|
34
34
|
end
|
35
35
|
|
36
36
|
def interpret(parent, keyword, *args, &block)
|
37
|
-
keyword = "j_#{keyword[1..-1]}" if keyword.match(/j[a-z]/)
|
37
|
+
keyword = "j_#{keyword[1..-1]}" if keyword.match(/j[a-z]/) # TODO move this logic to ComponentProxy
|
38
38
|
Glimmer::Swing::ComponentProxy.create(parent, keyword, *args, &block)
|
39
39
|
end
|
40
40
|
|
@@ -27,13 +27,16 @@ module Glimmer
|
|
27
27
|
module Swing
|
28
28
|
class PropertyExpression < Expression
|
29
29
|
def can_interpret?(parent, keyword, *args, &block)
|
30
|
-
|
30
|
+
(
|
31
|
+
parent.is_a?(Glimmer::Swing::ComponentProxy) or
|
32
|
+
parent.is_a?(Glimmer::Swing::ShapeProxy)
|
33
|
+
) and
|
31
34
|
block.nil? and
|
32
35
|
parent.respond_to?(keyword, *args)
|
33
36
|
end
|
34
37
|
|
35
38
|
def interpret(parent, keyword, *args, &block)
|
36
|
-
parent.send(keyword, *args)
|
39
|
+
parent.send("#{keyword}=", *args)
|
37
40
|
end
|
38
41
|
end
|
39
42
|
end
|
@@ -0,0 +1,48 @@
|
|
1
|
+
# Copyright (c) 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/expression'
|
23
|
+
require 'glimmer/dsl/parent_expression'
|
24
|
+
|
25
|
+
module Glimmer
|
26
|
+
module DSL
|
27
|
+
module Swing
|
28
|
+
class ShapeExpression < Expression
|
29
|
+
include ParentExpression
|
30
|
+
|
31
|
+
def can_interpret?(parent, keyword, *args, &block)
|
32
|
+
Glimmer::Swing::ShapeProxy.exist?(keyword)
|
33
|
+
end
|
34
|
+
|
35
|
+
def interpret(parent, keyword, *args, &block)
|
36
|
+
Glimmer::Swing::ShapeProxy.create(parent, keyword, *args, &block)
|
37
|
+
end
|
38
|
+
|
39
|
+
def add_content(parent, keyword, *args, &block)
|
40
|
+
super
|
41
|
+
parent.post_add_content
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
require 'glimmer/swing/shape_proxy'
|
@@ -31,11 +31,21 @@ module Glimmer
|
|
31
31
|
DEFAULT_WIDTH = 190
|
32
32
|
DEFAULT_HEIGHT = 150
|
33
33
|
|
34
|
+
def set_minimum_size(*args)
|
35
|
+
@minimum_size_set = true
|
36
|
+
if args.size == 1 && args.first.is_a?(Java::JavaAwt::Dimension)
|
37
|
+
super
|
38
|
+
else
|
39
|
+
super(Java::JavaAwt::Dimension.new(*args))
|
40
|
+
end
|
41
|
+
end
|
42
|
+
alias minimum_size= set_minimum_size
|
43
|
+
|
34
44
|
def post_add_content
|
35
45
|
unless @initial_content_added
|
36
46
|
@initial_content_added = true
|
37
|
-
the_width =
|
38
|
-
the_height =
|
47
|
+
the_width = @minimum_size_set ? minimum_size.width : DEFAULT_WIDTH
|
48
|
+
the_height = @minimum_size_set ? minimum_size.height : DEFAULT_HEIGHT
|
39
49
|
set_minimum_size(Java::JavaAwt::Dimension.new(the_width, the_height))
|
40
50
|
set_default_close_operation(Java::JavaxSwing::JFrame::EXIT_ON_CLOSE)
|
41
51
|
end
|
@@ -32,7 +32,7 @@ module Glimmer
|
|
32
32
|
|
33
33
|
class << self
|
34
34
|
def exist?(keyword)
|
35
|
-
!!
|
35
|
+
!!component_class(keyword)
|
36
36
|
end
|
37
37
|
|
38
38
|
def create(parent, keyword, *args, &block)
|
@@ -70,10 +70,10 @@ module Glimmer
|
|
70
70
|
end
|
71
71
|
|
72
72
|
def component_class(keyword)
|
73
|
-
unless flyweight_component_class
|
73
|
+
unless flyweight_component_class[keyword]
|
74
74
|
begin
|
75
|
-
|
76
|
-
|
75
|
+
component_class_name = component_class_symbol(keyword).to_s
|
76
|
+
component_class = eval(component_class_name)
|
77
77
|
unless component_class.ancestors.include?(Java::JavaAwt::Component)
|
78
78
|
component_class = component_class_manual_entries[keyword]
|
79
79
|
if component_class.nil?
|
@@ -81,6 +81,25 @@ module Glimmer
|
|
81
81
|
return nil
|
82
82
|
end
|
83
83
|
end
|
84
|
+
component_class = Class.new(component_class) {
|
85
|
+
attr_accessor :shape_proxies
|
86
|
+
|
87
|
+
def paint(g2)
|
88
|
+
super(g2)
|
89
|
+
shape_proxies.each do |shape_proxy|
|
90
|
+
original_color = g2.get_color
|
91
|
+
if shape_proxy.fill_color
|
92
|
+
g2.color = Color.new(shape_proxy.fill_color[:r], shape_proxy.fill_color[:g], shape_proxy.fill_color[:b], shape_proxy.fill_color[:a] || 255)
|
93
|
+
g2.fill(shape_proxy)
|
94
|
+
end
|
95
|
+
if shape_proxy.draw_color
|
96
|
+
g2.color = Color.new(shape_proxy.draw_color[:r], shape_proxy.draw_color[:g], shape_proxy.draw_color[:b], shape_proxy.draw_color[:a] || 255)
|
97
|
+
g2.draw(shape_proxy)
|
98
|
+
end
|
99
|
+
g2.color = original_color
|
100
|
+
end
|
101
|
+
end
|
102
|
+
}
|
84
103
|
flyweight_component_class[keyword] = component_class
|
85
104
|
rescue SyntaxError, NameError => e
|
86
105
|
Glimmer::Config.logger.debug {e.full_message}
|
@@ -106,7 +125,7 @@ module Glimmer
|
|
106
125
|
@keyword = keyword
|
107
126
|
@args = args
|
108
127
|
@block = block
|
109
|
-
|
128
|
+
build
|
110
129
|
post_add_content if @block.nil?
|
111
130
|
end
|
112
131
|
|
@@ -117,7 +136,15 @@ module Glimmer
|
|
117
136
|
|
118
137
|
# Subclasses may override to perform post initialization work on an added child (normally must also call super)
|
119
138
|
def post_initialize_child(child)
|
120
|
-
|
139
|
+
if child.is_a?(ComponentProxy)
|
140
|
+
add(child)
|
141
|
+
elsif child.is_a?(ShapeProxy)
|
142
|
+
shape_proxies << child
|
143
|
+
end
|
144
|
+
end
|
145
|
+
|
146
|
+
def shape_proxies
|
147
|
+
@shape_proxies ||= []
|
121
148
|
end
|
122
149
|
|
123
150
|
def respond_to?(method_name, *args, &block)
|
@@ -130,7 +157,9 @@ module Glimmer
|
|
130
157
|
end
|
131
158
|
|
132
159
|
def method_missing(method_name, *args, &block)
|
133
|
-
if
|
160
|
+
if respond_to?("#{method_name}=", true) && !args.empty?
|
161
|
+
send("#{method_name}=", *args)
|
162
|
+
elsif @original.respond_to?("set_#{method_name}", true) && !args.empty?
|
134
163
|
send_to_original("set_#{method_name}", *args, &block)
|
135
164
|
elsif @original.respond_to?(method_name, true)
|
136
165
|
send_to_original(method_name, *args, &block)
|
@@ -224,10 +253,9 @@ module Glimmer
|
|
224
253
|
|
225
254
|
private
|
226
255
|
|
227
|
-
def
|
228
|
-
pd keyword
|
229
|
-
pd ComponentProxy.component_class(keyword)
|
256
|
+
def build
|
230
257
|
@original = ComponentProxy.component_class(keyword).new(*normalize_args(args))
|
258
|
+
@original.shape_proxies = shape_proxies
|
231
259
|
end
|
232
260
|
|
233
261
|
def normalize_args(args)
|
@@ -240,3 +268,4 @@ module Glimmer
|
|
240
268
|
end
|
241
269
|
|
242
270
|
Dir[File.expand_path("./#{File.basename(__FILE__, '.rb')}/*.rb", __dir__)].each {|f| require f}
|
271
|
+
require 'glimmer/swing/shape_proxy'
|
@@ -0,0 +1,167 @@
|
|
1
|
+
# Copyright (c) 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/swing/packages'
|
23
|
+
|
24
|
+
module Glimmer
|
25
|
+
module Swing
|
26
|
+
# Proxy for Java2D shape objects
|
27
|
+
#
|
28
|
+
# Follows the Proxy Design Pattern
|
29
|
+
class ShapeProxy
|
30
|
+
include Packages
|
31
|
+
|
32
|
+
class << self
|
33
|
+
def exist?(keyword)
|
34
|
+
!!shape_class(keyword)
|
35
|
+
end
|
36
|
+
|
37
|
+
def create(parent, keyword, *args, &block)
|
38
|
+
shape_proxy_class(keyword).new(parent, keyword, *args, &block)
|
39
|
+
end
|
40
|
+
|
41
|
+
def shape_proxy_class(keyword)
|
42
|
+
begin
|
43
|
+
class_name = shape_proxy_class_symbol(keyword)
|
44
|
+
Glimmer::Swing::ShapeProxy.const_get(class_name)
|
45
|
+
rescue => e
|
46
|
+
Glimmer::Config.logger.debug e.full_message
|
47
|
+
Glimmer::Swing::ShapeProxy
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
def shape_proxy_class_symbol(keyword)
|
52
|
+
"#{keyword.camelcase(:upper)}Proxy".to_sym
|
53
|
+
end
|
54
|
+
|
55
|
+
def shape_class_symbol(keyword)
|
56
|
+
keyword.camelcase(:upper).to_sym
|
57
|
+
end
|
58
|
+
|
59
|
+
def keyword(shape_proxy_class)
|
60
|
+
shape_proxy_class.to_s.underscore.sub(/_proxy$/, '')
|
61
|
+
end
|
62
|
+
|
63
|
+
def shape_class_manual_entries
|
64
|
+
# add mappings for any classes (minus the namespace) that conflict with standard Ruby classes
|
65
|
+
{
|
66
|
+
# example:
|
67
|
+
# 'date_time' => Java::OrgEclipseSwtWidgets::DateTime
|
68
|
+
}
|
69
|
+
end
|
70
|
+
|
71
|
+
def shape_class(keyword)
|
72
|
+
unless flyweight_shape_class.keys.include?(keyword)
|
73
|
+
begin
|
74
|
+
shape_class_name = shape_class_symbol(keyword).to_s
|
75
|
+
shape_class = eval("#{shape_class_name}2D::Double") rescue eval(shape_class_name)
|
76
|
+
unless shape_class.ancestors.include?(Java::JavaAwt::Shape)
|
77
|
+
shape_class = shape_class_manual_entries[keyword]
|
78
|
+
if shape_class.nil?
|
79
|
+
Glimmer::Config.logger.debug {"Class #{shape_class} matching #{keyword} is not a subclass of java.awt.Component"}
|
80
|
+
return nil
|
81
|
+
end
|
82
|
+
end
|
83
|
+
flyweight_shape_class[keyword] = shape_class
|
84
|
+
rescue SyntaxError, NameError => e
|
85
|
+
Glimmer::Config.logger.debug {e.full_message}
|
86
|
+
nil
|
87
|
+
rescue => e
|
88
|
+
Glimmer::Config.logger.debug {e.full_message}
|
89
|
+
nil
|
90
|
+
end
|
91
|
+
end
|
92
|
+
flyweight_shape_class[keyword]
|
93
|
+
end
|
94
|
+
|
95
|
+
# Flyweight Design Pattern memoization cache. Can be cleared if memory is needed.
|
96
|
+
def flyweight_shape_class
|
97
|
+
@flyweight_shape_class ||= {}
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
101
|
+
attr_reader :parent_proxy, :original, :args, :keyword, :block
|
102
|
+
attr_accessor :draw_color, :fill_color
|
103
|
+
|
104
|
+
def initialize(parent, keyword, *args, &block)
|
105
|
+
@parent_proxy = parent
|
106
|
+
@keyword = keyword
|
107
|
+
@args = args
|
108
|
+
@block = block
|
109
|
+
build
|
110
|
+
post_add_content if @block.nil?
|
111
|
+
end
|
112
|
+
|
113
|
+
# Subclasses may override to perform post add_content work (normally must call super)
|
114
|
+
def post_add_content
|
115
|
+
@parent_proxy&.post_initialize_child(self)
|
116
|
+
end
|
117
|
+
|
118
|
+
# Subclasses may override to perform post initialization work on an added child (normally must also call super)
|
119
|
+
def post_initialize_child(child)
|
120
|
+
if child.is_a?(ShapeProxy)
|
121
|
+
add(child)
|
122
|
+
end
|
123
|
+
end
|
124
|
+
|
125
|
+
def respond_to?(method_name, *args, &block)
|
126
|
+
respond_to_original?(method_name, *args, &block) ||
|
127
|
+
super(method_name, true)
|
128
|
+
end
|
129
|
+
|
130
|
+
def respond_to_original?(method_name, *args, &block)
|
131
|
+
@original.respond_to?(method_name, true) || @original.respond_to?("set_#{method_name}", true)
|
132
|
+
end
|
133
|
+
|
134
|
+
def method_missing(method_name, *args, &block)
|
135
|
+
if @original.respond_to?("set_#{method_name}", true) && !args.empty?
|
136
|
+
send_to_original("set_#{method_name}", *args, &block)
|
137
|
+
elsif @original.respond_to?(method_name, true)
|
138
|
+
send_to_original(method_name, *args, &block)
|
139
|
+
else
|
140
|
+
super
|
141
|
+
end
|
142
|
+
end
|
143
|
+
|
144
|
+
def send_to_original(method_name, *args, &block)
|
145
|
+
@original.send(method_name, *normalize_args(args), &block)
|
146
|
+
end
|
147
|
+
|
148
|
+
def content(&block)
|
149
|
+
Glimmer::DSL::Engine.add_content(self, Glimmer::DSL::Swing::ShapeExpression.new, @keyword, &block)
|
150
|
+
end
|
151
|
+
|
152
|
+
private
|
153
|
+
|
154
|
+
def build
|
155
|
+
@original = ShapeProxy.shape_class(keyword).new(*normalize_args(args))
|
156
|
+
end
|
157
|
+
|
158
|
+
def normalize_args(args)
|
159
|
+
args.map do |arg|
|
160
|
+
arg.is_a?(ShapeProxy) ? arg.original : arg
|
161
|
+
end
|
162
|
+
end
|
163
|
+
end
|
164
|
+
end
|
165
|
+
end
|
166
|
+
|
167
|
+
Dir[File.expand_path("./#{File.basename(__FILE__, '.rb')}/*.rb", __dir__)].each {|f| require f}
|
data/lib/glimmer-dsl-swing.rb
CHANGED
@@ -36,8 +36,6 @@ require 'facets/string/camelcase'
|
|
36
36
|
require 'facets/hash/stringify_keys'
|
37
37
|
|
38
38
|
# Internal requires
|
39
|
-
# require 'ext/glimmer/config'
|
40
|
-
# require 'ext/glimmer'
|
41
39
|
require 'glimmer/swing'
|
42
40
|
require 'glimmer/swing/ext/glimmer'
|
43
41
|
require 'glimmer/swing/ext/glimmer/config'
|
@@ -4,10 +4,10 @@ include Glimmer
|
|
4
4
|
|
5
5
|
jframe('Hello, Button!') {
|
6
6
|
@button = jbutton('Click To Increment: 0') {
|
7
|
-
on_action_performed
|
8
|
-
button_text_match = @button.text.match(/(
|
7
|
+
on_action_performed do
|
8
|
+
button_text_match = @button.text.match(/([^0-9]+)(\d+)$/)
|
9
9
|
count = button_text_match[2].to_i + 1
|
10
10
|
@button.text = "#{button_text_match[1]}#{count}"
|
11
|
-
|
11
|
+
end
|
12
12
|
}
|
13
13
|
}.show
|
@@ -0,0 +1,49 @@
|
|
1
|
+
require 'glimmer-dsl-swing'
|
2
|
+
|
3
|
+
include Glimmer
|
4
|
+
|
5
|
+
jframe('Hello, Shapes!') {
|
6
|
+
minimum_size 400, 400
|
7
|
+
|
8
|
+
arc(40, 40, 90, 90, 30, 230, 0) {
|
9
|
+
fill_color r: 255, g: 0, b: 0
|
10
|
+
draw_color r: 0, g: 255, b: 255
|
11
|
+
}
|
12
|
+
|
13
|
+
arc(40, 140, 90, 90, 30, 230, 1) {
|
14
|
+
fill_color r: 255, g: 0, b: 0
|
15
|
+
draw_color r: 0, g: 255, b: 255
|
16
|
+
}
|
17
|
+
|
18
|
+
arc(40, 240, 90, 90, 30, 230, 2) {
|
19
|
+
fill_color r: 255, g: 0, b: 0
|
20
|
+
draw_color r: 0, g: 255, b: 255
|
21
|
+
}
|
22
|
+
|
23
|
+
ellipse(140, 40, 180, 90) {
|
24
|
+
fill_color r: 0, g: 255, b: 255
|
25
|
+
draw_color r: 255, g: 0, b: 0
|
26
|
+
}
|
27
|
+
|
28
|
+
rectangle(140, 140, 180, 90) {
|
29
|
+
fill_color r: 0, g: 255, b: 255
|
30
|
+
draw_color r: 255, g: 0, b: 0
|
31
|
+
}
|
32
|
+
|
33
|
+
round_rectangle(140, 240, 180, 90, 60, 40) {
|
34
|
+
fill_color r: 0, g: 255, b: 255
|
35
|
+
draw_color r: 255, g: 0, b: 0
|
36
|
+
}
|
37
|
+
|
38
|
+
line(180, 60, 280, 110) {
|
39
|
+
draw_color r: 0, g: 0, b: 0
|
40
|
+
}
|
41
|
+
|
42
|
+
quad_curve(170, 60, 180, 90, 220, 100) {
|
43
|
+
draw_color r: 0, g: 0, b: 0
|
44
|
+
}
|
45
|
+
|
46
|
+
cubic_curve(190, 60, 240, 40, 220, 80, 260, 70) {
|
47
|
+
draw_color r: 0, g: 0, b: 0
|
48
|
+
}
|
49
|
+
}.show
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: glimmer-dsl-swing
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Andy Maleh
|
@@ -202,6 +202,7 @@ executables:
|
|
202
202
|
- girb
|
203
203
|
extensions: []
|
204
204
|
extra_rdoc_files:
|
205
|
+
- CHANGELOG.md
|
205
206
|
- LICENSE.txt
|
206
207
|
- README.md
|
207
208
|
files:
|
@@ -217,6 +218,7 @@ files:
|
|
217
218
|
- lib/glimmer/dsl/swing/dsl.rb
|
218
219
|
- lib/glimmer/dsl/swing/listener_expression.rb
|
219
220
|
- lib/glimmer/dsl/swing/property_expression.rb
|
221
|
+
- lib/glimmer/dsl/swing/shape_expression.rb
|
220
222
|
- lib/glimmer/swing.rb
|
221
223
|
- lib/glimmer/swing/component_listener_proxy.rb
|
222
224
|
- lib/glimmer/swing/component_proxy.rb
|
@@ -224,7 +226,9 @@ files:
|
|
224
226
|
- lib/glimmer/swing/ext/glimmer.rb
|
225
227
|
- lib/glimmer/swing/ext/glimmer/config.rb
|
226
228
|
- lib/glimmer/swing/packages.rb
|
229
|
+
- lib/glimmer/swing/shape_proxy.rb
|
227
230
|
- samples/hello/hello_button.rb
|
231
|
+
- samples/hello/hello_shapes.rb
|
228
232
|
- samples/hello/hello_world.rb
|
229
233
|
homepage: http://github.com/AndyObtiva/glimmer-dsl-swing
|
230
234
|
licenses:
|
@@ -246,7 +250,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
246
250
|
- !ruby/object:Gem::Version
|
247
251
|
version: '0'
|
248
252
|
requirements: []
|
249
|
-
rubygems_version: 3.
|
253
|
+
rubygems_version: 3.2.29
|
250
254
|
signing_key:
|
251
255
|
specification_version: 4
|
252
256
|
summary: Glimmer DSL for Swing
|