glimmer-dsl-swt 4.18.4.8 → 4.18.4.9

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 89ea3be1af753358a8beaffbf28c8dfd6602eae3903b01a884e6999f0dbf6cfb
4
- data.tar.gz: 672422abf1637420ac51706373824ac821682eab77afe86b91e22b21f1e00eb6
3
+ metadata.gz: 641e17b39e98692f1c617da255c89361cdc49431fd77b20304fc08d4dc5fc301
4
+ data.tar.gz: 69549df2a3bf84d28445a9ba33cac1a3c4fb546927c3cb706c7cf5078e8094bb
5
5
  SHA512:
6
- metadata.gz: 7b502b353aa06f6b26e39487859ae8f4d9f8ee47d74a4a97a224b14dfa8b18acba6d8e48b6a66ee518a8075cd90a6303f1864726a22812edf98515f6a2754aa2
7
- data.tar.gz: a5926f825b0247d4b521bfa2f857d1b1f88d731dba9651690960cf7c516ef2a1c5aca9c6cce86878162358fb416a0913b3ba945b0589be19f78f94454848d0b5
6
+ metadata.gz: da95d92eadd7d0f768ab4945f57e9a6f582d7de7f1e4ac4eac65acc28de8628549aa2f0575ebbe34b964afb3e8616fe68e99fb8b9cc2084269707bd8edebf501
7
+ data.tar.gz: 77d070eaccd04104effb26b1fcc6914d5a9a0f4b381950220090293ac1a20cd1d8fe73daf55e00ba677b31a043038f557d75200b610237eec36c8f30893d7bd8
data/CHANGELOG.md CHANGED
@@ -1,5 +1,15 @@
1
1
  # Change Log
2
2
 
3
+ ### 4.18.4.9
4
+
5
+ - Hello, Cursor! Sample
6
+ - Log errors that occur in widget event listener blocks to help with troubleshooting
7
+ - disposed? method for Shape objects
8
+ - Add `dispose_images: false, dispose_patterns: false` options to `Shape#dispose` to avoid disposing images/patterns when needed
9
+ - Mandelbrot background thread pre-calculation of future zoom levels
10
+ - Mandelbrot menu bar menu items
11
+ - Mandelbrot panning via scrollbars or dragging
12
+
3
13
  ### 4.18.4.8
4
14
 
5
15
  - Make `image` a top-level expression keyword
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.8
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.9
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)
@@ -326,14 +326,14 @@ Please follow these instructions to make the `glimmer` command available on your
326
326
 
