glimmer-dsl-swt 4.18.6.3 → 4.18.7.0

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: 9db83aea9f51b0f0f2b7dfcb78a5180f00a5c7e7ebe7852f404c879c6417fa66
4
- data.tar.gz: af21fa66dff5e22c878fe564dcdeb34c6d83a9b8afd8eb66e1c827c047a8d28c
3
+ metadata.gz: 3b4bc038d1fcf459041884946826daa84949318cd2d588f30bbc91ce9cc343f3
4
+ data.tar.gz: 143c076d20310e24ca2a6bd5db70f7bd87bd7c7b171a501c23874cdfd1a989f8
5
5
  SHA512:
6
- metadata.gz: 80c988832fe70bf8505aca306b88d34e35957e8a8a936c9ef874ad35566c71e98e766cd7b732dd73bf2e3c088a52d1480fabe20f77fc557fcc47c9f4ead8d817
7
- data.tar.gz: 2b2a8f85e7ee15dc23f772a92c4ca4f9acad738ee22efc2a36dd45aab73e6f18e2e4f24b1efe1f7f68fa558ce7b2dc42f3a92c427c2c5074dab9a09c5979c0ec
6
+ metadata.gz: ae508739a7a491f83853d67867b0c1600323216615909a1cca6aac4b2f373d5d74cad21c6dd08275ed83bc4e537e4b13ef357fdda436cbc6966dec821a3aade7
7
+ data.tar.gz: 7c8110b246fbc0ee40d99fd930be19d782e75846ada53ad2fe09c742cec5bf2de36f59ccbabd4600d81bc6ac4b7183fae397c6590bce2fd8377d7ca38c89e3f1
data/CHANGELOG.md CHANGED
@@ -1,5 +1,14 @@
1
1
  # Change Log
2
2
 
3
+ ### 4.18.7.0
4
+
5
+ - Support direct use of the `shape` keyword as a shape composite that could contain other shapes and shares common attributes (e.g. background color) with all of them
6
+ - Hello, Shape! Sample (implements a method-based custom shape containing other nested shapes)
7
+ - Support custom shapes via including the Glimmer::UI::CustomShape module to add new shape keywords to the Glimmer GUI DSL / Canvas Shape DSL, representing shapes composed of a group of nested shapes (e.g. `car` shape representing a group of nested `polygon` shapes)
8
+ - Hello, Custom Shape! Sample (redoes Hello, Shape! with the use of a class-based custom shape)
9
+ - Support :max value for Canvas Shape DSL width and height, meaning fill up parent (useful for using rectangles as borders)
10
+ - Upgrade to glimmer v1.2.0
11
+
3
12
  ### 4.18.6.3
4
13
 
