glimmer-dsl-swt 4.18.5.3 → 4.18.5.4
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +7 -0
- data/README.md +4 -4
- data/VERSION +1 -1
- data/docs/reference/GLIMMER_GUI_DSL_SYNTAX.md +19 -13
- data/docs/reference/GLIMMER_SAMPLES.md +4 -0
- data/glimmer-dsl-swt.gemspec +3 -3
- data/lib/glimmer/swt/custom/shape.rb +234 -60
- data/lib/glimmer/swt/custom/shape/arc.rb +17 -4
- data/lib/glimmer/swt/custom/shape/image.rb +4 -4
- data/lib/glimmer/swt/custom/shape/line.rb +30 -4
- data/lib/glimmer/swt/custom/shape/oval.rb +3 -3
- data/lib/glimmer/swt/custom/shape/point.rb +8 -0
- data/lib/glimmer/swt/custom/shape/polygon.rb +52 -12
- data/lib/glimmer/swt/custom/shape/polyline.rb +36 -10
- data/lib/glimmer/swt/custom/shape/rectangle.rb +3 -2
- data/lib/glimmer/swt/custom/shape/text.rb +2 -4
- data/samples/hello/hello_canvas.rb +38 -21
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 495c8eacce66f3b425a8f1603eea5051f5b776f0cb8e8550419382079c58e85e
|
4
|
+
data.tar.gz: 7e922de5ff80a2e85facee8a36444fe70bd6a9e25a65416aeebec4bfabd10749
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 5ace8433246247b3210cced98a70bb45cfdc978808b632ad322b5c995a7b0e868fc7df9c6ed23293fd5845e50257696617ad9a85ad9e7a0f0b697aea55901cfc
|
7
|
+
data.tar.gz: 58c632f794d07225737d101b68300db72c41b90778320765971e29539242d48260512db44c77ed99fb1aa9307056d24364a5bb57e400b3a0aab49c41ac8babb4
|
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,12 @@
|
|
1
1
|
# Change Log
|
2
2
|
|
3
|
+
### 4.18.5.4
|
4
|
+
|
5
|
+
- 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
|
6
|
+
- Support [:default, width_delta], [:default, height_delta] attributes for width and height, which add/subtract from defaults used for shape
|
7
|
+
- Switch from use of `:default` with x_delta/y_delta to passing `[:default, x_delta]` or `[:default, y_delta]` (e.g. `image(file, [:default, -30], :default)` for x = default - 30 and y = default + 0)
|
8
|
+
- Support a bounding box for all shapes, implementing `#bounds` (x, y, width, and height) and `#size` (width, height) for the ones that don't receive as parameters (like polygon)
|
9
|
+
|
3
10
|
### 4.18.5.3
|
4
11
|
|
5
12
|
- Support nesting shapes within shapes, with relative positioning (meaning x, y coordinates are assumed relative to parent's x, y in nested shapes)
|
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.
|
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
|
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)
|
@@ -8,7 +8,7 @@
|
|
8
8
|
|
9
9
|
**[Contributors Wanted! (Submit a Glimmer App Sample to Get Started)](#contributing)**
|
10
10
|
|
11
|
-
[Glimmer
|
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
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
14
|
|
@@ -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.5.
|
345
|
+
jgem install glimmer-dsl-swt -v 4.18.5.4
|
346
346
|
```
|
347
347
|
|
348
348
|
`jgem` is JRuby's version of `gem` command.
|
@@ -360,7 +360,7 @@ Note: if you're using activerecord or activesupport, keep in mind that Glimmer u
|
|
360
360
|
|
361
361
|
Add the following to `Gemfile`:
|
362
362
|
```
|
363
|
-
gem 'glimmer-dsl-swt', '~> 4.18.5.
|
363
|
+
gem 'glimmer-dsl-swt', '~> 4.18.5.4'
|
364
364
|
```
|
365
365
|
|
366
366
|
And, then run:
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
4.18.5.
|
1
|
+
4.18.5.4
|
@@ -36,6 +36,7 @@ This guide should help you get started with Glimmer DSL for SWT. For more advanc
|
|
36
36
|
- [Layouts](#layouts)
|
37
37
|
- [Layout Data](#layout-data)
|
38
38
|
- [Canvas Shape DSL](#canvas-shape-dsl)
|
39
|
+
- [Shapes inside a Shape](#shapes-inside-a-shape)
|
39
40
|
- [Shapes inside a Widget](#shapes-inside-a-widget)
|
40
41
|
- [Shapes inside an Image](#shapes-inside-an-image)
|
41
42
|
- [Canvas Shape API](#canvas-shape-api)
|
@@ -1403,7 +1404,7 @@ Shape keywords and their args (including defaults) are listed below (they basica
|
|
1403
1404
|
- `rectangle(x, y, width, height, arcWidth = 60, arcHeight = 60, fill: false, round: true)` round rectangle, which can be optionally filled, and takes optional extra round angle arguments
|
1404
1405
|
- `rectangle(x, y, width, height, vertical = true, fill: true, gradient: true)` gradient rectangle, which is always filled, and takes an optional extra argument to specify true for vertical gradient (default) and false for horizontal gradient
|
1405
1406
|
- `text(string, x, y, is_transparent = true)` text with optional is_transparent to indicate if background is transparent (default is true)
|
1406
|
-
- `text(string, x, y, flags)` text with optional flags (flag format is `swt(comma_separated_flags)` where flags can be
|
1407
|
+
- `text(string, x, y, flags)` text with optional flags (flag format is `swt(comma_separated_flags)` where flags can be `:draw_delimiter` (i.e. new lines), `:draw_tab`, `:draw_mnemonic`, and `:draw_transparent` as explained in [GC API](https://help.eclipse.org/2020-12/topic/org.eclipse.platform.doc.isv/reference/api/org/eclipse/swt/graphics/GC.html))
|
1407
1408
|
|
1408
1409
|
Shape keywords that can be filled with color can take a keyword argument `fill: true`. Defaults to false when not specified unless background is set with no foreground (or foreground is set with no background), in which case a smart default is applied.
|
1409
1410
|
Smart defaults can be applied to automatically infer `gradient: true` (rectangle with both foreground and background) and `round: true` (rectangle with more than 4 args, the extra args are numeric) as well.
|
@@ -1460,7 +1461,7 @@ shell {
|
|
1460
1461
|
font height: 25, style: :bold
|
1461
1462
|
}
|
1462
1463
|
rectangle(200, 80, 108, 36) {
|
1463
|
-
foreground
|
1464
|
+
foreground rgb(0, 0, 0)
|
1464
1465
|
line_width 3
|
1465
1466
|
}
|
1466
1467
|
image(image_object, 70, 50)
|
@@ -1506,7 +1507,7 @@ shell {
|
|
1506
1507
|
font height: 25, style: :bold
|
1507
1508
|
}
|
1508
1509
|
rectangle(200, 80, 108, 36) {
|
1509
|
-
foreground
|
1510
|
+
foreground rgb(0, 0, 0)
|
1510
1511
|
line_width 3
|
1511
1512
|
}
|
1512
1513
|
image(image_object, 70, 50)
|
@@ -1541,7 +1542,7 @@ shell {
|
|
1541
1542
|
}
|
1542
1543
|
rectangle {
|
1543
1544
|
x 50
|
1544
|
-
|
1545
|
+
y 20
|
1545
1546
|
width 300
|
1546
1547
|
height 150
|
1547
1548
|
arc_width 30
|
@@ -1596,23 +1597,26 @@ shell {
|
|
1596
1597
|
minimum_size 320, 400
|
1597
1598
|
|
1598
1599
|
canvas {
|
1599
|
-
background :
|
1600
|
+
background :dark_yellow
|
1600
1601
|
|
1601
1602
|
on_paint_control { |paint_event|
|
1602
1603
|
gc = paint_event.gc
|
1603
|
-
gc.background = color(:red).swt_color
|
1604
|
-
gc.fill_rectangle(0, 0, 220, 400)
|
1605
1604
|
|
1606
|
-
gc.background = color(:
|
1607
|
-
gc.
|
1605
|
+
gc.background = color(:dark_red).swt_color
|
1606
|
+
gc.fill_rectangle(0, 0, 220, 400)
|
1608
1607
|
|
1609
|
-
gc.background = color(:
|
1610
|
-
gc.
|
1608
|
+
gc.background = color(:yellow).swt_color
|
1609
|
+
gc.fill_round_rectangle(50, 20, 300, 150, 30, 50)
|
1611
1610
|
|
1612
|
-
gc.
|
1613
|
-
gc.
|
1611
|
+
gc.background = color(:dark_red).swt_color
|
1612
|
+
gc.foreground = color(:yellow).swt_color
|
1613
|
+
gc.fill_gradient_rectangle(150, 200, 100, 70, true)
|
1614
1614
|
|
1615
|
+
gc.font = font(height: 25, style: :bold).swt_font
|
1615
1616
|
gc.foreground = color(:black).swt_color
|
1617
|
+
gc.draw_text('Glimmer', 208, 83, true)
|
1618
|
+
|
1619
|
+
gc.foreground = rgb(0, 0, 0).swt_color
|
1616
1620
|
gc.line_width = 3
|
1617
1621
|
gc.draw_rectangle(200, 80, 108, 36)
|
1618
1622
|
|
@@ -1762,6 +1766,8 @@ They are implemented with the help of the highly robust Java built-in shape geom
|
|
1762
1766
|
- `Shape#contain?(x, y)` : indicates if shape contains x, y point
|
1763
1767
|
- `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)
|
1764
1768
|
- `Shape#move_by(x_delta, y_delta)` : moves shape object at x, y location
|
1769
|
+
- `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
|
+
- `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)
|
1765
1771
|
|
1766
1772
|
Check [Hello, Canvas!](GLIMMER_SAMPLES.md#hello-canvas) for an example.
|
1767
1773
|
|
@@ -580,6 +580,10 @@ Hello, Canvas! Colors Changed
|
|
580
580
|
|
581
581
|
![Hello Canvas Colors Changed](/images/glimmer-hello-canvas-colors-changed.png)
|
582
582
|
|
583
|
+
Hello, Canvas! Data-Binding (changing a `text` shape `string` via data-binding changes from another thread)
|
584
|
+
|
585
|
+
![Hello Canvas Data Binding](/images/glimmer-hello-canvas-data-binding.gif)
|
586
|
+
|
583
587
|
#### Hello, Canvas Animation!
|
584
588
|
|
585
589
|
This sample demonstrates the use of the `canvas` widget and [Animation DSL](#canvas-animation-dsl) in Glimmer.
|
data/glimmer-dsl-swt.gemspec
CHANGED
@@ -2,16 +2,16 @@
|
|
2
2
|
# DO NOT EDIT THIS FILE DIRECTLY
|
3
3
|
# Instead, edit Juwelier::Tasks in Rakefile, and run 'rake gemspec'
|
4
4
|
# -*- encoding: utf-8 -*-
|
5
|
-
# stub: glimmer-dsl-swt 4.18.5.
|
5
|
+
# stub: glimmer-dsl-swt 4.18.5.4 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.
|
9
|
+
s.version = "4.18.5.4"
|
10
10
|
|
11
11
|
s.required_rubygems_version = Gem::Requirement.new(">= 0".freeze) if s.respond_to? :required_rubygems_version=
|
12
12
|
s.require_paths = ["lib".freeze]
|
13
13
|
s.authors = ["AndyMaleh".freeze]
|
14
|
-
s.date = "2021-02-
|
14
|
+
s.date = "2021-02-26"
|
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]
|
@@ -99,7 +99,7 @@ module Glimmer
|
|
99
99
|
end
|
100
100
|
|
101
101
|
attr_reader :drawable, :parent, :name, :args, :options, :shapes
|
102
|
-
attr_accessor :
|
102
|
+
attr_accessor :extent
|
103
103
|
|
104
104
|
def initialize(parent, keyword, *args, &property_block)
|
105
105
|
@parent = parent
|
@@ -110,8 +110,6 @@ module Glimmer
|
|
110
110
|
@args = args
|
111
111
|
@properties = {}
|
112
112
|
@shapes = [] # nested shapes
|
113
|
-
@x_delta = 0
|
114
|
-
@y_delta = 0
|
115
113
|
@options.reject {|key, value| %w[fill gradient round].include?(key.to_s)}.each do |property, property_args|
|
116
114
|
@properties[property] = property_args
|
117
115
|
end
|
@@ -121,6 +119,7 @@ module Glimmer
|
|
121
119
|
|
122
120
|
def add_shape(shape)
|
123
121
|
@shapes << shape
|
122
|
+
calculated_args_changed_for_default_size!
|
124
123
|
end
|
125
124
|
|
126
125
|
def draw?
|
@@ -141,26 +140,34 @@ module Glimmer
|
|
141
140
|
@options[:round]
|
142
141
|
end
|
143
142
|
|
144
|
-
#
|
143
|
+
# The bounding box top-left x, y, width, height in absolute positioning
|
144
|
+
def bounds
|
145
|
+
org.eclipse.swt.graphics.Rectangle.new(absolute_x, absolute_y, calculated_width, calculated_height)
|
146
|
+
end
|
147
|
+
|
148
|
+
# The bounding box width and height (as a Point object with x being width and y being height)
|
149
|
+
def size
|
150
|
+
org.eclipse.swt.graphics.Point.new(calculated_width, calculated_height)
|
151
|
+
end
|
152
|
+
|
153
|
+
def extent
|
154
|
+
@extent || size
|
155
|
+
end
|
156
|
+
|
157
|
+
# Returns if shape contains a point
|
158
|
+
# Subclasses (like polygon) may override to indicate if a point x,y coordinates falls inside the shape
|
145
159
|
# some shapes may choose to provide a fuzz factor to make usage of this method for mouse clicking more user friendly
|
146
160
|
def contain?(x, y)
|
147
161
|
# assume a rectangular filled shape by default (works for several shapes like image, text, and focus)
|
148
|
-
|
149
|
-
x.between?(self.absolute_x, self.absolute_x + width) && y.between?(self.absolute_y, self.absolute_y + height)
|
150
|
-
else
|
151
|
-
false # subclasses must provide implementation
|
152
|
-
end
|
162
|
+
x.between?(self.absolute_x, self.absolute_x + calculated_width) && y.between?(self.absolute_y, self.absolute_y + calculated_height)
|
153
163
|
end
|
154
164
|
|
155
|
-
#
|
165
|
+
# Returns if shape includes a point. When the shape is filled, this is the same as contain. When the shape is drawn, it only returns true if the point lies on the edge (boundary/border)
|
166
|
+
# Subclasses (like polygon) may override to indicate if a point x,y coordinates falls on the edge of a drawn shape or inside a filled shape
|
156
167
|
# some shapes may choose to provide a fuzz factor to make usage of this method for mouse clicking more user friendly
|
157
168
|
def include?(x, y)
|
158
169
|
# assume a rectangular shape by default
|
159
|
-
|
160
|
-
contain?(x, y)
|
161
|
-
else
|
162
|
-
false # subclasses must provide implementation
|
163
|
-
end
|
170
|
+
contain?(x, y)
|
164
171
|
end
|
165
172
|
|
166
173
|
# moves by x delta and y delta. Subclasses must implement
|
@@ -168,12 +175,12 @@ module Glimmer
|
|
168
175
|
def move_by(x_delta, y_delta)
|
169
176
|
if respond_to?(:x) && respond_to?(:y) && respond_to?(:x=) && respond_to?(:y=)
|
170
177
|
if default_x?
|
171
|
-
self.
|
178
|
+
self.default_x_delta += x_delta
|
172
179
|
else
|
173
180
|
self.x += x_delta
|
174
181
|
end
|
175
182
|
if default_y?
|
176
|
-
self.
|
183
|
+
self.default_y_delta += y_delta
|
177
184
|
else
|
178
185
|
self.y += y_delta
|
179
186
|
end
|
@@ -278,20 +285,22 @@ module Glimmer
|
|
278
285
|
end
|
279
286
|
|
280
287
|
def apply_shape_arg_defaults!
|
288
|
+
self.x = :default if current_parameter_name?(:x) && x.nil?
|
289
|
+
self.y = :default if current_parameter_name?(:y) && y.nil?
|
290
|
+
self.dest_x = :default if current_parameter_name?(:dest_x) && dest_x.nil?
|
291
|
+
self.dest_y = :default if current_parameter_name?(:dest_y) && dest_y.nil?
|
292
|
+
self.width = :default if current_parameter_name?(:width) && width.nil?
|
293
|
+
self.height = :default if current_parameter_name?(:height) && height.nil?
|
281
294
|
if @name.include?('rectangle') && round? && @args.size.between?(4, 5)
|
282
295
|
(6 - @args.size).times {@args << 60}
|
283
296
|
elsif @name.include?('rectangle') && gradient? && @args.size == 4
|
284
|
-
|
285
|
-
elsif (@name.include?('text') || @name.include?('string')) && !@properties.keys.map(&:to_s).include?('background') && @args.size
|
286
|
-
|
297
|
+
set_attribute('vertical', true, redraw: false)
|
298
|
+
elsif (@name.include?('text') || @name.include?('string')) && !@properties.keys.map(&:to_s).include?('background') && @args.size < 4
|
299
|
+
set_attribute('is_transparent', true, redraw: false)
|
287
300
|
end
|
288
301
|
if @name.include?('image')
|
289
302
|
@drawable.requires_shape_disposal = true
|
290
303
|
end
|
291
|
-
self.x = :default if current_parameter_name?(:x) && x.nil?
|
292
|
-
self.y = :default if current_parameter_name?(:y) && y.nil?
|
293
|
-
self.dest_x = :default if current_parameter_name?(:dest_x) && dest_x.nil?
|
294
|
-
self.dest_y = :default if current_parameter_name?(:dest_y) && dest_y.nil?
|
295
304
|
end
|
296
305
|
|
297
306
|
# Tolerates shape extra args added by user by mistake
|
@@ -341,11 +350,11 @@ module Glimmer
|
|
341
350
|
end
|
342
351
|
|
343
352
|
def current_parameter_name?(attribute_name)
|
344
|
-
parameter_names.
|
353
|
+
parameter_names.include?(attribute_name.to_s.to_sym)
|
345
354
|
end
|
346
355
|
|
347
356
|
def parameter_index(attribute_name)
|
348
|
-
parameter_names.
|
357
|
+
parameter_names.index(attribute_name.to_s.to_sym)
|
349
358
|
end
|
350
359
|
|
351
360
|
def set_parameter_attribute(attribute_name, *args)
|
@@ -357,9 +366,10 @@ module Glimmer
|
|
357
366
|
parameter_name?(attribute_name) or
|
358
367
|
(respond_to?(attribute_name, super: true) and respond_to?(ruby_attribute_setter(attribute_name), super: true))
|
359
368
|
end
|
360
|
-
|
369
|
+
|
361
370
|
def set_attribute(attribute_name, *args)
|
362
371
|
options = args.last if args.last.is_a?(Hash)
|
372
|
+
args.pop if !options.nil? && !options[:redraw].nil?
|
363
373
|
perform_redraw = @perform_redraw
|
364
374
|
perform_redraw = options[:redraw] if perform_redraw.nil? && !options.nil?
|
365
375
|
perform_redraw = true if perform_redraw.nil?
|
@@ -373,8 +383,10 @@ module Glimmer
|
|
373
383
|
if @content_added && perform_redraw && !drawable.is_disposed
|
374
384
|
@calculated_paint_args = false
|
375
385
|
attribute_name = ruby_attribute_getter(attribute_name)
|
376
|
-
@
|
377
|
-
|
386
|
+
@calculated_args = nil if location_parameter_names.map(&:to_s).include?(attribute_name)
|
387
|
+
if ['width', 'height'].include?(attribute_name)
|
388
|
+
calculated_args_changed_for_default_size!
|
389
|
+
end
|
378
390
|
# TODO consider redrawing an image proxy's gc in the future
|
379
391
|
drawable.redraw unless drawable.is_a?(ImageProxy)
|
380
392
|
end
|
@@ -447,6 +459,17 @@ module Glimmer
|
|
447
459
|
end
|
448
460
|
|
449
461
|
def paint(paint_event)
|
462
|
+
paint_children(paint_event) if default_width? || default_height?
|
463
|
+
paint_self(paint_event)
|
464
|
+
shapes.each(&:calculated_args_changed!) if default_width? || default_height?
|
465
|
+
paint_children(paint_event)
|
466
|
+
rescue => e
|
467
|
+
Glimmer::Config.logger.error {"Error encountered in painting shape (#{self.inspect}) with calculated args (#{@calculated_args}) and args (#{@args})"}
|
468
|
+
Glimmer::Config.logger.error {e.full_message}
|
469
|
+
end
|
470
|
+
|
471
|
+
def paint_self(paint_event)
|
472
|
+
@painting = true
|
450
473
|
calculate_paint_args!
|
451
474
|
@properties.each do |property, args|
|
452
475
|
method_name = attribute_setter(property)
|
@@ -456,16 +479,18 @@ module Glimmer
|
|
456
479
|
args.first.swt_transform.dispose
|
457
480
|
end
|
458
481
|
end
|
459
|
-
|
460
|
-
if !@
|
461
|
-
@
|
462
|
-
@calculated_absolute_args = true
|
482
|
+
ensure_extent(paint_event)
|
483
|
+
if !@calculated_args || parent_shape_absolute_location_changed?
|
484
|
+
@calculated_args = calculated_args
|
463
485
|
end
|
464
|
-
|
465
|
-
|
486
|
+
# 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
|
+
paint_event.gc.send(@method_name, *@calculated_args) unless parent.is_a?(Shape) && !parent.calculated_args?
|
488
|
+
@painting = false
|
466
489
|
rescue => e
|
467
|
-
Glimmer::Config.logger.error {"Error encountered in painting shape
|
490
|
+
Glimmer::Config.logger.error {"Error encountered in painting shape (#{self.inspect}) with calculated args (#{@calculated_args}) and args (#{@args})"}
|
468
491
|
Glimmer::Config.logger.error {e.full_message}
|
492
|
+
ensure
|
493
|
+
@painting = false
|
469
494
|
end
|
470
495
|
|
471
496
|
def paint_children(paint_event)
|
@@ -474,6 +499,20 @@ module Glimmer
|
|
474
499
|
end
|
475
500
|
end
|
476
501
|
|
502
|
+
def ensure_extent(paint_event)
|
503
|
+
old_extent = @extent
|
504
|
+
if ['text', 'string'].include?(@name)
|
505
|
+
extent_args = [string]
|
506
|
+
extent_flags = SWTProxy[:draw_transparent] if current_parameter_name?(:is_transparent) && is_transparent
|
507
|
+
extent_flags = flags if current_parameter_name?(:flags)
|
508
|
+
extent_args << extent_flags unless extent_flags.nil?
|
509
|
+
self.extent = paint_event.gc.send("#{@name}Extent", *extent_args)
|
510
|
+
end
|
511
|
+
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)
|
513
|
+
end
|
514
|
+
end
|
515
|
+
|
477
516
|
def expanded_shapes
|
478
517
|
if shapes.to_a.any?
|
479
518
|
shapes.map do |shape|
|
@@ -487,69 +526,198 @@ module Glimmer
|
|
487
526
|
def parent_shape_absolute_location_changed?
|
488
527
|
(parent.is_a?(Shape) && (parent.absolute_x != @parent_absolute_x || parent.absolute_y != @parent_absolute_y))
|
489
528
|
end
|
529
|
+
|
530
|
+
def calculated_args_changed!
|
531
|
+
# TODO add a children: true option to enable setting to false to avoid recalculating children args
|
532
|
+
@calculated_args = nil
|
533
|
+
shapes.each(&:calculated_args_changed!)
|
534
|
+
end
|
535
|
+
|
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!
|
540
|
+
elsif @content_added && !drawable.is_disposed
|
541
|
+
# 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
|
+
drawable.redraw if !@painting && !drawable.is_a?(ImageProxy)
|
543
|
+
end
|
544
|
+
end
|
545
|
+
|
546
|
+
def calculated_args?
|
547
|
+
!!@calculated_args
|
548
|
+
end
|
490
549
|
|
491
550
|
# args translated to absolute coordinates
|
492
|
-
def
|
493
|
-
return @args if !default_x? && !default_y? &&
|
551
|
+
def calculated_args
|
552
|
+
return @args if !default_x? && !default_y? && !default_width? && !default_height? && parent.is_a?(Drawable)
|
553
|
+
# Note: Must set x and move_by because not all shapes have a real x and some must translate all their points with move_by
|
554
|
+
# TODO change that by setting a bounding box for all shapes with a calculated top-left x, y and
|
555
|
+
# a setter that does the moving inside them instead so that I could rely on absolute_x and absolute_y
|
556
|
+
# here to get the job done of calculating absolute args
|
494
557
|
@perform_redraw = false
|
495
558
|
original_x = nil
|
496
559
|
original_y = nil
|
560
|
+
original_width = nil
|
561
|
+
original_height = nil
|
562
|
+
if default_width?
|
563
|
+
original_width = width
|
564
|
+
self.width = default_width + default_width_delta
|
565
|
+
end
|
566
|
+
if default_height?
|
567
|
+
original_height = height
|
568
|
+
self.height = default_height + default_height_delta
|
569
|
+
end
|
497
570
|
if default_x?
|
498
571
|
original_x = x
|
499
|
-
self.x = default_x
|
572
|
+
self.x = default_x + default_x_delta
|
500
573
|
end
|
501
574
|
if default_y?
|
502
575
|
original_y = y
|
503
|
-
self.y = default_y
|
576
|
+
self.y = default_y + default_y_delta
|
504
577
|
end
|
505
|
-
move_by(@x_delta, @y_delta)
|
506
578
|
if parent.is_a?(Shape)
|
507
579
|
@parent_absolute_x = parent.absolute_x
|
508
580
|
@parent_absolute_y = parent.absolute_y
|
509
581
|
move_by(parent.absolute_x, parent.absolute_y)
|
510
|
-
|
582
|
+
result_args = @args.clone
|
511
583
|
move_by(-1*parent.absolute_x, -1*parent.absolute_y)
|
512
584
|
else
|
513
|
-
|
585
|
+
result_args = @args.clone
|
514
586
|
end
|
515
|
-
move_by(-1*@x_delta, -1*@y_delta)
|
516
587
|
if original_x
|
517
588
|
self.x = original_x
|
518
589
|
end
|
519
590
|
if original_y
|
520
591
|
self.y = original_y
|
521
592
|
end
|
593
|
+
if original_width
|
594
|
+
self.width = original_width
|
595
|
+
end
|
596
|
+
if original_height
|
597
|
+
self.height = original_height
|
598
|
+
end
|
522
599
|
@perform_redraw = true
|
523
|
-
|
600
|
+
result_args
|
524
601
|
end
|
525
602
|
|
526
603
|
def default_x?
|
527
|
-
current_parameter_name?(
|
604
|
+
current_parameter_name?(:x) and
|
605
|
+
(x.nil? || x.to_s == 'default' || (x.is_a?(Array) && x.first.to_s == 'default'))
|
528
606
|
end
|
529
607
|
|
530
608
|
def default_y?
|
531
|
-
current_parameter_name?(
|
609
|
+
current_parameter_name?(:y) and
|
610
|
+
(y.nil? || y.to_s == 'default' || (y.is_a?(Array) && y.first.to_s == 'default'))
|
611
|
+
end
|
612
|
+
|
613
|
+
def default_width?
|
614
|
+
return false unless current_parameter_name?(:width)
|
615
|
+
width = self.width
|
616
|
+
(width.nil? || width == :default || width == 'default' || (width.is_a?(Array) && (width.first.to_s == :default || width.first.to_s == 'default')))
|
617
|
+
end
|
618
|
+
|
619
|
+
def default_height?
|
620
|
+
return false unless current_parameter_name?(:height)
|
621
|
+
height = self.height
|
622
|
+
(height.nil? || height == :default || height == 'default' || (height.is_a?(Array) && (height.first.to_s == :default || height.first.to_s == 'default')))
|
532
623
|
end
|
533
624
|
|
534
625
|
def default_x
|
535
|
-
|
536
|
-
|
537
|
-
|
538
|
-
0
|
539
|
-
end
|
626
|
+
result = ((parent.size.x - size.x) / 2)
|
627
|
+
result += parent.bounds.x - parent.absolute_x if parent.is_a?(Shape)
|
628
|
+
result
|
540
629
|
end
|
541
630
|
|
542
631
|
def default_y
|
543
|
-
|
544
|
-
|
545
|
-
|
546
|
-
|
632
|
+
result = ((parent.size.y - size.y) / 2)
|
633
|
+
result += parent.bounds.y - parent.absolute_y if parent.is_a?(Shape)
|
634
|
+
result
|
635
|
+
end
|
636
|
+
|
637
|
+
def default_width
|
638
|
+
x_start_end_pairs = shapes.map do |shape|
|
639
|
+
shape_x = shape.default_x? ? 0 : shape.x.to_f
|
640
|
+
shape_width = shape.calculated_width.to_f
|
641
|
+
[shape_x, shape_x + shape_width]
|
547
642
|
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
|
646
|
+
end
|
647
|
+
|
648
|
+
def default_height
|
649
|
+
y_start_end_pairs = shapes.map do |shape|
|
650
|
+
shape_y = shape.default_y? ? 0 : shape.y.to_f
|
651
|
+
shape_height = shape.calculated_height.to_f
|
652
|
+
[shape_y, shape_y + shape_height]
|
653
|
+
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
|
657
|
+
end
|
658
|
+
|
659
|
+
def calculated_width
|
660
|
+
default_width? ? default_width : width
|
661
|
+
end
|
662
|
+
|
663
|
+
def calculated_height
|
664
|
+
default_height? ? default_height : height
|
665
|
+
end
|
666
|
+
|
667
|
+
def default_x_delta
|
668
|
+
return 0 unless default_x? && x.is_a?(Array)
|
669
|
+
x[1].to_f
|
670
|
+
end
|
671
|
+
|
672
|
+
def default_y_delta
|
673
|
+
return 0 unless default_y? && y.is_a?(Array)
|
674
|
+
y[1].to_f
|
675
|
+
end
|
676
|
+
|
677
|
+
def default_width_delta
|
678
|
+
return 0 unless default_width? && width.is_a?(Array)
|
679
|
+
width[1].to_f
|
680
|
+
end
|
681
|
+
|
682
|
+
def default_height_delta
|
683
|
+
return 0 unless default_height? && height.is_a?(Array)
|
684
|
+
height[1].to_f
|
685
|
+
end
|
686
|
+
|
687
|
+
def default_x_delta=(delta)
|
688
|
+
return unless default_x?
|
689
|
+
self.x = [:default, delta]
|
690
|
+
end
|
691
|
+
|
692
|
+
def default_y_delta=(delta)
|
693
|
+
return unless default_y?
|
694
|
+
self.y = [:default, delta]
|
695
|
+
end
|
696
|
+
|
697
|
+
def default_width_delta=(delta)
|
698
|
+
return unless default_width?
|
699
|
+
self.width = [:default, delta]
|
700
|
+
end
|
701
|
+
|
702
|
+
def default_height_delta=(delta)
|
703
|
+
return unless default_height?
|
704
|
+
self.height = [:default, delta]
|
705
|
+
end
|
706
|
+
|
707
|
+
def calculated_x
|
708
|
+
result = default_x? ? default_x : self.x
|
709
|
+
result += default_x_delta
|
710
|
+
result
|
711
|
+
end
|
712
|
+
|
713
|
+
def calculated_y
|
714
|
+
result = default_y? ? default_y : self.y
|
715
|
+
result += default_y_delta
|
716
|
+
result
|
548
717
|
end
|
549
718
|
|
550
719
|
def absolute_x
|
551
|
-
x =
|
552
|
-
x += @x_delta
|
720
|
+
x = calculated_x
|
553
721
|
if parent.is_a?(Shape)
|
554
722
|
parent.absolute_x + x
|
555
723
|
else
|
@@ -558,8 +726,7 @@ module Glimmer
|
|
558
726
|
end
|
559
727
|
|
560
728
|
def absolute_y
|
561
|
-
y =
|
562
|
-
y += @y_delta
|
729
|
+
y = calculated_y
|
563
730
|
if parent.is_a?(Shape)
|
564
731
|
parent.absolute_y + y
|
565
732
|
else
|
@@ -567,6 +734,13 @@ module Glimmer
|
|
567
734
|
end
|
568
735
|
end
|
569
736
|
|
737
|
+
# Overriding inspect to avoid printing very long shape hierarchies
|
738
|
+
def inspect
|
739
|
+
"#<#{self.class.name}:0x#{self.hash.to_s(16)} args=#{@args.inspect}, properties=#{@properties.inspect}}>"
|
740
|
+
rescue => e
|
741
|
+
"#<#{self.class.name}:0x#{self.hash.to_s(16)}"
|
742
|
+
end
|
743
|
+
|
570
744
|
def calculate_paint_args!
|
571
745
|
unless @calculated_paint_args
|
572
746
|
if @name == 'pixel'
|
@@ -37,10 +37,23 @@ module Glimmer
|
|
37
37
|
[:x, :y, :width, :height, :start_angle, :arc_angle]
|
38
38
|
end
|
39
39
|
|
40
|
+
def bounds
|
41
|
+
shape_bounds = geometry.getBounds2D
|
42
|
+
org.eclipse.swt.graphics.Rectangle.new(shape_bounds.x, shape_bounds.y, shape_bounds.width, shape_bounds.height)
|
43
|
+
end
|
44
|
+
|
45
|
+
def size
|
46
|
+
shape_bounds = geometry.getBounds2D
|
47
|
+
org.eclipse.swt.graphics.Point.new(shape_bounds.width, shape_bounds.height)
|
48
|
+
end
|
49
|
+
|
50
|
+
def geometry
|
51
|
+
java.awt.geom.Arc2D::Double.new(self.absolute_x, self.absolute_y, calculated_width, calculated_height, start_angle, arc_angle, java.awt.geom.Arc2D::PIE)
|
52
|
+
end
|
53
|
+
|
40
54
|
# checks if shape contains the point denoted by x and y
|
41
55
|
def contain?(x, y)
|
42
|
-
|
43
|
-
shape_geometry.contains(x, y)
|
56
|
+
geometry.contains(x, y)
|
44
57
|
end
|
45
58
|
|
46
59
|
def include?(x, y)
|
@@ -48,8 +61,8 @@ module Glimmer
|
|
48
61
|
contain?(x, y)
|
49
62
|
else
|
50
63
|
# give it some fuzz to allow a larger region around the drawn oval to accept including a point (helps with mouse clickability on a shape)
|
51
|
-
outer_shape_geometry = java.awt.geom.Arc2D::Double.new(self.absolute_x, self.absolute_y,
|
52
|
-
inner_shape_geometry = java.awt.geom.Arc2D::Double.new(self.absolute_x, self.absolute_y,
|
64
|
+
outer_shape_geometry = java.awt.geom.Arc2D::Double.new(self.absolute_x, self.absolute_y, calculated_width + 3, calculated_height + 3, start_angle, arc_angle, java.awt.geom.Arc2D::PIE)
|
65
|
+
inner_shape_geometry = java.awt.geom.Arc2D::Double.new(self.absolute_x, self.absolute_y, calculated_width - 3, calculated_height - 3, start_angle, arc_angle, java.awt.geom.Arc2D::PIE)
|
53
66
|
outer_shape_geometry.contains(x, y) && !inner_shape_geometry.contains(x, y)
|
54
67
|
end
|
55
68
|
end
|
@@ -80,17 +80,17 @@ module Glimmer
|
|
80
80
|
|
81
81
|
def default_x?
|
82
82
|
super ||
|
83
|
-
current_parameter_name?(
|
83
|
+
current_parameter_name?(:dest_x) && (dest_x.nil? || dest_x.to_s == 'default')
|
84
84
|
end
|
85
85
|
|
86
86
|
def default_y?
|
87
87
|
super ||
|
88
|
-
current_parameter_name?(
|
88
|
+
current_parameter_name?(:dest_y) && (dest_y.nil? || dest_y.to_s == 'default')
|
89
89
|
end
|
90
90
|
|
91
91
|
def move_by(x_delta, y_delta)
|
92
92
|
if default_x?
|
93
|
-
self.
|
93
|
+
self.default_x_delta += x_delta
|
94
94
|
elsif dest_x
|
95
95
|
self.dest_x += x_delta
|
96
96
|
else
|
@@ -98,7 +98,7 @@ module Glimmer
|
|
98
98
|
end
|
99
99
|
|
100
100
|
if default_y?
|
101
|
-
self.
|
101
|
+
self.default_y_delta += y_delta
|
102
102
|
elsif dest_y
|
103
103
|
self.dest_y += y_delta
|
104
104
|
else
|
@@ -50,14 +50,40 @@ module Glimmer
|
|
50
50
|
parameter_names
|
51
51
|
end
|
52
52
|
|
53
|
-
|
53
|
+
def bounds
|
54
|
+
shape_bounds = geometry.getBounds2D
|
55
|
+
org.eclipse.swt.graphics.Rectangle.new(shape_bounds.x, shape_bounds.y, shape_bounds.width, shape_bounds.height)
|
56
|
+
end
|
57
|
+
|
58
|
+
def size
|
59
|
+
shape_bounds = geometry.getBounds2D
|
60
|
+
org.eclipse.swt.graphics.Point.new(shape_bounds.width, shape_bounds.height)
|
61
|
+
end
|
62
|
+
|
63
|
+
def geometry
|
64
|
+
java.awt.geom.Line2D::Double.new(absolute_x1, absolute_y1, absolute_x2, absolute_y2)
|
65
|
+
end
|
66
|
+
|
67
|
+
# Logical x coordinate relative to parent
|
54
68
|
def x
|
55
|
-
|
69
|
+
x_value = bounds.x
|
70
|
+
x_value -= parent.absolute_x if parent.is_a?(Shape)
|
71
|
+
x_value
|
56
72
|
end
|
57
73
|
|
58
|
-
# Logical y coordinate
|
74
|
+
# Logical y coordinate relative to parent
|
59
75
|
def y
|
60
|
-
|
76
|
+
y_value = bounds.y
|
77
|
+
y_value -= parent.absolute_y if parent.is_a?(Shape)
|
78
|
+
y_value
|
79
|
+
end
|
80
|
+
|
81
|
+
def width
|
82
|
+
bounds.width
|
83
|
+
end
|
84
|
+
|
85
|
+
def height
|
86
|
+
bounds.height
|
61
87
|
end
|
62
88
|
|
63
89
|
def absolute_x1
|
@@ -39,7 +39,7 @@ module Glimmer
|
|
39
39
|
|
40
40
|
# checks if shape contains the point denoted by x and y
|
41
41
|
def contain?(x, y)
|
42
|
-
shape_geometry = java.awt.geom.Ellipse2D::Double.new(self.absolute_x, self.absolute_y,
|
42
|
+
shape_geometry = java.awt.geom.Ellipse2D::Double.new(self.absolute_x, self.absolute_y, calculated_width, calculated_height)
|
43
43
|
shape_geometry.contains(x, y)
|
44
44
|
end
|
45
45
|
|
@@ -49,8 +49,8 @@ module Glimmer
|
|
49
49
|
contain?(x, y)
|
50
50
|
else
|
51
51
|
# give it some fuzz to allow a larger region around the drawn oval to accept including a point (helps with mouse clickability on a shape)
|
52
|
-
outer_shape_geometry = java.awt.geom.Ellipse2D::Double.new(self.absolute_x - 3, self.absolute_y - 3,
|
53
|
-
inner_shape_geometry = java.awt.geom.Ellipse2D::Double.new(self.absolute_x + 3, self.absolute_y + 3,
|
52
|
+
outer_shape_geometry = java.awt.geom.Ellipse2D::Double.new(self.absolute_x - 3, self.absolute_y - 3, calculated_width + 6, calculated_height + 6)
|
53
|
+
inner_shape_geometry = java.awt.geom.Ellipse2D::Double.new(self.absolute_x + 3, self.absolute_y + 3, calculated_width - 6, calculated_height - 6)
|
54
54
|
outer_shape_geometry.contains(x, y) && !inner_shape_geometry.contains(x, y)
|
55
55
|
end
|
56
56
|
end
|
@@ -37,6 +37,14 @@ module Glimmer
|
|
37
37
|
[:x, :y]
|
38
38
|
end
|
39
39
|
|
40
|
+
def width
|
41
|
+
1
|
42
|
+
end
|
43
|
+
|
44
|
+
def height
|
45
|
+
1
|
46
|
+
end
|
47
|
+
|
40
48
|
def include?(x, y)
|
41
49
|
# give it some fuzz (helps makes mouse clicking easier)
|
42
50
|
x.to_i.between?(self.absolute_x.to_i - 2, self.absolute_x.to_i + 2) && y.to_i.between?(self.absolute_y.to_i - 2, self.absolute_y.to_i + 2)
|
@@ -62,16 +62,6 @@ module Glimmer
|
|
62
62
|
x_array.zip(y_array)
|
63
63
|
end
|
64
64
|
|
65
|
-
# Logical x coordinate. Always assumes the first point in the polygon to be the x coordinate.
|
66
|
-
def x
|
67
|
-
x_array.first
|
68
|
-
end
|
69
|
-
|
70
|
-
# Logical y coordinate. Always assumes the first point in the polygon to be the y coordinate.
|
71
|
-
def y
|
72
|
-
y_array.first
|
73
|
-
end
|
74
|
-
|
75
65
|
def absolute_point_array
|
76
66
|
if parent.is_a?(Shape)
|
77
67
|
point_array.each_with_index.map do |coordinate, i|
|
@@ -98,9 +88,59 @@ module Glimmer
|
|
98
88
|
absolute_x_array.zip(absolute_y_array)
|
99
89
|
end
|
100
90
|
|
91
|
+
def bounds
|
92
|
+
the_point_array = point_array
|
93
|
+
if the_point_array != @bounds_point_array
|
94
|
+
@bounds_point_array = point_array
|
95
|
+
shape_bounds = geometry.getBounds2D
|
96
|
+
@bounds = org.eclipse.swt.graphics.Rectangle.new(shape_bounds.x, shape_bounds.y, shape_bounds.width, shape_bounds.height)
|
97
|
+
end
|
98
|
+
@bounds
|
99
|
+
end
|
100
|
+
|
101
|
+
def size
|
102
|
+
the_point_array = point_array
|
103
|
+
if the_point_array != @size_point_array
|
104
|
+
@size_point_array = point_array
|
105
|
+
shape_bounds = geometry.getBounds2D
|
106
|
+
@size = org.eclipse.swt.graphics.Point.new(shape_bounds.width, shape_bounds.height)
|
107
|
+
end
|
108
|
+
@size
|
109
|
+
end
|
110
|
+
|
111
|
+
def geometry
|
112
|
+
the_point_array = point_array
|
113
|
+
if the_point_array != @geometry_point_array
|
114
|
+
@geometry_point_array = point_array
|
115
|
+
@geometry = java.awt.Polygon.new(absolute_x_array.to_java(:int), absolute_y_array.to_java(:int), point_count)
|
116
|
+
end
|
117
|
+
@geometry
|
118
|
+
end
|
119
|
+
|
120
|
+
# Logical x coordinate relative to parent
|
121
|
+
def x
|
122
|
+
x_value = bounds.x
|
123
|
+
x_value -= parent.absolute_x if parent.is_a?(Shape)
|
124
|
+
x_value
|
125
|
+
end
|
126
|
+
|
127
|
+
# Logical y coordinate relative to parent
|
128
|
+
def y
|
129
|
+
y_value = bounds.y
|
130
|
+
y_value -= parent.absolute_y if parent.is_a?(Shape)
|
131
|
+
y_value
|
132
|
+
end
|
133
|
+
|
134
|
+
def width
|
135
|
+
bounds.width
|
136
|
+
end
|
137
|
+
|
138
|
+
def height
|
139
|
+
bounds.height
|
140
|
+
end
|
141
|
+
|
101
142
|
def include?(x, y)
|
102
|
-
|
103
|
-
shape_geometry.contains(x, y)
|
143
|
+
geometry.contains(x, y)
|
104
144
|
end
|
105
145
|
alias contain? include? # TODO make include do an outer/inner check of edge detection only
|
106
146
|
|
@@ -62,16 +62,6 @@ module Glimmer
|
|
62
62
|
x_array.zip(y_array)
|
63
63
|
end
|
64
64
|
|
65
|
-
# Logical x coordinate. Always assumes the first point in the polyline to be the x coordinate.
|
66
|
-
def x
|
67
|
-
x_array.first
|
68
|
-
end
|
69
|
-
|
70
|
-
# Logical y coordinate. Always assumes the first point in the polyline to be the y coordinate.
|
71
|
-
def y
|
72
|
-
y_array.first
|
73
|
-
end
|
74
|
-
|
75
65
|
def absolute_point_array
|
76
66
|
if parent.is_a?(Shape)
|
77
67
|
point_array.each_with_index.map do |coordinate, i|
|
@@ -98,6 +88,42 @@ module Glimmer
|
|
98
88
|
absolute_x_array.zip(absolute_y_array)
|
99
89
|
end
|
100
90
|
|
91
|
+
def bounds
|
92
|
+
shape_bounds = geometry.getBounds2D
|
93
|
+
org.eclipse.swt.graphics.Rectangle.new(shape_bounds.x, shape_bounds.y, shape_bounds.width, shape_bounds.height)
|
94
|
+
end
|
95
|
+
|
96
|
+
def size
|
97
|
+
shape_bounds = geometry.getBounds2D
|
98
|
+
org.eclipse.swt.graphics.Point.new(shape_bounds.width, shape_bounds.height)
|
99
|
+
end
|
100
|
+
|
101
|
+
def geometry
|
102
|
+
java.awt.Polygon.new(absolute_x_array.to_java(:int), absolute_y_array.to_java(:int), point_count)
|
103
|
+
end
|
104
|
+
|
105
|
+
# Logical x coordinate relative to parent
|
106
|
+
def x
|
107
|
+
x_value = bounds.x
|
108
|
+
x_value -= parent.absolute_x if parent.is_a?(Shape)
|
109
|
+
x_value
|
110
|
+
end
|
111
|
+
|
112
|
+
# Logical y coordinate relative to parent
|
113
|
+
def y
|
114
|
+
y_value = bounds.y
|
115
|
+
y_value -= parent.absolute_y if parent.is_a?(Shape)
|
116
|
+
y_value
|
117
|
+
end
|
118
|
+
|
119
|
+
def width
|
120
|
+
bounds.width
|
121
|
+
end
|
122
|
+
|
123
|
+
def height
|
124
|
+
bounds.height
|
125
|
+
end
|
126
|
+
|
101
127
|
def include?(x, y)
|
102
128
|
comparison_lines = absolute_point_xy_array.zip(absolute_point_xy_array.rotate(1))
|
103
129
|
comparison_lines.pop # ignore last pair since you don't want to compare last point with first point
|
@@ -34,6 +34,7 @@ module Glimmer
|
|
34
34
|
class Shape
|
35
35
|
class Rectangle < Shape
|
36
36
|
def parameter_names
|
37
|
+
# TODO consider optimizing just like text where it is set upon updating attribute and here you just return a variable
|
37
38
|
if @args.to_a.size >= 6
|
38
39
|
rectangle_round_parameter_names
|
39
40
|
elsif @args.to_a.size == 5
|
@@ -81,11 +82,11 @@ module Glimmer
|
|
81
82
|
end
|
82
83
|
|
83
84
|
def point_xy_array
|
84
|
-
[[x, y], [x +
|
85
|
+
[[x, y], [x + calculated_width, y], [x + calculated_width, y + calculated_height], [x, y + calculated_height]]
|
85
86
|
end
|
86
87
|
|
87
88
|
def absolute_point_xy_array
|
88
|
-
[[absolute_x, absolute_y], [absolute_x +
|
89
|
+
[[absolute_x, absolute_y], [absolute_x + calculated_width, absolute_y], [absolute_x + calculated_width, absolute_y + calculated_height], [absolute_x, absolute_y + calculated_height]]
|
89
90
|
end
|
90
91
|
|
91
92
|
# checks if drawn or filled rectangle includes the point denoted by x and y (if drawn, it only returns true if point lies on the edge)
|
@@ -33,8 +33,6 @@ module Glimmer
|
|
33
33
|
# That is because Shape is drawn on a parent as graphics and doesn't have an SWT widget for itself
|
34
34
|
class Shape
|
35
35
|
class Text < Shape
|
36
|
-
attr_accessor :extent
|
37
|
-
|
38
36
|
def parameter_names
|
39
37
|
@parameter_names || text_parameter_names
|
40
38
|
end
|
@@ -69,11 +67,11 @@ module Glimmer
|
|
69
67
|
end
|
70
68
|
|
71
69
|
def width
|
72
|
-
extent&.x
|
70
|
+
@extent&.x
|
73
71
|
end
|
74
72
|
|
75
73
|
def height
|
76
|
-
extent&.y
|
74
|
+
@extent&.y
|
77
75
|
end
|
78
76
|
|
79
77
|
end
|
@@ -25,9 +25,20 @@ class HelloCanvas
|
|
25
25
|
include Glimmer::UI::CustomShell
|
26
26
|
|
27
27
|
attr_accessor :selected_shape
|
28
|
+
attr_accessor :artist
|
28
29
|
|
29
30
|
before_body {
|
30
31
|
@image_object = image(File.expand_path('../../icons/scaffold_app.png', __dir__), width: 50)
|
32
|
+
@artist = ''
|
33
|
+
}
|
34
|
+
|
35
|
+
after_body {
|
36
|
+
Thread.new {
|
37
|
+
'Picasso'.chars.each do |character|
|
38
|
+
sleep(1)
|
39
|
+
self.artist += character
|
40
|
+
end
|
41
|
+
}
|
31
42
|
}
|
32
43
|
|
33
44
|
body {
|
@@ -38,10 +49,36 @@ class HelloCanvas
|
|
38
49
|
@canvas = canvas {
|
39
50
|
background :yellow
|
40
51
|
rectangle(0, 0, 220, 400) {
|
41
|
-
background
|
52
|
+
background rgb(255, 0, 0)
|
42
53
|
}
|
43
54
|
rectangle(50, 20, 300, 150, 30, 50) {
|
44
55
|
background :magenta
|
56
|
+
rectangle([:default, -70], :default, :default, [:default, 1]) {
|
57
|
+
foreground :cyan
|
58
|
+
text {
|
59
|
+
x :default, 1
|
60
|
+
# y is assumed to be the default (centered within parent)
|
61
|
+
string bind(self, :artist)
|
62
|
+
background :yellow
|
63
|
+
foreground :dark_magenta
|
64
|
+
font name: 'Courier', height: 30
|
65
|
+
}
|
66
|
+
}
|
67
|
+
rectangle(155, 30) { # width and height are assumed to be the default (calculated from children)
|
68
|
+
foreground :yellow
|
69
|
+
3.times { |n|
|
70
|
+
line(45, 70 + n*10, 65 + n*10, 30 + n*10) {
|
71
|
+
foreground :yellow
|
72
|
+
}
|
73
|
+
}
|
74
|
+
10.times {|n|
|
75
|
+
point(15 + n*5, 50 + n*5) {
|
76
|
+
foreground :yellow
|
77
|
+
}
|
78
|
+
}
|
79
|
+
polyline(45, 60, 55, 20, 65, 60, 85, 80, 45, 60)
|
80
|
+
image(@image_object, 0, 5)
|
81
|
+
}
|
45
82
|
}
|
46
83
|
rectangle(150, 200, 100, 70, true) {
|
47
84
|
background :dark_magenta
|
@@ -51,26 +88,6 @@ class HelloCanvas
|
|
51
88
|
background :magenta
|
52
89
|
foreground :dark_blue
|
53
90
|
}
|
54
|
-
rectangle(205, 50, 88, 96) {
|
55
|
-
foreground :yellow
|
56
|
-
3.times { |n|
|
57
|
-
line(45, 70 + n*10, 65 + n*10, 30 + n*10) {
|
58
|
-
foreground :yellow
|
59
|
-
}
|
60
|
-
}
|
61
|
-
10.times {|n|
|
62
|
-
point(15 + n*5, 50 + n*5) {
|
63
|
-
foreground :yellow
|
64
|
-
}
|
65
|
-
}
|
66
|
-
polyline(45, 60, 55, 20, 65, 60, 85, 80, 45, 60)
|
67
|
-
image(@image_object, 0, 5)
|
68
|
-
}
|
69
|
-
text('Picasso', 60, 80) {
|
70
|
-
background :yellow
|
71
|
-
foreground :dark_magenta
|
72
|
-
font name: 'Courier', height: 30
|
73
|
-
}
|
74
91
|
oval(110, 310, 100, 100) {
|
75
92
|
# patterns provide a differnet way to make gradients
|
76
93
|
background_pattern 0, 0, 105, 0, :yellow, rgb(128, 138, 248)
|
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.5.
|
4
|
+
version: 4.18.5.4
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- AndyMaleh
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2021-02-
|
11
|
+
date: 2021-02-26 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
requirement: !ruby/object:Gem::Requirement
|