glimmer-dsl-swt 4.18.5.4 → 4.18.6.3

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: 495c8eacce66f3b425a8f1603eea5051f5b776f0cb8e8550419382079c58e85e
4
- data.tar.gz: 7e922de5ff80a2e85facee8a36444fe70bd6a9e25a65416aeebec4bfabd10749
3
+ metadata.gz: 9db83aea9f51b0f0f2b7dfcb78a5180f00a5c7e7ebe7852f404c879c6417fa66
4
+ data.tar.gz: af21fa66dff5e22c878fe564dcdeb34c6d83a9b8afd8eb66e1c827c047a8d28c
5
5
  SHA512:
6
- metadata.gz: 5ace8433246247b3210cced98a70bb45cfdc978808b632ad322b5c995a7b0e868fc7df9c6ed23293fd5845e50257696617ad9a85ad9e7a0f0b697aea55901cfc
7
- data.tar.gz: 58c632f794d07225737d101b68300db72c41b90778320765971e29539242d48260512db44c77ed99fb1aa9307056d24364a5bb57e400b3a0aab49c41ac8babb4
6
+ metadata.gz: 80c988832fe70bf8505aca306b88d34e35957e8a8a936c9ef874ad35566c71e98e766cd7b732dd73bf2e3c088a52d1480fabe20f77fc557fcc47c9f4ead8d817
7
+ data.tar.gz: 2b2a8f85e7ee15dc23f772a92c4ca4f9acad738ee22efc2a36dd45aab73e6f18e2e4f24b1efe1f7f68fa558ce7b2dc42f3a92c427c2c5074dab9a09c5979c0ec
data/CHANGELOG.md CHANGED
@@ -1,5 +1,47 @@
1
1
  # Change Log
2
2
 
3
+ ### 4.18.6.3
4
+
5
+ - Support `Glimmer::SWT::Custom::Shape::PathSegment#dispose` method
6
+ - Amend Hello, Canvas Path! sample with ability to regenerate paths
7
+ - Make `tab_folder` preinit all its tabs by default while supporting the SWT style of `:initialize_tabs_on_select` to init tabs on first select instead.
8
+ - Support trimming line style symbols (no need to say line_ before each style. e.g. `:line_solid` becomes `:solid`) in Canvas Shape DSL line_style property
9
+ - Support `antialias true` as an alternative to `antialias :on`, `antialias false` as an alternative to `antialias :off`, and `antialias nil` as an alternative to `antialias :default`
10
+
11
+ ### 4.18.6.2
12
+
13
+ - Hello, Canvas Data Binding! Sample
14
+ - Update Stock Ticker sample to keep stock names visible when scrolling graphs off the screen
15
+ - `rgb` keyword tolerance of nil values (converts to 0)
16
+ - Canvas Path DSL Data-Binding
17
+ - Added `Glimmer::SWT::Custom::Shape::PathSegment` `#path` and `#root_path` API methods to enable determining what path/root-path the path segment is part of.
18
+ - Fixed issues with geometry calculation of path segments (especially line)
19
+
20
+ ### 4.18.6.1
21
+
22
+ - Fixed issues with Canvas Path DSL handling of connected vs non-connected path segments (including in geometry calculations)
23
+ - Optimized Canvas Path DSL redraw performance by removing extra redraws
24
+ - Fixed issues in the Hello, Canvas Path! sample and renamed to Stock Ticker
25
+ - Added a new simpler Hello, Canvas Path! sample
26
+
27
+ ### 4.18.6.0
28
+
29
+ - Canvas Path DSL support (Alpha) for `path` as drawn or filled (`fill: true`) to the Canvas Shape DSL, supporting `point`, `line` (first point is auto-derived from previous point if not specified)
30
+ - Hello, Canvas Path! sample showing a Stock Ticker with line curves for multiple company stocks, animated with randomly generated data, moving to the left out of screen second by second. Has multiple tabs demonstrating different types of paths for graphing/charting of different real world business applications: point, line, quad, cubic.
31
+ - Fix issue to allow invocation of `set_min_size` off of `scrolled_composite` proxy directly (not just swt_widget), thus taking advantage of implicit `auto_exec`
32
+ - Support `Shape#content {}` method just like `WidgetProxy#content` to enable reopening and adding nested shapes at runtime after initial construction
33
+ - Support a path containing a `quad` bezier curve with `point_array` property
34
+ - Support a path containing a `cubic` bezier curve with `point_array` property
35
+
36
+ ### 4.18.5.5
37
+
38
+ - Automatically recalculate default size (width/height) to accomodate nested shapes when changing x/y/width/height sticking out of parent from right or bottom.
39
+ - Support special case of centering a nested shape with default x/y within a parent with default width/height calculated from nested shape
40
+ - Consider Canvas Shape DSL support for LineAttributes `line_dash_offset` and `line_miter_limit`
41
+ - Canvas Shape DSL Polygon `include?` does an outer/inner check of edge detection only
42
+ - Ensure all Canvas Shape DSL properties are restored upon painting a shape to what they were prior to painting that shape
43
+ - Fix issue with bringing high score dialog up in Tetris caused by latest dialog changes for supporting the new `color_dialog` and `font_dialog`
44
+
3
45
  ### 4.18.5.4
4
46
 
5
47
  - Support passing width, height as :default (or nil or not passed in if they are the last args) in all shapes that include other shapes to indicate they are calculated automatically from nested shapes, text/string extent, or otherwise defaulting to 0, 0
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.5.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.6.3
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)
@@ -10,15 +10,13 @@
10
10
 
