glimmer-dsl-swt 4.18.6.0 → 4.18.6.1

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: 2b3fe4c65726425f091b0660bbf4dd4c55543c5c515bed56487aacb7e1458b7e
4
- data.tar.gz: 71580957a753685f1eac22fb60ea13c2e2f289bb47017293980d4d06d78d5eec
3
+ metadata.gz: 6951b42a995fd393c82fcb406f5bb308aacf9330d75b85e0050104451044870c
4
+ data.tar.gz: 1de171314b2b6da4c80e295152a91697085e8bc7b00502fb0af88aef2890defc
5
5
  SHA512:
6
- metadata.gz: 974be0abde39dbacdabe5d560c319a049907791e280f03aa6192e945b64057f814cbc57346f51cead9627ee98db52276367f4ca1f8f497b2882846d280a7f103
7
- data.tar.gz: 7b9c169a4705c8bfa390ef440e31100e40560eabca4f204d18d8e5197174d9834827fd9f76907384c2d8e3873f968c11b94f6a985c3a43eda0bbf9b8fc7b8bc9
6
+ metadata.gz: d996c3707e136ec0e059396a3a06d301953236acbde4012f428fdc85dab3e13843296ace25426d41fa6fe7d87031ab5990a40e62a2b572bfbd47b97759575892
7
+ data.tar.gz: 5c317cdc5e75597d03bf241436cad374cd05e64d4a91739d08945ed2b4a5464807128eb25f23b271a057fdb4dd7b79372eee3c68f6f336a4fd27af8448ce31a9
data/CHANGELOG.md CHANGED
@@ -1,5 +1,12 @@
1
1
  # Change Log
2
2
 
3
+ ### 4.18.6.1
4
+
5
+ - Fixed issues with Canvas Path DSL handling of connected vs non-connected path segments (including in geometry calculations)
6
+ - Optimized Canvas Path DSL redraw performance by removing extra redraws
7
+ - Fixed issues in the Hello, Canvas Path! sample and renamed to Stock Ticker
8
+ - Added a new simpler Hello, Canvas Path! sample
9
+
3
10
  ### 4.18.6.0
4
11
 
5
12
  - 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)
data/VERSION CHANGED
@@ -1 +1 @@
1
- 4.18.6.0
1
+ 4.18.6.1
@@ -1956,9 +1956,9 @@ As they say, there are many ways to skin a cat! This is in line with the Ruby wa
1956
1956
 
1957
1957
  ### Canvas Path DSL
1958
1958
 
1959
- **(EARLY ALPHA FEATURE)**
1959
+ **(ALPHA FEATURE)**
1960
1960
 
1961
- Unlike common imperative GUI charting 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 keywords underneath:
1961
+ 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:
1962
1962
  - `point(x1, y1)`: renders a Point (Dot) as part of a path.
1963
1963
  - `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.
1964
1964
  - `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.
@@ -1967,8 +1967,10 @@ Unlike common imperative GUI charting toolkits, Glimmer enables declarative rend
1967
1967
  Example:
1968
1968
 
1969
1969
  ```ruby
1970
+ include Glimmer
1971
+
1970
1972
  shell {
1971
- text 'Canvas Path DSL Example'
1973
+ text 'Canvas Path Example'
1972
1974
  minimum_size 300, 300
1973
1975
 
1974
1976
  canvas {
@@ -1984,9 +1986,11 @@ shell {
1984
1986
  }.open
1985
1987
  ```
1986
1988
 