5
14
  - Support `Glimmer::SWT::Custom::Shape::PathSegment#dispose` method
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.6.3
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.7.0
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)
@@ -13,7 +13,7 @@
13
13
  [<img src="https://covers.oreillystatic.com/images/9780596519650/lrg.jpg" width=105 /><br />
14
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)
15
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.
16
+ [Glimmer DSL for SWT](https://rubygems.org/gems/glimmer-dsl-swt) 4.18.7.0 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
17
 
18
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
19
 
@@ -340,7 +340,7 @@ jgem install glimmer-dsl-swt
340
340
 
341
341
  Or this command if you want a specific version:
342
342
  ```
343
- jgem install glimmer-dsl-swt -v 4.18.6.3
343
+ jgem install glimmer-dsl-swt -v 4.18.7.0
344
344
  ```
345
345
 
346
346
  `jgem` is JRuby's version of `gem` command.
@@ -358,7 +358,7 @@ Note: if you're using activerecord or activesupport, keep in mind that Glimmer u
358
358
 
359
359
  Add the following to `Gemfile`:
360
360
  ```
361
- gem 'glimmer-dsl-swt', '~> 4.18.6.3'
361
+ gem 'glimmer-dsl-swt', '~> 4.18.7.0'
362
362
  ```
363
363
 
364
364
  And, then run:
data/VERSION CHANGED
@@ -1 +1 @@
1
- 4.18.6.3
1
+ 4.18.7.0
@@ -39,6 +39,7 @@ This guide should help you get started with Glimmer DSL for SWT. For more advanc
39
39
  - [Shapes inside a Shape](#shapes-inside-a-shape)
40
40
  - [Shapes inside a Widget](#shapes-inside-a-widget)
41
41
  - [Shapes inside an Image](#shapes-inside-an-image)
42
+ - [Custom Shapes](#custom-shapes)
42
43
  - [Canvas Shape API](#canvas-shape-api)
43
44
  - [Pixel Graphics](#pixel-graphics)
44
45
  - [Canvas Path DSL](#canvas-path-dsl)
@@ -1767,6 +1768,21 @@ shell {
1767
1768
 
1768
1769
  ![Image Shape DSL](/images/glimmer-example-image-shape-dsl-app-switcher-icon.png)
1769
1770
 
1771
+ #### Custom Shapes
1772
+
1773
+ Glimmer enables defining custom shape keywords, which represent shapes made up of other nested shapes.
1774
+
1775
+ Custom shapes expand a software engineer's Glimmer GUI DSL vocabulary in their app development to be able to represent
1776
+ higher visual concepts like vehicles, scenes, and characters with a single keyword (e.g. `car`, `beach`, `player`),
1777
+ which embody and abstract all the details relating to the visual concept. This enables orders of magnitudes in increased
1778
+ productivity and readability/maintainability as a result.
1779
+
1780
+ Just like [custom widgets](#custom-widgets), custom shapes can be defined in one of two ways:
1781
+ - method-based custom shapes: Use the `shape` keyword as a parent to represent a shape composite (similar to widget composite) and include other shapes like rectangles, polygons, and lines within.
1782
+ - class-based custom shapes: Include the `Glimmer::UI::CustomShape` supermodule and define the `options`, `body {}` block, and `before_body/after_body` hooks (similar to how it is down with [custom widgets](#custom-widgets))
1783
+
1784
+ Check out [Hello, Shape!](/docs/reference/GLIMMER_SAMPLES.md#hello-shape) and [Hello, Custom Shape!](/docs/reference/GLIMMER_SAMPLES.md#hello-custom-shape) for examples of both approaches.
1785
+
1770
1786
  #### Canvas Shape API
1771
1787
 
1772
1788
  These Canvas Shape API methods help with manipulating shapes upon user interaction, such as mouse clicking a specific shape.
@@ -1798,6 +1814,7 @@ They are implemented with the help of the highly robust Java built-in shape geom
1798
1814
 
1799
1815
  Check [Hello, Canvas!](GLIMMER_SAMPLES.md#hello-canvas) for an example.
1800
1816
 
1817
+
1801
1818
  #### Pixel Graphics
1802
1819
 
1803
1820
  **(Early Alpha Feature)**
@@ -40,6 +40,8 @@
40
40
  - [Hello, Tree!](#hello-tree)
41
41
  - [Hello, Color Dialog!](#hello-color-dialog)
42
42
  - [Hello, Font Dialog!](#hello-font-dialog)
43
+ - [Hello, Shape!](#hello-shape)
44
+ - [Hello, Custom Shape!](#hello-custom-shape)
43
45
  - [Elaborate Samples](#elaborate-samples)
44
46
  - [User Profile](#user-profile)
45
47
  - [Login](#login)
@@ -717,6 +719,32 @@ Hello, Font Dialog!
717
719
 
718
720
  ![Hello Font Dialog Font Changed](/images/glimmer-hello-font-dialog-font-changed.png)
719
721
 
722
+ #### Hello, Shape!
723
+
724
+ This sample demonstrates the use of the `shape` keyword, which represents shape composites that contain other nested shapes.
725
+
726
+ Code:
727
+
728
+ [samples/hello/hello_shape.rb](/samples/hello/hello_shape.rb)
729
+
730
+ Hello, Shape!
731
+
732
+ ![Hello Shape](/images/glimmer-hello-shape.png)
733
+
734
+ #### Hello, Custom Shape!
735
+
736
+ This sample demonstrates the use of the `Glimmer::UI::CustomShape` module, which is used to author new custom shape keywords.
737
+ It reimplements Hello, Shape! with a class-based custom shape instead of a method-based custom shape.
738
+ Just provides another option that is useful when defining more elaborate shapes to separate them from the main app code.
739
+
740
+ Code:
741
+
742
+ [samples/hello/hello_custom_shape.rb](/samples/hello/hello_custom_shape.rb)
743
+
744
+ Hello, Custom Shape!
745
+
746
+ ![Hello Custom Shape](/images/glimmer-hello-custom-shape.png)
747
+
720
748
  ### Elaborate Samples
721
749
 
722
750
  For more elaborate samples, check the following:
@@ -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.6.3 ruby lib
5
+ # stub: glimmer-dsl-swt 4.18.7.0 ruby lib
6
6
 
7
7
  Gem::Specification.new do |s|
8
8
  s.name = "glimmer-dsl-swt".freeze
9
- s.version = "4.18.6.3"
9
+ s.version = "4.18.7.0"
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-03-03"
14
+ s.date = "2021-03-04"
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]
@@ -66,6 +66,7 @@ Gem::Specification.new do |s|
66
66
  "lib/glimmer/dsl/swt/column_properties_expression.rb",
67
67
  "lib/glimmer/dsl/swt/combo_selection_data_binding_expression.rb",
68
68
  "lib/glimmer/dsl/swt/cursor_expression.rb",
69
+ "lib/glimmer/dsl/swt/custom_shape_expression.rb",
69
70
  "lib/glimmer/dsl/swt/custom_widget_expression.rb",
70
71
  "lib/glimmer/dsl/swt/data_binding_expression.rb",
71
72
  "lib/glimmer/dsl/swt/dialog_expression.rb",
@@ -157,6 +158,7 @@ Gem::Specification.new do |s|
157
158
  "lib/glimmer/swt/widget_listener_proxy.rb",
158
159
  "lib/glimmer/swt/widget_proxy.rb",
159
160
  "lib/glimmer/ui.rb",
161
+ "lib/glimmer/ui/custom_shape.rb",
160
162
  "lib/glimmer/ui/custom_shell.rb",
161
163
  "lib/glimmer/ui/custom_widget.rb",
162
164
  "lib/glimmer/util/proc_tracker.rb",
@@ -197,6 +199,7 @@ Gem::Specification.new do |s|
197
199
  "samples/hello/hello_computed.rb",
198
200
  "samples/hello/hello_computed/contact.rb",
199
201
  "samples/hello/hello_cursor.rb",
202
+ "samples/hello/hello_custom_shape.rb",
200
203
  "samples/hello/hello_custom_shell.rb",
201
204
  "samples/hello/hello_custom_widget.rb",
202
205
  "samples/hello/hello_date_time.rb",
@@ -217,6 +220,7 @@ Gem::Specification.new do |s|
217
220
  "samples/hello/hello_radio.rb",
218
221
  "samples/hello/hello_radio_group.rb",
219
222
  "samples/hello/hello_sash_form.rb",
223
+ "samples/hello/hello_shape.rb",
220
224
  "samples/hello/hello_spinner.rb",
221
225
  "samples/hello/hello_styled_text.rb",
222
226
  "samples/hello/hello_tab.rb",
@@ -238,7 +242,7 @@ Gem::Specification.new do |s|
238
242
  s.specification_version = 4
239
243
 
240
244
  if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
241
- s.add_runtime_dependency(%q<glimmer>.freeze, ["~> 1.1.2"])
245
+ s.add_runtime_dependency(%q<glimmer>.freeze, ["~> 1.2.0"])
242
246
  s.add_runtime_dependency(%q<super_module>.freeze, [">= 1.4.1", "< 2.0.0"])
243
247
  s.add_runtime_dependency(%q<nested_inherited_jruby_include_package>.freeze, [">= 0.3.0", "< 2.0.0"])
244
248
  s.add_runtime_dependency(%q<puts_debuggerer>.freeze, [">= 0.11.0", "< 2.0.0"])
@@ -256,7 +260,7 @@ Gem::Specification.new do |s|
256
260
  s.add_development_dependency(%q<simplecov>.freeze, ["~> 0.16.1"])
257
261
  s.add_development_dependency(%q<simplecov-lcov>.freeze, ["~> 0.7.0"])
258
262
  else
259
- s.add_dependency(%q<glimmer>.freeze, ["~> 1.1.2"])
263
+ s.add_dependency(%q<glimmer>.freeze, ["~> 1.2.0"])
260
264
  s.add_dependency(%q<super_module>.freeze, [">= 1.4.1", "< 2.0.0"])
261
265
  s.add_dependency(%q<nested_inherited_jruby_include_package>.freeze, [">= 0.3.0", "< 2.0.0"])
262
266
  s.add_dependency(%q<puts_debuggerer>.freeze, [">= 0.11.0", "< 2.0.0"])
@@ -275,7 +279,7 @@ Gem::Specification.new do |s|
275
279
  s.add_dependency(%q<simplecov-lcov>.freeze, ["~> 0.7.0"])
276
280
  end
277
281
  else
278
- s.add_dependency(%q<glimmer>.freeze, ["~> 1.1.2"])
282
+ s.add_dependency(%q<glimmer>.freeze, ["~> 1.2.0"])
279
283
  s.add_dependency(%q<super_module>.freeze, [">= 1.4.1", "< 2.0.0"])
280
284
  s.add_dependency(%q<nested_inherited_jruby_include_package>.freeze, [">= 0.3.0", "< 2.0.0"])
281
285
  s.add_dependency(%q<puts_debuggerer>.freeze, [">= 0.11.0", "< 2.0.0"])
@@ -33,7 +33,7 @@ module Glimmer
33
33
  Glimmer::SWT::Custom::Animation.new(parent)
34
34
  end
35
35
 
36
- def add_content(parent, &block)
36
+ def add_content(parent, keyword, *args, &block)
37
37
  super
38
38
  parent.post_add_content
39
39
  end
@@ -0,0 +1,61 @@
1
+ # Copyright (c) 2007-2021 Andy Maleh
2
+ #
3
+ # Permission is hereby granted, free of charge, to any person obtaining
4
+ # a copy of this software and associated documentation files (the
5
+ # "Software"), to deal in the Software without restriction, including
6
+ # without limitation the rights to use, copy, modify, merge, publish,
7
+ # distribute, sublicense, and/or sell copies of the Software, and to
8
+ # permit persons to whom the Software is furnished to do so, subject to
9
+ # the following conditions:
10
+ #
11
+ # The above copyright notice and this permission notice shall be
12
+ # included in all copies or substantial portions of the Software.
13
+ #
14
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
21
+
22
+ require 'glimmer'
23
+ require 'glimmer/dsl/expression'
24
+ require 'glimmer/dsl/parent_expression'
25
+ require 'glimmer/dsl/top_level_expression'
26
+ require 'glimmer/ui/custom_shape'
27
+ require 'glimmer/swt/custom/code_text'
28
+ require 'glimmer/swt/custom/checkbox_group'
29
+
30
+ module Glimmer
31
+ module DSL
32
+ module SWT
33
+ class CustomShapeExpression < Expression
34
+ # TODO Make custom shapes automatically generate static expressions
35
+ include ParentExpression
36
+ include TopLevelExpression
37
+
38
+ def can_interpret?(parent, keyword, *args, &block)
39
+ !!UI::CustomShape.for(keyword)
40
+ end
41
+
42
+ def interpret(parent, keyword, *args, &block)
43
+ options = args.last.is_a?(Hash) ? args.pop : {}
44
+ UI::CustomShape.for(keyword).new(parent, *args, options, &block).tap do |new_custom_shape|
45
+ new_custom_shape.body_root.paint_pixel_by_pixel(&block) if block&.parameters&.count == 2
46
+ end
47
+ end
48
+
49
+ def add_content(parent, keyword, *args, &block)
50
+ # TODO consider avoiding source_location
51
+ return if block&.parameters&.count == 2
52
+ if block.source_location == parent.content&.__getobj__.source_location
53
+ parent.content.call(parent) unless parent.content.called?
54
+ else
55
+ super
56
+ end
57
+ end
58
+ end
59
+ end
60
+ end
61
+ end
@@ -51,7 +51,7 @@ module Glimmer
51
51
  end
52
52
  end
53
53
 
54
- def add_content(parent, &block)
54
+ def add_content(parent, keyword, *args, &block)
55
55
  # TODO consider avoiding source_location
56
56
  return if block&.parameters&.count == 2
57
57
  if block.source_location == parent.content&.__getobj__.source_location
@@ -57,6 +57,7 @@ module Glimmer
57
57
  widget
58
58
  custom_widget
59
59
  shape
60
+ custom_shape
60
61
  ]
61
62
  )
62
63
  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
@@ -49,7 +49,7 @@ module Glimmer
49
49
  Glimmer::SWT::ExpandItemProxy.new(parent, args)
50
50
  end
51
51
 
52
- def add_content(parent, &block)
52
+ def add_content(parent, keyword, *args, &block)
53
53
  super
54
54
  parent.post_add_content
55
55
  end
@@ -57,7 +57,7 @@ module Glimmer
57
57
  end
58
58
  end
59
59
 
60
- def add_content(parent, &block)
60
+ def add_content(parent, keyword, *args, &block)
61
61
  return if @create_pixel_by_pixel || block&.parameters&.count == 2
62
62
  super
63
63
  parent.post_add_content
@@ -39,7 +39,7 @@ module Glimmer
39
39
  Glimmer::SWT::TransformProxy.new(parent, *args, multiply: true)
40
40
  end
41
41
 
42
- def add_content(parent, &block)
42
+ def add_content(parent, keyword, *args, &block)
43
43
  super
44
44
  parent.post_add_content
45
45
  end
@@ -40,7 +40,7 @@ module Glimmer
40
40
  Glimmer::SWT::Custom::Shape.create(parent, keyword, *args, &block)
41
41
  end
42
42
 
43
- def add_content(parent, &block)
43
+ def add_content(parent, keyword, *args, &block)
44
44
  super
45
45
  parent.post_add_content
46
46
  end
@@ -41,7 +41,7 @@ module Glimmer
41
41
  Glimmer::SWT::TransformProxy.new(parent, *args)
42
42
  end
43
43
 
44
- def add_content(parent, &block)
44
+ def add_content(parent, keyword, *args, &block)
45
45
  super
46
46
  parent.post_add_content
47
47
  end
@@ -46,7 +46,7 @@ module Glimmer
46
46
  end
47
47
  end
48
48
 
49
- def add_content(parent, &block)
49
+ def add_content(parent, keyword, *args, &block)
50
50
  return if block&.parameters&.count == 2
51
51
  super
52
52
  parent.post_add_content
@@ -73,6 +73,7 @@ module Glimmer
73
73
  end
74
74
 
75
75
  def valid?(parent, keyword, *args, &block)
76
+ return true if keyword.to_s == 'shape'
76
77
  gc_instance_methods.include?(method_name(keyword, arg_options(args))) ||
77
78
  constants.include?(keyword.to_s.camelcase(:upper).to_sym)
78
79
  end
@@ -126,7 +127,7 @@ module Glimmer
126
127
  end
127
128
  end
128
129
 
129
- attr_reader :drawable, :parent, :name, :args, :options, :shapes
130
+ attr_reader :drawable, :parent, :name, :args, :options, :shapes, :properties
130
131
  attr_accessor :extent
131
132
 
132
133
  def initialize(parent, keyword, *args, &property_block)
@@ -134,7 +135,7 @@ module Glimmer
134
135
  @drawable = @parent.is_a?(Drawable) ? @parent : @parent.drawable
135
136
  @name = keyword
136
137
  @options = self.class.arg_options(args, extract: true)
137
- @method_name = self.class.method_name(keyword, @options)
138
+ @method_name = self.class.method_name(keyword, @options) unless keyword.to_s == 'shape'
138
139
  @args = args
139
140
  @properties = {}
140
141
  @shapes = [] # nested shapes
@@ -227,7 +228,7 @@ module Glimmer
227
228
 
228
229
  def content(&block)
229
230
  Glimmer::SWT::DisplayProxy.instance.auto_exec do
230
- Glimmer::DSL::Engine.add_content(self, Glimmer::DSL::SWT::ShapeExpression.new, &block)
231
+ Glimmer::DSL::Engine.add_content(self, Glimmer::DSL::SWT::ShapeExpression.new, @name, &block)
231
232
  calculated_args_changed!(children: false)
232
233
  end
233
234
  end
@@ -248,7 +249,8 @@ module Glimmer
248
249
  end
249
250
  end
250
251
 
251
- def apply_property_arg_conversions(method_name, property, args)
252
+ def apply_property_arg_conversions(property, args)
253
+ method_name = attribute_setter(property)
252
254
  args = args.dup
253
255
  the_java_method = org.eclipse.swt.graphics.GC.java_class.declared_instance_methods.detect {|m| m.name == method_name}
254
256
  return args if the_java_method.nil?
@@ -348,10 +350,16 @@ module Glimmer
348
350
  end
349
351
 
350
352
  def apply_shape_arg_defaults!
351
- self.x = :default if current_parameter_name?(:x) && x.nil?
352
- self.y = :default if current_parameter_name?(:y) && y.nil?
353
- self.dest_x = :default if current_parameter_name?(:dest_x) && dest_x.nil?
354
- self.dest_y = :default if current_parameter_name?(:dest_y) && dest_y.nil?
353
+ if current_parameter_name?(:dest_x) && dest_x.nil?
354
+ self.dest_x = :default
355
+ elsif parameter_name?(:x) && x.nil?
356
+ self.x = :default
357
+ end
358
+ if current_parameter_name?(:dest_y) && dest_y.nil?
359
+ self.dest_y = :default
360
+ elsif parameter_name?(:y) && y.nil?
361
+ self.y = :default
362
+ end
355
363
  self.width = :default if current_parameter_name?(:width) && width.nil?
356
364
  self.height = :default if current_parameter_name?(:height) && height.nil?
357
365
  if @name.include?('rectangle') && round? && @args.size.between?(4, 5)
@@ -396,7 +404,7 @@ module Glimmer
396
404
 
397
405
  # parameter names for arguments to pass to SWT GC.xyz method for rendering shape (e.g. draw_image(image, x, y) yields :image, :x, :y parameter names)
398
406
  def parameter_names
399
- []
407
+ [:x, :y, :width, :height]
400
408
  end
401
409
 
402
410
  # subclasses may override to specify location parameter names if different from x and y (e.g. all polygon points are location parameters)
@@ -532,8 +540,39 @@ module Glimmer
532
540
  drawable.redraw if redraw && !drawable.is_a?(ImageProxy)
533
541
  end
534
542
 
543
+ # Indicate if this is a shape composite (meaning a shape bag that just contains nested shapes, but doesn't render anything of its own)
544
+ def shape_composite?
545
+ @name == 'shape'
546
+ end
547
+
548
+ # ordered from closest to farthest parent
549
+ def parent_shapes
550
+ current_parent = parent
551
+ the_parent_shapes = []
552
+ until current_parent.is_a?(Drawable)
553
+ the_parent_shapes << current_parent
554
+ current_parent = current_parent.parent
555
+ end
556
+ the_parent_shapes
557
+ end
558
+
559
+ # ordered from closest to farthest parent
560
+ def parent_shape_composites
561
+ parent_shapes.select(&:shape_composite?)
562
+ end
563
+
564
+ def all_parent_properties
565
+ # TODO consider providing a converted property version of this ready for consumption
566
+ @all_parent_properties ||= parent_shape_composites.reverse.reduce({}) do |all_properties, parent_shape|
567
+ parent_properties = parent_shape.properties
568
+ parent_properties.each do |property, args|
569
+ parent_properties[property] = apply_property_arg_conversions(property, args)
570
+ end
571
+ all_properties.merge(parent_properties)
572
+ end
573
+ end
574
+
535
575
  def paint(paint_event)
536
- # pre-paint children an extra-time first when default width/height need to be calculated for defaults
537
576
  paint_children(paint_event) if default_width? || default_height?
538
577
  paint_self(paint_event)
539
578
  # re-paint children from scratch in the special case of pre-calculating parent width/height to re-center within new parent dimensions
@@ -546,24 +585,29 @@ module Glimmer
546
585
 
547
586
  def paint_self(paint_event)
548
587
  @painting = true
549
- calculate_paint_args!
550
- @original_properties_backup = {}
551
- @properties.each do |property, args|
552
- method_name = attribute_setter(property)
553
- @original_properties_backup[method_name] = paint_event.gc.send(method_name.sub('set', 'get')) rescue nil
554
- paint_event.gc.send(method_name, *args)
555
- if property == 'transform' && args.first.is_a?(TransformProxy)
556
- args.first.swt_transform.dispose
588
+ unless shape_composite?
589
+ calculate_paint_args!
590
+ @original_gc_properties = {} # this stores GC properties before making calls to updates TODO avoid using in pixel graphics
591
+ @original_properties = @properties # this stores original shape attributes like background/foreground/font
592
+ @properties.merge(all_parent_properties).each do |property, args|
593
+ method_name = attribute_setter(property)
594
+ @original_gc_properties[method_name] = paint_event.gc.send(method_name.sub('set', 'get')) rescue nil
595
+ paint_event.gc.send(method_name, *args)
596
+ if property == 'transform' && args.first.is_a?(TransformProxy)
597
+ args.first.swt_transform.dispose
598
+ end
557
599
  end
600
+ ensure_extent(paint_event)
558
601
  end
559
- ensure_extent(paint_event)
560
602
  if !@calculated_args || parent_shape_absolute_location_changed?
561
603
  @calculated_args = calculated_args
562
604
  end
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
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)
605
+ unless shape_composite?
606
+ # 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
607
+ paint_event.gc.send(@method_name, *@calculated_args) unless (parent.is_a?(Shape) && !parent.calculated_args?)
608
+ @original_gc_properties.each do |method_name, value|
609
+ paint_event.gc.send(method_name, value)
610
+ end
567
611
  end
568
612
  @painting = false
569
613
  rescue => e
@@ -648,11 +692,19 @@ module Glimmer
648
692
  end
649
693
  if default_width?
650
694
  original_width = width
651
- self.width = default_width + default_width_delta
695
+ self.width = default_width + width_delta
652
696
  end
653
697
  if default_height?
654
698
  original_height = height
655
- self.height = default_height + default_height_delta
699
+ self.height = default_height + height_delta
700
+ end
701
+ if max_width?
702
+ original_width = width
703
+ self.width = max_width + width_delta
704
+ end
705
+ if max_height?
706
+ original_height = height
707
+ self.height = max_height + height_delta
656
708
  end
657
709
  if default_x?
658
710
  original_x = x
@@ -707,6 +759,16 @@ module Glimmer
707
759
  (height.nil? || height == :default || height == 'default' || (height.is_a?(Array) && (height.first.to_s == :default || height.first.to_s == 'default')))
708
760
  end
709
761
 
762
+ def max_width?
763
+ current_parameter_name?(:width) and
764
+ (width.nil? || width.to_s == 'max' || (width.is_a?(Array) && width.first.to_s == 'max'))
765
+ end
766
+
767
+ def max_height?
768
+ current_parameter_name?(:height) and
769
+ (height.nil? || height.to_s == 'max' || (height.is_a?(Array) && height.first.to_s == 'max'))
770
+ end
771
+
710
772
  def default_x
711
773
  result = ((parent.size.x - size.x) / 2)
712
774
  result += parent.bounds.x - parent.absolute_x if parent.is_a?(Shape) && parent.irregular?
@@ -722,29 +784,61 @@ module Glimmer
722
784
  def default_width
723
785
  # TODO consider caching
724
786
  x_ends = shapes.map do |shape|
725
- shape_width = shape.calculated_width.to_f
726
- shape_x = shape.default_x? ? 0 : shape.x.to_f
727
- shape_x + shape_width
787
+ if shape.max_width?
788
+ 0
789
+ else
790
+ shape_width = shape.calculated_width.to_f
791
+ shape_x = shape.default_x? ? 0 : shape.x.to_f
792
+ shape_x + shape_width
793
+ end
794
+ end
795
+ if shapes.size == 1 && shapes.first.max_width?
796
+ self.parent.size.x
797
+ else
798
+ x_ends.max.to_f
728
799
  end
729
- x_ends.max.to_f
730
800
  end
731
801
 
732
802
  def default_height
733
803
  # TODO consider caching
734
804
  y_ends = shapes.map do |shape|
735
- shape_height = shape.calculated_height.to_f
736
- shape_y = shape.default_y? ? 0 : shape.y.to_f
737
- shape_y + shape_height
805
+ if shape.max_height?
806
+ 0
807
+ else
808
+ shape_height = shape.calculated_height.to_f
809
+ shape_y = shape.default_y? ? 0 : shape.y.to_f
810
+ shape_y + shape_height
811
+ end
812
+ end
813
+ if shapes.size == 1 && shapes.first.max_height?
814
+ self.parent.size.y
815
+ else
816
+ y_ends.max.to_f
738
817
  end
739
- y_ends.max.to_f
818
+ end
819
+
820
+ def max_width
821
+ # consider caching
822
+ parent.is_a?(Drawable) ? parent.size.x : parent.calculated_width
823
+ end
824
+
825
+ def max_height
826
+ # consider caching
827
+ parent.is_a?(Drawable) ? parent.size.y : parent.calculated_height
740
828
  end
741
829
 
742
830
  def calculated_width
743
- default_width? ? (default_width + default_width_delta) : width
831
+ result_width = width
832
+ result_width = (default_width + width_delta) if default_width?
833
+ result_width = (max_width + width_delta) if max_width?
834
+ result_width
744
835
  end
745
836
 
746
837
  def calculated_height
747
- default_height? ? (default_height + default_height_delta) : height
838
+ result_height = height
839
+ result_height = (default_height + height_delta) if default_height?
840
+ result_height = (max_height + height_delta) if max_height?
841
+ result_height
748
842
  end
749
843
 
750
844
  def default_x_delta
@@ -757,12 +851,12 @@ module Glimmer
757
851
  y[1].to_f
758
852
  end
759
853
 
760
- def default_width_delta
854
+ def width_delta
761
855
  return 0 unless default_width? && width.is_a?(Array)
762
856
  width[1].to_f
763
857
  end
764
858
 
765
- def default_height_delta
859
+ def height_delta
766
860
  return 0 unless default_height? && height.is_a?(Array)
767
861
  height[1].to_f
768
862
  end
@@ -777,12 +871,12 @@ module Glimmer
777
871
  self.y = [:default, delta]
778
872
  end
779
873
 
780
- def default_width_delta=(delta)
874
+ def width_delta=(delta)
781
875
  return unless default_width?
782
876
  self.width = [:default, delta]
783
877
  end
784
878
 
785
- def default_height_delta=(delta)
879
+ def height_delta=(delta)
786
880
  return unless default_height?
787
881
  self.height = [:default, delta]
788
882
  end
@@ -850,9 +944,7 @@ module Glimmer
850
944
  # Also do that with all future-added properties
851
945
  @properties['transform'] = [nil] if @drawable.respond_to?(:transform) && !@properties.keys.map(&:to_s).include?('transform')
852
946
  @properties.each do |property, args|
853
- method_name = attribute_setter(property)
854
- converted_args = apply_property_arg_conversions(method_name, property, args)
855
- @properties[property] = converted_args
947
+ @properties[property] = apply_property_arg_conversions(property, args)
856
948
  end
857
949
  apply_shape_arg_conversions!
858
950
  apply_shape_arg_defaults!