11
11
  [Glimmer](https://github.com/AndyObtiva/glimmer) DSL for SWT is a native-GUI cross-platform desktop development library written in [JRuby](https://www.jruby.org/), an OS-threaded faster JVM version of [Ruby](https://www.ruby-lang.org/en/). [Glimmer](https://github.com/AndyObtiva/glimmer)'s main innovation is a declarative [Ruby DSL](docs/reference/GLIMMER_GUI_DSL_SYNTAX.md#glimmer-dsl-syntax) that enables productive and efficient authoring of desktop application user-interfaces by relying on the robust [Eclipse SWT library](https://www.eclipse.org/swt/). [Glimmer](https://rubygems.org/gems/glimmer) additionally innovates by having built-in [data-binding](docs/reference/GLIMMER_GUI_DSL_SYNTAX.md#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](docs/reference/GLIMMER_GUI_DSL_SYNTAX.md#widgets), but it also supports drawing Canvas Graphics like [Shapes](docs/reference/GLIMMER_GUI_DSL_SYNTAX.md#canvas-shape-dsl) and [Animations](docs/reference/GLIMMER_GUI_DSL_SYNTAX.md#canvas-animation-dsl). To get started quickly, [Glimmer](https://rubygems.org/gems/glimmer) offers [scaffolding](docs/reference/GLIMMER_COMMAND.md#scaffolding) options for [Apps](#in-production), [Gems](docs/reference/GLIMMER_COMMAND.md#custom-shell-gem), and [Custom Widgets](docs/reference/GLIMMER_GUI_DSL_SYNTAX.md#custom-widgets). [Glimmer](https://rubygems.org/gems/glimmer) also includes native-executable [packaging](docs/reference/GLIMMER_PACKAGING_AND_DISTRIBUTION.md) support, sorely lacking in other libraries, thus enabling the delivery of desktop apps written in [Ruby](https://www.ruby-lang.org/en/) as truly native DMG/PKG/APP files on the [Mac](https://www.apple.com/ca/macos) + [App Store](https://developer.apple.com/macos/distribution/), MSI/EXE files on [Windows](https://www.microsoft.com/en-ca/windows), and [Gem Packaged Shell Scripts](docs/reference/GLIMMER_COMMAND.md#packaging) on [Linux](https://www.linux.org/).
12
12
 
13
- [Glimmer receives two updates per month](https://rubygems.org/gems/glimmer-dsl-swt/versions). You can trust [Glimmer](https://rubygems.org/gems/glimmer) with your Ruby desktop GUI development needs. Please make [Glimmer](https://rubygems.org/gems/glimmer) even better by providing feedback and [contributing](#contributing) when possible.
14
-
15
- Gem version numbers are in sync with the SWT library versions. The first two digits represent the SWT version number. The last two digits represent the minor and patch versions of Glimmer DSL for SWT.
16
-
17
- [Glimmer DSL for SWT](https://rubygems.org/gems/glimmer-dsl-swt) versions 4.18.x.y come with [SWT 4.18](https://download.eclipse.org/eclipse/downloads/drops4/R-4.18-202012021800/), which was released on December 2, 2020.
18
-
19
13
  [<img src="https://covers.oreillystatic.com/images/9780596519650/lrg.jpg" width=105 /><br />
20
14
  Featured in JRuby Cookbook](http://shop.oreilly.com/product/9780596519650.do) and [Chalmers/Gothenburg University Software Engineering Master's Lecture Material](http://www.cse.chalmers.se/~bergert/slides/guest_lecture_DSLs.pdf)
21
15
 
16
+ [Glimmer DSL for SWT](https://rubygems.org/gems/glimmer-dsl-swt) 4.18.6.3 includes [SWT 4.18](https://download.eclipse.org/eclipse/downloads/drops4/R-4.18-202012021800/), which was released on December 2, 2020. Gem version numbers are in sync with the SWT library versions. The first two digits represent the SWT version number. The last two digits represent the minor and patch versions of Glimmer DSL for SWT.
17
+
18
+ [Glimmer DSL for SWT receives two updates per month](https://rubygems.org/gems/glimmer-dsl-swt/versions). You can trust [Glimmer DSL for SWT](https://rubygems.org/gems/glimmer-dsl-swt) with your Ruby desktop GUI development needs! [Glimmer DSL for SWT](https://rubygems.org/gems/glimmer-dsl-swt) brings great ideas to the table, such as declarative programming via domain specific languages, currently under-utilized in the GUI domain. That said, it may not be feature complete enough for everybody's needs, so please help make [Glimmer DSL for SWT](https://rubygems.org/gems/glimmer-dsl-swt) even better by providing feedback and [contributing](#contributing) when possible. The project is very active, so any feature suggestions that are accepted could be implemented within weeks if not days. Also, you are welcome to [hire me](#hire-me) full-time if you want long-term development of [Glimmer DSL for SWT](https://rubygems.org/gems/glimmer-dsl-swt) for your project needs.
19
+
22
20
  Glimmer DSL gems:
23
21
  - [glimmer-dsl-swt](https://github.com/AndyObtiva/glimmer-dsl-swt): Glimmer DSL for SWT (JRuby Desktop Development GUI Framework)
24
22
  - [glimmer-dsl-opal](https://github.com/AndyObtiva/glimmer-dsl-opal): Glimmer DSL for Opal (Pure Ruby Web GUI and Auto-Webifier of Desktop Apps)
@@ -342,7 +340,7 @@ jgem install glimmer-dsl-swt
342
340
 
343
341
  Or this command if you want a specific version:
344
342
  ```
345
- jgem install glimmer-dsl-swt -v 4.18.5.4
343
+ jgem install glimmer-dsl-swt -v 4.18.6.3
346
344
  ```
347
345
 
348
346
  `jgem` is JRuby's version of `gem` command.
@@ -360,7 +358,7 @@ Note: if you're using activerecord or activesupport, keep in mind that Glimmer u
360
358
 
361
359
  Add the following to `Gemfile`:
362
360
  ```
363
- gem 'glimmer-dsl-swt', '~> 4.18.5.4'
361
+ gem 'glimmer-dsl-swt', '~> 4.18.6.3'
364
362
  ```
365
363
 
366
364
  And, then run:
data/VERSION CHANGED
@@ -1 +1 @@
1
- 4.18.5.4
1
+ 4.18.6.3
@@ -41,6 +41,7 @@ This guide should help you get started with Glimmer DSL for SWT. For more advanc
41
41
  - [Shapes inside an Image](#shapes-inside-an-image)
42
42
  - [Canvas Shape API](#canvas-shape-api)
43
43
  - [Pixel Graphics](#pixel-graphics)
44
+ - [Canvas Path DSL](#canvas-path-dsl)
44
45
  - [Canvas Transform DSL](#canvas-transform-dsl)
45
46
  - [Top-Level Transform Fluent Interface](#top-level-transform-fluent-interface)
46
47
  - [Canvas Animation DSL](#canvas-animation-dsl)
@@ -409,6 +410,14 @@ Example (you may copy/paste in [`girb`](GLIMMER_GIRB.md)):
409
410
  @shell.open
410
411
  ```
411
412
 
413
+ ##### Tab Folder API
414
+
415
+ Unlike basic SWT usage, `tab_folder` has the smart default of pre-initializing all tabs so that they are properly sized/filled so no delays occur when a user browses through them for the first time by selecting unselected tabs.
416
+
417
+ The [Stock Ticker](/docs/reference/GLIMMER_SAMPLES.md#stock-ticker) sample takes advantage of this to ensure all tabs are pre-initialized and filled with rendered data even before the user selects any of them.
418
+
419
+ That said, `tab_folder` can optionally receive a custom Glimmer SWT style named `:initialize_tabs_on_select`, which disables that behavior by going back to SWT's default of initializing tabs upon first selection (e.g. upon clicking with the mouse).
420
+
412
421
  ##### Shell Icon
413
422
 
414
423
  To set the shell icon, simply set the `image` property under the `shell` widget. This shows up in the operating system toolbar and app-switcher (e.g. CMD+TAB) (and application window top-left corner in Windows)
@@ -1414,7 +1423,7 @@ Optionally, a shape keyword takes a block that can set any attributes from [org.
1414
1423
  Here is a list of supported attributes nestable within a block under shapes:
1415
1424
  - `advanced` enables advanced graphics subsystem (boolean value). Typically gets enabled automatically when setting alpha, antialias, patterns, interpolation, clipping. Rendering sometimes differs between advanced and non-advanced mode for basic graphics too, so you could enable manually if you prefer its look even for basic graphics.
1416
1425
  - `alpha` sets transparency (integer between `0` and `255`)
1417
- - `antialias` enables antialiasing (SWT style value of `:default`, `:off`, `:on` whereby `:default` applies OS default, which varies per OS)
1426
+ - `antialias` enables antialiasing (SWT style value of `:default` (or nil), `:off` (or false), `:on` (or true) whereby `:default` applies OS default, which varies per OS)
1418
1427
  - `background` sets fill color for fillable shapes (standard color symbol (e.g. `:red`), `rgb(red_integer, green_integer, blue_integer)` color, or Color/ColorProxy object directly)
1419
1428
  - `background_pattern` sets fill gradient/image pattern for fillable shape background (takes the same arguments as the SWT [Pattern](https://help.eclipse.org/2020-12/topic/org.eclipse.platform.doc.isv/reference/api/org/eclipse/swt/graphics/Pattern.html) class [e.g. `background_pattern 2.3, 4.2, 5.4, 7.2, :red, :blue`] / note: this feature isn't extensively tested yet)
1420
1429
  - `clipping` clips area of painting (numeric values for `(x, y, width, height)`)
@@ -1426,7 +1435,7 @@ Here is a list of supported attributes nestable within a block under shapes:
1426
1435
  - `line_cap` sets line cap (SWT style value of `:cap_flat`, `:cap_round`, or `:cap_square`)
1427
1436
  - `line_dash` line dash float values (automatically sets `line_style` to SWT style value of `:line_custom`)
1428
1437
  - `line_join` line join style (SWT style value of `:join_miter`, `:join_round`, or `:join_bevel`)
1429
- - `line_style` line join style (SWT style value of `:line_solid`, `:line_dash`, `:line_dot`, `:line_dashdot`, or `:line_dashdotdot`)
1438
+ - `line_style` line join style (SWT style value of `:solid`, `:dash`, `:dot`, `:dashdot`, `:dashdotdot`, or `:custom` while requiring `line_dash` attribute (or alternatively with `line_` prefix as per official SWT docs like `:line_solid` for `:solid`)
1430
1439
  - `line_width` line width in integer (used in draw operations)
1431
1440
  - `text_anti_alias` enables text antialiasing (SWT style value of `:default`, `:off`, `:on` whereby `:default` applies OS default, which varies per OS)
1432
1441
  - `transform` sets transform object using [Canvas Transform DSL](#canvas-transform-dsl) syntax
@@ -1475,7 +1484,7 @@ Screenshot:
1475
1484
 
1476
1485
  If you specify the x and y coordinates as `:default`, `nil`, or leave them out, they get calculated automatically by centering the shape within its parent `canvas`.
1477
1486
 
1478
- Note that you could shift a shape off its centered position within its parent `canvas` by using `x_delta` and `y_delta` instead of `x` and `y`
1487
+ Note that you could shift a shape off its centered position within its parent `canvas` by setting `x` to `[:default, x_delta]` and `y` to `[:default, y_delta]`
1479
1488
 
1480
1489
  The round and gradient options could be dropped since Glimmer DSL for SWT supports auto-inference of them based on shape parameters.
1481
1490
 
@@ -1632,9 +1641,11 @@ Shapes can be nested within each other. If you nest a shape within another, its
1632
1641
 
1633
1642
  As such, if you move the parent, it moves all its children with it.
1634
1643
 
1635
- If you specify the x and y coordinates as `:default`, `nil`, or leave them out, they get calculated automatically by centering the shape within its parent shape relatively.
1644
+ If you specify the `x` and `y` coordinates as `:default`, `nil`, or leave them out, they get calculated automatically by centering the shape within its parent shape relatively.
1636
1645
 
1637
- Note that you could shift a shape off its centered position within its parent shape by using `x_delta` and `y_delta` instead of `x` and `y`
1646
+ If you specify the `width` and `height` parameters as `:default`, `nil`, or leave them out, they get calculated automatically from the shape's nested children shapes (e.g calculating the dimensions of a text from its extent according to its font size).
1647
+
1648
+ Note that you could shift a shape off its centered position within its parent shape by setting `x` to `[:default, x_delta]` and `y` to `[:default, y_delta]`
1638
1649
 
1639
1650
  Check [Hello, Canvas!](GLIMMER_SAMPLES.md#hello-canvas) for an example that nests lines, points, a polyline, and an image within a drawn rectangle parent:
1640
1651
 
@@ -1766,8 +1777,24 @@ They are implemented with the help of the highly robust Java built-in shape geom
1766
1777
  - `Shape#contain?(x, y)` : indicates if shape contains x, y point
1767
1778
  - `Shape#include?(x, y)` : indicates if shape includes x, y point on the edge if drawn or inside if filled (include uses contain for filled shapes)
1768
1779
  - `Shape#move_by(x_delta, y_delta)` : moves shape object at x, y location
1780
+ - `Shape#dispose` : disposes of shape, removing it form its parent canvas, widget, or shape
1781
+ - `Shape#content {}` : reopens a shape to add more content inside it using the Glimmer GUI DSL (e.g. Canvas Shape DSL) just like `WidgetProxy#content {}`.
1769
1782
  - `Shape#size` : calculated size for shape bounding box (e.g. a polygon with an irregular shape will have its bounding box width and height calculated)
1770
1783
  - `Shape#bounds` : calculated bounds (x, y, width, height) for shape bounding box (e.g. a polygon with an irregular shape will have its bounding box top-left x, y, width and height calculated)
1784
+ - `Shape#width` : static (including `:default`) or derived width for shape (including irregular geometric shapes like Polygon)
1785
+ - `Shape#height` : static (including `:default`) or derived height for shape (including irregular geometric shapes like Polygon)
1786
+ - `Shape#default_width?` : whether `:default` or `[:default, delta]` is set for static width
1787
+ - `Shape#default_height?` : whether `:default` or `[:default, delta]` is set for static height
1788
+ - `Shape#calculated_width` : calculated width for shape when set to :default to indicate it is sized by its children (e.g. in the case of containing text with a specific font size not knowing its width/height dimensions in advance)
1789
+ - `Shape#calculated_height` : calculated height for shape when set to :default to indicate it is sized by its children (e.g. in the case of containing text with a specific font size not knowing its width/height dimensions in advance)
1790
+ - `Shape#x` : top-left corner x position, static or `:default` (could be relative if shape is nested within another shape)
1791
+ - `Shape#y` : top-left corner y position, static or `:default` (could be relative if shape is nested within another shape)
1792
+ - `Shape#absolute_x` : absolute top-left corner x position
1793
+ - `Shape#absolute_y` : absolute top-left corner y position
1794
+ - `Shape#default_x?` : whether x is specified via `:default` style to indicate centering within parent (or `[:default, offset]`)
1795
+ - `Shape#default_y?` : calculated top-left corner y position
1796
+ - `Shape#calculated_x` : calculated top-left corner x position when default/delta is set (i.e. centered within parent)
1797
+ - `Shape#calculated_y` : calculated top-left corner y position when default/delta is set (i.e. centered within parent)
1771
1798
 
1772
1799
  Check [Hello, Canvas!](GLIMMER_SAMPLES.md#hello-canvas) for an example.
1773
1800
 
@@ -1953,6 +1980,52 @@ shell {
1953
1980
 
1954
1981
  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.
1955
1982
 
1983
+ ### Canvas Path DSL
1984
+
1985
+ **(ALPHA FEATURE)**
1986
+
1987
+ Unlike common imperative GUI graphing toolkits, Glimmer enables declarative rendering of paths with the new Canvas Path DSL (Early Alpha) via the new `path { }` keyword and by nesting one of the following path segment keywords underneath:
1988
+ - `point(x1, y1)`: renders a Point (Dot) as part of a path.
1989
+ - `line(x1, y1, x2=nil, y2=nil)`: renders a Line as part of a path. If you drop x2, y2, it joins to the previous point automatically. You may repeat for a series of lines forming a curve.
1990
+ - `quad(x1, y1, x2, y2, x3=nil, y3=nil)`: renders a Quadratic Bezier Curve. If you drop x3 and y3, it joins to the previous point automatically.
1991
+ - `cubic(x1, y1, x2, y2, x3, y3, x4=nil, y4=nil)`: renders a Cubic Bezier Curve. If you drop x4 and y4, it joins to the previous point automatically.
1992
+
1993
+ Example:
1994
+
1995
+ ```ruby
1996
+ include Glimmer
1997
+
1998
+ shell {
1999
+ text 'Canvas Path Example'
2000
+ minimum_size 300, 300
2001
+
2002
+ canvas {
2003
+ path {
2004
+ foreground :black
2005
+ 250.times {|n|
2006
+ cubic(n + n%30, n+ n%50, 40, 40, 70, 70, n + 20 + n%30, n%30*-1 * n%50)
2007
+ }
2008
+ }
2009
+ }
2010
+
2011
+ }.open
2012
+ ```
2013
+
2014
+ ![Canvas Path Example](/images/glimmer-example-canvas-path.png)
2015
+
2016
+ Learn more at the [Hello, Canvas Path!](GLIMMER_SAMPLES.md#hello-canvas-path) and [Stock Ticker](GLIMMER_SAMPLES.md#stock-ticker) samples.
2017
+
2018
+ ![Stock Ticker](/images/glimmer-stock-ticker.gif)
2019
+
2020
+ #### Canvas Path API
2021
+
2022
+ Every path segment object (mixing in [`Glimmer::SWT::Custom::PathSegment`](/lib/glimmer/swt/custom/shape/path_segment.rb) like `path`, `point`, `line`, `quad`, and `cubic`) has the following API methods:
2023
+ - `#path`: indicates which path the segment is part of.
2024
+ - `#path_root`: indicates the root path the segment is part of.
2025
+ - `#dispose`: disposes a path segment from its path
2026
+ - `#content {}` : reopens a path to add more segments inside it using the Glimmer GUI DSL (e.g. Canvas Path DSL) just like `WidgetProxy#content {}`.
2027
+ - `#first_path_segment?`: indicates if the path segment is the first in the path
2028
+
1956
2029
  ### Canvas Transform DSL
1957
2030
 
1958
2031
  **(ALPHA FEATURE)**
@@ -12,6 +12,8 @@ glimmer package
12
12
 
13
13
  It works out of the box for any application scaffolded by [Glimmer Scaffolding](#scaffolding), generating all available packaging types on the current platform (e.g. `DMG`, `PKG`, `APP` on the Mac) and displaying a message indicating what pre-requisite setup tools are needed if not installed already (e.g. [Wix Toolset](https://wixtoolset.org/) to generate MSI files on Windows). If you install Wix, make sure it is on the system PATH by adding for example "C:\Program Files (x86)\WiX Toolset v3.11\bin" to the Windows Environment Variables.
14
14
 
15
+ (note: if you see this error on the Mac 'Error: Bundler "DMG Installer" (dmg) failed to produce a bundle.', ignore it as it should have produced a bundle anyways. It is a harmless issue in 3rd party dependency: javapackager.)
16
+
15
17
  You may choose to generate a specific type of packaging instead by addionally passing in the `[type]` option. For example, this generates an MSI setup file on Windows:
16
18
 
17
19
  ```
@@ -33,6 +33,8 @@
33
33
  - [Hello, Canvas!](#hello-canvas)
34
34
  - [Hello, Canvas Animation!](#hello-canvas-animation)
35
35
  - [Hello, Canvas Transform!](#hello-canvas-transform)
36
+ - [Hello, Canvas Path!](#hello-canvas-path)
37
+ - [Hello, Canvas Data Binding!](#hello-canvas-data-binding)
36
38
  - [Hello, Cursor!](#hello-cursor)
37
39
  - [Hello, Progress Bar!](#hello-progress-bar)
38
40
  - [Hello, Tree!](#hello-tree)
@@ -45,6 +47,7 @@
45
47
  - [Contact Manager](#contact-manager)
46
48
  - [Glimmer Tetris](#glimmer-tetris)
47
49
  - [Mandelbrot Fractal](#mandelbrot-fractal)
50
+ - [Stock Ticker](#stock-ticker)
48
51
  - [External Samples](#external-samples)
49
52
  - [Glimmer Calculator](#glimmer-calculator)
50
53
  - [Gladiator](#gladiator)
@@ -564,6 +567,10 @@ Hello, Canvas!
564
567
 
565
568
  ![Hello Canvas](/images/glimmer-hello-canvas.png)
566
569
 
570
+ Hello, Canvas! Moving Shapes and Nested Shapes via Drag'n'Drop
571
+
572
+ ![Hello Canvas Moving Shapes](/images/glimmer-hello-canvas-moving-shapes.gif)
573
+
567
574
  Hello, Canvas! with Moved Shapes (via Drag'n'Drop)
568
575
 
569
576
  ![Hello Canvas Moved Shapes](/images/glimmer-hello-canvas-moved-shapes.png)
@@ -612,6 +619,32 @@ Hello, Canvas Transform!
612
619
 
613
620
  ![Hello Canvas Transform](/images/glimmer-hello-canvas-transform.png)
614
621
 
622
+ #### Hello, Canvas Path!
623
+
624
+ This sample demonstrates the use of the `path`, `quad`, `cubic`, `line`, and `point` keywords as part of the [Canvas Path DSL](/docs/reference/GLIMMER_GUI_DSL_SYNTAX.md#canvas-path-dsl) within the [Canvas Shape DSL](/docs/reference/GLIMMER_GUI_DSL_SYNTAX.md#canvas-shape-dsl).
625
+
626
+ Code:
627
+
628
+ [samples/hello/hello_canvas_path.rb](/samples/hello/hello_canvas_path.rb)
629
+
630
+ Hello, Canvas Path!
631
+
632
+ ![Hello Canvas Path](/images/glimmer-hello-canvas-path.png)
633
+
634
+ #### Hello, Canvas Data Binding!
635
+
636
+ This sample demonstrates Canvas Shape DSL data-binding.
637
+
638
+ Code:
639
+
640
+ [samples/hello/hello_canvas_data_binding.rb](/samples/hello/hello_canvas_data_binding.rb)
641
+
642
+ Hello, Canvas Data Binding!
643
+
644
+ ![Hello Canvas Data Binding](/images/glimmer-hello-canvas-data-binding.png)
645
+
646
+ ![Hello Canvas Data Binding Line Changed](/images/glimmer-hello-canvas-data-binding-line-changed.png)
647
+
615
648
  #### Hello, Cursor!
616
649
 
617
650
  This sample demonstrates the use of the `cursor` property keyword to change the mouse cursor.
@@ -808,6 +841,16 @@ Code:
808
841
 
809
842
  ![Mandelbrot Fractal Help Menu](/images/glimmer-mandelbrot-menu-help.png)
810
843
 
844
+ #### Stock Ticker
845
+
846
+ This sample demonstrates a Stock Ticker that generates random stock price data for 4 different stocks and provides 4 different tab views of the graphed data using the [Canvas Path DSL](/docs/reference/GLIMMER_GUI_DSL_SYNTAX.md#canvas-path-dsl). It leverages a thread that runs in the background and ticks the stocks to generate random new stock prices before amending the graphed paths with them.
847
+
848
+ Code:
849
+
850
+ [samples/elaborate/stock_ticker.rb](/samples/elaborate/stock_ticker.rb)
851
+
852
+ ![Stock Ticker](/images/glimmer-stock-ticker.gif)
853
+
811
854
  ### External Samples
812
855
 
813
856
  #### Glimmer Calculator
@@ -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.5.4 ruby lib
5
+ # stub: glimmer-dsl-swt 4.18.6.3 ruby lib
6
6
 
7
7
  Gem::Specification.new do |s|
8
8
  s.name = "glimmer-dsl-swt".freeze
9
- s.version = "4.18.5.4"
9
+ s.version = "4.18.6.3"
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-26"
14
+ s.date = "2021-03-03"
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]
@@ -115,13 +115,17 @@ Gem::Specification.new do |s|
115
115
  "lib/glimmer/swt/custom/radio_group.rb",
116
116
  "lib/glimmer/swt/custom/shape.rb",
117
117
  "lib/glimmer/swt/custom/shape/arc.rb",
118
+ "lib/glimmer/swt/custom/shape/cubic.rb",
118
119
  "lib/glimmer/swt/custom/shape/focus.rb",
119
120
  "lib/glimmer/swt/custom/shape/image.rb",
120
121
  "lib/glimmer/swt/custom/shape/line.rb",
121
122
  "lib/glimmer/swt/custom/shape/oval.rb",
123
+ "lib/glimmer/swt/custom/shape/path.rb",
124
+ "lib/glimmer/swt/custom/shape/path_segment.rb",
122
125
  "lib/glimmer/swt/custom/shape/point.rb",
123
126
  "lib/glimmer/swt/custom/shape/polygon.rb",
124
127
  "lib/glimmer/swt/custom/shape/polyline.rb",
128
+ "lib/glimmer/swt/custom/shape/quad.rb",
125
129
  "lib/glimmer/swt/custom/shape/rectangle.rb",
126
130
  "lib/glimmer/swt/custom/shape/text.rb",
127
131
  "lib/glimmer/swt/date_time_proxy.rb",
@@ -144,6 +148,7 @@ Gem::Specification.new do |s|
144
148
  "lib/glimmer/swt/style_constantizable.rb",
145
149
  "lib/glimmer/swt/styled_text_proxy.rb",
146
150
  "lib/glimmer/swt/swt_proxy.rb",
151
+ "lib/glimmer/swt/tab_folder_proxy.rb",
147
152
  "lib/glimmer/swt/tab_item_proxy.rb",
148
153
  "lib/glimmer/swt/table_column_proxy.rb",
149
154
  "lib/glimmer/swt/table_proxy.rb",
@@ -162,6 +167,7 @@ Gem::Specification.new do |s|
162
167
  "samples/elaborate/login.rb",
163
168
  "samples/elaborate/mandelbrot_fractal.rb",
164
169
  "samples/elaborate/meta_sample.rb",
170
+ "samples/elaborate/stock_ticker.rb",
165
171
  "samples/elaborate/tetris.rb",
166
172
  "samples/elaborate/tetris/model/block.rb",
167
173
  "samples/elaborate/tetris/model/game.rb",
@@ -180,6 +186,8 @@ Gem::Specification.new do |s|
180
186
  "samples/hello/hello_button.rb",
181
187
  "samples/hello/hello_canvas.rb",
182
188
  "samples/hello/hello_canvas_animation.rb",
189
+ "samples/hello/hello_canvas_data_binding.rb",
190
+ "samples/hello/hello_canvas_path.rb",
183
191
  "samples/hello/hello_canvas_transform.rb",
184
192
  "samples/hello/hello_checkbox.rb",
185
193
  "samples/hello/hello_checkbox_group.rb",
@@ -69,3 +69,4 @@ require 'glimmer/swt/table_column_proxy'
69
69
  require 'glimmer/swt/sash_form_proxy'
70
70
  require 'glimmer/swt/styled_text_proxy'
71
71
  require 'glimmer/swt/date_time_proxy'
72
+ require 'glimmer/swt/tab_folder_proxy'
@@ -99,7 +99,7 @@ module Glimmer
99
99
  def ensure_arg_values_within_valid_bounds
100
100
  if @args.to_a.size >= 3
101
101
  @args = @args.map do |value|
102
- [[value, 255].min, 0].max
102
+ [[value.to_f, 255].min, 0].max
103
103
  end
104
104
  end
105
105
  end
@@ -26,13 +26,40 @@ require 'glimmer/swt/color_proxy'
26
26
  require 'glimmer/swt/font_proxy'
27
27
  require 'glimmer/swt/transform_proxy'
28
28
 
29
+ class Java::OrgEclipseSwtGraphics::GC
30
+ def setLineDashOffset(value)
31
+ lineMiterLimit = getLineAttributes&.miterLimit || 999_999
32
+ setLineAttributes(Java::OrgEclipseSwtGraphics::LineAttributes.new(getLineWidth, getLineCap, getLineJoin, getLineStyle, getLineDash.map(&:to_f).to_java(:float), value, lineMiterLimit))
33
+ end
34
+ alias set_line_dash_offset setLineDashOffset
35
+ alias line_dash_offset= setLineDashOffset
36
+
37
+ def getLineDashOffset
38
+ getLineAttributes&.dashOffset
39
+ end
40
+ alias get_line_dash_offset getLineDashOffset
41
+ alias line_dash_offset getLineDashOffset
42
+
43
+ def setLineMiterLimit(value)
44
+ lineDashOffset = getLineAttributes&.dashOffset || 0
45
+ setLineAttributes(Java::OrgEclipseSwtGraphics::LineAttributes.new(getLineWidth, getLineCap, getLineJoin, getLineStyle, getLineDash.map(&:to_f).to_java(:float), lineDashOffset, value))
46
+ end
47
+ alias set_line_miter_limit setLineMiterLimit
48
+ alias line_miter_limit= setLineMiterLimit
49
+
50
+ def getLineMiterLimit
51
+ getLineAttributes&.miterLimit
52
+ end
53
+ alias get_line_miter_limit getLineMiterLimit
54
+ alias line_miter_limit getLineMiterLimit
55
+ end
56
+
29
57
  module Glimmer
30
58
  module SWT
31
59
  module Custom
32
60
  # Represents a shape (graphics) to be drawn on a control/widget/canvas/display
33
61
  # That is because Shape is drawn on a parent as graphics and doesn't have an SWT widget for itself
34
62
  class Shape
35
- include Packages
36
63
  include Properties
37
64
 
38
65
  class << self
@@ -46,7 +73,8 @@ module Glimmer
46
73
  end
47
74
 
48
75
  def valid?(parent, keyword, *args, &block)
49
- gc_instance_methods.include?(method_name(keyword, arg_options(args)))
76
+ gc_instance_methods.include?(method_name(keyword, arg_options(args))) ||
77
+ constants.include?(keyword.to_s.camelcase(:upper).to_sym)
50
78
  end
51
79
 
52
80
  def gc_instance_methods
@@ -119,7 +147,7 @@ module Glimmer
119
147
 
120
148
  def add_shape(shape)
121
149
  @shapes << shape
122
- calculated_args_changed_for_default_size!
150
+ calculated_args_changed_for_defaults!
123
151
  end
124
152
 
125
153
  def draw?
@@ -145,6 +173,11 @@ module Glimmer
145
173
  org.eclipse.swt.graphics.Rectangle.new(absolute_x, absolute_y, calculated_width, calculated_height)
146
174
  end
147
175
 
176
+ # The bounding box top-left x and y
177
+ def location
178
+ org.eclipse.swt.graphics.Point.new(bounds.x, bounds.y)
179
+ end
180
+
148
181
  # The bounding box width and height (as a Point object with x being width and y being height)
149
182
  def size
150
183
  org.eclipse.swt.graphics.Point.new(calculated_width, calculated_height)
@@ -169,6 +202,11 @@ module Glimmer
169
202
  # assume a rectangular shape by default
170
203
  contain?(x, y)
171
204
  end
205
+
206
+ # Indicates if a shape's x, y, width, height differ from its bounds calculation (e.g. arc / polygon)
207
+ def irregular?
208
+ false
209
+ end
172
210
 
173
211
  # moves by x delta and y delta. Subclasses must implement
174
212
  # provdies a default implementation that assumes moving x and y is sufficient by default (not for polygons though, which must override)
@@ -187,6 +225,13 @@ module Glimmer
187
225
  end
188
226
  end
189
227
 
228
+ def content(&block)
229
+ Glimmer::SWT::DisplayProxy.instance.auto_exec do
230
+ Glimmer::DSL::Engine.add_content(self, Glimmer::DSL::SWT::ShapeExpression.new, &block)
231
+ calculated_args_changed!(children: false)
232
+ end
233
+ end
234
+
190
235
  def has_some_background?
191
236
  @properties.keys.map(&:to_s).include?('background') || @properties.keys.map(&:to_s).include?('background_pattern')
192
237
  end
@@ -196,8 +241,8 @@ module Glimmer
196
241
  end
197
242
 
198
243
  def post_add_content
199
- unless @content_added
200
- amend_method_name_options_based_on_properties!
244
+ amend_method_name_options_based_on_properties!
245
+ if !@content_added || @method_name != @original_method_name
201
246
  @drawable.setup_shape_painting unless @drawable.is_a?(ImageProxy)
202
247
  @content_added = true
203
248
  end
@@ -206,16 +251,34 @@ module Glimmer
206
251
  def apply_property_arg_conversions(method_name, property, args)
207
252
  args = args.dup
208
253
  the_java_method = org.eclipse.swt.graphics.GC.java_class.declared_instance_methods.detect {|m| m.name == method_name}
209
- if the_java_method.parameter_types.first == Color.java_class && args.first.is_a?(RGB)
254
+ return args if the_java_method.nil?
255
+ if the_java_method.parameter_types.first == org.eclipse.swt.graphics.Color.java_class && args.first.is_a?(org.eclipse.swt.graphics.RGB)
210
256
  args[0] = [args[0].red, args[0].green, args[0].blue]
211
257
  end
212
258
  if ['setBackground', 'setForeground'].include?(method_name.to_s) && args.first.is_a?(Array)
213
259
  args[0] = ColorProxy.new(args[0])
214
260
  end
261
+ if method_name.to_s == 'setLineDash' && args.size > 1
262
+ args[0] = args.dup
263
+ args[1..-1] = []
264
+ end
265
+ if method_name.to_s == 'setAntialias' && [nil, true, false].include?(args.first)
266
+ args[0] = case args.first
267
+ when true
268
+ args[0] = :on
269
+ when false
270
+ args[0] = :off
271
+ when nil
272
+ args[0] = :default
273
+ end
274
+ end
215
275
  if args.first.is_a?(Symbol) || args.first.is_a?(::String)
216
- if the_java_method.parameter_types.first == Color.java_class
276
+ if the_java_method.parameter_types.first == org.eclipse.swt.graphics.Color.java_class
217
277
  args[0] = ColorProxy.new(args[0])
218
278
  end
279
+ if method_name.to_s == 'setLineStyle'
280
+ args[0] = "line_#{args[0]}" if !args[0].to_s.downcase.start_with?('line_')
281
+ end
219
282
  if the_java_method.parameter_types.first == Java::int.java_class
220
283
  args[0] = SWTProxy.constant(args[0])
221
284
  end
@@ -223,7 +286,7 @@ module Glimmer
223
286
  if args.first.is_a?(ColorProxy)
224
287
  args[0] = args[0].swt_color
225
288
  end
226
- if (args.first.is_a?(Hash) || args.first.is_a?(FontData)) && the_java_method.parameter_types.first == Font.java_class
289
+ if (args.first.is_a?(Hash) || args.first.is_a?(org.eclipse.swt.graphics.FontData)) && the_java_method.parameter_types.first == org.eclipse.swt.graphics.Font.java_class
227
290
  args[0] = FontProxy.new(args[0])
228
291
  end
229
292
  if args.first.is_a?(FontProxy)
@@ -236,7 +299,7 @@ module Glimmer
236
299
  @drawable.requires_shape_disposal = true
237
300
  args = args.first if args.first.is_a?(Array)
238
301
  args.each_with_index do |arg, i|
239
- arg = ColorProxy.new(arg.red, arg.green, arg.blue) if arg.is_a?(RGB)
302
+ arg = ColorProxy.new(arg.red, arg.green, arg.blue) if arg.is_a?(org.eclipse.swt.graphics.RGB)
240
303
  arg = ColorProxy.new(arg) if arg.is_a?(Symbol) || arg.is_a?(::String)
241
304
  arg = arg.swt_color if arg.is_a?(ColorProxy)
242
305
  args[i] = arg
@@ -315,6 +378,7 @@ module Glimmer
315
378
  end
316
379
 
317
380
  def amend_method_name_options_based_on_properties!
381
+ @original_method_name = @method_name
318
382
  return if @name == 'point'
319
383
  if @name != 'text' && @name != 'string' && has_some_background? && !has_some_foreground?
320
384
  @options[:fill] = true
@@ -382,10 +446,18 @@ module Glimmer
382
446
  end
383
447
  if @content_added && perform_redraw && !drawable.is_disposed
384
448
  @calculated_paint_args = false
449
+ if is_a?(PathSegment)
450
+ root_path&.calculated_path_args = @calculated_path_args = false
451
+ calculated_args_changed!
452
+ root_path&.calculated_args_changed!
453
+ end
385
454
  attribute_name = ruby_attribute_getter(attribute_name)
386
- @calculated_args = nil if location_parameter_names.map(&:to_s).include?(attribute_name)
455
+ if location_parameter_names.map(&:to_s).include?(attribute_name)
456
+ @calculated_args = nil
457
+ parent.calculated_args_changed_for_defaults! if parent.is_a?(Shape)
458
+ end
387
459
  if ['width', 'height'].include?(attribute_name)
388
- calculated_args_changed_for_default_size!
460
+ calculated_args_changed_for_defaults!
389
461
  end
390
462
  # TODO consider redrawing an image proxy's gc in the future
391
463
  drawable.redraw unless drawable.is_a?(ImageProxy)
@@ -444,7 +516,8 @@ module Glimmer
444
516
  pattern_args(type: 'foreground')
445
517
  end
446
518
 
447
- def dispose(dispose_images: true, dispose_patterns: true)
519
+ def dispose(dispose_images: true, dispose_patterns: true, redraw: true)
520
+ shapes.each { |shape| shape.is_a?(Shape::Path) && shape.dispose }
448
521
  if dispose_patterns
449
522
  @background_pattern&.dispose
450
523
  @background_pattern = nil
@@ -456,11 +529,14 @@ module Glimmer
456
529
  @image = nil
457
530
  end
458
531
  @parent.shapes.delete(self)
532
+ drawable.redraw if redraw && !drawable.is_a?(ImageProxy)
459
533
  end
460
-
534
+
461
535
  def paint(paint_event)
536
+ # pre-paint children an extra-time first when default width/height need to be calculated for defaults
462
537
  paint_children(paint_event) if default_width? || default_height?
463
538
  paint_self(paint_event)
539
+ # re-paint children from scratch in the special case of pre-calculating parent width/height to re-center within new parent dimensions
464
540
  shapes.each(&:calculated_args_changed!) if default_width? || default_height?
465
541
  paint_children(paint_event)
466
542
  rescue => e
@@ -471,9 +547,10 @@ module Glimmer
471
547
  def paint_self(paint_event)
472
548
  @painting = true
473
549
  calculate_paint_args!
550
+ @original_properties_backup = {}
474
551
  @properties.each do |property, args|
475
552
  method_name = attribute_setter(property)
476
- # TODO consider optimization of not setting a background/foreground/font if it didn't change from last shape
553
+ @original_properties_backup[method_name] = paint_event.gc.send(method_name.sub('set', 'get')) rescue nil
477
554
  paint_event.gc.send(method_name, *args)
478
555
  if property == 'transform' && args.first.is_a?(TransformProxy)
479
556
  args.first.swt_transform.dispose
@@ -485,9 +562,12 @@ module Glimmer
485
562
  end
486
563
  # paint unless parent's calculated args are not calculated yet, meaning it is about to get painted and trigger a paint on this child anyways
487
564
  paint_event.gc.send(@method_name, *@calculated_args) unless parent.is_a?(Shape) && !parent.calculated_args?
565
+ @original_properties_backup.each do |method_name, value|
566
+ paint_event.gc.send(method_name, value)
567
+ end
488
568
  @painting = false
489
569
  rescue => e
490
- Glimmer::Config.logger.error {"Error encountered in painting shape (#{self.inspect}) with calculated args (#{@calculated_args}) and args (#{@args})"}
570
+ Glimmer::Config.logger.error {"Error encountered in painting shape (#{self.inspect}) with method (#{@method_name}) calculated args (#{@calculated_args}) and args (#{@args})"}
491
571
  Glimmer::Config.logger.error {e.full_message}
492
572
  ensure
493
573
  @painting = false
@@ -509,7 +589,8 @@ module Glimmer
509
589
  self.extent = paint_event.gc.send("#{@name}Extent", *extent_args)
510
590
  end
511
591
  if !@extent.nil? && (old_extent&.x != @extent&.x || old_extent&.y != @extent&.y)
512
- parent.calculated_args_changed_for_default_size! if parent.is_a?(Shape)
592
+ calculated_args_changed!
593
+ parent.calculated_args_changed_for_defaults! if parent.is_a?(Shape)
513
594
  end
514
595
  end
515
596
 
@@ -527,16 +608,18 @@ module Glimmer
527
608
  (parent.is_a?(Shape) && (parent.absolute_x != @parent_absolute_x || parent.absolute_y != @parent_absolute_y))
528
609
  end
529
610
 
530
- def calculated_args_changed!
611
+ def calculated_args_changed!(children: true)
531
612
  # TODO add a children: true option to enable setting to false to avoid recalculating children args
532
613
  @calculated_args = nil
533
- shapes.each(&:calculated_args_changed!)
614
+ shapes.each(&:calculated_args_changed!) if children
534
615
  end
535
616
 
536
- def calculated_args_changed_for_default_size!
537
- @calculated_args = nil if default_width? || default_height?
538
- if parent.is_a?(Shape)
539
- parent.calculated_args_changed_for_default_size!
617
+ def calculated_args_changed_for_defaults!
618
+ has_default_dimensions = default_width? || default_height?
619
+ parent_calculated_args_changed_for_defaults = has_default_dimensions
620
+ @calculated_args = nil if default_x? || default_y? || has_default_dimensions
621
+ if has_default_dimensions && parent.is_a?(Shape)
622
+ parent.calculated_args_changed_for_defaults!
540
623
  elsif @content_added && !drawable.is_disposed
541
624
  # TODO consider optimizing in the future if needed by ensuring one redraw for all parents in the hierarchy at the end instead of doing one per parent that needs it
542
625
  drawable.redraw if !@painting && !drawable.is_a?(ImageProxy)
@@ -559,6 +642,10 @@ module Glimmer
559
642
  original_y = nil
560
643
  original_width = nil
561
644
  original_height = nil
645
+ if parent.is_a?(Shape)
646
+ @parent_absolute_x = parent.absolute_x
647
+ @parent_absolute_y = parent.absolute_y
648
+ end
562
649
  if default_width?
563
650
  original_width = width
564
651
  self.width = default_width + default_width_delta
@@ -576,11 +663,9 @@ module Glimmer
576
663
  self.y = default_y + default_y_delta
577
664
  end
578
665
  if parent.is_a?(Shape)
579
- @parent_absolute_x = parent.absolute_x
580
- @parent_absolute_y = parent.absolute_y
581
- move_by(parent.absolute_x, parent.absolute_y)
666
+ move_by(@parent_absolute_x, @parent_absolute_y)
582
667
  result_args = @args.clone
583
- move_by(-1*parent.absolute_x, -1*parent.absolute_y)
668
+ move_by(-1*@parent_absolute_x, -1*@parent_absolute_y)
584
669
  else
585
670
  result_args = @args.clone
586
671
  end
@@ -624,44 +709,42 @@ module Glimmer
624
709
 
625
710
  def default_x
626
711
  result = ((parent.size.x - size.x) / 2)
627
- result += parent.bounds.x - parent.absolute_x if parent.is_a?(Shape)
712
+ result += parent.bounds.x - parent.absolute_x if parent.is_a?(Shape) && parent.irregular?
628
713
  result
629
714
  end
630
715
 
631
716
  def default_y
632
717
  result = ((parent.size.y - size.y) / 2)
633
- result += parent.bounds.y - parent.absolute_y if parent.is_a?(Shape)
718
+ result += parent.bounds.y - parent.absolute_y if parent.is_a?(Shape) && parent.irregular?
634
719
  result
635
720
  end
636
721
 
637
722
  def default_width
638
- x_start_end_pairs = shapes.map do |shape|
639
- shape_x = shape.default_x? ? 0 : shape.x.to_f
723
+ # TODO consider caching
724
+ x_ends = shapes.map do |shape|
640
725
  shape_width = shape.calculated_width.to_f
641
- [shape_x, shape_x + shape_width]
726
+ shape_x = shape.default_x? ? 0 : shape.x.to_f
727
+ shape_x + shape_width
642
728
  end
643
- min_x = x_start_end_pairs.map(&:first).min.to_f
644
- max_x = x_start_end_pairs.map(&:last).max.to_f
645
- max_x - min_x
729
+ x_ends.max.to_f
646
730
  end
647
731
 
648
732
  def default_height
649
- y_start_end_pairs = shapes.map do |shape|
650
- shape_y = shape.default_y? ? 0 : shape.y.to_f
733
+ # TODO consider caching
734
+ y_ends = shapes.map do |shape|
651
735
  shape_height = shape.calculated_height.to_f
652
- [shape_y, shape_y + shape_height]
736
+ shape_y = shape.default_y? ? 0 : shape.y.to_f
737
+ shape_y + shape_height
653
738
  end
654
- min_y = y_start_end_pairs.map(&:first).min.to_f
655
- max_y = y_start_end_pairs.map(&:last).max.to_f
656
- max_y - min_y
739
+ y_ends.max.to_f
657
740
  end
658
741
 
659
742
  def calculated_width
660
- default_width? ? default_width : width
743
+ default_width? ? (default_width + default_width_delta) : width
661
744
  end
662
745
 
663
746
  def calculated_height
664
- default_height? ? default_height : height
747
+ default_height? ? (default_height + default_height_delta) : height
665
748
  end
666
749
 
667
750
  def default_x_delta
@@ -746,7 +829,7 @@ module Glimmer
746
829
  if @name == 'pixel'
747
830
  @name = 'point'
748
831
  # optimized performance calculation for pixel points
749
- if !@properties[:foreground].is_a?(Color)
832
+ if !@properties[:foreground].is_a?(org.eclipse.swt.graphics.Color)
750
833
  if @properties[:foreground].is_a?(Array)
751
834
  @properties[:foreground] = ColorProxy.new(@properties[:foreground], ensure_bounds: false)
752
835
  end
@@ -763,7 +846,7 @@ module Glimmer
763
846
  # TODO regarding alpha, make sure to reset it to parent stored alpha once we allow setting shape properties on parents directly without shapes
764
847
  @properties['alpha'] ||= [255]
765
848
  @properties['font'] = [@drawable.font] if @drawable.respond_to?(:font) && draw? && !@properties.keys.map(&:to_s).include?('font')
766
- # TODO regarding transform, make sure to reset it to parent stored alpha once we allow setting shape properties on parents directly without shapes
849
+ # TODO regarding transform, make sure to reset it to parent stored transform once we allow setting shape properties on parents directly without shapes
767
850
  # Also do that with all future-added properties
768
851
  @properties['transform'] = [nil] if @drawable.respond_to?(:transform) && !@properties.keys.map(&:to_s).include?('transform')
769
852
  @properties.each do |property, args|