glimmer-dsl-swt 4.18.4.10 → 4.18.4.11
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +11 -0
- data/README.md +4 -4
- data/VERSION +1 -1
- data/docs/reference/GLIMMER_GUI_DSL_SYNTAX.md +169 -86
- data/docs/reference/GLIMMER_SAMPLES.md +10 -0
- data/glimmer-dsl-swt.gemspec +3 -3
- data/lib/glimmer/dsl/swt/color_expression.rb +1 -1
- data/lib/glimmer/dsl/swt/custom_widget_expression.rb +4 -1
- data/lib/glimmer/dsl/swt/image_expression.rb +8 -1
- data/lib/glimmer/dsl/swt/widget_expression.rb +4 -1
- data/lib/glimmer/swt/color_proxy.rb +1 -1
- data/lib/glimmer/swt/custom/code_text.rb +22 -0
- data/lib/glimmer/swt/custom/drawable.rb +44 -0
- data/lib/glimmer/swt/custom/shape.rb +4 -0
- data/lib/glimmer/swt/image_proxy.rb +14 -3
- data/samples/elaborate/mandelbrot_fractal.rb +16 -20
- data/samples/elaborate/meta_sample.rb +1 -1
- data/samples/hello/hello_combo.rb +1 -1
- data/samples/hello/hello_list_multi_selection.rb +1 -1
- data/samples/hello/hello_list_single_selection.rb +1 -1
- data/samples/hello/hello_progress_bar.rb +2 -0
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: cb72ad5f93c5c27a2f2ead87225e0ee045e2663e50b04346f5be6065fbf269c2
|
4
|
+
data.tar.gz: 394f955a01f7d5b568ae433dcab240f86b48749e5db428296299388ceaff5773
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 18dd1f7062fdb14e063820d29168815df77b70f04275559fc812b605d2daf6053815b94579030a749cfc942188115150db093b0f0fc9863247177d112d165d90
|
7
|
+
data.tar.gz: c1809fda609b22045fd5872624cbc234b1353173522f2430767b8f36e4afd096063d5b4fe5fc41b0a24b0f96ec00d9fc0aada8df9537201d1d87fe8eebe26d59
|
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,16 @@
|
|
1
1
|
# Change Log
|
2
2
|
|
3
|
+
### 4.18.4.11
|
4
|
+
|
5
|
+
- Support creating images pixel by pixel with `image(width, height) {|x,y| [r, g, b]}` keyword, which takes a block with x, y coordinates based on the image width and height and returns a pixel foreground color per point
|
6
|
+
- Add proper indentation in code_text upon hitting ENTER
|
7
|
+
- Reset Canvas Shape DSL alpha value to 255 when not explicitly set on a shape (Apply in Hello, Canvas! Sample)
|
8
|
+
- Provide terse syntax for building canvas objects (autodetecting its width and height)
|
9
|
+
- Provide terse syntax for building `:image_double_buffered` canvas objects (autodetecting its width and height):
|
10
|
+
- Center mandelbrot where mouse is clicked upon zoom
|
11
|
+
- Fix issue with Mandelbrot sample off by one error on Cores selected via Menu
|
12
|
+
- Fix use of on_events in code_text widget with lines mode true
|
13
|
+
|
3
14
|
### 4.18.4.10
|
4
15
|
|
5
16
|
- Hello, Progress Bar!
|
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 SWT 4.18.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 SWT 4.18.4.11
|
2
2
|
## JRuby Desktop Development GUI Framework
|
3
3
|
[![Gem Version](https://badge.fury.io/rb/glimmer-dsl-swt.svg)](http://badge.fury.io/rb/glimmer-dsl-swt)
|
4
4
|
[![Travis CI](https://travis-ci.com/AndyObtiva/glimmer-dsl-swt.svg?branch=master)](https://travis-ci.com/github/AndyObtiva/glimmer-dsl-swt)
|
@@ -342,7 +342,7 @@ jgem install glimmer-dsl-swt
|
|
342
342
|
|
343
343
|
Or this command if you want a specific version:
|
344
344
|
```
|
345
|
-
jgem install glimmer-dsl-swt -v 4.18.4.
|
345
|
+
jgem install glimmer-dsl-swt -v 4.18.4.11
|
346
346
|
```
|
347
347
|
|
348
348
|
`jgem` is JRuby's version of `gem` command.
|
@@ -360,7 +360,7 @@ Note: if you're using activerecord or activesupport, keep in mind that Glimmer u
|
|
360
360
|
|
361
361
|
Add the following to `Gemfile`:
|
362
362
|
```
|
363
|
-
gem 'glimmer-dsl-swt', '~> 4.18.4.
|
363
|
+
gem 'glimmer-dsl-swt', '~> 4.18.4.11'
|
364
364
|
```
|
365
365
|
|
366
366
|
And, then run:
|
@@ -432,7 +432,7 @@ If you have a Glimmer app you would like referenced here, please mention in a Pu
|
|
432
432
|
|
433
433
|
### Connector
|
434
434
|
|
435
|
-
[<img alt="Connector Logo" src="https://raw.githubusercontent.com/AndyObtiva/connector/master/package/linux/Connector.png" height=40 /> Connector](https://github.com/AndyObtiva/connector): A minimalist open-source web browser
|
435
|
+
[<img alt="Connector Logo" src="https://raw.githubusercontent.com/AndyObtiva/connector/master/package/linux/Connector.png" height=40 /> Connector](https://github.com/AndyObtiva/connector): A minimalist open-source multi-engine web browser
|
436
436
|
|
437
437
|
## Packaging & Distribution
|
438
438
|
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
4.18.4.
|
1
|
+
4.18.4.11
|
@@ -411,6 +411,10 @@ Although SWT Display is not technically a widget, it has similar APIs and DSL su
|
|
411
411
|
|
412
412
|
[JRuby](https://www.jruby.org/) supports [truly parallel multi-threading](https://github.com/jruby/jruby/wiki/Concurrency-in-jruby) since it relies on the JVM (Java Virtual Machine). As such, it enables development of highly-interactive desktop applications that can do background work while the user is interacting with the GUI. However, any code that interacts with the GUI from a thread other than the main (first) GUI thread must do so only through sync_exec (if it is standard synchronous code) or async_exec.
|
413
413
|
|
414
|
+
Most of the time, you simply get away with Ruby [Threads](https://ruby-doc.org/core-2.5.7/Thread.html) and [Mutexes](https://ruby-doc.org/core-2.5.7/Mutex.html).
|
415
|
+
|
416
|
+
Otherwise, if you need more advanced concurrency, Glimmer includes the [concurrent-ruby gem](https://rubygems.org/gems/concurrent-ruby), which supports many helpful concurrency techniques such as [Thread Pools](http://ruby-concurrency.github.io/concurrent-ruby/master/file.thread_pools.html) (used in the [Mandelbrot Fractal](GLIMMER_SAMPLES.md#mandelbrot-fractal) sample).
|
417
|
+
|
414
418
|
##### async_exec
|
415
419
|
|
416
420
|
`async_exec {}` is a Glimmer DSL keyword in addition to being a method on `display`. It accepts a block and when invoked, adds the block to the end of a queue of GUI events scheduled to run on the SWT event loop, executing asynchronously.
|
@@ -1411,6 +1415,106 @@ shell {
|
|
1411
1415
|
}.open
|
1412
1416
|
```
|
1413
1417
|
|
1418
|
+
#### Shapes inside a Widget
|
1419
|
+
|
1420
|
+
Keep in mind that the Shape DSL can be used inside any widget, not just `canvas`. Unlike shapes on a `canvas`, which are standalone graphics, when included in a widget, which already has its own look and feel, shapes are used as a decorative add-on that complements its look by getting painted on top of it. For example, shapes were used to decorate `composite` blocks in the [Tetris](#tetris) sample to have a more bevel look. In summary, Shapes can be used in a hybrid approach (shapes inside a widget), not just standalone in a `canvas`.
|
1421
|
+
|
1422
|
+
#### Shapes inside an Image
|
1423
|
+
|
1424
|
+
You can build an image using the Canvas Shape DSL (including setting the icon of the application).
|
1425
|
+
|
1426
|
+
Example (you may copy/paste in [`girb`](GLIMMER_GIRB.md)):
|
1427
|
+
|
1428
|
+
```
|
1429
|
+
include Glimmer
|
1430
|
+
|
1431
|
+
shell {
|
1432
|
+
text 'Image Shape DSL Example'
|
1433
|
+
label {
|
1434
|
+
bevel_constant = 20
|
1435
|
+
icon_block_size = 64
|
1436
|
+
icon_bevel_size = icon_block_size.to_f / 25.to_f
|
1437
|
+
icon_bevel_pixel_size = 0.16*icon_block_size.to_f
|
1438
|
+
icon_size = 8
|
1439
|
+
icon_pixel_size = icon_block_size * icon_size
|
1440
|
+
image(icon_pixel_size, icon_pixel_size) {
|
1441
|
+
icon_size.times { |row|
|
1442
|
+
icon_size.times { |column|
|
1443
|
+
colored = row >= 1 && column.between?(1, 6)
|
1444
|
+
color = colored ? color([:white, :red, :blue, :green, :yellow, :magenta, :cyan, :dark_blue].sample) : color(:white)
|
1445
|
+
x = column * icon_block_size
|
1446
|
+
y = row * icon_block_size
|
1447
|
+
rectangle(x, y, icon_block_size, icon_block_size) {
|
1448
|
+
background color
|
1449
|
+
}
|
1450
|
+
polygon(x, y, x + icon_block_size, y, x + icon_block_size - icon_bevel_pixel_size, y + icon_bevel_pixel_size, x + icon_bevel_pixel_size, y + icon_bevel_pixel_size) {
|
1451
|
+
background rgb(color.red + 4*bevel_constant, color.green + 4*bevel_constant, color.blue + 4*bevel_constant)
|
1452
|
+
}
|
1453
|
+
polygon(x + icon_block_size, y, x + icon_block_size - icon_bevel_pixel_size, y + icon_bevel_pixel_size, x + icon_block_size - icon_bevel_pixel_size, y + icon_block_size - icon_bevel_pixel_size, x + icon_block_size, y + icon_block_size) {
|
1454
|
+
background rgb(color.red - bevel_constant, color.green - bevel_constant, color.blue - bevel_constant)
|
1455
|
+
}
|
1456
|
+
polygon(x + icon_block_size, y + icon_block_size, x, y + icon_block_size, x + icon_bevel_pixel_size, y + icon_block_size - icon_bevel_pixel_size, x + icon_block_size - icon_bevel_pixel_size, y + icon_block_size - icon_bevel_pixel_size) {
|
1457
|
+
background rgb(color.red - 2*bevel_constant, color.green - 2*bevel_constant, color.blue - 2*bevel_constant)
|
1458
|
+
}
|
1459
|
+
polygon(x, y, x, y + icon_block_size, x + icon_bevel_pixel_size, y + icon_block_size - icon_bevel_pixel_size, x + icon_bevel_pixel_size, y + icon_bevel_pixel_size) {
|
1460
|
+
background rgb(color.red - bevel_constant, color.green - bevel_constant, color.blue - bevel_constant)
|
1461
|
+
}
|
1462
|
+
}
|
1463
|
+
}
|
1464
|
+
}
|
1465
|
+
}
|
1466
|
+
}.open
|
1467
|
+
```
|
1468
|
+
|
1469
|
+
![Image Shape DSL](/images/glimmer-example-image-shape-dsl.png)
|
1470
|
+
|
1471
|
+
Example setting the icon of the application (you may copy/paste in [`girb`](GLIMMER_GIRB.md)):
|
1472
|
+
|
1473
|
+
```
|
1474
|
+
include Glimmer
|
1475
|
+
|
1476
|
+
shell {
|
1477
|
+
text 'Image Shape DSL Example'
|
1478
|
+
label {
|
1479
|
+
text 'Image Shape DSL Example'
|
1480
|
+
font height: 30
|
1481
|
+
}
|
1482
|
+
bevel_constant = 20
|
1483
|
+
icon_block_size = 64
|
1484
|
+
icon_bevel_size = icon_block_size.to_f / 25.to_f
|
1485
|
+
icon_bevel_pixel_size = 0.16*icon_block_size.to_f
|
1486
|
+
icon_size = 8
|
1487
|
+
icon_pixel_size = icon_block_size * icon_size
|
1488
|
+
image(icon_pixel_size, icon_pixel_size) {
|
1489
|
+
icon_size.times { |row|
|
1490
|
+
icon_size.times { |column|
|
1491
|
+
colored = row >= 1 && column.between?(1, 6)
|
1492
|
+
color = colored ? color([:white, :red, :blue, :green, :yellow, :magenta, :cyan, :dark_blue].sample) : color(:white)
|
1493
|
+
x = column * icon_block_size
|
1494
|
+
y = row * icon_block_size
|
1495
|
+
rectangle(x, y, icon_block_size, icon_block_size) {
|
1496
|
+
background color
|
1497
|
+
}
|
1498
|
+
polygon(x, y, x + icon_block_size, y, x + icon_block_size - icon_bevel_pixel_size, y + icon_bevel_pixel_size, x + icon_bevel_pixel_size, y + icon_bevel_pixel_size) {
|
1499
|
+
background rgb(color.red + 4*bevel_constant, color.green + 4*bevel_constant, color.blue + 4*bevel_constant)
|
1500
|
+
}
|
1501
|
+
polygon(x + icon_block_size, y, x + icon_block_size - icon_bevel_pixel_size, y + icon_bevel_pixel_size, x + icon_block_size - icon_bevel_pixel_size, y + icon_block_size - icon_bevel_pixel_size, x + icon_block_size, y + icon_block_size) {
|
1502
|
+
background rgb(color.red - bevel_constant, color.green - bevel_constant, color.blue - bevel_constant)
|
1503
|
+
}
|
1504
|
+
polygon(x + icon_block_size, y + icon_block_size, x, y + icon_block_size, x + icon_bevel_pixel_size, y + icon_block_size - icon_bevel_pixel_size, x + icon_block_size - icon_bevel_pixel_size, y + icon_block_size - icon_bevel_pixel_size) {
|
1505
|
+
background rgb(color.red - 2*bevel_constant, color.green - 2*bevel_constant, color.blue - 2*bevel_constant)
|
1506
|
+
}
|
1507
|
+
polygon(x, y, x, y + icon_block_size, x + icon_bevel_pixel_size, y + icon_block_size - icon_bevel_pixel_size, x + icon_bevel_pixel_size, y + icon_bevel_pixel_size) {
|
1508
|
+
background rgb(color.red - bevel_constant, color.green - bevel_constant, color.blue - bevel_constant)
|
1509
|
+
}
|
1510
|
+
}
|
1511
|
+
}
|
1512
|
+
}
|
1513
|
+
}.open
|
1514
|
+
```
|
1515
|
+
|
1516
|
+
![Image Shape DSL](/images/glimmer-example-image-shape-dsl-app-switcher-icon.png)
|
1517
|
+
|
1414
1518
|
#### Pixel Graphics
|
1415
1519
|
|
1416
1520
|
**(Early Alpha Feature)**
|
@@ -1440,6 +1544,21 @@ Result:
|
|
1440
1544
|
|
1441
1545
|
![glimmer example pixel graphics](/images/glimmer-example-pixel-graphics.png)
|
1442
1546
|
|
1547
|
+
If you are strictly dealing with pixels (no other shapes), you could even avoid the `pixel` keyword altogether and just provide direct foreground colors by passing a block that receives x, y coordinates:
|
1548
|
+
|
1549
|
+
```ruby
|
1550
|
+
include Glimmer
|
1551
|
+
|
1552
|
+
shell {
|
1553
|
+
minimum_size 250, 265
|
1554
|
+
text 'Pixel Graphics Example'
|
1555
|
+
|
1556
|
+
canvas { |x, y|
|
1557
|
+
[y%255, x%255, (x+y)%255]
|
1558
|
+
}
|
1559
|
+
}.open
|
1560
|
+
```
|
1561
|
+
|
1443
1562
|
Remember that you could always default to direct SWT painting via [org.eclipse.swt.graphics.GC](https://help.eclipse.org/2020-12/topic/org.eclipse.platform.doc.isv/reference/api/org/eclipse/swt/graphics/GC.html) too for even faster performance when needed in rare circumstances. Learn more at the [SWT Graphics Guide](https://www.eclipse.org/articles/Article-SWT-graphics/SWT_graphics.html) and [SWT Image Guide](https://www.eclipse.org/articles/Article-SWT-images/graphics-resources.html#Saving%20Images).
|
1444
1563
|
|
1445
1564
|
Example of manually doing the same things as in the previous example without relying on the declarative Glimmer Shape DSL (you may copy/paste in [`girb`](GLIMMER_GIRB.md)):
|
@@ -1465,6 +1584,8 @@ shell {
|
|
1465
1584
|
}.open
|
1466
1585
|
```
|
1467
1586
|
|
1587
|
+
(the code could be optimized further if you are repeating colors by simply reusing `Color` objects instead of re-constructing them)
|
1588
|
+
|
1468
1589
|
The only downside with the approach above is that it repaints all pixels on repaints to the window (e.g. during window resize). To get around that, we can rely on a technique called **Image Double-Buffering**. That is to buffer the graphics on an Image first and then set it on the Canvas so that resizes of the shell dont cause a repaint of all the pixels. Additionally, this gives us the added benefit of being able to use the image as a Shell icon via its `image` property.
|
1469
1590
|
|
1470
1591
|
Example (you may copy/paste in [`girb`](GLIMMER_GIRB.md)):
|
@@ -1501,127 +1622,80 @@ If you need a transparent background for the image, replace the image constructi
|
|
1501
1622
|
|
1502
1623
|
That way, wherever you don't draw a point, you get transparency (seeing what is behind the image).
|
1503
1624
|
|
1504
|
-
|
1505
|
-
|
1506
|
-
Example (you may copy/paste in [`girb`](GLIMMER_GIRB.md)):
|
1625
|
+
Alternatively, with a very minor performance penalty, Glimmer enables you to build the image pixel by pixel with a friendly Ruby syntax by passing a block that takes the x and y coordinates and returns a foreground color rgb array or Color/ColorProxy object.
|
1507
1626
|
|
1508
1627
|
```ruby
|
1509
1628
|
include Glimmer
|
1510
1629
|
|
1630
|
+
@the_image = image(250, 250) {|x, y|
|
1631
|
+
[y%255, x%255, (x+y)%255]
|
1632
|
+
}
|
1633
|
+
|
1511
1634
|
shell {
|
1512
1635
|
minimum_size 250, 265
|
1513
1636
|
text 'Pixel Graphics Example'
|
1637
|
+
image @the_image
|
1514
1638
|
|
1515
|
-
canvas
|
1516
|
-
|
1517
|
-
250.times {|x|
|
1518
|
-
pixel(x, y, foreground: [y%255, x%255, (x+y)%255])
|
1519
|
-
}
|
1520
|
-
}
|
1639
|
+
canvas {
|
1640
|
+
image @the_image
|
1521
1641
|
}
|
1522
1642
|
}.open
|
1523
1643
|
```
|
1524
1644
|
|
1525
|
-
|
1645
|
+
If you don't need a `shell` image (icon), you can nest the image directly under the canvas by passing in the `top_level` keyword to treat `image` as a top-level keyword (pretending it is built outside the shell).
|
1526
1646
|
|
1527
|
-
|
1647
|
+
```ruby
|
1648
|
+
include Glimmer
|
1528
1649
|
|
1529
|
-
|
1650
|
+
shell {
|
1651
|
+
minimum_size 250, 265
|
1652
|
+
text 'Pixel Graphics Example'
|
1653
|
+
|
1654
|
+
canvas {
|
1655
|
+
image image(250, 250, top_level: true) {|x, y|
|
1656
|
+
[y%255, x%255, (x+y)%255]
|
1657
|
+
}
|
1658
|
+
}
|
1659
|
+
}.open
|
1660
|
+
```
|
1530
1661
|
|
1531
|
-
|
1662
|
+
If you don't need a `shell` image (icon) and `pixel` performance is enough, you can automatically apply **Image Double-Buffering** with the `:image_double_buffered` SWT style (custom Glimmer style not available in SWT itself)
|
1532
1663
|
|
1533
1664
|
Example (you may copy/paste in [`girb`](GLIMMER_GIRB.md)):
|
1534
1665
|
|
1535
|
-
```
|
1666
|
+
```ruby
|
1536
1667
|
include Glimmer
|
1537
1668
|
|
1538
1669
|
shell {
|
1539
|
-
|
1540
|
-
|
1541
|
-
|
1542
|
-
|
1543
|
-
|
1544
|
-
|
1545
|
-
|
1546
|
-
icon_pixel_size = icon_block_size * icon_size
|
1547
|
-
image(icon_pixel_size, icon_pixel_size) {
|
1548
|
-
icon_size.times { |row|
|
1549
|
-
icon_size.times { |column|
|
1550
|
-
colored = row >= 1 && column.between?(1, 6)
|
1551
|
-
color = colored ? color([:white, :red, :blue, :green, :yellow, :magenta, :cyan, :dark_blue].sample) : color(:white)
|
1552
|
-
x = column * icon_block_size
|
1553
|
-
y = row * icon_block_size
|
1554
|
-
rectangle(x, y, icon_block_size, icon_block_size) {
|
1555
|
-
background color
|
1556
|
-
}
|
1557
|
-
polygon(x, y, x + icon_block_size, y, x + icon_block_size - icon_bevel_pixel_size, y + icon_bevel_pixel_size, x + icon_bevel_pixel_size, y + icon_bevel_pixel_size) {
|
1558
|
-
background rgb(color.red + 4*bevel_constant, color.green + 4*bevel_constant, color.blue + 4*bevel_constant)
|
1559
|
-
}
|
1560
|
-
polygon(x + icon_block_size, y, x + icon_block_size - icon_bevel_pixel_size, y + icon_bevel_pixel_size, x + icon_block_size - icon_bevel_pixel_size, y + icon_block_size - icon_bevel_pixel_size, x + icon_block_size, y + icon_block_size) {
|
1561
|
-
background rgb(color.red - bevel_constant, color.green - bevel_constant, color.blue - bevel_constant)
|
1562
|
-
}
|
1563
|
-
polygon(x + icon_block_size, y + icon_block_size, x, y + icon_block_size, x + icon_bevel_pixel_size, y + icon_block_size - icon_bevel_pixel_size, x + icon_block_size - icon_bevel_pixel_size, y + icon_block_size - icon_bevel_pixel_size) {
|
1564
|
-
background rgb(color.red - 2*bevel_constant, color.green - 2*bevel_constant, color.blue - 2*bevel_constant)
|
1565
|
-
}
|
1566
|
-
polygon(x, y, x, y + icon_block_size, x + icon_bevel_pixel_size, y + icon_block_size - icon_bevel_pixel_size, x + icon_bevel_pixel_size, y + icon_bevel_pixel_size) {
|
1567
|
-
background rgb(color.red - bevel_constant, color.green - bevel_constant, color.blue - bevel_constant)
|
1568
|
-
}
|
1569
|
-
}
|
1670
|
+
minimum_size 250, 265
|
1671
|
+
text 'Pixel Graphics Example'
|
1672
|
+
|
1673
|
+
canvas(:image_double_buffered) {
|
1674
|
+
250.times {|y|
|
1675
|
+
250.times {|x|
|
1676
|
+
pixel(x, y, foreground: [y%255, x%255, (x+y)%255])
|
1570
1677
|
}
|
1571
1678
|
}
|
1572
1679
|
}
|
1573
1680
|
}.open
|
1574
1681
|
```
|
1575
1682
|
|
1576
|
-
|
1577
|
-
|
1578
|
-
Example setting the icon of the application (you may copy/paste in [`girb`](GLIMMER_GIRB.md)):
|
1683
|
+
Of course, you could also take advantage of the pixel-less terser syntax:
|
1579
1684
|
|
1580
|
-
```
|
1685
|
+
```ruby
|
1581
1686
|
include Glimmer
|
1582
1687
|
|
1583
1688
|
shell {
|
1584
|
-
|
1585
|
-
|
1586
|
-
|
1587
|
-
|
1588
|
-
|
1589
|
-
bevel_constant = 20
|
1590
|
-
icon_block_size = 64
|
1591
|
-
icon_bevel_size = icon_block_size.to_f / 25.to_f
|
1592
|
-
icon_bevel_pixel_size = 0.16*icon_block_size.to_f
|
1593
|
-
icon_size = 8
|
1594
|
-
icon_pixel_size = icon_block_size * icon_size
|
1595
|
-
image(icon_pixel_size, icon_pixel_size) {
|
1596
|
-
icon_size.times { |row|
|
1597
|
-
icon_size.times { |column|
|
1598
|
-
colored = row >= 1 && column.between?(1, 6)
|
1599
|
-
color = colored ? color([:white, :red, :blue, :green, :yellow, :magenta, :cyan, :dark_blue].sample) : color(:white)
|
1600
|
-
x = column * icon_block_size
|
1601
|
-
y = row * icon_block_size
|
1602
|
-
rectangle(x, y, icon_block_size, icon_block_size) {
|
1603
|
-
background color
|
1604
|
-
}
|
1605
|
-
polygon(x, y, x + icon_block_size, y, x + icon_block_size - icon_bevel_pixel_size, y + icon_bevel_pixel_size, x + icon_bevel_pixel_size, y + icon_bevel_pixel_size) {
|
1606
|
-
background rgb(color.red + 4*bevel_constant, color.green + 4*bevel_constant, color.blue + 4*bevel_constant)
|
1607
|
-
}
|
1608
|
-
polygon(x + icon_block_size, y, x + icon_block_size - icon_bevel_pixel_size, y + icon_bevel_pixel_size, x + icon_block_size - icon_bevel_pixel_size, y + icon_block_size - icon_bevel_pixel_size, x + icon_block_size, y + icon_block_size) {
|
1609
|
-
background rgb(color.red - bevel_constant, color.green - bevel_constant, color.blue - bevel_constant)
|
1610
|
-
}
|
1611
|
-
polygon(x + icon_block_size, y + icon_block_size, x, y + icon_block_size, x + icon_bevel_pixel_size, y + icon_block_size - icon_bevel_pixel_size, x + icon_block_size - icon_bevel_pixel_size, y + icon_block_size - icon_bevel_pixel_size) {
|
1612
|
-
background rgb(color.red - 2*bevel_constant, color.green - 2*bevel_constant, color.blue - 2*bevel_constant)
|
1613
|
-
}
|
1614
|
-
polygon(x, y, x, y + icon_block_size, x + icon_bevel_pixel_size, y + icon_block_size - icon_bevel_pixel_size, x + icon_bevel_pixel_size, y + icon_bevel_pixel_size) {
|
1615
|
-
background rgb(color.red - bevel_constant, color.green - bevel_constant, color.blue - bevel_constant)
|
1616
|
-
}
|
1617
|
-
}
|
1618
|
-
}
|
1689
|
+
minimum_size 250, 265
|
1690
|
+
text 'Pixel Graphics Example'
|
1691
|
+
|
1692
|
+
canvas(:image_double_buffered) { |x, y|
|
1693
|
+
[y%255, x%255, (x+y)%255]
|
1619
1694
|
}
|
1620
1695
|
}.open
|
1621
1696
|
```
|
1622
1697
|
|
1623
|
-
!
|
1624
|
-
|
1698
|
+
As they say, there are many ways to skin a cat! This is in line with the Ruby way of providing more ways than one. Pick and choose the right tool for the job just like true software engineers.
|
1625
1699
|
|
1626
1700
|
### Canvas Transform DSL
|
1627
1701
|
|
@@ -2715,6 +2789,8 @@ To use, simply use `code_text` in place of the `text` or `styled_text` widget. I
|
|
2715
2789
|
**lines**
|
2716
2790
|
(default: `false`)
|
2717
2791
|
|
2792
|
+
**(BETA FEATURE)**
|
2793
|
+
|
2718
2794
|
Shows line numbers when set to true.
|
2719
2795
|
|
2720
2796
|
If set to a hash like `{width: 4}`, it sets the initial width of the line numbers lane in character count (default: 4)
|
@@ -2724,6 +2800,8 @@ Keep in mind that if the text grows and required a wider line numbers area, it g
|
|
2724
2800
|
**theme**
|
2725
2801
|
(default: `'glimmer'`)
|
2726
2802
|
|
2803
|
+
**(BETA FEATURE)**
|
2804
|
+
|
2727
2805
|
Changes syntax color highlighting theme. Can be one of the following:
|
2728
2806
|
- glimmer
|
2729
2807
|
- github
|
@@ -2732,6 +2810,8 @@ Changes syntax color highlighting theme. Can be one of the following:
|
|
2732
2810
|
**language**
|
2733
2811
|
(default: `'ruby'`)
|
2734
2812
|
|
2813
|
+
**(BETA FEATURE)**
|
2814
|
+
|
2735
2815
|
Sets the code language, which can be one of the following [rouge gem](#https://rubygems.org/gems/rouge) supported languages:
|
2736
2816
|
- abap
|
2737
2817
|
- actionscript
|
@@ -2941,10 +3021,13 @@ Sets the code language, which can be one of the following [rouge gem](#https://r
|
|
2941
3021
|
**default_behavior**
|
2942
3022
|
(default: true)
|
2943
3023
|
|
3024
|
+
**(BETA FEATURE)**
|
3025
|
+
|
2944
3026
|
This adds some default keyboard shortcuts:
|
2945
3027
|
- CMD+A (CTRL+A on Windows/Linux) to select all
|
2946
3028
|
- CTRL+A on Mac to jump to beginning of line
|
2947
3029
|
- CTRL+E on Mac to jump to end of line
|
3030
|
+
- Attempts to add proper indentation upon adding a new line when hitting ENTER (currently supporting Ruby only)
|
2948
3031
|
|
2949
3032
|
If you prefer it to be vanilla with no default key event listeners, then pass the `default_behavior: false` option.
|
2950
3033
|
|
@@ -605,6 +605,10 @@ Hello, Cursor!
|
|
605
605
|
|
606
606
|
This sample demonstrates the use of the `progress_bar` widget keyword.
|
607
607
|
|
608
|
+
It includes an `:indeterminate` progress bar on top, for cases when you could not calculate progress, but still want to inform the user there is an operation happening in the background.
|
609
|
+
|
610
|
+
Below it, there are a determinate `:horizontal` (default) progress bar and a `:vertical` progress bar.
|
611
|
+
|
608
612
|
Code:
|
609
613
|
|
610
614
|
[samples/hello/hello_progress_bar.rb](/samples/hello/hello_progress_bar.rb)
|
@@ -731,6 +735,12 @@ Code:
|
|
731
735
|
|
732
736
|
![Mandelbrot Fractal Zoom 5](/images/glimmer-mandelbrot-zoom5.png)
|
733
737
|
|
738
|
+
![Mandelbrot Fractal View Menu](/images/glimmer-mandelbrot-menu-view.png)
|
739
|
+
|
740
|
+
![Mandelbrot Fractal Cores Menu](/images/glimmer-mandelbrot-menu-cores.png)
|
741
|
+
|
742
|
+
![Mandelbrot Fractal Help Menu](/images/glimmer-mandelbrot-menu-help.png)
|
743
|
+
|
734
744
|
### External Samples
|
735
745
|
|
736
746
|
#### Glimmer Calculator
|
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.11 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.11"
|
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-19"
|
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]
|
@@ -46,11 +46,14 @@ module Glimmer
|
|
46
46
|
|
47
47
|
def interpret(parent, keyword, *args, &block)
|
48
48
|
options = args.last.is_a?(Hash) ? args.pop : {}
|
49
|
-
UI::CustomWidget.for(keyword).new(parent, *args, options, &block)
|
49
|
+
UI::CustomWidget.for(keyword).new(parent, *args, options, &block).tap do |new_custom_widget|
|
50
|
+
new_custom_widget.body_root.paint_pixel_by_pixel(&block) if block&.parameters&.count == 2
|
51
|
+
end
|
50
52
|
end
|
51
53
|
|
52
54
|
def add_content(parent, &block)
|
53
55
|
# TODO consider avoiding source_location
|
56
|
+
return if block&.parameters&.count == 2
|
54
57
|
if block.source_location == parent.content&.__getobj__.source_location
|
55
58
|
parent.content.call(parent) unless parent.content.called?
|
56
59
|
else
|
@@ -40,11 +40,18 @@ module Glimmer
|
|
40
40
|
|
41
41
|
def interpret(parent, keyword, *args, &block)
|
42
42
|
options = args.last.is_a?(Hash) ? args.last : {}
|
43
|
+
coordinate_args = args.size == (options.empty? ? 2 : 3)
|
43
44
|
args.unshift(parent) unless parent.nil? || options[:top_level]
|
44
|
-
|
45
|
+
@create_pixel_by_pixel = coordinate_args && block&.parameters&.count == 2
|
46
|
+
if @create_pixel_by_pixel
|
47
|
+
Glimmer::SWT::ImageProxy.create_pixel_by_pixel(*args, &block)
|
48
|
+
else
|
49
|
+
Glimmer::SWT::ImageProxy.create(*args, &block)
|
50
|
+
end
|
45
51
|
end
|
46
52
|
|
47
53
|
def add_content(parent, &block)
|
54
|
+
return if @create_pixel_by_pixel || block&.parameters&.count == 2
|
48
55
|
super
|
49
56
|
parent.post_add_content
|
50
57
|
end
|
@@ -40,10 +40,13 @@ module Glimmer
|
|
40
40
|
end
|
41
41
|
|
42
42
|
def interpret(parent, keyword, *args, &block)
|
43
|
-
Glimmer::SWT::WidgetProxy.create(keyword, parent, args)
|
43
|
+
Glimmer::SWT::WidgetProxy.create(keyword, parent, args).tap do |new_widget_proxy|
|
44
|
+
new_widget_proxy.paint_pixel_by_pixel(&block) if block&.parameters&.count == 2
|
45
|
+
end
|
44
46
|
end
|
45
47
|
|
46
48
|
def add_content(parent, &block)
|
49
|
+
return if block&.parameters&.count == 2
|
47
50
|
super
|
48
51
|
parent.post_add_content
|
49
52
|
parent.finish_add_content!
|
@@ -64,6 +64,18 @@ module Glimmer
|
|
64
64
|
respond_to?(method_name)
|
65
65
|
end
|
66
66
|
|
67
|
+
def can_handle_observation_request?(observation_request)
|
68
|
+
@styled_text_proxy.can_handle_observation_request?(observation_request)
|
69
|
+
rescue
|
70
|
+
super
|
71
|
+
end
|
72
|
+
|
73
|
+
def handle_observation_request(observation_request, &block)
|
74
|
+
@styled_text_proxy.handle_observation_request(observation_request, &block)
|
75
|
+
rescue
|
76
|
+
super
|
77
|
+
end
|
78
|
+
|
67
79
|
def root_block=(block)
|
68
80
|
body_root.content(&block)
|
69
81
|
end
|
@@ -153,6 +165,7 @@ module Glimmer
|
|
153
165
|
top_margin 5
|
154
166
|
right_margin 5
|
155
167
|
bottom_margin 5
|
168
|
+
tabs 2
|
156
169
|
|
157
170
|
if default_behavior
|
158
171
|
on_key_pressed { |event|
|
@@ -166,6 +179,15 @@ module Glimmer
|
|
166
179
|
jump_to_end_of_line
|
167
180
|
end
|
168
181
|
}
|
182
|
+
on_verify_text { |verify_event|
|
183
|
+
if verify_event.text == "\n"
|
184
|
+
line_index = verify_event.widget.get_line_at_offset(verify_event.widget.get_caret_offset)
|
185
|
+
line = verify_event.widget.get_line(line_index)
|
186
|
+
line_indent = line.match(/^([ ]*)/)[1].to_s.size
|
187
|
+
verify_event.text += ' '*line_indent
|
188
|
+
verify_event.text += ' '*2 if line.strip.end_with?('{') || line.strip.match(/do([ ]*[|][^|]*[|])?$/) || line.start_with?('class') || line.start_with?('module') || line.strip.start_with?('def')
|
189
|
+
end
|
190
|
+
}
|
169
191
|
end
|
170
192
|
|
171
193
|
on_modify_text { |event|
|
@@ -51,6 +51,50 @@ module Glimmer
|
|
51
51
|
shapes.dup.each {|s| s.dispose(dispose_images: dispose_images, dispose_patterns: dispose_patterns) } if requires_shape_disposal?
|
52
52
|
end
|
53
53
|
|
54
|
+
def paint_pixel_by_pixel(width = nil, height = nil, &each_pixel_color)
|
55
|
+
if @image_double_buffered
|
56
|
+
work = lambda do |paint_event|
|
57
|
+
width ||= swt_drawable.bounds.width
|
58
|
+
height ||= swt_drawable.bounds.height
|
59
|
+
@image_proxy_buffer ||= ImageProxy.create_pixel_by_pixel(width, height, &each_pixel_color)
|
60
|
+
@image_proxy_buffer.shape(self).paint(paint_event)
|
61
|
+
end
|
62
|
+
else
|
63
|
+
work = lambda do |paint_event_or_image|
|
64
|
+
the_gc = paint_event_or_image.gc
|
65
|
+
current_foreground = nil
|
66
|
+
width ||= swt_drawable.bounds.width
|
67
|
+
height ||= swt_drawable.bounds.height
|
68
|
+
height.times do |y|
|
69
|
+
width.times do |x|
|
70
|
+
new_foreground = each_pixel_color.call(x, y)
|
71
|
+
new_foreground = Glimmer::SWT::ColorProxy.create(new_foreground, ensure_bounds: false) unless new_foreground.is_a?(ColorProxy) || new_foreground.is_a?(Color)
|
72
|
+
new_foreground = new_foreground.swt_color if new_foreground.is_a?(Glimmer::SWT::ColorProxy)
|
73
|
+
the_gc.foreground = current_foreground = new_foreground unless new_foreground == current_foreground
|
74
|
+
the_gc.draw_point x, y
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|
79
|
+
if respond_to?(:gc)
|
80
|
+
work.call(self)
|
81
|
+
else
|
82
|
+
on_swt_paint(&work)
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
def swt_drawable
|
87
|
+
swt_drawable = nil
|
88
|
+
if respond_to?(:swt_image)
|
89
|
+
swt_drawable = swt_image
|
90
|
+
elsif respond_to?(:swt_display)
|
91
|
+
swt_drawable = swt_display
|
92
|
+
elsif respond_to?(:swt_widget)
|
93
|
+
swt_drawable = swt_widget
|
94
|
+
end
|
95
|
+
swt_drawable
|
96
|
+
end
|
97
|
+
|
54
98
|
def deregister_shape_painting
|
55
99
|
@paint_listener_proxy&.deregister
|
56
100
|
end
|
@@ -308,7 +308,11 @@ module Glimmer
|
|
308
308
|
else
|
309
309
|
@properties['background'] = [@parent.background] if fill? && !has_some_background?
|
310
310
|
@properties['foreground'] = [@parent.foreground] if @parent.respond_to?(:foreground) && draw? && !has_some_foreground?
|
311
|
+
# TODO regarding alpha, make sure to reset it to parent stored alpha once we allow setting shape properties on parents directly without shapes
|
312
|
+
@properties['alpha'] ||= [255]
|
311
313
|
@properties['font'] = [@parent.font] if @parent.respond_to?(:font) && draw? && !@properties.keys.map(&:to_s).include?('font')
|
314
|
+
# TODO regarding transform, make sure to reset it to parent stored alpha once we allow setting shape properties on parents directly without shapes
|
315
|
+
# Also do that with all future-added properties
|
312
316
|
@properties['transform'] = [nil] if @parent.respond_to?(:transform) && !@properties.keys.map(&:to_s).include?('transform')
|
313
317
|
@properties.each do |property, args|
|
314
318
|
method_name = attribute_setter(property)
|
@@ -34,13 +34,24 @@ module Glimmer
|
|
34
34
|
include Properties
|
35
35
|
|
36
36
|
class << self
|
37
|
-
|
37
|
+
include_package 'org.eclipse.swt.graphics'
|
38
|
+
|
39
|
+
def create(*args, &content)
|
38
40
|
if args.size == 1 && args.first.is_a?(ImageProxy)
|
39
41
|
args.first
|
40
42
|
else
|
41
|
-
new(*args)
|
43
|
+
new(*args, &content)
|
42
44
|
end
|
43
45
|
end
|
46
|
+
|
47
|
+
def create_pixel_by_pixel(*args, &each_pixel_color)
|
48
|
+
image_proxy = create(*args)
|
49
|
+
options = args.last.is_a?(Hash) ? args.pop : {}
|
50
|
+
height = args[-1]
|
51
|
+
width = args[-2]
|
52
|
+
image_proxy.paint_pixel_by_pixel(width, height, &each_pixel_color)
|
53
|
+
image_proxy
|
54
|
+
end
|
44
55
|
end
|
45
56
|
|
46
57
|
include_package 'org.eclipse.swt.widgets'
|
@@ -88,7 +99,7 @@ module Glimmer
|
|
88
99
|
# TODO consider adding a get_data/set_data method to conform with other SWT widgets
|
89
100
|
@swt_image.singleton_class.define_method(:dispose) do
|
90
101
|
proxy.clear_shapes
|
91
|
-
super
|
102
|
+
super()
|
92
103
|
end
|
93
104
|
post_add_content if content.nil?
|
94
105
|
end
|
@@ -55,7 +55,7 @@ class Mandelbrot
|
|
55
55
|
end
|
56
56
|
|
57
57
|
def processor_count
|
58
|
-
@processor_count ||= Concurrent.
|
58
|
+
@processor_count ||= Concurrent.physical_processor_count
|
59
59
|
end
|
60
60
|
end
|
61
61
|
|
@@ -222,8 +222,8 @@ class MandelbrotFractal
|
|
222
222
|
on_mouse_up { |mouse_event|
|
223
223
|
if !@drag_detected
|
224
224
|
origin = @scrolled_composite.origin
|
225
|
-
@location_x =
|
226
|
-
@location_y =
|
225
|
+
@location_x = mouse_event.x
|
226
|
+
@location_y = mouse_event.y
|
227
227
|
if mouse_event.button == 1
|
228
228
|
zoom_in
|
229
229
|
elsif mouse_event.button > 2
|
@@ -265,7 +265,7 @@ class MandelbrotFractal
|
|
265
265
|
menu {
|
266
266
|
text '&Cores'
|
267
267
|
|
268
|
-
Concurrent.
|
268
|
+
Concurrent.physical_processor_count.times {|n|
|
269
269
|
processor_number = n + 1
|
270
270
|
menu_item(:radio) {
|
271
271
|
text "&#{processor_number}"
|
@@ -279,10 +279,10 @@ class MandelbrotFractal
|
|
279
279
|
accelerator COMMAND, :alt, (processor_number - 20).to_s
|
280
280
|
end
|
281
281
|
|
282
|
-
selection true if processor_number == Concurrent.
|
282
|
+
selection true if processor_number == Concurrent.physical_processor_count
|
283
283
|
|
284
284
|
on_widget_selected {
|
285
|
-
Mandelbrot.processor_count =
|
285
|
+
Mandelbrot.processor_count = processor_number
|
286
286
|
}
|
287
287
|
}
|
288
288
|
}
|
@@ -316,21 +316,16 @@ class MandelbrotFractal
|
|
316
316
|
width = the_mandelbrot.width
|
317
317
|
height = the_mandelbrot.height
|
318
318
|
pixels = the_mandelbrot.points
|
319
|
-
new_mandelbrot_image = image(width, height, top_level: true) # invoke as a top-level parentless keyword to avoid nesting under any widget
|
320
|
-
new_mandelbrot_image_gc = new_mandelbrot_image.gc
|
321
|
-
current_foreground = nil
|
322
319
|
Mandelbrot.work_in_progress = "Consuming Points To Build Image for Zoom #{mandelbrot_zoom}x"
|
323
|
-
Mandelbrot.progress = Mandelbrot::PROGRESS_MAX
|
320
|
+
Mandelbrot.progress = Mandelbrot::PROGRESS_MAX + 1
|
324
321
|
point_index = 0
|
325
322
|
point_count = width*height
|
326
|
-
|
327
|
-
|
328
|
-
|
329
|
-
|
330
|
-
|
331
|
-
|
332
|
-
Mandelbrot.progress -= 1 if (Mandelbrot::PROGRESS_MAX - (point_index.to_f / point_count.to_f)*Mandelbrot::PROGRESS_MAX) < Mandelbrot.progress
|
333
|
-
}
|
323
|
+
# invoke as a top-level parentless keyword to avoid nesting under any widget
|
324
|
+
new_mandelbrot_image = image(width, height, top_level: true) { |x, y|
|
325
|
+
point_index += 1
|
326
|
+
Mandelbrot.progress -= 1 if (Mandelbrot::PROGRESS_MAX - (point_index.to_f / point_count.to_f)*Mandelbrot::PROGRESS_MAX) < Mandelbrot.progress
|
327
|
+
pixel_color_index = pixels[y][x]
|
328
|
+
color_palette[pixel_color_index]
|
334
329
|
}
|
335
330
|
Mandelbrot.progress = 0
|
336
331
|
flyweight_mandelbrot_images[mandelbrot_zoom] = new_mandelbrot_image
|
@@ -387,8 +382,9 @@ class MandelbrotFractal
|
|
387
382
|
@canvas.set_size @mandelbrot_image.bounds.width, @mandelbrot_image.bounds.height
|
388
383
|
@scrolled_composite.swt_widget.set_min_size(Point.new(@mandelbrot_image.bounds.width, @mandelbrot_image.bounds.height))
|
389
384
|
if @location_x && @location_y
|
385
|
+
# center on mouse click location
|
390
386
|
factor = (zoom / last_zoom)
|
391
|
-
@scrolled_composite.set_origin(factor*@location_x, factor*@location_y)
|
387
|
+
@scrolled_composite.set_origin(factor*@location_x - @scrolled_composite.client_area.width/2.0, factor*@location_y - @scrolled_composite.client_area.height/2.0)
|
392
388
|
@location_x = @location_y = nil
|
393
389
|
end
|
394
390
|
update_mandelbrot_shell_title!
|
@@ -404,7 +400,7 @@ class MandelbrotFractal
|
|
404
400
|
Left-click to zoom in.
|
405
401
|
Right-click to zoom out.
|
406
402
|
Scroll or drag to pan.
|
407
|
-
|
403
|
+
Adjust cores to get a more responsive interaction.
|
408
404
|
|
409
405
|
Enjoy!
|
410
406
|
MULTI_LINE_STRING
|
@@ -219,7 +219,7 @@ class MetaSampleApplication
|
|
219
219
|
SampleDirectory.sample_directories.each { |sample_directory|
|
220
220
|
expand_item {
|
221
221
|
layout_data(:fill, :fill, true, true)
|
222
|
-
text " #{sample_directory.name} Samples"
|
222
|
+
text " #{sample_directory.name} Samples (#{sample_directory.samples.count})"
|
223
223
|
|
224
224
|
radio_group { |radio_group_proxy|
|
225
225
|
row_layout(:vertical) {
|
@@ -110,6 +110,8 @@ class HelloProgressBar
|
|
110
110
|
# (killing is not dangerous since it is only a thread about updating progress)
|
111
111
|
@current_thread&.kill
|
112
112
|
@current_thread = Thread.new {
|
113
|
+
# GUI updates must happen in sync_exec calls.
|
114
|
+
# Alternatively, add `sync_exec: true` to all the updated property `bind(...)` statements above
|
113
115
|
sync_exec { @progress_model.selection = @progress_model.minimum }
|
114
116
|
(@progress_model.minimum..@progress_model.maximum).to_a.each do |n|
|
115
117
|
sync_exec {
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: glimmer-dsl-swt
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 4.18.4.
|
4
|
+
version: 4.18.4.11
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- AndyMaleh
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2021-02-
|
11
|
+
date: 2021-02-19 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
requirement: !ruby/object:Gem::Requirement
|