327
327
  If you intend to learn the basics of Glimmer but are not ready to build a Glimmer app yet, pick Option 1 ([Direct Install](#option-1-direct-install)).
328
328
 
329
- If you intend to build a Glimmer app from scratch with [scaffolding](#scaffolding), pick Option 1 ([Direct Install](#option-1-direct-install)) as well.
329
+ If you intend to build a Glimmer app from scratch with [scaffolding](https://github.com/AndyObtiva/glimmer-dsl-swt/blob/master/docs/reference/GLIMMER_COMMAND.md#scaffolding), pick Option 1 ([Direct Install](#option-1-direct-install)) as well.
330
330
 
331
- Otherwise, Option 2 ([Bundler](#option-2-bundler)) can be followed in rare cases where you want to build an app without [scaffolding](#scaffolding).
331
+ Otherwise, Option 2 ([Bundler](#option-2-bundler)) can be followed in rare cases where you want to build an app without [scaffolding](https://github.com/AndyObtiva/glimmer-dsl-swt/blob/master/docs/reference/GLIMMER_COMMAND.md#scaffolding).
332
332
 
333
333
  **Note:** if you encounter any [issues](https://github.com/AndyObtiva/glimmer-dsl-swt/issues), please [report](https://github.com/AndyObtiva/glimmer-dsl-swt/issues) and then install a previous version instead from the list of [Glimmer Releases](https://rubygems.org/gems/glimmer-dsl-swt/versions) (keep looking back till you find one that works). Do not be disheartened as nearly everything is only a few days of work away. That said, keep in mind that this project is free and open source, meaning provided as is, so do not expect anything, but if you help with reporting and contributing, you could speed things up or even become part of the project.
334
334
 
335
335
  ### Option 1: Direct Install
336
- (Use for [Scaffolding](#scaffolding))
336
+ (Use for [Scaffolding](https://github.com/AndyObtiva/glimmer-dsl-swt/blob/master/docs/reference/GLIMMER_COMMAND.md#scaffolding))
337
337
 
338
338
  Run this command to install directly:
339
339
  ```
@@ -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.8
345
+ jgem install glimmer-dsl-swt -v 4.18.4.9
346
346
  ```
347
347
 
348
348
  `jgem` is JRuby's version of `gem` command.
@@ -351,7 +351,7 @@ Otherwise, you may also run `jruby -S gem install ...`
351
351
 
352
352
  If you are new to Glimmer and would like to continue learning the basics, you may continue to the [Glimmer Command](https://github.com/AndyObtiva/glimmer#glimmer-command) section.
353
353
 
354
- Otherwise, if you are ready to build a Glimmer app, you can jump to the [Glimmer Scaffolding](https://github.com/AndyObtiva/glimmer#scaffolding) section next.
354
+ Otherwise, if you are ready to build a Glimmer app, you can jump to the [Glimmer Scaffolding](https://github.com/AndyObtiva/glimmer-dsl-swt/blob/master/docs/reference/GLIMMER_COMMAND.md#scaffolding) section next.
355
355
 
356
356
  Note: if you're using activerecord or activesupport, keep in mind that Glimmer unhooks ActiveSupport::Dependencies as it does not rely on it.
357
357
 
@@ -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.8'
363
+ gem 'glimmer-dsl-swt', '~> 4.18.4.9'
364
364
  ```
365
365
 
366
366
  And, then run:
@@ -386,11 +386,12 @@ You can use `girb` as an alternative to `irb` when prototyping Glimmer DSL for S
386
386
 
387
387
  ## Glimmer GUI DSL Syntax
388
388
 
389
- This guide should help you get started with Glimmer DSL for SWT. For more advanced SWT details, please refer to the [SWT Reference](#swt-reference).
390
-
389
+ This guide should help you get started with Glimmer DSL for SWT.
391
390
 
392
391
  [docs/reference/GLIMMER_GUI_DSL_SYNTAX.md](docs/reference/GLIMMER_GUI_DSL_SYNTAX.md)
393
392
 
393
+ For more advanced SWT details, please refer to the [SWT Reference](#swt-reference).
394
+
394
395
  ## Glimmer Configuration
395
396
 
396
397
  Glimmer configuration may be done via the `Glimmer::Config` module.
@@ -425,6 +426,14 @@ If you have a Glimmer app you would like referenced here, please mention in a Pu
425
426
 
426
427
  [<img alt="Garderie Rainbow Daily Agenda Logo" src="https://github.com/AndyObtiva/garderie_rainbow_daily_agenda/raw/master/images/garderie_rainbow_daily_agenda_logo.png" width="40" />Garderie Rainbow Daily Agenda](https://github.com/AndyObtiva/garderie_rainbow_daily_agenda): A child nursery daily agenda reporting desktop app
427
428
 
429
+ ### Glimmer Gab
430
+
431
+ [<img alt="Glimmer Gab Logo" src="https://raw.githubusercontent.com/AndyObtiva/glimmer_gab/master/package/linux/Glimmer%20Gab.png" height=40 /> Glimmer Gab](https://github.com/AndyObtiva/glimmer_gab): Desktop App for Gab.com
432
+
433
+ ### Connector
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
436
+
428
437
  ## Packaging & Distribution
429
438
 
430
439
  Glimmer simplifies the process of native-executable packaging and distribution on Mac and Windows via a single `glimmer package` command:
@@ -438,7 +447,7 @@ Glimmer already supports automatic (and manual) app updates via the Mac App Stor
438
447
  ## Glimmer Supporting Libraries
439
448
 
440
449
  Here is a list of notable 3rd party gems used by Glimmer:
441
- - [juwelier](https://rubygems.org/gems/juwelier): generates app gems during [Glimmer Scaffolding](#scaffolding)
450
+ - [juwelier](https://rubygems.org/gems/juwelier): generates app gems during [Glimmer Scaffolding](https://github.com/AndyObtiva/glimmer-dsl-swt/blob/master/docs/reference/GLIMMER_COMMAND.md#scaffolding)
442
451
  - [logging](https://github.com/TwP/logging): provides extra logging capabilities not available in Ruby Logger such as multi-threaded buffered asynchronous logging (to avoid affecting app performance) and support for multiple appenders such as stdout, syslog, and log files (the last one is needed on Windows where syslog is not supported)
443
452
  - [nested_inherited_jruby_include_package](https://github.com/AndyObtiva/nested_inherited_jruby_include_package): makes included [SWT](https://www.eclipse.org/swt/)/[Java](https://www.java.com/en/) packages available to all classes/modules that mix in the Glimmer module without having to manually reimport
444
453
  - [os](https://github.com/rdp/os): provides OS detection capabilities (e.g. `OS.mac?` or `OS.windows?`) to write cross-platform code inexpensively
data/VERSION CHANGED
@@ -1 +1 @@
1
- 4.18.4.8
1
+ 4.18.4.9
@@ -284,7 +284,7 @@ Shell widget proxy has extra methods specific to SWT Shell:
284
284
  - `#show`: Alias for `#open`
285
285
  - `#hide`: Hides a shell setting "visible" property to false
286
286
  - `#close`: Closes the shell
287
- - `#center`: Centers the shell within monitor it is in
287
+ - `#center_within_display`: Centers the shell within monitor it is in
288
288
  - `#start_event_loop`: (happens as part of `#open`) Starts SWT Event Loop (you may learn more about it here: https://help.eclipse.org/2019-12/nftopic/org.eclipse.platform.doc.isv/reference/api/org/eclipse/swt/widgets/Display.html). This method is not needed except in rare circumstances where there is a need to start the SWT Event Loop before opening the shell.
289
289
  - `#visible?`: Returns whether a shell is visible
290
290
  - `#opened_before?`: Returns whether a shell has been opened at least once before (additionally implying the SWT Event Loop has been started already)
@@ -800,7 +800,7 @@ You may check out a more full-fledged example in [Hello, Sash Form!](#hello-sash
800
800
 
801
801
  ![Hello Browser](/images/glimmer-hello-browser.png)
802
802
 
803
- Glimmer supports the SWT Browser widget, which can load URLs or render HTML. It can even be instrumented with JavaScript when needed (though highly discouraged since it defeats the purpose of using Ruby except in very rare cases like leveraging a pre-existing web codebase in a desktop app).
803
+ Glimmer supports the [SWT Browser widget](https://help.eclipse.org/2020-12/topic/org.eclipse.platform.doc.isv/reference/api/org/eclipse/swt/browser/Browser.html), which can load URLs or render HTML. It can even be instrumented with JavaScript when needed (though highly discouraged since it defeats the purpose of using Ruby except in very rare cases like leveraging a pre-existing web codebase in a desktop app).
804
804
 
805
805
  Example loading a URL (you may copy/paste in [`girb`](GLIMMER_GIRB.md)):
806
806
 
@@ -834,6 +834,8 @@ shell {
834
834
  }.open
835
835
  ```
836
836
 
837
+ Learn more at the [SWT Browser widget](https://help.eclipse.org/2020-12/topic/org.eclipse.platform.doc.isv/reference/api/org/eclipse/swt/browser/Browser.html) API.
838
+
837
839
  ### Widget Styles
838
840
 
839
841
  SWT widgets receive `SWT` styles in their constructor as per this guide:
@@ -1471,11 +1473,10 @@ Example (you may copy/paste in [`girb`](GLIMMER_GIRB.md)):
1471
1473
  include Glimmer
1472
1474
 
1473
1475
  @the_image = image(250, 250)
1474
- gc = org.eclipse.swt.graphics.GC.new(@the_image)
1475
1476
  250.times {|y|
1476
1477
  250.times {|x|
1477
- gc.foreground = Color.new(y%255, x%255, (x+y)%255)
1478
- gc.draw_point(x, y)
1478
+ @the_image.gc.foreground = Color.new(y%255, x%255, (x+y)%255)
1479
+ @the_image.gc.draw_point(x, y)
1479
1480
  }
1480
1481
  }
1481
1482
 
@@ -1,6 +1,55 @@
1
1
  ## Samples
2
2
 
3
- Check the [samples](samples) directory in [glimmer-dsl-swt](https://github.com/AndyObtiva/glimmer-dsl-swt) for examples on how to write Glimmer applications. To run a sample, make sure to install the `glimmer` gem first and then use the `glimmer samples` command to run it (alternatively, you may clone the repo, follow [CONTRIBUTING.md](CONTRIBUTING.md) instructions, and run samples locally with development glimmer command: `bin/glimmer`).
3
+ - [Samples](#samples)
4
+ - [Hello Samples](#hello-samples)
5
+ - [Hello, World!](#hello-world)
6
+ - [Hello, Tab!](#hello-tab)
7
+ - [Hello, Combo!](#hello-combo)
8
+ - [Hello, List Single Selection!](#hello-list-single-selection)
9
+ - [Hello, List Multi Selection!](#hello-list-multi-selection)
10
+ - [Hello, Computed!](#hello-computed)
11
+ - [Hello, Message Box!](#hello-message-box)
12
+ - [Hello, Browser!](#hello-browser)
13
+ - [Hello, Drag and Drop!](#hello-drag-and-drop)
14
+ - [Hello, Menu Bar!](#hello-menu-bar)
15
+ - [Hello, Pop Up Context Menu!](#hello-pop-up-context-menu)
16
+ - [Hello, Custom Widget!](#hello-custom-widget)
17
+ - [Hello, Custom Shell!](#hello-custom-shell)
18
+ - [Hello, Sash Form!](#hello-sash-form)
19
+ - [Hello, Styled Text!](#hello-styled-text)
20
+ - [Hello, Expand Bar!](#hello-expand-bar)
21
+ - [Hello, Radio!](#hello-radio)
22
+ - [Hello, Radio Group!](#hello-radio-group)
23
+ - [Hello, Group!](#hello-group)
24
+ - [Hello, Checkbox!](#hello-checkbox)
25
+ - [Hello, Checkbox Group!](#hello-checkbox-group)
26
+ - [Hello, Directory Dialog!](#hello-directory-dialog)
27
+ - [Hello, File Dialog!](#hello-file-dialog)
28
+ - [Hello, Date Time!](#hello-date-time)
29
+ - [Hello, Spinner!](#hello-spinner)
30
+ - [Hello, Table!](#hello-table)
31
+ - [Hello, Button!](#hello-button)
32
+ - [Hello, Link!](#hello-link)
33
+ - [Hello, Dialog!](#hello-dialog)
34
+ - [Hello, Code Text!](#hello-code-text)
35
+ - [Hello, Canvas!](#hello-canvas)
36
+ - [Hello, Canvas Animation!](#hello-canvas-animation)
37
+ - [Hello, Canvas Transform!](#hello-canvas-transform)
38
+ - [Hello, Cursor!](#hello-cursor)
39
+ - [Elaborate Samples](#elaborate-samples)
40
+ - [User Profile](#user-profile)
41
+ - [Login](#login)
42
+ - [Tic Tac Toe](#tic-tac-toe)
43
+ - [Contact Manager](#contact-manager)
44
+ - [Glimmer Tetris](#glimmer-tetris)
45
+ - [Mandelbrot Fractal](#mandelbrot-fractal)
46
+ - [External Samples](#external-samples)
47
+ - [Glimmer Calculator](#glimmer-calculator)
48
+ - [Gladiator](#gladiator)
49
+ - [Timer](#timer)
50
+ - [License](#license)
51
+
52
+ Check the [samples](/samples) directory in [glimmer-dsl-swt](https://github.com/AndyObtiva/glimmer-dsl-swt) for examples on how to write Glimmer applications. To run a sample, make sure to install the `glimmer` gem first and then use the `glimmer samples` command to run it (alternatively, you may clone the repo, follow [CONTRIBUTING.md](CONTRIBUTING.md) instructions, and run samples locally with development glimmer command: `bin/glimmer`).
4
53
 
5
54
  You may run any sample via this command:
6
55
 
@@ -8,7 +57,7 @@ You may run any sample via this command:
8
57
  glimmer samples
9
58
  ```
10
59
 
11
- This brings up the [Glimmer Meta-Sample (The Sample of Samples)](samples/elaborate/meta_sample.rb)
60
+ This brings up the [Glimmer Meta-Sample (The Sample of Samples)](/samples/elaborate/meta_sample.rb)
12
61
 
13
62
  ![Glimmer Meta-Sample](/images/glimmer-meta-sample.png)
14
63
 
@@ -28,7 +77,7 @@ For hello-type simple samples, check the following.
28
77
 
29
78
  Code:
30
79
 
31
- [samples/hello/hello_world.rb](samples/hello/hello_world.rb)
80
+ [samples/hello/hello_world.rb](/samples/hello/hello_world.rb)
32
81
 
33
82
  ![Hello World](/images/glimmer-hello-world.png)
34
83
 
@@ -36,7 +85,7 @@ Code:
36
85
 
37
86
  Code:
38
87
 
39
- [samples/hello/hello_tab.rb](samples/hello/hello_tab.rb)
88
+ [samples/hello/hello_tab.rb](/samples/hello/hello_tab.rb)
40
89
 
41
90
  ![Hello Tab English](/images/glimmer-hello-tab-english.png)
42
91
  ![Hello Tab French](/images/glimmer-hello-tab-french.png)
@@ -47,7 +96,7 @@ This sample demonstrates combo data-binding.
47
96
 
48
97
  Code:
49
98
 
50
- [samples/hello/hello_combo.rb](samples/hello/hello_combo.rb)
99
+ [samples/hello/hello_combo.rb](/samples/hello/hello_combo.rb)
51
100
 
52
101
  ![Hello Combo](/images/glimmer-hello-combo.png)
53
102
  ![Hello Combo Expanded](/images/glimmer-hello-combo-expanded.png)
@@ -58,7 +107,7 @@ This sample demonstrates list single-selection data-binding.
58
107
 
59
108
  Code:
60
109
 
61
- [samples/hello/hello_list_single_selection.rb](samples/hello/hello_list_single_selection.rb)
110
+ [samples/hello/hello_list_single_selection.rb](/samples/hello/hello_list_single_selection.rb)
62
111
 
63
112
  ![Hello List Single Selection](/images/glimmer-hello-list-single-selection.png)
64
113
 
@@ -68,7 +117,7 @@ This sample demonstrates list multi-selection data-binding.
68
117
 
69
118
  Code:
70
119
 
71
- [samples/hello/hello_list_multi_selection.rb](samples/hello/hello_list_multi_selection.rb)
120
+ [samples/hello/hello_list_multi_selection.rb](/samples/hello/hello_list_multi_selection.rb)
72
121
 
73
122
  ![Hello List Multi Selection](/images/glimmer-hello-list-multi-selection.png)
74
123
 
@@ -78,7 +127,7 @@ This sample demonstrates computed data-binding.
78
127
 
79
128
  Code:
80
129
 
81
- [samples/hello/hello_computed.rb](samples/hello/hello_computed.rb)
130
+ [samples/hello/hello_computed.rb](/samples/hello/hello_computed.rb)
82
131
 
83
132
  ![Hello Browser](/images/glimmer-hello-computed.png)
84
133
 
@@ -88,7 +137,7 @@ This sample demonstrates a `message_box` dialog.
88
137
 
89
138
  Code:
90
139
 
91
- [samples/hello/hello_message_box.rb](samples/hello/hello_message_box.rb)
140
+ [samples/hello/hello_message_box.rb](/samples/hello/hello_message_box.rb)
92
141
 
93
142
  ![Hello Message Box](/images/glimmer-hello-message-box.png)
94
143
  ![Hello Message Box Dialog](/images/glimmer-hello-message-box-dialog.png)
@@ -99,7 +148,7 @@ This sample demonstrates the `browser` widget.
99
148
 
100
149
  Code:
101
150
 
102
- [samples/hello/hello_browser.rb](samples/hello/hello_browser.rb)
151
+ [samples/hello/hello_browser.rb](/samples/hello/hello_browser.rb)
103
152
 
104
153
  ![Hello Browser](/images/glimmer-hello-browser.png)
105
154
 
@@ -109,7 +158,7 @@ This sample demonstrates drag and drop in Glimmer.
109
158
 
110
159
  Code:
111
160
 
112
- [samples/hello/hello_drag_and_drop.rb](samples/hello/hello_drag_and_drop.rb)
161
+ [samples/hello/hello_drag_and_drop.rb](/samples/hello/hello_drag_and_drop.rb)
113
162
 
114
163
  ![Hello Drag and Drop](/images/glimmer-hello-drag-and-drop.gif)
115
164
 
@@ -119,7 +168,7 @@ This sample demonstrates menus in Glimmer, including accelerators on the Mac.
119
168
 
120
169
  Code:
121
170
 
122
- [samples/hello/hello_menu_bar.rb](samples/hello/hello_menu_bar.rb)
171
+ [samples/hello/hello_menu_bar.rb](/samples/hello/hello_menu_bar.rb)
123
172
 
124
173
  ![Hello Menu Bar](/images/glimmer-hello-menu-bar.png)
125
174
 
@@ -163,7 +212,7 @@ This sample demonstrates pop up context menus in Glimmer.
163
212
 
164
213
  Code:
165
214
 
166
- [samples/hello/hello_pop_up_context_menu.rb](samples/hello/hello_pop_up_context_menu.rb)
215
+ [samples/hello/hello_pop_up_context_menu.rb](/samples/hello/hello_pop_up_context_menu.rb)
167
216
 
168
217
  ![Hello Pop Up Context Menu](/images/glimmer-hello-pop-up-context-menu.png)
169
218
  ![Hello Pop Up Context Menu Popped Up](/images/glimmer-hello-pop-up-context-menu-popped-up.png)
@@ -174,7 +223,7 @@ This sample demonstrates the use of a custom widget in Glimmer.
174
223
 
175
224
  Code:
176
225
 
177
- [samples/hello/hello_custom_widget.rb](samples/hello/hello_custom_widget.rb)
226
+ [samples/hello/hello_custom_widget.rb](/samples/hello/hello_custom_widget.rb)
178
227
 
179
228
  ![Hello Custom Widget](/images/glimmer-hello-custom-widget.gif)
180
229
 
@@ -184,7 +233,7 @@ This sample demonstrates the use of a custom shell (aka custom window) in Glimme
184
233
 
185
234
  Code:
186
235
 
187
- [samples/hello/hello_custom_shell.rb](samples/hello/hello_custom_shell.rb)
236
+ [samples/hello/hello_custom_shell.rb](/samples/hello/hello_custom_shell.rb)
188
237
 
189
238
  ![Hello Custom Shell](/images/glimmer-hello-custom-shell.png)
190
239
  ![Hello Custom Shell Email1](/images/glimmer-hello-custom-shell-email1.png)
@@ -197,7 +246,7 @@ This sample demonstrates the use of a `sash_form` in Glimmer.
197
246
 
198
247
  Code:
199
248
 
200
- [samples/hello/hello_sash_form.rb](samples/hello/hello_sash_form.rb)
249
+ [samples/hello/hello_sash_form.rb](/samples/hello/hello_sash_form.rb)
201
250
 
202
251
  Hello, Sash Form! Horizontal Orientation
203
252
 
@@ -229,7 +278,7 @@ This sample demonstrates the use of a `styled_text` in Glimmer.
229
278
 
230
279
  Code:
231
280
 
232
- [samples/hello/hello_styled_text.rb](samples/hello/hello_styled_text.rb)
281
+ [samples/hello/hello_styled_text.rb](/samples/hello/hello_styled_text.rb)
233
282
 
234
283
  Hello, Styled Text!
235
284
 
@@ -241,7 +290,7 @@ This sample demonstrates the use of a `expand_bar` and `expand_item` in Glimmer.
241
290
 
242
291
  Code:
243
292
 
244
- [samples/hello/hello_expand_bar.rb](samples/hello/hello_expand_bar.rb)
293
+ [samples/hello/hello_expand_bar.rb](/samples/hello/hello_expand_bar.rb)
245
294
 
246
295
  Hello, Expand Bar! All Expanded
247
296
 
@@ -265,7 +314,7 @@ This sample demonstrates the use of a `radio` (aka `button(:radio)`) in Glimmer.
265
314
 
266
315
  Code:
267
316
 
268
- [samples/hello/hello_radio.rb](samples/hello/hello_radio.rb)
317
+ [samples/hello/hello_radio.rb](/samples/hello/hello_radio.rb)
269
318
 
270
319
  Hello, Radio!
271
320
 
@@ -277,7 +326,7 @@ This sample demonstrates the use of a `radio_group` in Glimmer, which provides t
277
326
 
278
327
  Code:
279
328
 
280
- [samples/hello/hello_radio_group.rb](samples/hello/hello_radio_group.rb)
329
+ [samples/hello/hello_radio_group.rb](/samples/hello/hello_radio_group.rb)
281
330
 
282
331
  Hello, Radio Group!
283
332
 
@@ -289,7 +338,7 @@ This sample demonstrates the use of a `group` in Glimmer (not to be confused wit
289
338
 
290
339
  Code:
291
340
 
292
- [samples/hello/hello_group.rb](samples/hello/hello_group.rb)
341
+ [samples/hello/hello_group.rb](/samples/hello/hello_group.rb)
293
342
 
294
343
  Hello, Group!
295
344
 
@@ -301,7 +350,7 @@ This sample demonstrates the use of a `checkbox` (aka `check` or `button(:check)
301
350
 
302
351
  Code:
303
352
 
304
- [samples/hello/hello_checkbox.rb](samples/hello/hello_checkbox.rb)
353
+ [samples/hello/hello_checkbox.rb](/samples/hello/hello_checkbox.rb)
305
354
 
306
355
  Hello, Checkbox!
307
356
 
@@ -313,7 +362,7 @@ This sample demonstrates the use of a `checkbox_group` (aka `check_group`) in Gl
313
362
 
314
363
  Code:
315
364
 
316
- [samples/hello/hello_checkbox_group.rb](samples/hello/hello_checkbox_group.rb)
365
+ [samples/hello/hello_checkbox_group.rb](/samples/hello/hello_checkbox_group.rb)
317
366
 
318
367
  Hello, Checkbox Group!
319
368
 
@@ -325,7 +374,7 @@ This sample demonstrates the use of a `directory_dialog` in Glimmer.
325
374
 
326
375
  Code:
327
376
 
328
- [samples/hello/hello_directory_dialog.rb](samples/hello/hello_directory_dialog.rb)
377
+ [samples/hello/hello_directory_dialog.rb](/samples/hello/hello_directory_dialog.rb)
329
378
 
330
379
  Hello, Directory Dialog!
331
380
 
@@ -345,7 +394,7 @@ This sample demonstrates the use of a `file_dialog` in Glimmer.
345
394
 
346
395
  Code:
347
396
 
348
- [samples/hello/hello_file_dialog.rb](samples/hello/hello_file_dialog.rb)
397
+ [samples/hello/hello_file_dialog.rb](/samples/hello/hello_file_dialog.rb)
349
398
 
350
399
  Hello, File Dialog!
351
400
 
@@ -365,7 +414,7 @@ This sample demonstrates the use of [date_time](#datetime) widget keywords in Gl
365
414
 
366
415
  Code:
367
416
 
368
- [samples/hello/hello_date_time.rb](samples/hello/hello_date_time.rb)
417
+ [samples/hello/hello_date_time.rb](/samples/hello/hello_date_time.rb)
369
418
 
370
419
  Hello, Date Time!
371
420
 
@@ -377,7 +426,7 @@ This sample demonstrates the use of `spinner` widget in Glimmer
377
426
 
378
427
  Code:
379
428
 
380
- [samples/hello/hello_spinner.rb](samples/hello/hello_spinner.rb)
429
+ [samples/hello/hello_spinner.rb](/samples/hello/hello_spinner.rb)
381
430
 
382
431
  Hello, Spinner!
383
432
 
@@ -389,7 +438,7 @@ This sample demonstrates the use of [table](#table) widget in Glimmer, including
389
438
 
390
439
  Code:
391
440
 
392
- [samples/hello/hello_table.rb](samples/hello/hello_table.rb)
441
+ [samples/hello/hello_table.rb](/samples/hello/hello_table.rb)
393
442
 
394
443
  Hello, Table!
395
444
 
@@ -437,7 +486,7 @@ This sample demonstrates the use of the `button` widget in Glimmer, including da
437
486
 
438
487
  Code:
439
488
 
440
- [samples/hello/hello_button.rb](samples/hello/hello_button.rb)
489
+ [samples/hello/hello_button.rb](/samples/hello/hello_button.rb)
441
490
 
442
491
  Hello, Button!
443
492
 
@@ -453,7 +502,7 @@ This sample demonstrates the use of the `link` widget in Glimmer, including iden
453
502
 
454
503
  Code:
455
504
 
456
- [samples/hello/hello_link.rb](samples/hello/hello_link.rb)
505
+ [samples/hello/hello_link.rb](/samples/hello/hello_link.rb)
457
506
 
458
507
  Hello, Link!
459
508
 
@@ -469,7 +518,7 @@ This sample demonstrates the use of the `dialog` widget in Glimmer, which provid
469
518
 
470
519
  Code:
471
520
 
472
- [samples/hello/hello_dialog.rb](samples/hello/hello_dialog.rb)
521
+ [samples/hello/hello_dialog.rb](/samples/hello/hello_dialog.rb)
473
522
 
474
523
  Hello, Dialog!
475
524
 
@@ -485,7 +534,7 @@ This sample demonstrates the Glimmer Built-In [Code Text Custom Widget](#code-te
485
534
 
486
535
  Code:
487
536
 
488
- [samples/hello/hello_code_text.rb](samples/hello/hello_code_text.rb)
537
+ [samples/hello/hello_code_text.rb](/samples/hello/hello_code_text.rb)
489
538
 
490
539
  Hello, Code Text! Ruby Language / Glimmer Theme / Show Line Numbers (default width of 4)
491
540
 
@@ -505,7 +554,7 @@ This sample demonstrates the use of the `canvas` widget and [Shape DSL](#canvas-
505
554
 
506
555
  Code:
507
556
 
508
- [samples/hello/hello_canvas.rb](samples/hello/hello_canvas.rb)
557
+ [samples/hello/hello_canvas.rb](/samples/hello/hello_canvas.rb)
509
558
 
510
559
  Hello, Canvas!
511
560
 
@@ -517,7 +566,7 @@ This sample demonstrates the use of the `canvas` widget and [Animation DSL](#can
517
566
 
518
567
  Code:
519
568
 
520
- [samples/hello/hello_canvas_animation.rb](samples/hello/hello_canvas_animation.rb)
569
+ [samples/hello/hello_canvas_animation.rb](/samples/hello/hello_canvas_animation.rb)
521
570
 
522
571
  Hello, Canvas Animation!
523
572
 
@@ -533,12 +582,24 @@ This sample demonstrates the use of the `transform` keyword as part of the [Tran
533
582
 
534
583
  Code:
535
584
 
536
- [samples/hello/hello_canvas_transform.rb](samples/hello/hello_canvas_transform.rb)
585
+ [samples/hello/hello_canvas_transform.rb](/samples/hello/hello_canvas_transform.rb)
537
586
 
538
587
  Hello, Canvas Transform!
539
588
 
540
589
  ![Hello Canvas Transform](/images/glimmer-hello-canvas-transform.png)
541
590
 
591
+ #### Hello, Cursor!
592
+
593
+ This sample demonstrates the use of the `cursor` property keyword to change the mouse cursor.
594
+
595
+ Code:
596
+
597
+ [samples/hello/hello_cursor.rb](/samples/hello/hello_cursor.rb)
598
+
599
+ Hello, Cursor!
600
+
601
+ ![Hello Cursor](/images/glimmer-hello-cursor.gif)
602
+
542
603
 
543
604
  ### Elaborate Samples
544
605
 
@@ -552,7 +613,7 @@ Please note that the code has changed since that article was written (the GUI DS
552
613
 
553
614
  Code:
554
615
 
555
- [samples/elaborate/user_profile.rb](samples/elaborate/user_profile.rb)
616
+ [samples/elaborate/user_profile.rb](/samples/elaborate/user_profile.rb)
556
617
 
557
618
  ![User Profile](/images/glimmer-user-profile.png)
558
619
 
@@ -562,7 +623,7 @@ This sample demonstrates basic data-binding, password and text fields, and field
562
623
 
563
624
  Code:
564
625
 
565
- [samples/elaborate/login.rb](samples/elaborate/login.rb)
626
+ [samples/elaborate/login.rb](/samples/elaborate/login.rb)
566
627
 
567
628
  ![Login](/images/glimmer-login.png)
568
629
  ![Login Filled In](/images/glimmer-login-filled-in.png)
@@ -576,7 +637,7 @@ Code:
576
637
 
577
638
  (Please note that on some Linux instances where the display x-axis is set to double-scale, you need to set the `shell` `minimum_size` to `300, 178` instead of `150, 178`)
578
639
 
579
- [samples/elaborate/tic_tac_toe.rb](samples/elaborate/tic_tac_toe.rb)
640
+ [samples/elaborate/tic_tac_toe.rb](/samples/elaborate/tic_tac_toe.rb)
580
641
 
581
642
  ![Tic Tac Toe](/images/glimmer-tic-tac-toe.png)
582
643
  ![Tic Tac Toe In Progress](/images/glimmer-tic-tac-toe-in-progress.png)
@@ -588,7 +649,7 @@ This sample demonstrates table data-binding, sorting, filtering, GUI layout, MVP
588
649
 
589
650
  Code:
590
651
 
591
- [samples/elaborate/contact_manager.rb](samples/elaborate/contact_manager.rb)
652
+ [samples/elaborate/contact_manager.rb](/samples/elaborate/contact_manager.rb)
592
653
 
593
654
  Contact Manager
594
655
 
@@ -618,7 +679,7 @@ Note that it works optimally on the Mac. It is very new, so it has not been opti
618
679
 
619
680
  Code:
620
681
 
621
- [samples/elaborate/tetris.rb](samples/elaborate/tetris.rb)
682
+ [samples/elaborate/tetris.rb](/samples/elaborate/tetris.rb)
622
683
 
623
684
  ![Tetris Icon](/images/glimmer-tetris-icon.png)
624
685
 
@@ -638,6 +699,24 @@ Code:
638
699
 
639
700
  ![Tetris Help Menu](/images/glimmer-tetris-help-menu.png)
640
701
 
702
+ #### Mandelbrot Fractal
703
+
704
+ This sample demonstrates how to render canvas graphics with multi-threaded processing taking advantage of all CPU cores and doing background processing of images.
705
+
706
+ It renders the famous Mandelbrot Fractal, enabling zooming and panning (go to Help -> Instructions for more details)
707
+
708
+ The Mandelbrot Fractal is known to take a long time to render, but thanks to multi-core processing, the app starts in about 10 seconds (runs faster the more cores you have)
709
+
710
+ Code:
711
+
712
+ [samples/elaborate/mandelbrot_fractal.rb](/samples/elaborate/mandelbrot_fractal.rb)
713
+
714
+ ![Mandelbrot Fractal Zoom 1](/images/glimmer-mandelbrot-zoom1.png)
715
+
716
+ ![Mandelbrot Fractal Zoom 3](/images/glimmer-mandelbrot-zoom3.png)
717
+
718
+ ![Mandelbrot Fractal Zoom 5](/images/glimmer-mandelbrot-zoom5.png)
719
+
641
720
  ### External Samples
642
721
 
643
722
  #### Glimmer Calculator
@@ -648,7 +727,7 @@ Code:
648
727
 
649
728
  #### Gladiator
650
729
 
651
- [<img src='https://raw.githubusercontent.com/AndyObtiva/glimmer-cs-gladiator/master/images/glimmer-cs-gladiator-logo.svg' height=40 /> Gladiator](https://github.com/AndyObtiva/glimmer-cs-gladiator) (short for Glimmer Editor) is a Glimmer sample project under on-going development.
730
+ [<img src='https://raw.githubusercontent.com/AndyObtiva/glimmer-cs-gladiator/master/images/glimmer-cs-gladiator-logo.png' height=40 /> Gladiator](https://github.com/AndyObtiva/glimmer-cs-gladiator) (short for Glimmer Editor) is a Glimmer sample project under on-going development.
652
731
  You may check it out to learn how to build a Glimmer Custom Shell gem.
653
732
 
654
733
  [<img src="https://raw.githubusercontent.com/AndyObtiva/glimmer-cs-gladiator/master/images/glimmer-gladiator.png" />](https://github.com/AndyObtiva/glimmer-cs-gladiator)
@@ -2,22 +2,28 @@
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.8 ruby lib
5
+ # stub: glimmer-dsl-swt 4.18.4.9 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.8"
9
+ s.version = "4.18.4.9"
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-11"
14
+ s.date = "2021-02-16"
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]
18
18
  s.extra_rdoc_files = [
19
- "LICENSE.txt",
20
- "README.md"
19
+ "README.md",
20
+ "docs/reference/GLIMMER_COMMAND.md",
21
+ "docs/reference/GLIMMER_CONFIGURATION.md",
22
+ "docs/reference/GLIMMER_GIRB.md",
23
+ "docs/reference/GLIMMER_GUI_DSL_SYNTAX.md",
24
+ "docs/reference/GLIMMER_PACKAGING_AND_DISTRIBUTION.md",
25
+ "docs/reference/GLIMMER_SAMPLES.md",
26
+ "docs/reference/GLIMMER_STYLE_GUIDE.md"
21
27
  ]
22
28
  s.files = [
23
29
  "CHANGELOG.md",
@@ -171,6 +177,7 @@ Gem::Specification.new do |s|
171
177
  "samples/hello/hello_combo.rb",
172
178
  "samples/hello/hello_computed.rb",
173
179
  "samples/hello/hello_computed/contact.rb",
180
+ "samples/hello/hello_cursor.rb",
174
181
  "samples/hello/hello_custom_shell.rb",
175
182
  "samples/hello/hello_custom_widget.rb",
176
183
  "samples/hello/hello_date_time.rb",
@@ -35,11 +35,12 @@ module Glimmer
35
35
 
36
36
  def can_interpret?(parent, keyword, *args, &block)
37
37
  (keyword == 'image') and
38
- (parent.nil? or parent.respond_to?('image='))
38
+ (parent.nil? or parent.respond_to?('image=') or args.first.is_a?(Numeric))
39
39
  end
40
40
 
41
41
  def interpret(parent, keyword, *args, &block)
42
- args.unshift(parent) unless parent.nil?
42
+ options = args.last.is_a?(Hash) ? args.last : {}
43
+ args.unshift(parent) unless parent.nil? || options[:top_level]
43
44
  Glimmer::SWT::ImageProxy.new(*args, &block)
44
45
  end
45
46
 
@@ -51,6 +51,7 @@ module Glimmer
51
51
  widget_binding.call(model_binding.evaluate_property)
52
52
  widget_binding.observe(model, model_binding.property_name_expression)
53
53
 
54
+ raise(Glimmer::Error, "No radios found! Make sure radio selection is data-bound to a property having property_options as non-empty array!") if parent.items.empty?
54
55
  parent.on_widget_selected do
55
56
  model_binding.call(widget_binding.evaluate_property)
56
57
  end
@@ -46,9 +46,9 @@ module Glimmer
46
46
  end
47
47
  end
48
48
 
49
- def clear_shapes
49
+ def clear_shapes(dispose_images: true, dispose_patterns: true)
50
50
  # Optimize further by having a collection of disposable_shapes independent of shapes, which is much smaller and only has shapes that require disposal (shapes with patterns or image)
51
- shapes.dup.each(&:dispose) if requires_shape_disposal?
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
54
  def deregister_shape_painting
@@ -73,7 +73,8 @@ module Glimmer
73
73
  end
74
74
 
75
75
  def can_handle_observation_request?(observation_request)
76
- radios.first&.can_handle_observation_request?(observation_request) || super(observation_request)
76
+ radios.first&.can_handle_observation_request?(observation_request) or
77
+ super(observation_request)
77
78
  end
78
79
 
79
80
  def handle_observation_request(observation_request, &block)
@@ -263,16 +263,20 @@ module Glimmer
263
263
  the_pattern
264
264
  end
265
265
 
266
- def dispose
267
- @background_pattern&.dispose
268
- @background_pattern = nil
269
- @foreground_pattern&.dispose
270
- @foreground_pattern = nil
271
- @image&.dispose
272
- @image = nil
266
+ def dispose(dispose_images: true, dispose_patterns: true)
267
+ if dispose_patterns
268
+ @background_pattern&.dispose
269
+ @background_pattern = nil
270
+ @foreground_pattern&.dispose
271
+ @foreground_pattern = nil
272
+ end
273
+ if dispose_images
274
+ @image&.dispose
275
+ @image = nil
276
+ end
273
277
  @parent.shapes.delete(self)
274
278
  end
275
-
279
+
276
280
  def paint(paint_event)
277
281
  calculate_paint_args!
278
282
  @properties.each do |property, args|
@@ -97,7 +97,7 @@ module Glimmer
97
97
  if shapes.any?
98
98
  setup_shape_painting
99
99
  end
100
- if @parent.respond_to?('image=')
100
+ if @parent.respond_to?('image=') && !@parent.is_disposed
101
101
  @parent&.image = swt_image
102
102
  end
103
103
  end
@@ -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
@@ -24,14 +24,23 @@ require 'glimmer/swt/swt_proxy'
24
24
 
25
25
  module Glimmer
26
26
  module SWT
27
- class ScrolledCompositeProxy < Glimmer::SWT::WidgetProxy
27
+ class ScrolledCompositeProxy < Glimmer::SWT::WidgetProxy
28
28
  def post_initialize_child(child)
29
- swt_widget.content = child.swt_widget
29
+ swt_widget.content = child.swt_widget
30
+ # TODO consider triggering this method in the future upon resizing of content with a listener (on_control_resized)
31
+ # child.on_control_resized do
32
+ # swt_widget.set_min_size(swt_widget.computeSize(child.bounds.width, child.bounds.height))
33
+ # end
30
34
  end
31
35
 
32
36
  def post_add_content
37
+ calculate_min_size
38
+ end
39
+
40
+ def calculate_min_size
33
41
  swt_widget.set_min_size(swt_widget.computeSize(SWTProxy[:default], SWTProxy[:default]))
34
- end
42
+ end
43
+ alias recalculate_min_size calculate_min_size
35
44
  end
36
45
  end
37
46
  end
@@ -49,6 +49,7 @@ module Glimmer
49
49
  @widget_proxy = SWT::WidgetProxy.new('tab_item', parent, style)
50
50
  @swt_tab_item = @widget_proxy.swt_widget
51
51
  @swt_tab_item.control = swt_widget
52
+ # parent.pack # TODO auto fix the tab folder to avoid having to do this manually (including maintaining bounds and minimum size of shell)
52
53
  end
53
54
 
54
55
  def has_attribute?(attribute_name, *args)
@@ -719,7 +719,13 @@ module Glimmer
719
719
  def add_listener(underscored_listener_name, &block)
720
720
  widget_add_listener_method, listener_class, listener_method = self.class.find_listener(@swt_widget.getClass, underscored_listener_name)
721
721
  widget_listener_proxy = nil
722
- safe_block = lambda { |*args| block.call(*args) unless @swt_widget.isDisposed }
722
+ safe_block = lambda do |*args|
723
+ begin
724
+ block.call(*args) unless @swt_widget.isDisposed
725
+ rescue => e
726
+ Glimmer::Config.logger.error {e}
727
+ end
728
+ end
723
729
  listener = listener_class.new(listener_method => safe_block)
724
730
  @swt_widget.send(widget_add_listener_method, listener)
725
731
  WidgetListenerProxy.new(swt_widget: @swt_widget, swt_listener: listener, widget_add_listener_method: widget_add_listener_method, swt_listener_class: listener_class, swt_listener_method: listener_method)
@@ -23,35 +23,101 @@ require 'complex'
23
23
  require 'bigdecimal'
24
24
  require 'concurrent-ruby'
25
25
 
26
- # Mandelbrot implementation
27
- # Courtesy of open-source code at:
28
- # https://github.com/gotbadger/ruby-mandelbrot
26
+ # Mandelbrot multi-threaded implementation leveraging all processor cores.
29
27
  class Mandelbrot
30
-
31
- attr_accessor :max_iterations
32
-
33
- def initialize(max_iterations)
28
+ DEFAULT_STEP = 0.0030
29
+ Y_START = -1.0
30
+ Y_END = 1.0
31
+ X_START = -2.0
32
+ X_END = 0.5
33
+
34
+ class << self
35
+ def for(max_iterations:, zoom:, background: false)
36
+ key = [max_iterations, zoom]
37
+ creation_mutex.synchronize do
38
+ unless flyweight_mandelbrots.keys.include?(key)
39
+ flyweight_mandelbrots[key] = new(max_iterations: max_iterations, zoom: zoom, background: background)
40
+ end
41
+ end
42
+ flyweight_mandelbrots[key].background = background
43
+ flyweight_mandelbrots[key]
44
+ end
45
+
46
+ def flyweight_mandelbrots
47
+ @flyweight_mandelbrots ||= {}
48
+ end
49
+
50
+ def creation_mutex
51
+ @creation_mutex ||= Mutex.new
52
+ end
53
+ end
54
+
55
+ attr_accessor :max_iterations, :background
56
+ attr_reader :zoom, :points_calculated
57
+ alias points_calculated? points_calculated
58
+
59
+ # max_iterations is the maximum number of Mandelbrot calculation iterations
60
+ # zoom is how much zoom there is on the Mandelbrot points from the default view of zoom 1
61
+ # background indicates whether to do calculation in the background for caching purposes,
62
+ # thus utilizing less CPU cores to avoid disrupting user experience
63
+ def initialize(max_iterations:, zoom: 1.0, background: false)
34
64
  @max_iterations = max_iterations
65
+ @zoom = zoom
66
+ @background = background
67
+ end
68
+
69
+ def step
70
+ DEFAULT_STEP / zoom
71
+ end
72
+
73
+ def y_array
74
+ @y_array ||= Y_START.step(Y_END, step).to_a
75
+ end
76
+
77
+ def x_array
78
+ @x_array ||= X_START.step(X_END, step).to_a
35
79
  end
36
80
 
37
- def calculate_all(x_array, y_array)
38
- thread_pool = Concurrent::FixedThreadPool.new(Concurrent.processor_count)
39
- width = x_array.size
40
- height = y_array.size
41
- pixel_rows_array = Concurrent::Array.new(height)
81
+ def height
82
+ y_array.size
83
+ end
84
+
85
+ def width
86
+ x_array.size
87
+ end
88
+
89
+ def points
90
+ @points ||= calculate_points
91
+ end
92
+
93
+ def thread_count
94
+ @background ? [Concurrent.processor_count - 1, 1].max : Concurrent.processor_count
95
+ end
96
+
97
+ def calculate_points
98
+ puts "Background calculation activated at zoom #{zoom}" if @background
99
+ if @points_calculated
100
+ puts "Points calculated already. Returning previously calculated points..."
101
+ return @points
102
+ end
103
+ thread_pool = Concurrent::FixedThreadPool.new(thread_count, fallback_policy: :discard)
104
+ @points = Concurrent::Array.new(height)
42
105
  height.times do |y|
43
- pixel_rows_array[y] ||= Concurrent::Array.new(width)
106
+ @points[y] ||= Concurrent::Array.new(width)
44
107
  width.times do |x|
45
108
  thread_pool.post do
46
- pixel_rows_array[y][x] = calculate(x_array[x], y_array[y]).last
109
+ @points[y][x] = calculate(x_array[x], y_array[y]).last
47
110
  end
48
111
  end
49
112
  end
50
113
  thread_pool.shutdown
51
114
  thread_pool.wait_for_termination
52
- pixel_rows_array
115
+ @points_calculated = true
116
+ @points
53
117
  end
54
-
118
+
119
+ # Calculates a Mandelbrot point, borrowing some open-source code from:
120
+ # https://github.com/gotbadger/ruby-mandelbrot
55
121
  def calculate(x,y)
56
122
  base_case = [Complex(x,y), 0]
57
123
  Array.new(max_iterations, base_case).inject(base_case) do |prev ,base|
@@ -67,37 +133,222 @@ end
67
133
  class MandelbrotFractal
68
134
  include Glimmer::UI::CustomShell
69
135
 
136
+ COMMAND = OS.mac? ? :command : :ctrl
137
+
138
+ option :zoom, default: 1.0
139
+
70
140
  before_body {
71
- @colors = [[0, 0, 0]] + 40.times.map { |i| [255 - i*5, 255 - i*5, 55 + i*5] }
72
- @colors = @colors.map {|color_data| rgb(*color_data).swt_color}
73
- mandelbrot = Mandelbrot.new(@colors.size - 1)
74
- @y_array = (1.0).step(-1,-0.0030).to_a
75
- @x_array = (-2.0).step(0.5,0.0030).to_a
76
- @height = @y_array.size
77
- @width = @x_array.size
78
- @pixel_rows_array = mandelbrot.calculate_all(@x_array, @y_array)
79
- @image = Image.new(display.swt_display, @width, @height)
80
- image_gc = org.eclipse.swt.graphics.GC.new(@image)
81
- @height.times { |y|
82
- @width.times { |x|
83
- new_foreground = @colors[@pixel_rows_array[y][x]]
84
- image_gc.foreground = @current_foreground = new_foreground unless new_foreground == @current_foreground
85
- image_gc.draw_point x, y
141
+ Display.app_name = 'Mandelbrot Fractal'
142
+ # pre-calculate mandelbrot image
143
+ @mandelbrot_image = build_mandelbrot_image
144
+ }
145
+
146
+ after_body {
147
+ # pre-calculate zoomed mandelbrot images even before the user zooms in
148
+ puts 'Starting background calculation thread...'
149
+ Thread.new {
150
+ future_zoom = 1.5
151
+ loop {
152
+ puts "Creating mandelbrot for background calculation at zoom: #{future_zoom}"
153
+ the_mandelbrot = Mandelbrot.for(max_iterations: color_palette.size - 1, zoom: future_zoom, background: true)
154
+ pixels = the_mandelbrot.calculate_points
155
+ build_mandelbrot_image(mandelbrot_zoom: future_zoom)
156
+ sync_exec {
157
+ swt_widget.text = mandelbrot_shell_title
158
+ @canvas.cursor = :cross
159
+ }
160
+ future_zoom += 0.5
86
161
  }
87
162
  }
88
163
  }
89
-
164
+
90
165
  body {
91
- shell {
92
- text 'Mandelbrot Fractal'
93
- minimum_size @width, @height + 12
94
- image @image
166
+ shell(:no_resize) {
167
+ text mandelbrot_shell_title
168
+ minimum_size mandelbrot.width, mandelbrot.height + 30
169
+ image @mandelbrot_image
170
+
171
+ @scrolled_composite = scrolled_composite {
172
+ @canvas = canvas {
173
+ image @mandelbrot_image
174
+ cursor :no
175
+
176
+ on_mouse_down {
177
+ @drag_detected = false
178
+ @canvas.cursor = :hand
179
+ }
180
+
181
+ on_drag_detected { |drag_detect_event|
182
+ @drag_detected = true
183
+ @drag_start_x = drag_detect_event.x
184
+ @drag_start_y = drag_detect_event.y
185
+ }
186
+
187
+ on_mouse_move { |mouse_event|
188
+ if @drag_detected
189
+ origin = @scrolled_composite.origin
190
+ new_x = origin.x - (mouse_event.x - @drag_start_x)
191
+ new_y = origin.y - (mouse_event.y - @drag_start_y)
192
+ @scrolled_composite.set_origin(new_x, new_y)
193
+ end
194
+ }
195
+
196
+ on_mouse_up { |mouse_event|
197
+ if !@drag_detected
198
+ origin = @scrolled_composite.origin
199
+ @location_x = [[origin.x + mouse_event.x - @scrolled_composite.bounds.width / 2.0, 0].max, @scrolled_composite.bounds.width].min
200
+ @location_y = [[origin.y + mouse_event.y - @scrolled_composite.bounds.height / 2.0, 0].max, @scrolled_composite.bounds.height].min
201
+ if mouse_event.button == 1
202
+ zoom_in
203
+ elsif mouse_event.button > 2
204
+ zoom_out
205
+ end
206
+ end
207
+ @canvas.cursor = can_zoom_in? ? :cross : :no
208
+ @drag_detected = false
209
+ }
210
+
211
+ }
212
+ }
95
213
 
96
- canvas {
97
- image @image
214
+ menu_bar {
215
+ menu {
216
+ text '&View'
217
+
218
+ menu_item {
219
+ text 'Zoom &In'
220
+ accelerator COMMAND, '+'
221
+
222
+ on_widget_selected { zoom_in }
223
+ }
224
+
225
+ menu_item {
226
+ text 'Zoom &Out'
227
+ accelerator COMMAND, '-'
228
+
229
+ on_widget_selected { zoom_out }
230
+ }
231
+
232
+ menu_item {
233
+ text '&Reset Zoom'
234
+ accelerator COMMAND, '0'
235
+
236
+ on_widget_selected { perform_zoom(mandelbrot_zoom: 1.0) }
237
+ }
238
+ }
239
+ menu {
240
+ text '&Help'
241
+
242
+ menu_item {
243
+ text '&Instructions'
244
+ accelerator COMMAND, :shift, :i
245
+
246
+ on_widget_selected {
247
+ display_help_instructions
248
+ }
249
+ }
250
+ }
98
251
  }
99
252
  }
100
253
  }
254
+
255
+ def mandelbrot_shell_title
256
+ "Mandelbrot Fractal - Zoom #{zoom}x (Calculated Max: #{flyweight_mandelbrot_images.keys.max}x)"
257
+ end
258
+
259
+ def build_mandelbrot_image(mandelbrot_zoom: nil)
260
+ mandelbrot_zoom ||= zoom
261
+ unless flyweight_mandelbrot_images.keys.include?(mandelbrot_zoom)
262
+ the_mandelbrot = mandelbrot(mandelbrot_zoom: mandelbrot_zoom)
263
+ width = the_mandelbrot.width
264
+ height = the_mandelbrot.height
265
+ pixels = the_mandelbrot.points
266
+ new_mandelbrot_image = image(width, height, top_level: true) # invoke as a top-level parentless keyword to avoid nesting under any widget
267
+ new_mandelbrot_image_gc = new_mandelbrot_image.gc
268
+ current_foreground = nil
269
+ height.times { |y|
270
+ width.times { |x|
271
+ new_foreground = color_palette[pixels[y][x]]
272
+ new_mandelbrot_image_gc.foreground = current_foreground = new_foreground unless new_foreground == current_foreground
273
+ new_mandelbrot_image_gc.draw_point x, y
274
+ }
275
+ }
276
+ flyweight_mandelbrot_images[mandelbrot_zoom] = new_mandelbrot_image
277
+ end
278
+ flyweight_mandelbrot_images[mandelbrot_zoom]
279
+ end
280
+
281
+ def flyweight_mandelbrot_images
282
+ @flyweight_mandelbrot_images ||= {}
283
+ end
284
+
285
+ def mandelbrot(mandelbrot_zoom: nil)
286
+ mandelbrot_zoom ||= zoom
287
+ Mandelbrot.for(max_iterations: color_palette.size - 1, zoom: mandelbrot_zoom)
288
+ end
289
+
290
+ def color_palette
291
+ if @color_palette.nil?
292
+ @color_palette = [[0, 0, 0]] + 40.times.map { |i| [255 - i*5, 255 - i*5, 55 + i*5] }
293
+ @color_palette = @color_palette.map {|color_data| rgb(*color_data).swt_color}
294
+ end
295
+ @color_palette
296
+ end
297
+
298
+ def zoom_in
299
+ if can_zoom_in?
300
+ perform_zoom(zoom_delta: 0.5)
301
+ @canvas.cursor = can_zoom_in? ? :cross : :no
302
+ end
303
+ end
304
+
305
+ def can_zoom_in?
306
+ flyweight_mandelbrot_images.keys.include?(zoom + 0.5)
307
+ end
308
+
309
+ def zoom_out
310
+ perform_zoom(zoom_delta: -0.5)
311
+ end
312
+
313
+ def perform_zoom(zoom_delta: 0, mandelbrot_zoom: nil)
314
+ mandelbrot_zoom ||= self.zoom + zoom_delta
315
+ @canvas.cursor = :wait
316
+ last_zoom = self.zoom
317
+ self.zoom = [mandelbrot_zoom, 1.0].max
318
+ @canvas.clear_shapes(dispose_images: false)
319
+ @mandelbrot_image = build_mandelbrot_image
320
+ body_root.content {
321
+ image @mandelbrot_image
322
+ }
323
+ @canvas.content {
324
+ image @mandelbrot_image
325
+ }
326
+ @canvas.set_size @mandelbrot_image.bounds.width, @mandelbrot_image.bounds.height
327
+ @scrolled_composite.swt_widget.set_min_size(Point.new(@mandelbrot_image.bounds.width, @mandelbrot_image.bounds.height))
328
+ if @location_x && @location_y
329
+ factor = (zoom / last_zoom)
330
+ @scrolled_composite.set_origin(factor*@location_x, factor*@location_y)
331
+ @location_x = @location_y = nil
332
+ end
333
+ @canvas.cursor = :cross
334
+ swt_widget.text = mandelbrot_shell_title
335
+ end
336
+
337
+ def display_help_instructions
338
+ message_box(body_root) {
339
+ text 'Mandelbrot Fractal - Help'
340
+ message <<~MULTI_LINE_STRING
341
+ The Mandelbrot Fractal precalculates zoomed renderings in the background. Wait if you hit a zoom level that is not calculated yet.
342
+
343
+ Left-click to zoom in.
344
+ Right-click to zoom out.
345
+ Scroll or drag to pan.
346
+
347
+ Enjoy!
348
+ MULTI_LINE_STRING
349
+ }.open
350
+ end
351
+
101
352
  end
102
353
 
103
354
  MandelbrotFractal.launch
@@ -0,0 +1,57 @@
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
+ class HelloCursor
23
+ include Glimmer::UI::CustomShell
24
+
25
+ attr_accessor :selected_cursor
26
+
27
+ def selected_cursor_options
28
+ org.eclipse.swt.SWT.constants.select {|c| c.to_s.start_with?('CURSOR_')}.map {|c| c.to_s.sub('CURSOR_', '').downcase}
29
+ end
30
+
31
+ after_body {
32
+ observe(self, :selected_cursor) {
33
+ body_root.cursor = selected_cursor
34
+ }
35
+ }
36
+
37
+ body {
38
+ shell {
39
+ grid_layout
40
+
41
+ text 'Hello, Cursor!'
42
+ cursor :wait
43
+
44
+ label {
45
+ text 'Please select a cursor style and see it change the mouse cursor (varies per platform):'
46
+ font style: :bold
47
+ cursor :no
48
+ }
49
+ radio_group {
50
+ grid_layout 5, true
51
+ selection bind(self, :selected_cursor)
52
+ }
53
+ }
54
+ }
55
+ end
56
+
57
+ HelloCursor.launch
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.8
4
+ version: 4.18.4.9
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 00:00:00.000000000 Z
11
+ date: 2021-02-16 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  requirement: !ruby/object:Gem::Requirement
@@ -350,8 +350,14 @@ executables:
350
350
  - girb
351
351
  extensions: []
352
352
  extra_rdoc_files:
353
- - LICENSE.txt
354
353
  - README.md
354
+ - docs/reference/GLIMMER_COMMAND.md
355
+ - docs/reference/GLIMMER_CONFIGURATION.md
356
+ - docs/reference/GLIMMER_GIRB.md
357
+ - docs/reference/GLIMMER_GUI_DSL_SYNTAX.md
358
+ - docs/reference/GLIMMER_PACKAGING_AND_DISTRIBUTION.md
359
+ - docs/reference/GLIMMER_SAMPLES.md
360
+ - docs/reference/GLIMMER_STYLE_GUIDE.md
355
361
  files:
356
362
  - CHANGELOG.md
357
363
  - LICENSE.txt
@@ -504,6 +510,7 @@ files:
504
510
  - samples/hello/hello_combo.rb
505
511
  - samples/hello/hello_computed.rb
506
512
  - samples/hello/hello_computed/contact.rb
513
+ - samples/hello/hello_cursor.rb
507
514
  - samples/hello/hello_custom_shell.rb
508
515
  - samples/hello/hello_custom_widget.rb
509
516
  - samples/hello/hello_date_time.rb