1987
- Learn more at the [Hello, Canvas Path! Sample](/samples/hello/hello_canvas_path.rb).
1989
+ ![Canvas Path Example](/images/glimmer-example-canvas-path.png)
1990
+
1991
+ Learn more at the [Hello, Canvas Path!](GLIMMER_SAMPLES.md#hello-canvas-path) and [Stock Ticker](GLIMMER_SAMPLES.md#stock-ticker) samples.
1988
1992
 
1989
- ![Hello Canvas Path Sample](/images/glimmer-hello-canvas-path.gif)
1993
+ ![Stock Ticker](/images/glimmer-stock-ticker.gif)
1990
1994
 
1991
1995
  ### Canvas Transform DSL
1992
1996
 
@@ -33,6 +33,7 @@
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)
36
37
  - [Hello, Cursor!](#hello-cursor)
37
38
  - [Hello, Progress Bar!](#hello-progress-bar)
38
39
  - [Hello, Tree!](#hello-tree)
@@ -45,6 +46,7 @@
45
46
  - [Contact Manager](#contact-manager)
46
47
  - [Glimmer Tetris](#glimmer-tetris)
47
48
  - [Mandelbrot Fractal](#mandelbrot-fractal)
49
+ - [Stock Ticker](#stock-ticker)
48
50
  - [External Samples](#external-samples)
49
51
  - [Glimmer Calculator](#glimmer-calculator)
50
52
  - [Gladiator](#gladiator)
@@ -616,6 +618,18 @@ Hello, Canvas Transform!
616
618
 
617
619
  ![Hello Canvas Transform](/images/glimmer-hello-canvas-transform.png)
618
620
 
621
+ #### Hello, Canvas Path!
622
+
623
+ 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).
624
+
625
+ Code:
626
+
627
+ [samples/hello/hello_canvas_path.rb](/samples/hello/hello_canvas_path.rb)
628
+
629
+ Hello, Canvas Path!
630
+
631
+ ![Hello Canvas Path](/images/glimmer-hello-canvas-path.png)
632
+
619
633
  #### Hello, Cursor!
620
634
 
621
635
  This sample demonstrates the use of the `cursor` property keyword to change the mouse cursor.
@@ -812,6 +826,16 @@ Code:
812
826
 
813
827
  ![Mandelbrot Fractal Help Menu](/images/glimmer-mandelbrot-menu-help.png)
814
828
 
829
+ #### Stock Ticker
830
+
831
+ 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.
832
+
833
+ Code:
834
+
835
+ [samples/elaborate/stock_ticker.rb](/samples/elaborate/stock_ticker.rb)
836
+
837
+ ![Stock Ticker](/images/glimmer-stock-ticker.gif)
838
+
815
839
  ### External Samples
816
840
 
817
841
  #### 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.6.0 ruby lib
5
+ # stub: glimmer-dsl-swt 4.18.6.1 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.0"
9
+ s.version = "4.18.6.1"
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-28"
14
+ s.date = "2021-03-01"
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]
@@ -166,6 +166,7 @@ Gem::Specification.new do |s|
166
166
  "samples/elaborate/login.rb",
167
167
  "samples/elaborate/mandelbrot_fractal.rb",
168
168
  "samples/elaborate/meta_sample.rb",
169
+ "samples/elaborate/stock_ticker.rb",
169
170
  "samples/elaborate/tetris.rb",
170
171
  "samples/elaborate/tetris/model/block.rb",
171
172
  "samples/elaborate/tetris/model/game.rb",
@@ -230,7 +230,6 @@ module Glimmer
230
230
  Glimmer::SWT::DisplayProxy.instance.auto_exec do
231
231
  Glimmer::DSL::Engine.add_content(self, Glimmer::DSL::SWT::ShapeExpression.new, &block)
232
232
  calculated_args_changed!(children: false)
233
- drawable.redraw unless drawable.is_a?(ImageProxy)
234
233
  end
235
234
  end
236
235
 
@@ -243,11 +242,11 @@ module Glimmer
243
242
  end
244
243
 
245
244
  def post_add_content
246
- # unless @content_added # TODO delete if no longer needed
247
- amend_method_name_options_based_on_properties!
245
+ amend_method_name_options_based_on_properties!
246
+ if !@content_added || @method_name != @original_method_name
248
247
  @drawable.setup_shape_painting unless @drawable.is_a?(ImageProxy)
249
248
  @content_added = true
250
- # end
249
+ end
251
250
  end
252
251
 
253
252
  def apply_property_arg_conversions(method_name, property, args)
@@ -367,6 +366,7 @@ module Glimmer
367
366
  end
368
367
 
369
368
  def amend_method_name_options_based_on_properties!
369
+ @original_method_name = @method_name
370
370
  return if @name == 'point'
371
371
  if @name != 'text' && @name != 'string' && has_some_background? && !has_some_foreground?
372
372
  @options[:fill] = true
@@ -39,14 +39,15 @@ module Glimmer
39
39
  end
40
40
 
41
41
  def geometry
42
- if @point_array != @geometry_point_array
43
- @geometry_point_array = @point_array
42
+ the_point_array = point_array
43
+ if the_point_array != @geometry_point_array
44
+ @geometry_point_array = the_point_array
44
45
  @geometry = Java::JavaAwtGeom::Path2D::Double.new
45
- @geometry.send(path_segment_geometry_method_name, *path_segment_geometry_args)
46
+ add_to_geometry(@geometry)
46
47
  end
47
48
  @geometry
48
49
  end
49
-
50
+
50
51
  def contain?(x, y)
51
52
  include?(x, y, filled: true)
52
53
  end
@@ -74,7 +75,7 @@ module Glimmer
74
75
  the_point_array = the_point_array.first if the_point_array.first.is_a?(Array)
75
76
  self.point_array = the_point_array.each_with_index.map {|coordinate, i| i.even? ? coordinate + x_delta : coordinate + y_delta}
76
77
  end
77
-
78
+
78
79
  def path_segment_method_name
79
80
  'cubicTo'
80
81
  end
@@ -84,12 +85,20 @@ module Glimmer
84
85
  @args.to_a
85
86
  end
86
87
 
88
+ def default_path_segment_arg_count
89
+ 8
90
+ end
91
+
92
+ def default_connected_path_segment_arg_count
93
+ 6
94
+ end
95
+
87
96
  def path_segment_geometry_method_name
88
97
  'curveTo'
89
98
  end
90
99
 
91
100
  def previous_point_connected?
92
- @args.compact.count <= 6 && !first_path_segment?
101
+ @args.compact.count == 6 && !first_path_segment?
93
102
  end
94
103
 
95
104
  def eql?(other)
@@ -147,6 +147,14 @@ module Glimmer
147
147
  @args
148
148
  end
149
149
 
150
+ def default_path_segment_arg_count
151
+ 4
152
+ end
153
+
154
+ def default_connected_path_segment_arg_count
155
+ 2
156
+ end
157
+
150
158
  def path_segment_geometry_args
151
159
  # TODO make args auto-infer first point if previous_point_connected is true or if there is only x1,y1 or x2,y2 (but not both), or if there is an x, y, or if there is a point_array with 1 point
152
160
  @args[0..1]
@@ -97,16 +97,22 @@ module Glimmer
97
97
  end
98
98
 
99
99
  def calculated_args
100
+ new_swt_path = @swt_path.nil?
100
101
  @swt_path ||= org.eclipse.swt.graphics.Path.new(Glimmer::SWT::DisplayProxy.instance.swt_display)
101
102
  # TODO recreate @swt_path only if one of the children get disposed (must notify parent on dispose)
102
103
  @args = [@swt_path]
103
- @uncalculated_path_segments.dup.each do |path_segment|
104
+ @uncalculated_path_segments.each do |path_segment|
104
105
  path_segment.add_to_swt_path(@swt_path)
105
106
  @uncalculated_path_segments.delete(path_segment)
106
107
  end
107
- super
108
+ if new_swt_path
109
+ @path_calculated_args = super
110
+ else
111
+ @path_calculated_args
112
+ end
108
113
  rescue => e
109
114
  Glimmer::Config.logger.error {e.full_message}
115
+ @args
110
116
  end
111
117
 
112
118
  def move_by(x_delta, y_delta)
@@ -158,7 +164,7 @@ module Glimmer
158
164
  @geometry_path_segments = @path_segments
159
165
  @geometry = Java::JavaAwtGeom::Path2D::Double.new
160
166
  @path_segments.each do |path_segment|
161
- @geometry.send(path_segment.path_segment_geometry_method_name, *path_segment.path_segment_geometry_args)
167
+ path_segment.add_to_geometry(@geometry)
162
168
  end
163
169
  end
164
170
  @geometry
@@ -173,12 +179,20 @@ module Glimmer
173
179
  end
174
180
 
175
181
  def path_segment_geometry_method_name
176
- 'append'
182
+ if self.class == Path
183
+ 'append'
184
+ else
185
+ super
186
+ end
177
187
  end
178
188
 
179
189
  def path_segment_geometry_args
180
- # TODO consider supporting connected true instead of false (2nd arg)
181
- [geometry, false]
190
+ if self.class == Path
191
+ # TODO consider supporting connected true instead of false (2nd arg)
192
+ [geometry, false]
193
+ else
194
+ super
195
+ end
182
196
  end
183
197
 
184
198
  def eql?(other)
@@ -38,6 +38,12 @@ module Glimmer
38
38
  def path_segment_args
39
39
  []
40
40
  end
41
+ # Subclasses must override to indicate expected complete count of args when previous point is NOT connected (e.g. 4 for line, 6 for quad, 8 for cubic)
42
+ def default_path_segment_arg_count
43
+ end
44
+ # Subclasses must override to indicate expected count of args when previous point IS connected (e.g. 2 for line, 4 for quad, 6 for cubic)
45
+ def default_connected_path_segment_arg_count
46
+ end
41
47
  # Subclasses may override to provide name of method to invoke for geometry object obtained from the Java AWT library java.awt.geom.Path2D.Double (e.g. curveTo vs cubicTo)
42
48
  def path_segment_geometry_method_name
43
49
  path_segment_method_name
@@ -67,18 +73,37 @@ module Glimmer
67
73
  if @swt_path != swt_path
68
74
  @swt_path = swt_path
69
75
  the_path_segment_args = path_segment_args.dup
70
- if !previous_point_connected? && !is_a?(Point)
71
- if the_path_segment_args.count > 2
72
- point = the_path_segment_args.shift, the_path_segment_args.shift
76
+ if !is_a?(Point) && self.class != Path
77
+ if !previous_point_connected?
78
+ if the_path_segment_args.count == default_path_segment_arg_count
79
+ point = the_path_segment_args.shift, the_path_segment_args.shift
80
+ @swt_path.moveTo(*point)
81
+ elsif first_path_segment?
82
+ point = the_path_segment_args[0..1]
83
+ @swt_path.moveTo(*point)
84
+ end
85
+ end
86
+ end
87
+ @swt_path.send(path_segment_method_name, *the_path_segment_args)
88
+ end
89
+ end
90
+
91
+ def add_to_geometry(geometry)
92
+ the_path_segment_geometry_args = path_segment_geometry_args.dup
93
+ if !is_a?(Point) && self.class != Path
94
+ if !previous_point_connected?
95
+ if the_path_segment_geometry_args.count == default_path_segment_arg_count
96
+ point = the_path_segment_geometry_args.shift, the_path_segment_geometry_args.shift
73
97
  @swt_path.moveTo(*point)
74
- elsif first_path_segment? && self.class != Path
75
- point = the_path_segment_args[0..1]
98
+ elsif first_path_segment?
99
+ point = the_path_segment_geometry_args[0..1]
76
100
  @swt_path.moveTo(*point)
77
101
  end
78
102
  end
79
- @swt_path.send(path_segment_method_name, *the_path_segment_args)
80
103
  end
104
+ geometry.send(path_segment_geometry_method_name, *the_path_segment_geometry_args)
81
105
  end
106
+
82
107
  end
83
108
  end
84
109
  end
@@ -39,10 +39,11 @@ module Glimmer
39
39
  end
40
40
 
41
41
  def geometry
42
- if @point_array != @geometry_point_array
43
- @geometry_point_array = @point_array
42
+ the_point_array = point_array
43
+ if the_point_array != @geometry_point_array
44
+ @geometry_point_array = the_point_array
44
45
  @geometry = Java::JavaAwtGeom::Path2D::Double.new
45
- @geometry.send(path_segment_geometry_method_name, *path_segment_geometry_args)
46
+ add_to_geometry(@geometry)
46
47
  end
47
48
  @geometry
48
49
  end
@@ -84,8 +85,16 @@ module Glimmer
84
85
  @args.to_a
85
86
  end
86
87
 
88
+ def default_path_segment_arg_count
89
+ 6
90
+ end
91
+
92
+ def default_connected_path_segment_arg_count
93
+ 4
94
+ end
95
+
87
96
  def previous_point_connected?
88
- @args.compact.count <= 4 && !first_path_segment?
97
+ @args.compact.count == 4 && !first_path_segment?
89
98
  end
90
99
 
91
100
  def eql?(other)
@@ -0,0 +1,229 @@
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-dsl-swt'
23
+
24
+ # This Sample is an Early Alpha (New Canvas Path DSL Feature)
25
+
26
+ class StockTicker
27
+ class Stock
28
+ class << self
29
+ attr_writer :stock_price_min, :stock_price_max
30
+
31
+ def stock_price_min
32
+ @stock_price_min ||= 1
33
+ end
34
+
35
+ def stock_price_max
36
+ @stock_price_max ||= 600
37
+ end
38
+ end
39
+
40
+ attr_reader :name, :stock_prices
41
+ attr_accessor :stock_price
42
+
43
+ def initialize(name, stock_price)
44
+ @name = name
45
+ @stock_price = stock_price
46
+ @stock_prices = [@stock_price]
47
+ @delta_sign = 1
48
+ start_new_trend!
49
+ end
50
+
51
+ def tick!
52
+ @tick_count = @tick_count.to_i + 1
53
+ delta = @tick_count%@trend_length
54
+ if delta == 0
55
+ @delta_sign *= -1
56
+ start_new_trend!
57
+ end
58
+ stock_prices << self.stock_price = [[@stock_price + @delta_sign*delta, Stock.stock_price_min].max, Stock.stock_price_max].min
59
+ end
60
+
61
+ def start_new_trend!
62
+ @trend_length = (rand*12).to_i + 1
63
+ end
64
+ end
65
+
66
+ include Glimmer::UI::CustomShell
67
+
68
+ before_body {
69
+ @stocks = [
70
+ Stock.new('DELL', 81),
71
+ Stock.new('AAPL', 121),
72
+ Stock.new('MSFT', 232),
73
+ Stock.new('ADBE', 459),
74
+ ]
75
+ @stock_colors = [:red, :dark_green, :blue, :dark_magenta]
76
+ max_stock_name_width = 0
77
+ left_margin = 5
78
+ @tabs = ['Lines', 'Quadratic Bezier Curves', 'Cubic Bezier Curves', 'Points'].map {|title| {title: title, stock_paths: [], stock_transforms: []}}
79
+ @stocks.each_with_index do |stock, stock_index|
80
+ observe(stock, :stock_price) do |new_price|
81
+ begin
82
+ @tabs.each do |tab|
83
+ new_x = stock.stock_prices.count - 1
84
+ new_y = @tabs.first[:canvas].bounds.height - new_price - 1
85
+ max_stock_name_width = tab[:text]&.bounds&.width if tab[:text]&.bounds&.width.to_f > max_stock_name_width
86
+ if new_x > 0
87
+ case tab[:title]
88
+ when 'Cubic Bezier Curves'
89
+ if new_x%3 == 0 && stock.stock_prices[new_x] && stock.stock_prices[new_x - 1] && stock.stock_prices[new_x - 2]
90
+ tab[:stock_paths][stock_index].content {
91
+ cubic(new_x - 2, @tabs.first[:canvas].bounds.height - stock.stock_prices[new_x - 2] - 1, new_x - 1, @tabs.first[:canvas].bounds.height - stock.stock_prices[new_x - 1] - 1, new_x, new_y)
92
+ tab[:stock_transforms][stock_index] ||= transform {
93
+ translate max_stock_name_width + 5 + left_margin, tab[:text].bounds.height / 2.0
94
+ }
95
+ }
96
+ end
97
+ when 'Quadratic Bezier Curves'
98
+ if new_x%2 == 0 && stock.stock_prices[new_x] && stock.stock_prices[new_x - 1]
99
+ tab[:stock_paths][stock_index].content {
100
+ quad(new_x - 1, @tabs.first[:canvas].bounds.height - stock.stock_prices[new_x - 1] - 1, new_x, new_y)
101
+ tab[:stock_transforms][stock_index] ||= transform {
102
+ translate max_stock_name_width + 5 + left_margin, tab[:text].bounds.height / 2.0
103
+ }
104
+ }
105
+ end
106
+ when 'Lines'
107
+ tab[:stock_paths][stock_index].content {
108
+ line(new_x, new_y)
109
+ tab[:stock_transforms][stock_index] ||= transform {
110
+ translate max_stock_name_width + 5 + left_margin, tab[:text].bounds.height / 2.0
111
+ }
112
+ }
113
+ when 'Points'
114
+ tab[:stock_paths][stock_index].content {
115
+ point(new_x, new_y)
116
+ tab[:stock_transforms][stock_index] ||= transform {
117
+ translate max_stock_name_width + 5 + left_margin, tab[:text].bounds.height / 2.0
118
+ }
119
+ }
120
+ end
121
+ new_x_location = new_x + max_stock_name_width + 5 + left_margin + 5
122
+ canvas_width = tab[:canvas].bounds.width
123
+ if new_x_location > canvas_width
124
+ tab[:canvas].set_size(new_x_location, @tabs.first[:canvas].bounds.height)
125
+ tab[:canvas].cursor = :hand
126
+ tab[:scrolled_composite].set_min_size(new_x_location, @tabs.first[:canvas].bounds.height)
127
+ tab[:scrolled_composite].set_origin(tab[:scrolled_composite].origin.x + 1, tab[:scrolled_composite].origin.y) if (tab[:scrolled_composite].origin.x + tab[:scrolled_composite].client_area.width) == canvas_width
128
+ end
129
+ else
130
+ tab[:canvas].content {
131
+ tab[:text] = text(stock.name, new_x + left_margin, new_y) {
132
+ foreground @stock_colors[stock_index]
133
+ }
134
+ }
135
+ end
136
+ end
137
+ rescue => e
138
+ Glimmer::Config.logger.error {e.full_message}
139
+ end
140
+ end
141
+ end
142
+ }
143
+
144
+ after_body {
145
+ @thread = Thread.new {
146
+ loop {
147
+ @stocks.each(&:tick!)
148
+ sleep(0.01)
149
+ }
150
+ }
151
+ }
152
+
153
+ body {
154
+ shell {
155
+ fill_layout {
156
+ margin_width 15
157
+ margin_height 15
158
+ }
159
+ text 'Stock Ticker'
160
+ minimum_size 650, 650
161
+ background :white
162
+
163
+ @tab_folder = tab_folder {
164
+ @tabs.each do |tab|
165
+ tab_item {
166
+ fill_layout {
167
+ margin_width 0
168
+ margin_height 0
169
+ }
170
+ text tab[:title]
171
+
172
+ tab[:scrolled_composite] = scrolled_composite {
173
+ tab[:canvas] = canvas {
174
+ background :white
175
+
176
+ @stocks.count.times do |stock_index|
177
+ tab[:stock_paths][stock_index] = path {
178
+ antialias :on
179
+ foreground @stock_colors[stock_index]
180
+ }
181
+ end
182
+
183
+ on_mouse_down {
184
+ @drag_detected = false
185
+ }
186
+
187
+ on_drag_detected { |drag_detect_event|
188
+ @drag_detected = true
189
+ @drag_start_x = drag_detect_event.x
190
+ @drag_start_y = drag_detect_event.y
191
+ }
192
+
193
+ on_mouse_move { |mouse_event|
194
+ if @drag_detected
195
+ origin = tab[:scrolled_composite].origin
196
+ new_x = origin.x - (mouse_event.x - @drag_start_x)
197
+ new_y = origin.y - (mouse_event.y - @drag_start_y)
198
+ tab[:scrolled_composite].set_origin(new_x, new_y)
199
+ end
200
+ }
201
+
202
+ on_mouse_up { |mouse_event|
203
+ @drag_detected = false
204
+ }
205
+ }
206
+ }
207
+ }
208
+ end
209
+ }
210
+
211
+ on_swt_show {
212
+ Stock.stock_price_min = 25
213
+ Stock.stock_price_max = @tabs.first[:canvas].bounds.height - 6
214
+ # pre-initialize all tabs by selecting them so that they render content when they are later in the background
215
+ @tab_folder.items.each do |item|
216
+ @tab_folder.selection = item
217
+ end
218
+ @tab_folder.selection = @tab_folder.items.first
219
+ }
220
+
221
+ on_widget_disposed {
222
+ @thread.kill # safe to kill as data is in memory only
223
+ }
224
+ }
225
+ }
226
+ end
227
+
228
+ StockTicker.launch
229
+
@@ -1,223 +1,66 @@
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
1
  require 'glimmer-dsl-swt'
23
-
24
- # This Sample is an Early Alpha (New Canvas Path DSL Feature)
25
-
26
- class HelloCanvasPath
27
- class Stock
28
- class << self
29
- attr_writer :stock_price_min, :stock_price_max
30
-
31
- def stock_price_min
32
- @stock_price_min ||= 1
33
- end
34
-
35
- def stock_price_max
36
- @stock_price_max ||= 600
37
- end
38
- end
39
-
40
- attr_reader :name, :stock_prices
41
- attr_accessor :stock_price
42
-
43
- def initialize(name, stock_price)
44
- @name = name
45
- @stock_price = stock_price
46
- @stock_prices = [@stock_price]
47
- @delta_sign = 1
48
- start_new_trend!
49
- end
50
-
51
- def tick!
52
- @tick_count = @tick_count.to_i + 1
53
- delta = @tick_count%@trend_length
54
- if delta == 0
55
- @delta_sign *= -1
56
- start_new_trend!
57
- end
58
- stock_prices << self.stock_price = [[@stock_price + @delta_sign*delta, Stock.stock_price_min].max, Stock.stock_price_max].min
59
- end
60
-
61
- def start_new_trend!
62
- @trend_length = (rand*25).to_i + 1
63
- end
64
- end
2
+
3
+ include Glimmer
65
4
 
66
- include Glimmer::UI::CustomShell
5
+ shell {
6
+ text 'Hello, Canvas Path!'
7
+ minimum_size 800, 700
8
+ background :white
67
9
 
68
- before_body {
69
- @stocks = [
70
- Stock.new('AAPL', 121),
71
- Stock.new('MSFT', 232),
72
- ]
73
- @stock_colors = [:red, :dark_green, :blue, :magenta]
74
- max_stock_name_width = 0
75
- left_margin = 5
76
- @tabs = ['Cubic Bezier Curves', 'Quadratic Bezier Curves', 'Lines', 'Points'].map {|title| {title: title, paths: [], transforms: []}}
77
- @stocks.each_with_index do |stock, i|
78
- x = 0
79
- observe(stock, :stock_price) do |new_price|
80
- begin
81
- @tabs.each do |tab|
82
- new_x = x
83
- new_y = @tabs.first[:canvas].bounds.height - new_price - 1
84
- max_stock_name_width = tab[:text]&.bounds&.width if tab[:text]&.bounds&.width.to_f > max_stock_name_width
85
- if new_x > 0
86
- case tab[:title]
87
- when 'Cubic Bezier Curves'
88
- if stock.stock_prices[i] && stock.stock_prices[i - 1] && stock.stock_prices[i - 2]
89
- tab[:paths][i].content {
90
- cubic(new_x - 2, @tabs.first[:canvas].bounds.height - stock.stock_prices[i - 2] - 1, new_x - 1, @tabs.first[:canvas].bounds.height - stock.stock_prices[i - 1] - 1, new_x, new_y)
91
- tab[:transforms][i] ||= transform {
92
- translate max_stock_name_width + 5 + left_margin, tab[:text].bounds.height / 2.0
93
- }
94
- }
95
- end
96
- when 'Quadratic Bezier Curves'
97
- if stock.stock_prices[i] && stock.stock_prices[i - 1]
98
- tab[:paths][i].content {
99
- quad(new_x - 1, @tabs.first[:canvas].bounds.height - stock.stock_prices[i - 1] - 1, new_x, new_y)
100
- tab[:transforms][i] ||= transform {
101
- translate max_stock_name_width + 5 + left_margin, tab[:text].bounds.height / 2.0
102
- }
103
- }
104
- end
105
- when 'Lines'
106
- tab[:paths][i].content {
107
- line(new_x, new_y)
108
- tab[:transforms][i] ||= transform {
109
- translate max_stock_name_width + 5 + left_margin, tab[:text].bounds.height / 2.0
110
- }
111
- }
112
- when 'Points'
113
- tab[:paths][i].content {
114
- point(new_x, new_y)
115
- tab[:transforms][i] ||= transform {
116
- translate max_stock_name_width + 5 + left_margin, tab[:text].bounds.height / 2.0
117
- }
118
- }
119
- end
120
- new_x_location = new_x + max_stock_name_width + 5 + left_margin + 5
121
- canvas_width = tab[:canvas].bounds.width
122
- if new_x_location > canvas_width
123
- tab[:canvas].set_size(new_x_location, @tabs.first[:canvas].bounds.height)
124
- tab[:canvas].cursor = :hand
125
- tab[:scrolled_composite].set_min_size(new_x_location, @tabs.first[:canvas].bounds.height)
126
- tab[:scrolled_composite].set_origin(tab[:scrolled_composite].origin.x + 1, tab[:scrolled_composite].origin.y) if (tab[:scrolled_composite].origin.x + tab[:scrolled_composite].client_area.width) == canvas_width
127
- end
128
- else
129
- tab[:canvas].content {
130
- tab[:text] = text(stock.name, new_x + left_margin, new_y) {
131
- foreground @stock_colors[i]
132
- }
133
- }
134
- end
135
- end
136
- x += 1
137
- rescue => e
138
- Glimmer::Config.logger.error {e.full_message}
139
- end
140
- end
141
- end
142
- }
143
-
144
- after_body {
145
- @thread = Thread.new {
146
- loop {
147
- @stocks.each(&:tick!)
148
- sleep(0.01)
10
+ canvas {
11
+ background :white
12
+
13
+ text('line', 15, 200) {
14
+ foreground :red
149
15
  }
150
- }
151
- }
152
-
153
- body {
154
- shell {
155
- fill_layout {
156
- margin_width 15
157
- margin_height 15
16
+ @path1 = path {
17
+ antialias :on
18
+ foreground :red
158
19
  }
159
- text 'Hello, Canvas Path!'
160
- minimum_size 650, 650
161
- background :white
162
20
 
163
- tab_folder {
164
- @tabs.each do |tab|
165
- tab_item {
166
- fill_layout {
167
- margin_width 0
168
- margin_height 0
169
- }
170
- text tab[:title]
171
-
172
- tab[:scrolled_composite] = scrolled_composite {
173
- tab[:canvas] = canvas {
174
- background :white
175
-
176
- @stocks.count.times do |n|
177
- tab[:paths][n] = path {
178
- foreground @stock_colors[n]
179
- }
180
- end
181
-
182
- on_mouse_down {
183
- @drag_detected = false
184
- }
185
-
186
- on_drag_detected { |drag_detect_event|
187
- @drag_detected = true
188
- @drag_start_x = drag_detect_event.x
189
- @drag_start_y = drag_detect_event.y
190
- }
191
-
192
- on_mouse_move { |mouse_event|
193
- if @drag_detected
194
- origin = tab[:scrolled_composite].origin
195
- new_x = origin.x - (mouse_event.x - @drag_start_x)
196
- new_y = origin.y - (mouse_event.y - @drag_start_y)
197
- tab[:scrolled_composite].set_origin(new_x, new_y)
198
- end
199
- }
200
-
201
- on_mouse_up { |mouse_event|
202
- @drag_detected = false
203
- }
204
- }
205
- }
206
- }
207
- end
21
+ text('quad', 15, 300) {
22
+ foreground :dark_green
208
23
  }
209
-
210
- on_swt_show {
211
- Stock.stock_price_min = 25
212
- Stock.stock_price_max = @tabs.first[:canvas].bounds.height - 6
24
+ @path2 = path {
25
+ antialias :on
26
+ foreground :dark_green
213
27
  }
214
28
 
215
- on_widget_disposed {
216
- @thread.kill # safe to kill as memory is in data only
29
+ text('cubic', 15, 400) {
30
+ foreground :blue
217
31
  }
32
+ @path3 = path {
33
+ antialias :on
34
+ foreground :blue
35
+ }
36
+ }
37
+
38
+ on_swt_show {
39
+ Thread.new {
40
+ y1 = y2 = y3 = 300
41
+ 800.times.each do |x|
42
+ x += 55
43
+ x1 = x - 2
44
+ x2 = x - 1
45
+ x3 = x
46
+ y1 = y3
47
+ y2 = y1
48
+ y3 = [[y3 + (rand*24 - 12), 0].max, 700].min
49
+ @path1.content {
50
+ line(x1, y1 - 100)
51
+ }
52
+ if x % 2 == 0
53
+ @path2.content {
54
+ quad(x1, y1, x2, y2)
55
+ }
56
+ end
57
+ if x % 3 == 0
58
+ @path3.content {
59
+ cubic(x1, y1 + 100, x2, y2 + 100, x3, y3 + 100)
60
+ }
61
+ end
62
+ sleep(0.01)
63
+ end
218
64
  }
219
65
  }
220
- end
221
-
222
- HelloCanvasPath.launch
223
-
66
+ }.open
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.6.0
4
+ version: 4.18.6.1
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-28 00:00:00.000000000 Z
11
+ date: 2021-03-01 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  requirement: !ruby/object:Gem::Requirement
@@ -485,6 +485,7 @@ files:
485
485
  - samples/elaborate/login.rb
486
486
  - samples/elaborate/mandelbrot_fractal.rb
487
487
  - samples/elaborate/meta_sample.rb
488
+ - samples/elaborate/stock_ticker.rb
488
489
  - samples/elaborate/tetris.rb
489
490
  - samples/elaborate/tetris/model/block.rb
490
491
  - samples/elaborate/tetris/model/game.rb