glimmer-dsl-swt 4.18.5.5 → 4.18.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
 - data/CHANGELOG.md +9 -0
 - data/README.md +4 -4
 - data/VERSION +1 -1
 - data/docs/reference/GLIMMER_GUI_DSL_SYNTAX.md +35 -0
 - data/glimmer-dsl-swt.gemspec +8 -3
 - data/lib/glimmer/swt/custom/shape.rb +14 -4
 - data/lib/glimmer/swt/custom/shape/cubic.rb +108 -0
 - data/lib/glimmer/swt/custom/shape/line.rb +37 -4
 - data/lib/glimmer/swt/custom/shape/path.rb +197 -0
 - data/lib/glimmer/swt/custom/shape/path_segment.rb +86 -0
 - data/lib/glimmer/swt/custom/shape/point.rb +33 -0
 - data/lib/glimmer/swt/custom/shape/polygon.rb +2 -2
 - data/lib/glimmer/swt/custom/shape/quad.rb +104 -0
 - data/lib/glimmer/swt/proxy_properties.rb +1 -1
 - data/samples/elaborate/mandelbrot_fractal.rb +1 -1
 - data/samples/hello/hello_canvas_path.rb +223 -0
 - metadata +7 -2
 
    
        checksums.yaml
    CHANGED
    
    | 
         @@ -1,7 +1,7 @@ 
     | 
|
| 
       1 
1 
     | 
    
         
             
            ---
         
     | 
| 
       2 
2 
     | 
    
         
             
            SHA256:
         
     | 
| 
       3 
     | 
    
         
            -
              metadata.gz:  
     | 
| 
       4 
     | 
    
         
            -
              data.tar.gz:  
     | 
| 
      
 3 
     | 
    
         
            +
              metadata.gz: 2b3fe4c65726425f091b0660bbf4dd4c55543c5c515bed56487aacb7e1458b7e
         
     | 
| 
      
 4 
     | 
    
         
            +
              data.tar.gz: 71580957a753685f1eac22fb60ea13c2e2f289bb47017293980d4d06d78d5eec
         
     | 
| 
       5 
5 
     | 
    
         
             
            SHA512:
         
     | 
| 
       6 
     | 
    
         
            -
              metadata.gz:  
     | 
| 
       7 
     | 
    
         
            -
              data.tar.gz:  
     | 
| 
      
 6 
     | 
    
         
            +
              metadata.gz: 974be0abde39dbacdabe5d560c319a049907791e280f03aa6192e945b64057f814cbc57346f51cead9627ee98db52276367f4ca1f8f497b2882846d280a7f103
         
     | 
| 
      
 7 
     | 
    
         
            +
              data.tar.gz: 7b9c169a4705c8bfa390ef440e31100e40560eabca4f204d18d8e5197174d9834827fd9f76907384c2d8e3873f968c11b94f6a985c3a43eda0bbf9b8fc7b8bc9
         
     | 
    
        data/CHANGELOG.md
    CHANGED
    
    | 
         @@ -1,5 +1,14 @@ 
     | 
|
| 
       1 
1 
     | 
    
         
             
            # Change Log
         
     | 
| 
       2 
2 
     | 
    
         | 
| 
      
 3 
     | 
    
         
            +
            ### 4.18.6.0
         
     | 
| 
      
 4 
     | 
    
         
            +
             
     | 
| 
      
 5 
     | 
    
         
            +
            - 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)
         
     | 
| 
      
 6 
     | 
    
         
            +
            - Hello, Canvas Path! sample showing a Stock Ticker with line curves for multiple company stocks, animated with randomly generated data, moving to the left out of screen second by second. Has multiple tabs demonstrating different types of paths for graphing/charting of different real world business applications: point, line, quad, cubic.
         
     | 
| 
      
 7 
     | 
    
         
            +
            - Fix issue to allow invocation of `set_min_size` off of `scrolled_composite` proxy directly (not just swt_widget), thus taking advantage of implicit `auto_exec`
         
     | 
| 
      
 8 
     | 
    
         
            +
            - Support `Shape#content {}` method just like `WidgetProxy#content` to enable reopening and adding nested shapes at runtime after initial construction
         
     | 
| 
      
 9 
     | 
    
         
            +
            - Support a path containing a `quad` bezier curve with `point_array` property
         
     | 
| 
      
 10 
     | 
    
         
            +
            - Support a path containing a `cubic` bezier curve with `point_array` property
         
     | 
| 
      
 11 
     | 
    
         
            +
             
     | 
| 
       3 
12 
     | 
    
         
             
            ### 4.18.5.5
         
     | 
| 
       4 
13 
     | 
    
         | 
| 
       5 
14 
     | 
    
         
             
            - Automatically recalculate default size (width/height) to accomodate nested shapes when changing x/y/width/height sticking out of parent from right or bottom.
         
     | 
    
        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. 
     | 
| 
      
 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.0
         
     | 
| 
       2 
2 
     | 
    
         
             
            ## JRuby Desktop Development GUI Framework
         
     | 
| 
       3 
3 
     | 
    
         
             
            [](http://badge.fury.io/rb/glimmer-dsl-swt)
         
     | 
| 
       4 
4 
     | 
    
         
             
            [](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. 
     | 
| 
      
 16 
     | 
    
         
            +
            [Glimmer DSL for SWT](https://rubygems.org/gems/glimmer-dsl-swt) 4.18.6.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. 
     | 
| 
      
 343 
     | 
    
         
            +
            jgem install glimmer-dsl-swt -v 4.18.6.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. 
     | 
| 
      
 361 
     | 
    
         
            +
            gem 'glimmer-dsl-swt', '~> 4.18.6.0'
         
     | 
| 
       362 
362 
     | 
    
         
             
            ```
         
     | 
| 
       363 
363 
     | 
    
         | 
| 
       364 
364 
     | 
    
         
             
            And, then run:
         
     | 
    
        data/VERSION
    CHANGED
    
    | 
         @@ -1 +1 @@ 
     | 
|
| 
       1 
     | 
    
         
            -
            4.18. 
     | 
| 
      
 1 
     | 
    
         
            +
            4.18.6.0
         
     | 
| 
         @@ -41,6 +41,7 @@ This guide should help you get started with Glimmer DSL for SWT. For more advanc 
     | 
|
| 
       41 
41 
     | 
    
         
             
                - [Shapes inside an Image](#shapes-inside-an-image)
         
     | 
| 
       42 
42 
     | 
    
         
             
                - [Canvas Shape API](#canvas-shape-api)
         
     | 
| 
       43 
43 
     | 
    
         
             
                - [Pixel Graphics](#pixel-graphics)
         
     | 
| 
      
 44 
     | 
    
         
            +
              - [Canvas Path DSL](#canvas-path-dsl)
         
     | 
| 
       44 
45 
     | 
    
         
             
              - [Canvas Transform DSL](#canvas-transform-dsl)
         
     | 
| 
       45 
46 
     | 
    
         
             
                - [Top-Level Transform Fluent Interface](#top-level-transform-fluent-interface)
         
     | 
| 
       46 
47 
     | 
    
         
             
              - [Canvas Animation DSL](#canvas-animation-dsl)
         
     | 
| 
         @@ -1953,6 +1954,40 @@ shell { 
     | 
|
| 
       1953 
1954 
     | 
    
         | 
| 
       1954 
1955 
     | 
    
         
             
            As they say, there are many ways to skin a cat! This is in line with the Ruby way of providing more ways than one. Pick and choose the right tool for the job just like true software engineers.
         
     | 
| 
       1955 
1956 
     | 
    
         | 
| 
      
 1957 
     | 
    
         
            +
            ### Canvas Path DSL
         
     | 
| 
      
 1958 
     | 
    
         
            +
             
     | 
| 
      
 1959 
     | 
    
         
            +
            **(EARLY ALPHA FEATURE)**
         
     | 
| 
      
 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:
         
     | 
| 
      
 1962 
     | 
    
         
            +
            - `point(x1, y1)`: renders a Point (Dot) as part of a path.
         
     | 
| 
      
 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 
     | 
    
         
            +
            - `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.
         
     | 
| 
      
 1965 
     | 
    
         
            +
            - `cubic(x1, y1, x2, y2, x3, y3, x4=nil, y4=nil)`: renders a Cubic Bezier Curve. If you drop x4 and y4, it joins to the previous point automatically.
         
     | 
| 
      
 1966 
     | 
    
         
            +
             
     | 
| 
      
 1967 
     | 
    
         
            +
            Example:
         
     | 
| 
      
 1968 
     | 
    
         
            +
             
     | 
| 
      
 1969 
     | 
    
         
            +
            ```ruby
         
     | 
| 
      
 1970 
     | 
    
         
            +
            shell {
         
     | 
| 
      
 1971 
     | 
    
         
            +
              text 'Canvas Path DSL Example'
         
     | 
| 
      
 1972 
     | 
    
         
            +
              minimum_size 300, 300
         
     | 
| 
      
 1973 
     | 
    
         
            +
              
         
     | 
| 
      
 1974 
     | 
    
         
            +
              canvas {
         
     | 
| 
      
 1975 
     | 
    
         
            +
                path {
         
     | 
| 
      
 1976 
     | 
    
         
            +
                  foreground :black
         
     | 
| 
      
 1977 
     | 
    
         
            +
                  point(0, 0)
         
     | 
| 
      
 1978 
     | 
    
         
            +
                  250.times {|n|
         
     | 
| 
      
 1979 
     | 
    
         
            +
                    cubic(n + n%30, n+ n%50, 40, 40, 70, 70, n + 20 + n%30, n%30*-1 * n%50)
         
     | 
| 
      
 1980 
     | 
    
         
            +
                  }
         
     | 
| 
      
 1981 
     | 
    
         
            +
                }
         
     | 
| 
      
 1982 
     | 
    
         
            +
              }
         
     | 
| 
      
 1983 
     | 
    
         
            +
              
         
     | 
| 
      
 1984 
     | 
    
         
            +
            }.open
         
     | 
| 
      
 1985 
     | 
    
         
            +
            ```
         
     | 
| 
      
 1986 
     | 
    
         
            +
             
     | 
| 
      
 1987 
     | 
    
         
            +
            Learn more at the [Hello, Canvas Path! Sample](/samples/hello/hello_canvas_path.rb).
         
     | 
| 
      
 1988 
     | 
    
         
            +
             
     | 
| 
      
 1989 
     | 
    
         
            +
            
         
     | 
| 
      
 1990 
     | 
    
         
            +
             
     | 
| 
       1956 
1991 
     | 
    
         
             
            ### Canvas Transform DSL
         
     | 
| 
       1957 
1992 
     | 
    
         | 
| 
       1958 
1993 
     | 
    
         
             
            **(ALPHA FEATURE)**
         
     | 
    
        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 
     | 
    
         
            +
            # stub: glimmer-dsl-swt 4.18.6.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. 
     | 
| 
      
 9 
     | 
    
         
            +
              s.version = "4.18.6.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-02- 
     | 
| 
      
 14 
     | 
    
         
            +
              s.date = "2021-02-28"
         
     | 
| 
       15 
15 
     | 
    
         
             
              s.description = "Glimmer DSL for SWT (JRuby Desktop Development GUI Framework) is a native-GUI cross-platform desktop development library written in JRuby, an OS-threaded faster JVM version of Ruby. Glimmer's main innovation is a declarative Ruby DSL that enables productive and efficient authoring of desktop application user-interfaces by relying on the robust Eclipse SWT library. Glimmer additionally innovates by having built-in data-binding support, which greatly facilitates synchronizing the GUI with domain models, thus achieving true decoupling of object oriented components and enabling developers to solve business problems (test-first) without worrying about GUI concerns, or alternatively drive development GUI-first, and then write clean business models (test-first) afterwards. Not only does Glimmer provide a large set of GUI widgets, but it also supports drawing Canvas Graphics like Shapes and Animations. To get started quickly, Glimmer offers scaffolding options for Apps, Gems, and Custom Widgets. Glimmer also includes native-executable packaging support, sorely lacking in other libraries, thus enabling the delivery of desktop apps written in Ruby as truly native DMG/PKG/APP files on the Mac + App Store, MSI/EXE files on Windows, and Gem Packaged Shell Scripts on Linux.".freeze
         
     | 
| 
       16 
16 
     | 
    
         
             
              s.email = "andy.am@gmail.com".freeze
         
     | 
| 
       17 
17 
     | 
    
         
             
              s.executables = ["glimmer".freeze, "girb".freeze]
         
     | 
| 
         @@ -115,13 +115,17 @@ Gem::Specification.new do |s| 
     | 
|
| 
       115 
115 
     | 
    
         
             
                "lib/glimmer/swt/custom/radio_group.rb",
         
     | 
| 
       116 
116 
     | 
    
         
             
                "lib/glimmer/swt/custom/shape.rb",
         
     | 
| 
       117 
117 
     | 
    
         
             
                "lib/glimmer/swt/custom/shape/arc.rb",
         
     | 
| 
      
 118 
     | 
    
         
            +
                "lib/glimmer/swt/custom/shape/cubic.rb",
         
     | 
| 
       118 
119 
     | 
    
         
             
                "lib/glimmer/swt/custom/shape/focus.rb",
         
     | 
| 
       119 
120 
     | 
    
         
             
                "lib/glimmer/swt/custom/shape/image.rb",
         
     | 
| 
       120 
121 
     | 
    
         
             
                "lib/glimmer/swt/custom/shape/line.rb",
         
     | 
| 
       121 
122 
     | 
    
         
             
                "lib/glimmer/swt/custom/shape/oval.rb",
         
     | 
| 
      
 123 
     | 
    
         
            +
                "lib/glimmer/swt/custom/shape/path.rb",
         
     | 
| 
      
 124 
     | 
    
         
            +
                "lib/glimmer/swt/custom/shape/path_segment.rb",
         
     | 
| 
       122 
125 
     | 
    
         
             
                "lib/glimmer/swt/custom/shape/point.rb",
         
     | 
| 
       123 
126 
     | 
    
         
             
                "lib/glimmer/swt/custom/shape/polygon.rb",
         
     | 
| 
       124 
127 
     | 
    
         
             
                "lib/glimmer/swt/custom/shape/polyline.rb",
         
     | 
| 
      
 128 
     | 
    
         
            +
                "lib/glimmer/swt/custom/shape/quad.rb",
         
     | 
| 
       125 
129 
     | 
    
         
             
                "lib/glimmer/swt/custom/shape/rectangle.rb",
         
     | 
| 
       126 
130 
     | 
    
         
             
                "lib/glimmer/swt/custom/shape/text.rb",
         
     | 
| 
       127 
131 
     | 
    
         
             
                "lib/glimmer/swt/date_time_proxy.rb",
         
     | 
| 
         @@ -180,6 +184,7 @@ Gem::Specification.new do |s| 
     | 
|
| 
       180 
184 
     | 
    
         
             
                "samples/hello/hello_button.rb",
         
     | 
| 
       181 
185 
     | 
    
         
             
                "samples/hello/hello_canvas.rb",
         
     | 
| 
       182 
186 
     | 
    
         
             
                "samples/hello/hello_canvas_animation.rb",
         
     | 
| 
      
 187 
     | 
    
         
            +
                "samples/hello/hello_canvas_path.rb",
         
     | 
| 
       183 
188 
     | 
    
         
             
                "samples/hello/hello_canvas_transform.rb",
         
     | 
| 
       184 
189 
     | 
    
         
             
                "samples/hello/hello_checkbox.rb",
         
     | 
| 
       185 
190 
     | 
    
         
             
                "samples/hello/hello_checkbox_group.rb",
         
     | 
| 
         @@ -74,7 +74,8 @@ module Glimmer 
     | 
|
| 
       74 
74 
     | 
    
         
             
                      end
         
     | 
| 
       75 
75 
     | 
    
         | 
| 
       76 
76 
     | 
    
         
             
                      def valid?(parent, keyword, *args, &block)
         
     | 
| 
       77 
     | 
    
         
            -
                        gc_instance_methods.include?(method_name(keyword, arg_options(args)))
         
     | 
| 
      
 77 
     | 
    
         
            +
                        gc_instance_methods.include?(method_name(keyword, arg_options(args))) ||
         
     | 
| 
      
 78 
     | 
    
         
            +
                          constants.include?(keyword.to_s.camelcase(:upper).to_sym)
         
     | 
| 
       78 
79 
     | 
    
         
             
                      end
         
     | 
| 
       79 
80 
     | 
    
         | 
| 
       80 
81 
     | 
    
         
             
                      def gc_instance_methods
         
     | 
| 
         @@ -225,6 +226,14 @@ module Glimmer 
     | 
|
| 
       225 
226 
     | 
    
         
             
                      end
         
     | 
| 
       226 
227 
     | 
    
         
             
                    end
         
     | 
| 
       227 
228 
     | 
    
         | 
| 
      
 229 
     | 
    
         
            +
                    def content(&block)
         
     | 
| 
      
 230 
     | 
    
         
            +
                      Glimmer::SWT::DisplayProxy.instance.auto_exec do
         
     | 
| 
      
 231 
     | 
    
         
            +
                        Glimmer::DSL::Engine.add_content(self, Glimmer::DSL::SWT::ShapeExpression.new, &block)
         
     | 
| 
      
 232 
     | 
    
         
            +
                        calculated_args_changed!(children: false)
         
     | 
| 
      
 233 
     | 
    
         
            +
                        drawable.redraw unless drawable.is_a?(ImageProxy)
         
     | 
| 
      
 234 
     | 
    
         
            +
                      end
         
     | 
| 
      
 235 
     | 
    
         
            +
                    end
         
     | 
| 
      
 236 
     | 
    
         
            +
                    
         
     | 
| 
       228 
237 
     | 
    
         
             
                    def has_some_background?
         
     | 
| 
       229 
238 
     | 
    
         
             
                      @properties.keys.map(&:to_s).include?('background') || @properties.keys.map(&:to_s).include?('background_pattern')
         
     | 
| 
       230 
239 
     | 
    
         
             
                    end
         
     | 
| 
         @@ -234,11 +243,11 @@ module Glimmer 
     | 
|
| 
       234 
243 
     | 
    
         
             
                    end
         
     | 
| 
       235 
244 
     | 
    
         | 
| 
       236 
245 
     | 
    
         
             
                    def post_add_content
         
     | 
| 
       237 
     | 
    
         
            -
             
     | 
| 
      
 246 
     | 
    
         
            +
            #           unless @content_added # TODO delete if no longer needed
         
     | 
| 
       238 
247 
     | 
    
         
             
                        amend_method_name_options_based_on_properties!
         
     | 
| 
       239 
248 
     | 
    
         
             
                        @drawable.setup_shape_painting unless @drawable.is_a?(ImageProxy)
         
     | 
| 
       240 
249 
     | 
    
         
             
                        @content_added = true
         
     | 
| 
       241 
     | 
    
         
            -
             
     | 
| 
      
 250 
     | 
    
         
            +
            #           end
         
     | 
| 
       242 
251 
     | 
    
         
             
                    end
         
     | 
| 
       243 
252 
     | 
    
         | 
| 
       244 
253 
     | 
    
         
             
                    def apply_property_arg_conversions(method_name, property, args)
         
     | 
| 
         @@ -491,6 +500,7 @@ module Glimmer 
     | 
|
| 
       491 
500 
     | 
    
         
             
                    end
         
     | 
| 
       492 
501 
     | 
    
         | 
| 
       493 
502 
     | 
    
         
             
                    def dispose(dispose_images: true, dispose_patterns: true)
         
     | 
| 
      
 503 
     | 
    
         
            +
                      shapes.each { |shape| shape.is_a?(Shape::Path) && shape.dispose }
         
     | 
| 
       494 
504 
     | 
    
         
             
                      if dispose_patterns
         
     | 
| 
       495 
505 
     | 
    
         
             
                        @background_pattern&.dispose
         
     | 
| 
       496 
506 
     | 
    
         
             
                        @background_pattern = nil
         
     | 
| 
         @@ -818,7 +828,7 @@ module Glimmer 
     | 
|
| 
       818 
828 
     | 
    
         
             
                          # TODO regarding alpha, make sure to reset it to parent stored alpha once we allow setting shape properties on parents directly without shapes
         
     | 
| 
       819 
829 
     | 
    
         
             
                          @properties['alpha'] ||= [255]
         
     | 
| 
       820 
830 
     | 
    
         
             
                          @properties['font'] = [@drawable.font] if @drawable.respond_to?(:font) && draw? && !@properties.keys.map(&:to_s).include?('font')
         
     | 
| 
       821 
     | 
    
         
            -
                          # TODO regarding transform, make sure to reset it to parent stored  
     | 
| 
      
 831 
     | 
    
         
            +
                          # TODO regarding transform, make sure to reset it to parent stored transform once we allow setting shape properties on parents directly without shapes
         
     | 
| 
       822 
832 
     | 
    
         
             
                          # Also do that with all future-added properties
         
     | 
| 
       823 
833 
     | 
    
         
             
                          @properties['transform'] = [nil] if @drawable.respond_to?(:transform) && !@properties.keys.map(&:to_s).include?('transform')
         
     | 
| 
       824 
834 
     | 
    
         
             
                          @properties.each do |property, args|
         
     | 
| 
         @@ -0,0 +1,108 @@ 
     | 
|
| 
      
 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/swt/custom/shape'
         
     | 
| 
      
 23 
     | 
    
         
            +
            require 'glimmer/swt/custom/shape/path_segment'
         
     | 
| 
      
 24 
     | 
    
         
            +
            require 'glimmer/swt/swt_proxy'
         
     | 
| 
      
 25 
     | 
    
         
            +
            require 'glimmer/swt/display_proxy'
         
     | 
| 
      
 26 
     | 
    
         
            +
            require 'glimmer/swt/color_proxy'
         
     | 
| 
      
 27 
     | 
    
         
            +
            require 'glimmer/swt/font_proxy'
         
     | 
| 
      
 28 
     | 
    
         
            +
            require 'glimmer/swt/transform_proxy'
         
     | 
| 
      
 29 
     | 
    
         
            +
             
     | 
| 
      
 30 
     | 
    
         
            +
            module Glimmer
         
     | 
| 
      
 31 
     | 
    
         
            +
              module SWT
         
     | 
| 
      
 32 
     | 
    
         
            +
                module Custom
         
     | 
| 
      
 33 
     | 
    
         
            +
                  # Represents a shape (graphics) to be drawn on a control/widget/canvas/display
         
     | 
| 
      
 34 
     | 
    
         
            +
                  # That is because Shape is drawn on a parent as graphics and doesn't have an SWT widget for itself
         
     | 
| 
      
 35 
     | 
    
         
            +
                  class Shape
         
     | 
| 
      
 36 
     | 
    
         
            +
                    class Cubic < Path
         
     | 
| 
      
 37 
     | 
    
         
            +
                      def parameter_names
         
     | 
| 
      
 38 
     | 
    
         
            +
                        [:point_array]
         
     | 
| 
      
 39 
     | 
    
         
            +
                      end
         
     | 
| 
      
 40 
     | 
    
         
            +
                      
         
     | 
| 
      
 41 
     | 
    
         
            +
                      def geometry
         
     | 
| 
      
 42 
     | 
    
         
            +
                        if @point_array != @geometry_point_array
         
     | 
| 
      
 43 
     | 
    
         
            +
                          @geometry_point_array = @point_array
         
     | 
| 
      
 44 
     | 
    
         
            +
                          @geometry = Java::JavaAwtGeom::Path2D::Double.new
         
     | 
| 
      
 45 
     | 
    
         
            +
                          @geometry.send(path_segment_geometry_method_name, *path_segment_geometry_args)
         
     | 
| 
      
 46 
     | 
    
         
            +
                        end
         
     | 
| 
      
 47 
     | 
    
         
            +
                        @geometry
         
     | 
| 
      
 48 
     | 
    
         
            +
                      end
         
     | 
| 
      
 49 
     | 
    
         
            +
                    
         
     | 
| 
      
 50 
     | 
    
         
            +
                      def contain?(x, y)
         
     | 
| 
      
 51 
     | 
    
         
            +
                        include?(x, y, filled: true)
         
     | 
| 
      
 52 
     | 
    
         
            +
                      end
         
     | 
| 
      
 53 
     | 
    
         
            +
                    
         
     | 
| 
      
 54 
     | 
    
         
            +
                      # 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)
         
     | 
| 
      
 55 
     | 
    
         
            +
                      def include?(x, y, filled: nil)
         
     | 
| 
      
 56 
     | 
    
         
            +
                        filled = filled? if filled.nil?
         
     | 
| 
      
 57 
     | 
    
         
            +
                        makeshift_gc = org.eclipse.swt.graphics.GC.new(Glimmer::SWT::DisplayProxy.instance.swt_display)
         
     | 
| 
      
 58 
     | 
    
         
            +
                        swt_path = org.eclipse.swt.graphics.Path.new(Glimmer::SWT::DisplayProxy.instance.swt_display)
         
     | 
| 
      
 59 
     | 
    
         
            +
                        the_path_segment_args = path_segment_args.dup
         
     | 
| 
      
 60 
     | 
    
         
            +
                        if previous_point_connected?
         
     | 
| 
      
 61 
     | 
    
         
            +
                          the_previous_path_segment = previous_path_segment
         
     | 
| 
      
 62 
     | 
    
         
            +
                          swt_path.moveTo(the_previous_path_segment.x, the_previous_path_segment.y)
         
     | 
| 
      
 63 
     | 
    
         
            +
                        else
         
     | 
| 
      
 64 
     | 
    
         
            +
                          swt_path.moveTo(the_path_segment_args.shift, the_path_segment_args.shift)
         
     | 
| 
      
 65 
     | 
    
         
            +
                        end
         
     | 
| 
      
 66 
     | 
    
         
            +
                        swt_path.curveTo(*the_path_segment_args)
         
     | 
| 
      
 67 
     | 
    
         
            +
                        swt_path.contains(x.to_f, y.to_f, makeshift_gc, !filled)
         
     | 
| 
      
 68 
     | 
    
         
            +
                      ensure
         
     | 
| 
      
 69 
     | 
    
         
            +
                        swt_path.dispose
         
     | 
| 
      
 70 
     | 
    
         
            +
                      end
         
     | 
| 
      
 71 
     | 
    
         
            +
                        
         
     | 
| 
      
 72 
     | 
    
         
            +
                      def move_by(x_delta, y_delta)
         
     | 
| 
      
 73 
     | 
    
         
            +
                        the_point_array = @args.compact
         
     | 
| 
      
 74 
     | 
    
         
            +
                        the_point_array = the_point_array.first if the_point_array.first.is_a?(Array)
         
     | 
| 
      
 75 
     | 
    
         
            +
                        self.point_array = the_point_array.each_with_index.map {|coordinate, i| i.even? ? coordinate + x_delta : coordinate + y_delta}
         
     | 
| 
      
 76 
     | 
    
         
            +
                      end
         
     | 
| 
      
 77 
     | 
    
         
            +
                                          
         
     | 
| 
      
 78 
     | 
    
         
            +
                      def path_segment_method_name
         
     | 
| 
      
 79 
     | 
    
         
            +
                        'cubicTo'
         
     | 
| 
      
 80 
     | 
    
         
            +
                      end
         
     | 
| 
      
 81 
     | 
    
         
            +
                      
         
     | 
| 
      
 82 
     | 
    
         
            +
                      def path_segment_args
         
     | 
| 
      
 83 
     | 
    
         
            +
                        # TODO make args auto-infer control points if previous_point_connected is true or if there is only a point_array with 1 point
         
     | 
| 
      
 84 
     | 
    
         
            +
                        @args.to_a
         
     | 
| 
      
 85 
     | 
    
         
            +
                      end
         
     | 
| 
      
 86 
     | 
    
         
            +
                      
         
     | 
| 
      
 87 
     | 
    
         
            +
                      def path_segment_geometry_method_name
         
     | 
| 
      
 88 
     | 
    
         
            +
                        'curveTo'
         
     | 
| 
      
 89 
     | 
    
         
            +
                      end
         
     | 
| 
      
 90 
     | 
    
         
            +
                      
         
     | 
| 
      
 91 
     | 
    
         
            +
                      def previous_point_connected?
         
     | 
| 
      
 92 
     | 
    
         
            +
                        @args.compact.count <= 6 && !first_path_segment?
         
     | 
| 
      
 93 
     | 
    
         
            +
                      end
         
     | 
| 
      
 94 
     | 
    
         
            +
                      
         
     | 
| 
      
 95 
     | 
    
         
            +
                      def eql?(other)
         
     | 
| 
      
 96 
     | 
    
         
            +
                        point_array == (other && other.respond_to?(:point_array) && other.point_array)
         
     | 
| 
      
 97 
     | 
    
         
            +
                      end
         
     | 
| 
      
 98 
     | 
    
         
            +
                      alias == eql?
         
     | 
| 
      
 99 
     | 
    
         
            +
                      
         
     | 
| 
      
 100 
     | 
    
         
            +
                      def hash
         
     | 
| 
      
 101 
     | 
    
         
            +
                        point_array.hash
         
     | 
| 
      
 102 
     | 
    
         
            +
                      end
         
     | 
| 
      
 103 
     | 
    
         
            +
                                
         
     | 
| 
      
 104 
     | 
    
         
            +
                    end
         
     | 
| 
      
 105 
     | 
    
         
            +
                  end
         
     | 
| 
      
 106 
     | 
    
         
            +
                end
         
     | 
| 
      
 107 
     | 
    
         
            +
              end
         
     | 
| 
      
 108 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -20,6 +20,7 @@ 
     | 
|
| 
       20 
20 
     | 
    
         
             
            # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
         
     | 
| 
       21 
21 
     | 
    
         | 
| 
       22 
22 
     | 
    
         
             
            require 'glimmer/swt/custom/shape'
         
     | 
| 
      
 23 
     | 
    
         
            +
            require 'glimmer/swt/custom/shape/path_segment'
         
     | 
| 
       23 
24 
     | 
    
         
             
            require 'glimmer/swt/swt_proxy'
         
     | 
| 
       24 
25 
     | 
    
         
             
            require 'glimmer/swt/display_proxy'
         
     | 
| 
       25 
26 
     | 
    
         
             
            require 'glimmer/swt/color_proxy'
         
     | 
| 
         @@ -33,6 +34,8 @@ module Glimmer 
     | 
|
| 
       33 
34 
     | 
    
         
             
                  # That is because Shape is drawn on a parent as graphics and doesn't have an SWT widget for itself
         
     | 
| 
       34 
35 
     | 
    
         
             
                  class Shape
         
     | 
| 
       35 
36 
     | 
    
         
             
                    class Line < Shape
         
     | 
| 
      
 37 
     | 
    
         
            +
                      include PathSegment
         
     | 
| 
      
 38 
     | 
    
         
            +
                      
         
     | 
| 
       36 
39 
     | 
    
         
             
                      class << self
         
     | 
| 
       37 
40 
     | 
    
         
             
                        def include?(x1, y1, x2, y2, x, y)
         
     | 
| 
       38 
41 
     | 
    
         
             
                          distance1 = Math.sqrt((x - x1)**2 + (y - y1)**2)
         
     | 
| 
         @@ -79,11 +82,11 @@ module Glimmer 
     | 
|
| 
       79 
82 
     | 
    
         
             
                      end
         
     | 
| 
       80 
83 
     | 
    
         | 
| 
       81 
84 
     | 
    
         
             
                      def width
         
     | 
| 
       82 
     | 
    
         
            -
                         
     | 
| 
      
 85 
     | 
    
         
            +
                        size.x
         
     | 
| 
       83 
86 
     | 
    
         
             
                      end
         
     | 
| 
       84 
87 
     | 
    
         | 
| 
       85 
88 
     | 
    
         
             
                      def height
         
     | 
| 
       86 
     | 
    
         
            -
                         
     | 
| 
      
 89 
     | 
    
         
            +
                        size.y
         
     | 
| 
       87 
90 
     | 
    
         
             
                      end
         
     | 
| 
       88 
91 
     | 
    
         | 
| 
       89 
92 
     | 
    
         
             
                      def absolute_x1
         
     | 
| 
         @@ -104,7 +107,7 @@ module Glimmer 
     | 
|
| 
       104 
107 
     | 
    
         | 
| 
       105 
108 
     | 
    
         
             
                      def absolute_x2
         
     | 
| 
       106 
109 
     | 
    
         
             
                        if parent.is_a?(Shape)
         
     | 
| 
       107 
     | 
    
         
            -
                          parent.absolute_x + x2
         
     | 
| 
      
 110 
     | 
    
         
            +
                          parent.absolute_x + x2.to_f
         
     | 
| 
       108 
111 
     | 
    
         
             
                        else
         
     | 
| 
       109 
112 
     | 
    
         
             
                          x2
         
     | 
| 
       110 
113 
     | 
    
         
             
                        end
         
     | 
| 
         @@ -112,7 +115,7 @@ module Glimmer 
     | 
|
| 
       112 
115 
     | 
    
         | 
| 
       113 
116 
     | 
    
         
             
                      def absolute_y2
         
     | 
| 
       114 
117 
     | 
    
         
             
                        if parent.is_a?(Shape)
         
     | 
| 
       115 
     | 
    
         
            -
                          parent.absolute_y +  
     | 
| 
      
 118 
     | 
    
         
            +
                          parent.absolute_y + y2.to_f
         
     | 
| 
       116 
119 
     | 
    
         
             
                        else
         
     | 
| 
       117 
120 
     | 
    
         
             
                          y2
         
     | 
| 
       118 
121 
     | 
    
         
             
                        end
         
     | 
| 
         @@ -134,7 +137,37 @@ module Glimmer 
     | 
|
| 
       134 
137 
     | 
    
         
             
                      def irregular?
         
     | 
| 
       135 
138 
     | 
    
         
             
                        true
         
     | 
| 
       136 
139 
     | 
    
         
             
                      end
         
     | 
| 
      
 140 
     | 
    
         
            +
                                
         
     | 
| 
      
 141 
     | 
    
         
            +
                      def path_segment_method_name
         
     | 
| 
      
 142 
     | 
    
         
            +
                        'lineTo'
         
     | 
| 
      
 143 
     | 
    
         
            +
                      end
         
     | 
| 
      
 144 
     | 
    
         
            +
                      
         
     | 
| 
      
 145 
     | 
    
         
            +
                      def path_segment_args
         
     | 
| 
      
 146 
     | 
    
         
            +
                        # 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
         
     | 
| 
      
 147 
     | 
    
         
            +
                        @args
         
     | 
| 
      
 148 
     | 
    
         
            +
                      end
         
     | 
| 
      
 149 
     | 
    
         
            +
                      
         
     | 
| 
      
 150 
     | 
    
         
            +
                      def path_segment_geometry_args
         
     | 
| 
      
 151 
     | 
    
         
            +
                        # 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 
     | 
    
         
            +
                        @args[0..1]
         
     | 
| 
      
 153 
     | 
    
         
            +
                      end
         
     | 
| 
      
 154 
     | 
    
         
            +
                      
         
     | 
| 
      
 155 
     | 
    
         
            +
                      def previous_point_connected?
         
     | 
| 
      
 156 
     | 
    
         
            +
                        @args.compact.count == 2 && !first_path_segment?
         
     | 
| 
      
 157 
     | 
    
         
            +
                      end
         
     | 
| 
       137 
158 
     | 
    
         | 
| 
      
 159 
     | 
    
         
            +
                      def eql?(other)
         
     | 
| 
      
 160 
     | 
    
         
            +
                        x1 == (other && other.respond_to?(:x1) && other.x1) &&
         
     | 
| 
      
 161 
     | 
    
         
            +
                          y1 == (other && other.respond_to?(:y1) && other.y1) &&
         
     | 
| 
      
 162 
     | 
    
         
            +
                          x2 == (other && other.respond_to?(:x2) && other.x2) &&
         
     | 
| 
      
 163 
     | 
    
         
            +
                          y2 == (other && other.respond_to?(:y2) && other.y2)
         
     | 
| 
      
 164 
     | 
    
         
            +
                      end
         
     | 
| 
      
 165 
     | 
    
         
            +
                      alias == eql?
         
     | 
| 
      
 166 
     | 
    
         
            +
                      
         
     | 
| 
      
 167 
     | 
    
         
            +
                      def hash
         
     | 
| 
      
 168 
     | 
    
         
            +
                        [x1, y1, x2, y2].hash
         
     | 
| 
      
 169 
     | 
    
         
            +
                      end
         
     | 
| 
      
 170 
     | 
    
         
            +
                                
         
     | 
| 
       138 
171 
     | 
    
         
             
                    end
         
     | 
| 
       139 
172 
     | 
    
         
             
                  end
         
     | 
| 
       140 
173 
     | 
    
         
             
                end
         
     | 
| 
         @@ -0,0 +1,197 @@ 
     | 
|
| 
      
 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/swt/custom/shape'
         
     | 
| 
      
 23 
     | 
    
         
            +
            require 'glimmer/swt/custom/shape/path_segment'
         
     | 
| 
      
 24 
     | 
    
         
            +
            require 'glimmer/swt/swt_proxy'
         
     | 
| 
      
 25 
     | 
    
         
            +
            require 'glimmer/swt/display_proxy'
         
     | 
| 
      
 26 
     | 
    
         
            +
            require 'glimmer/swt/color_proxy'
         
     | 
| 
      
 27 
     | 
    
         
            +
            require 'glimmer/swt/font_proxy'
         
     | 
| 
      
 28 
     | 
    
         
            +
            require 'glimmer/swt/display_proxy'
         
     | 
| 
      
 29 
     | 
    
         
            +
             
     | 
| 
      
 30 
     | 
    
         
            +
            module Glimmer
         
     | 
| 
      
 31 
     | 
    
         
            +
              module SWT
         
     | 
| 
      
 32 
     | 
    
         
            +
                module Custom
         
     | 
| 
      
 33 
     | 
    
         
            +
                  # Represents a path to be drawn on a control/widget/canvas/display
         
     | 
| 
      
 34 
     | 
    
         
            +
                  # That is because Shape is drawn on a parent as graphics and doesn't have an SWT widget for itself
         
     | 
| 
      
 35 
     | 
    
         
            +
                  class Shape
         
     | 
| 
      
 36 
     | 
    
         
            +
                    class Path < Shape
         
     | 
| 
      
 37 
     | 
    
         
            +
                      include PathSegment # a path may behave as a path segment in another path
         
     | 
| 
      
 38 
     | 
    
         
            +
                      
         
     | 
| 
      
 39 
     | 
    
         
            +
                      attr_accessor :flatness, :closed
         
     | 
| 
      
 40 
     | 
    
         
            +
                      attr_reader :swt_path, :path_segments
         
     | 
| 
      
 41 
     | 
    
         
            +
                    
         
     | 
| 
      
 42 
     | 
    
         
            +
                      def initialize(parent, keyword, *args, &property_block)
         
     | 
| 
      
 43 
     | 
    
         
            +
                        super
         
     | 
| 
      
 44 
     | 
    
         
            +
                        @path_segments = []
         
     | 
| 
      
 45 
     | 
    
         
            +
                        @uncalculated_path_segments = []
         
     | 
| 
      
 46 
     | 
    
         
            +
                      end
         
     | 
| 
      
 47 
     | 
    
         
            +
                      
         
     | 
| 
      
 48 
     | 
    
         
            +
                      def parameter_names
         
     | 
| 
      
 49 
     | 
    
         
            +
                        [:swt_path]
         
     | 
| 
      
 50 
     | 
    
         
            +
                      end
         
     | 
| 
      
 51 
     | 
    
         
            +
                      
         
     | 
| 
      
 52 
     | 
    
         
            +
                      def add_shape(shape)
         
     | 
| 
      
 53 
     | 
    
         
            +
                        if shape.is_a?(PathSegment)
         
     | 
| 
      
 54 
     | 
    
         
            +
                          @path_segments << shape
         
     | 
| 
      
 55 
     | 
    
         
            +
                          @uncalculated_path_segments << shape
         
     | 
| 
      
 56 
     | 
    
         
            +
                        else
         
     | 
| 
      
 57 
     | 
    
         
            +
                          super
         
     | 
| 
      
 58 
     | 
    
         
            +
                        end
         
     | 
| 
      
 59 
     | 
    
         
            +
                      end
         
     | 
| 
      
 60 
     | 
    
         
            +
                      
         
     | 
| 
      
 61 
     | 
    
         
            +
                      def contain?(x, y)
         
     | 
| 
      
 62 
     | 
    
         
            +
                        makeshift_gc = org.eclipse.swt.graphics.GC.new(Glimmer::SWT::DisplayProxy.instance.swt_display)
         
     | 
| 
      
 63 
     | 
    
         
            +
                        @swt_path.contains(x.to_f, y.to_f, makeshift_gc, false)
         
     | 
| 
      
 64 
     | 
    
         
            +
                      end
         
     | 
| 
      
 65 
     | 
    
         
            +
                      
         
     | 
| 
      
 66 
     | 
    
         
            +
                      def contain?(x, y)
         
     | 
| 
      
 67 
     | 
    
         
            +
                        include?(x, y, filled: true)
         
     | 
| 
      
 68 
     | 
    
         
            +
                      end
         
     | 
| 
      
 69 
     | 
    
         
            +
                    
         
     | 
| 
      
 70 
     | 
    
         
            +
                      # 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)
         
     | 
| 
      
 71 
     | 
    
         
            +
                      def include?(x, y, filled: nil)
         
     | 
| 
      
 72 
     | 
    
         
            +
                        filled = filled? if filled.nil?
         
     | 
| 
      
 73 
     | 
    
         
            +
                        makeshift_gc = org.eclipse.swt.graphics.GC.new(Glimmer::SWT::DisplayProxy.instance.swt_display)
         
     | 
| 
      
 74 
     | 
    
         
            +
                        @swt_path.contains(x.to_f, y.to_f, makeshift_gc, !filled)
         
     | 
| 
      
 75 
     | 
    
         
            +
                      end
         
     | 
| 
      
 76 
     | 
    
         
            +
                      
         
     | 
| 
      
 77 
     | 
    
         
            +
                      def irregular?
         
     | 
| 
      
 78 
     | 
    
         
            +
                        true
         
     | 
| 
      
 79 
     | 
    
         
            +
                      end
         
     | 
| 
      
 80 
     | 
    
         
            +
                      
         
     | 
| 
      
 81 
     | 
    
         
            +
                      def post_dispose_content(path_segment)
         
     | 
| 
      
 82 
     | 
    
         
            +
                        @path_segments.delete(path_segment)
         
     | 
| 
      
 83 
     | 
    
         
            +
                        @uncalculated_path_segments = @path_segments.dup
         
     | 
| 
      
 84 
     | 
    
         
            +
                        dispose
         
     | 
| 
      
 85 
     | 
    
         
            +
                      end
         
     | 
| 
      
 86 
     | 
    
         
            +
                      
         
     | 
| 
      
 87 
     | 
    
         
            +
                      def dispose
         
     | 
| 
      
 88 
     | 
    
         
            +
                        @swt_path&.dispose
         
     | 
| 
      
 89 
     | 
    
         
            +
                        @swt_path = nil
         
     | 
| 
      
 90 
     | 
    
         
            +
                        @args = []
         
     | 
| 
      
 91 
     | 
    
         
            +
                        calculated_args_changed!(children: false)
         
     | 
| 
      
 92 
     | 
    
         
            +
                        super
         
     | 
| 
      
 93 
     | 
    
         
            +
                      end
         
     | 
| 
      
 94 
     | 
    
         
            +
                      
         
     | 
| 
      
 95 
     | 
    
         
            +
                      def calculated_args_changed!(children: true)
         
     | 
| 
      
 96 
     | 
    
         
            +
                        super
         
     | 
| 
      
 97 
     | 
    
         
            +
                      end
         
     | 
| 
      
 98 
     | 
    
         
            +
                      
         
     | 
| 
      
 99 
     | 
    
         
            +
                      def calculated_args
         
     | 
| 
      
 100 
     | 
    
         
            +
                        @swt_path ||= org.eclipse.swt.graphics.Path.new(Glimmer::SWT::DisplayProxy.instance.swt_display)
         
     | 
| 
      
 101 
     | 
    
         
            +
                        # TODO recreate @swt_path only if one of the children get disposed (must notify parent on dispose)
         
     | 
| 
      
 102 
     | 
    
         
            +
                        @args = [@swt_path]
         
     | 
| 
      
 103 
     | 
    
         
            +
                        @uncalculated_path_segments.dup.each do |path_segment|
         
     | 
| 
      
 104 
     | 
    
         
            +
                          path_segment.add_to_swt_path(@swt_path)
         
     | 
| 
      
 105 
     | 
    
         
            +
                          @uncalculated_path_segments.delete(path_segment)
         
     | 
| 
      
 106 
     | 
    
         
            +
                        end
         
     | 
| 
      
 107 
     | 
    
         
            +
                        super
         
     | 
| 
      
 108 
     | 
    
         
            +
                      rescue => e
         
     | 
| 
      
 109 
     | 
    
         
            +
                        Glimmer::Config.logger.error {e.full_message}
         
     | 
| 
      
 110 
     | 
    
         
            +
                      end
         
     | 
| 
      
 111 
     | 
    
         
            +
                      
         
     | 
| 
      
 112 
     | 
    
         
            +
                      def move_by(x_delta, y_delta)
         
     | 
| 
      
 113 
     | 
    
         
            +
                        @path_segments.each {|path_segment| path_segment.move_by(x_delta, y_delta)}
         
     | 
| 
      
 114 
     | 
    
         
            +
                      end
         
     | 
| 
      
 115 
     | 
    
         
            +
                      
         
     | 
| 
      
 116 
     | 
    
         
            +
                      def bounds
         
     | 
| 
      
 117 
     | 
    
         
            +
                        if @path_segments != @bounds_path_segments
         
     | 
| 
      
 118 
     | 
    
         
            +
                          @bounds_path_segments = @path_segments
         
     | 
| 
      
 119 
     | 
    
         
            +
                          shape_bounds = geometry.getBounds2D
         
     | 
| 
      
 120 
     | 
    
         
            +
                          @bounds = org.eclipse.swt.graphics.Rectangle.new(shape_bounds.x, shape_bounds.y, shape_bounds.width, shape_bounds.height)
         
     | 
| 
      
 121 
     | 
    
         
            +
                        end
         
     | 
| 
      
 122 
     | 
    
         
            +
                        @bounds
         
     | 
| 
      
 123 
     | 
    
         
            +
                      end
         
     | 
| 
      
 124 
     | 
    
         
            +
                      
         
     | 
| 
      
 125 
     | 
    
         
            +
                      def size
         
     | 
| 
      
 126 
     | 
    
         
            +
                        if @path_segments != @size_path_segments
         
     | 
| 
      
 127 
     | 
    
         
            +
                          @size_path_segments = @path_segments
         
     | 
| 
      
 128 
     | 
    
         
            +
                          shape_bounds = geometry.getBounds2D
         
     | 
| 
      
 129 
     | 
    
         
            +
                          @size = org.eclipse.swt.graphics.Point.new(shape_bounds.width, shape_bounds.height)
         
     | 
| 
      
 130 
     | 
    
         
            +
                        end
         
     | 
| 
      
 131 
     | 
    
         
            +
                        @size
         
     | 
| 
      
 132 
     | 
    
         
            +
                      end
         
     | 
| 
      
 133 
     | 
    
         
            +
                      
         
     | 
| 
      
 134 
     | 
    
         
            +
                      # Logical x coordinate relative to parent
         
     | 
| 
      
 135 
     | 
    
         
            +
                      def x
         
     | 
| 
      
 136 
     | 
    
         
            +
                        x_value = bounds.x
         
     | 
| 
      
 137 
     | 
    
         
            +
                        x_value -= parent.absolute_x if parent.is_a?(Shape)
         
     | 
| 
      
 138 
     | 
    
         
            +
                        x_value
         
     | 
| 
      
 139 
     | 
    
         
            +
                      end
         
     | 
| 
      
 140 
     | 
    
         
            +
                      
         
     | 
| 
      
 141 
     | 
    
         
            +
                      # Logical y coordinate relative to parent
         
     | 
| 
      
 142 
     | 
    
         
            +
                      def y
         
     | 
| 
      
 143 
     | 
    
         
            +
                        y_value = bounds.y
         
     | 
| 
      
 144 
     | 
    
         
            +
                        y_value -= parent.absolute_y if parent.is_a?(Shape)
         
     | 
| 
      
 145 
     | 
    
         
            +
                        y_value
         
     | 
| 
      
 146 
     | 
    
         
            +
                      end
         
     | 
| 
      
 147 
     | 
    
         
            +
                      
         
     | 
| 
      
 148 
     | 
    
         
            +
                      def width
         
     | 
| 
      
 149 
     | 
    
         
            +
                        size.x
         
     | 
| 
      
 150 
     | 
    
         
            +
                      end
         
     | 
| 
      
 151 
     | 
    
         
            +
                      
         
     | 
| 
      
 152 
     | 
    
         
            +
                      def height
         
     | 
| 
      
 153 
     | 
    
         
            +
                        size.y
         
     | 
| 
      
 154 
     | 
    
         
            +
                      end
         
     | 
| 
      
 155 
     | 
    
         
            +
                      
         
     | 
| 
      
 156 
     | 
    
         
            +
                      def geometry
         
     | 
| 
      
 157 
     | 
    
         
            +
                        if @path_segments != @geometry_path_segments
         
     | 
| 
      
 158 
     | 
    
         
            +
                          @geometry_path_segments = @path_segments
         
     | 
| 
      
 159 
     | 
    
         
            +
                          @geometry = Java::JavaAwtGeom::Path2D::Double.new
         
     | 
| 
      
 160 
     | 
    
         
            +
                          @path_segments.each do |path_segment|
         
     | 
| 
      
 161 
     | 
    
         
            +
                            @geometry.send(path_segment.path_segment_geometry_method_name, *path_segment.path_segment_geometry_args)
         
     | 
| 
      
 162 
     | 
    
         
            +
                          end
         
     | 
| 
      
 163 
     | 
    
         
            +
                        end
         
     | 
| 
      
 164 
     | 
    
         
            +
                        @geometry
         
     | 
| 
      
 165 
     | 
    
         
            +
                      end
         
     | 
| 
      
 166 
     | 
    
         
            +
                                        
         
     | 
| 
      
 167 
     | 
    
         
            +
                      def path_segment_method_name
         
     | 
| 
      
 168 
     | 
    
         
            +
                        'addPath'
         
     | 
| 
      
 169 
     | 
    
         
            +
                      end
         
     | 
| 
      
 170 
     | 
    
         
            +
                                
         
     | 
| 
      
 171 
     | 
    
         
            +
                      def path_segment_args
         
     | 
| 
      
 172 
     | 
    
         
            +
                        @args
         
     | 
| 
      
 173 
     | 
    
         
            +
                      end
         
     | 
| 
      
 174 
     | 
    
         
            +
                                        
         
     | 
| 
      
 175 
     | 
    
         
            +
                      def path_segment_geometry_method_name
         
     | 
| 
      
 176 
     | 
    
         
            +
                        'append'
         
     | 
| 
      
 177 
     | 
    
         
            +
                      end
         
     | 
| 
      
 178 
     | 
    
         
            +
                                
         
     | 
| 
      
 179 
     | 
    
         
            +
                      def path_segment_geometry_args
         
     | 
| 
      
 180 
     | 
    
         
            +
                        # TODO consider supporting connected true instead of false (2nd arg)
         
     | 
| 
      
 181 
     | 
    
         
            +
                        [geometry, false]
         
     | 
| 
      
 182 
     | 
    
         
            +
                      end
         
     | 
| 
      
 183 
     | 
    
         
            +
                      
         
     | 
| 
      
 184 
     | 
    
         
            +
                      def eql?(other)
         
     | 
| 
      
 185 
     | 
    
         
            +
                        geometry.equals(other && other.respond_to?(:geometry) && other.geometry)
         
     | 
| 
      
 186 
     | 
    
         
            +
                      end
         
     | 
| 
      
 187 
     | 
    
         
            +
                      alias == eql?
         
     | 
| 
      
 188 
     | 
    
         
            +
                      
         
     | 
| 
      
 189 
     | 
    
         
            +
                      def hash
         
     | 
| 
      
 190 
     | 
    
         
            +
                        geometry.hashCode
         
     | 
| 
      
 191 
     | 
    
         
            +
                      end
         
     | 
| 
      
 192 
     | 
    
         
            +
                      
         
     | 
| 
      
 193 
     | 
    
         
            +
                    end
         
     | 
| 
      
 194 
     | 
    
         
            +
                  end
         
     | 
| 
      
 195 
     | 
    
         
            +
                end
         
     | 
| 
      
 196 
     | 
    
         
            +
              end
         
     | 
| 
      
 197 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,86 @@ 
     | 
|
| 
      
 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/swt/custom/shape'
         
     | 
| 
      
 23 
     | 
    
         
            +
             
     | 
| 
      
 24 
     | 
    
         
            +
            module Glimmer
         
     | 
| 
      
 25 
     | 
    
         
            +
              module SWT
         
     | 
| 
      
 26 
     | 
    
         
            +
                module Custom
         
     | 
| 
      
 27 
     | 
    
         
            +
                  # Represents a path to be drawn on a control/widget/canvas/display
         
     | 
| 
      
 28 
     | 
    
         
            +
                  # That is because Shape is drawn on a parent as graphics and doesn't have an SWT widget for itself
         
     | 
| 
      
 29 
     | 
    
         
            +
                  class Shape
         
     | 
| 
      
 30 
     | 
    
         
            +
                    # Represents path segments like point, line, quad, and cubic curves
         
     | 
| 
      
 31 
     | 
    
         
            +
                    # Shapes could mix in
         
     | 
| 
      
 32 
     | 
    
         
            +
                    module PathSegment
         
     | 
| 
      
 33 
     | 
    
         
            +
                      # Subclasses must override and implement to indicate method name to invoke on SWT Path object to add segment
         
     | 
| 
      
 34 
     | 
    
         
            +
                      def path_segment_method_name
         
     | 
| 
      
 35 
     | 
    
         
            +
                        nil
         
     | 
| 
      
 36 
     | 
    
         
            +
                      end
         
     | 
| 
      
 37 
     | 
    
         
            +
                      # Subclasses must override and implement to indicate args to pass when invoking SWT Path object method
         
     | 
| 
      
 38 
     | 
    
         
            +
                      def path_segment_args
         
     | 
| 
      
 39 
     | 
    
         
            +
                        []
         
     | 
| 
      
 40 
     | 
    
         
            +
                      end
         
     | 
| 
      
 41 
     | 
    
         
            +
                      # 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 
     | 
    
         
            +
                      def path_segment_geometry_method_name
         
     | 
| 
      
 43 
     | 
    
         
            +
                        path_segment_method_name
         
     | 
| 
      
 44 
     | 
    
         
            +
                      end
         
     | 
| 
      
 45 
     | 
    
         
            +
                      # Subclasses must override and implement to indicate args to pass when invoking SWT Path object method
         
     | 
| 
      
 46 
     | 
    
         
            +
                      def path_segment_geometry_args
         
     | 
| 
      
 47 
     | 
    
         
            +
                        path_segment_args
         
     | 
| 
      
 48 
     | 
    
         
            +
                      end
         
     | 
| 
      
 49 
     | 
    
         
            +
                      # Subclasses must override to indicate otherwise
         
     | 
| 
      
 50 
     | 
    
         
            +
                      def previous_point_connected?
         
     | 
| 
      
 51 
     | 
    
         
            +
                        true
         
     | 
| 
      
 52 
     | 
    
         
            +
                      end
         
     | 
| 
      
 53 
     | 
    
         
            +
                      
         
     | 
| 
      
 54 
     | 
    
         
            +
                      def dispose
         
     | 
| 
      
 55 
     | 
    
         
            +
                        parent.post_dispose_content(self) if parent.is_a?(Path)
         
     | 
| 
      
 56 
     | 
    
         
            +
                      end
         
     | 
| 
      
 57 
     | 
    
         
            +
                      
         
     | 
| 
      
 58 
     | 
    
         
            +
                      def first_path_segment?
         
     | 
| 
      
 59 
     | 
    
         
            +
                        parent.path_segments.first == self
         
     | 
| 
      
 60 
     | 
    
         
            +
                      end
         
     | 
| 
      
 61 
     | 
    
         
            +
                      
         
     | 
| 
      
 62 
     | 
    
         
            +
                      def previous_path_segment
         
     | 
| 
      
 63 
     | 
    
         
            +
                        parent.path_segments[parent.path_segments.index(self) - 1] || self
         
     | 
| 
      
 64 
     | 
    
         
            +
                      end
         
     | 
| 
      
 65 
     | 
    
         
            +
                      
         
     | 
| 
      
 66 
     | 
    
         
            +
                      def add_to_swt_path(swt_path)
         
     | 
| 
      
 67 
     | 
    
         
            +
                        if @swt_path != swt_path
         
     | 
| 
      
 68 
     | 
    
         
            +
                          @swt_path = swt_path
         
     | 
| 
      
 69 
     | 
    
         
            +
                          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
         
     | 
| 
      
 73 
     | 
    
         
            +
                              @swt_path.moveTo(*point)
         
     | 
| 
      
 74 
     | 
    
         
            +
                            elsif first_path_segment? && self.class != Path
         
     | 
| 
      
 75 
     | 
    
         
            +
                              point = the_path_segment_args[0..1]
         
     | 
| 
      
 76 
     | 
    
         
            +
                              @swt_path.moveTo(*point)
         
     | 
| 
      
 77 
     | 
    
         
            +
                            end
         
     | 
| 
      
 78 
     | 
    
         
            +
                          end
         
     | 
| 
      
 79 
     | 
    
         
            +
                          @swt_path.send(path_segment_method_name, *the_path_segment_args)
         
     | 
| 
      
 80 
     | 
    
         
            +
                        end
         
     | 
| 
      
 81 
     | 
    
         
            +
                      end
         
     | 
| 
      
 82 
     | 
    
         
            +
                    end
         
     | 
| 
      
 83 
     | 
    
         
            +
                  end
         
     | 
| 
      
 84 
     | 
    
         
            +
                end
         
     | 
| 
      
 85 
     | 
    
         
            +
              end
         
     | 
| 
      
 86 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -20,6 +20,7 @@ 
     | 
|
| 
       20 
20 
     | 
    
         
             
            # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
         
     | 
| 
       21 
21 
     | 
    
         | 
| 
       22 
22 
     | 
    
         
             
            require 'glimmer/swt/custom/shape'
         
     | 
| 
      
 23 
     | 
    
         
            +
            require 'glimmer/swt/custom/shape/path_segment'
         
     | 
| 
       23 
24 
     | 
    
         
             
            require 'glimmer/swt/swt_proxy'
         
     | 
| 
       24 
25 
     | 
    
         
             
            require 'glimmer/swt/display_proxy'
         
     | 
| 
       25 
26 
     | 
    
         
             
            require 'glimmer/swt/color_proxy'
         
     | 
| 
         @@ -33,6 +34,8 @@ module Glimmer 
     | 
|
| 
       33 
34 
     | 
    
         
             
                  # That is because Shape is drawn on a parent as graphics and doesn't have an SWT widget for itself
         
     | 
| 
       34 
35 
     | 
    
         
             
                  class Shape
         
     | 
| 
       35 
36 
     | 
    
         
             
                    class Point < Shape
         
     | 
| 
      
 37 
     | 
    
         
            +
                      include PathSegment
         
     | 
| 
      
 38 
     | 
    
         
            +
                      
         
     | 
| 
       36 
39 
     | 
    
         
             
                      def parameter_names
         
     | 
| 
       37 
40 
     | 
    
         
             
                        [:x, :y]
         
     | 
| 
       38 
41 
     | 
    
         
             
                      end
         
     | 
| 
         @@ -50,6 +53,36 @@ module Glimmer 
     | 
|
| 
       50 
53 
     | 
    
         
             
                        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)
         
     | 
| 
       51 
54 
     | 
    
         
             
                      end
         
     | 
| 
       52 
55 
     | 
    
         
             
                      alias contain? include?
         
     | 
| 
      
 56 
     | 
    
         
            +
                      
         
     | 
| 
      
 57 
     | 
    
         
            +
                      def path_segment_method_name
         
     | 
| 
      
 58 
     | 
    
         
            +
                        'addRectangle'
         
     | 
| 
      
 59 
     | 
    
         
            +
                      end
         
     | 
| 
      
 60 
     | 
    
         
            +
                                
         
     | 
| 
      
 61 
     | 
    
         
            +
                      def path_segment_args
         
     | 
| 
      
 62 
     | 
    
         
            +
                        @args + [1, 1]
         
     | 
| 
      
 63 
     | 
    
         
            +
                      end
         
     | 
| 
      
 64 
     | 
    
         
            +
                      
         
     | 
| 
      
 65 
     | 
    
         
            +
                      def path_segment_geometry_method_name
         
     | 
| 
      
 66 
     | 
    
         
            +
                        'moveTo'
         
     | 
| 
      
 67 
     | 
    
         
            +
                      end
         
     | 
| 
      
 68 
     | 
    
         
            +
                                
         
     | 
| 
      
 69 
     | 
    
         
            +
                      def path_segment_geometry_args
         
     | 
| 
      
 70 
     | 
    
         
            +
                        @args
         
     | 
| 
      
 71 
     | 
    
         
            +
                      end
         
     | 
| 
      
 72 
     | 
    
         
            +
                      
         
     | 
| 
      
 73 
     | 
    
         
            +
                      def previous_point_connected?
         
     | 
| 
      
 74 
     | 
    
         
            +
                        false
         
     | 
| 
      
 75 
     | 
    
         
            +
                      end
         
     | 
| 
      
 76 
     | 
    
         
            +
                      
         
     | 
| 
      
 77 
     | 
    
         
            +
                      def eql?(other)
         
     | 
| 
      
 78 
     | 
    
         
            +
                        x == (other && other.respond_to?(:x) && other.x) && y == (other && other.respond_to?(:y) && other.y)
         
     | 
| 
      
 79 
     | 
    
         
            +
                      end
         
     | 
| 
      
 80 
     | 
    
         
            +
                      alias == eql?
         
     | 
| 
      
 81 
     | 
    
         
            +
                      
         
     | 
| 
      
 82 
     | 
    
         
            +
                      def hash
         
     | 
| 
      
 83 
     | 
    
         
            +
                        [x, y].hash
         
     | 
| 
      
 84 
     | 
    
         
            +
                      end
         
     | 
| 
      
 85 
     | 
    
         
            +
                      
         
     | 
| 
       53 
86 
     | 
    
         
             
                    end
         
     | 
| 
       54 
87 
     | 
    
         
             
                  end
         
     | 
| 
       55 
88 
     | 
    
         
             
                end
         
     | 
| 
         @@ -0,0 +1,104 @@ 
     | 
|
| 
      
 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/swt/custom/shape'
         
     | 
| 
      
 23 
     | 
    
         
            +
            require 'glimmer/swt/custom/shape/path_segment'
         
     | 
| 
      
 24 
     | 
    
         
            +
            require 'glimmer/swt/swt_proxy'
         
     | 
| 
      
 25 
     | 
    
         
            +
            require 'glimmer/swt/display_proxy'
         
     | 
| 
      
 26 
     | 
    
         
            +
            require 'glimmer/swt/color_proxy'
         
     | 
| 
      
 27 
     | 
    
         
            +
            require 'glimmer/swt/font_proxy'
         
     | 
| 
      
 28 
     | 
    
         
            +
            require 'glimmer/swt/transform_proxy'
         
     | 
| 
      
 29 
     | 
    
         
            +
             
     | 
| 
      
 30 
     | 
    
         
            +
            module Glimmer
         
     | 
| 
      
 31 
     | 
    
         
            +
              module SWT
         
     | 
| 
      
 32 
     | 
    
         
            +
                module Custom
         
     | 
| 
      
 33 
     | 
    
         
            +
                  # Represents a shape (graphics) to be drawn on a control/widget/canvas/display
         
     | 
| 
      
 34 
     | 
    
         
            +
                  # That is because Shape is drawn on a parent as graphics and doesn't have an SWT widget for itself
         
     | 
| 
      
 35 
     | 
    
         
            +
                  class Shape
         
     | 
| 
      
 36 
     | 
    
         
            +
                    class Quad < Path
         
     | 
| 
      
 37 
     | 
    
         
            +
                      def parameter_names
         
     | 
| 
      
 38 
     | 
    
         
            +
                        [:point_array]
         
     | 
| 
      
 39 
     | 
    
         
            +
                      end
         
     | 
| 
      
 40 
     | 
    
         
            +
                      
         
     | 
| 
      
 41 
     | 
    
         
            +
                      def geometry
         
     | 
| 
      
 42 
     | 
    
         
            +
                        if @point_array != @geometry_point_array
         
     | 
| 
      
 43 
     | 
    
         
            +
                          @geometry_point_array = @point_array
         
     | 
| 
      
 44 
     | 
    
         
            +
                          @geometry = Java::JavaAwtGeom::Path2D::Double.new
         
     | 
| 
      
 45 
     | 
    
         
            +
                          @geometry.send(path_segment_geometry_method_name, *path_segment_geometry_args)
         
     | 
| 
      
 46 
     | 
    
         
            +
                        end
         
     | 
| 
      
 47 
     | 
    
         
            +
                        @geometry
         
     | 
| 
      
 48 
     | 
    
         
            +
                      end
         
     | 
| 
      
 49 
     | 
    
         
            +
                    
         
     | 
| 
      
 50 
     | 
    
         
            +
                      def contain?(x, y)
         
     | 
| 
      
 51 
     | 
    
         
            +
                        include?(x, y, filled: true)
         
     | 
| 
      
 52 
     | 
    
         
            +
                      end
         
     | 
| 
      
 53 
     | 
    
         
            +
                    
         
     | 
| 
      
 54 
     | 
    
         
            +
                      # 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)
         
     | 
| 
      
 55 
     | 
    
         
            +
                      def include?(x, y, filled: nil)
         
     | 
| 
      
 56 
     | 
    
         
            +
                        filled = filled? if filled.nil?
         
     | 
| 
      
 57 
     | 
    
         
            +
                        makeshift_gc = org.eclipse.swt.graphics.GC.new(Glimmer::SWT::DisplayProxy.instance.swt_display)
         
     | 
| 
      
 58 
     | 
    
         
            +
                        swt_path = org.eclipse.swt.graphics.Path.new(Glimmer::SWT::DisplayProxy.instance.swt_display)
         
     | 
| 
      
 59 
     | 
    
         
            +
                        the_path_segment_args = path_segment_args.dup
         
     | 
| 
      
 60 
     | 
    
         
            +
                        if previous_point_connected?
         
     | 
| 
      
 61 
     | 
    
         
            +
                          the_previous_path_segment = previous_path_segment
         
     | 
| 
      
 62 
     | 
    
         
            +
                          swt_path.moveTo(the_previous_path_segment.x, the_previous_path_segment.y)
         
     | 
| 
      
 63 
     | 
    
         
            +
                        else
         
     | 
| 
      
 64 
     | 
    
         
            +
                          swt_path.moveTo(the_path_segment_args.shift, the_path_segment_args.shift)
         
     | 
| 
      
 65 
     | 
    
         
            +
                        end
         
     | 
| 
      
 66 
     | 
    
         
            +
                        swt_path.quadTo(*the_path_segment_args)
         
     | 
| 
      
 67 
     | 
    
         
            +
                        swt_path.contains(x.to_f, y.to_f, makeshift_gc, !filled)
         
     | 
| 
      
 68 
     | 
    
         
            +
                      ensure
         
     | 
| 
      
 69 
     | 
    
         
            +
                        swt_path.dispose
         
     | 
| 
      
 70 
     | 
    
         
            +
                      end
         
     | 
| 
      
 71 
     | 
    
         
            +
                        
         
     | 
| 
      
 72 
     | 
    
         
            +
                      def move_by(x_delta, y_delta)
         
     | 
| 
      
 73 
     | 
    
         
            +
                        the_point_array = @args.compact
         
     | 
| 
      
 74 
     | 
    
         
            +
                        the_point_array = the_point_array.first if the_point_array.first.is_a?(Array)
         
     | 
| 
      
 75 
     | 
    
         
            +
                        self.point_array = the_point_array.each_with_index.map {|coordinate, i| i.even? ? coordinate + x_delta : coordinate + y_delta}
         
     | 
| 
      
 76 
     | 
    
         
            +
                      end
         
     | 
| 
      
 77 
     | 
    
         
            +
                                          
         
     | 
| 
      
 78 
     | 
    
         
            +
                      def path_segment_method_name
         
     | 
| 
      
 79 
     | 
    
         
            +
                        'quadTo'
         
     | 
| 
      
 80 
     | 
    
         
            +
                      end
         
     | 
| 
      
 81 
     | 
    
         
            +
                      
         
     | 
| 
      
 82 
     | 
    
         
            +
                      def path_segment_args
         
     | 
| 
      
 83 
     | 
    
         
            +
                        # TODO make args auto-infer control points if previous_point_connected is true or if there is only a point_array with 1 point
         
     | 
| 
      
 84 
     | 
    
         
            +
                        @args.to_a
         
     | 
| 
      
 85 
     | 
    
         
            +
                      end
         
     | 
| 
      
 86 
     | 
    
         
            +
                      
         
     | 
| 
      
 87 
     | 
    
         
            +
                      def previous_point_connected?
         
     | 
| 
      
 88 
     | 
    
         
            +
                        @args.compact.count <= 4 && !first_path_segment?
         
     | 
| 
      
 89 
     | 
    
         
            +
                      end
         
     | 
| 
      
 90 
     | 
    
         
            +
                      
         
     | 
| 
      
 91 
     | 
    
         
            +
                      def eql?(other)
         
     | 
| 
      
 92 
     | 
    
         
            +
                        point_array == (other && other.respond_to?(:point_array) && other.point_array)
         
     | 
| 
      
 93 
     | 
    
         
            +
                      end
         
     | 
| 
      
 94 
     | 
    
         
            +
                      alias == eql?
         
     | 
| 
      
 95 
     | 
    
         
            +
                      
         
     | 
| 
      
 96 
     | 
    
         
            +
                      def hash
         
     | 
| 
      
 97 
     | 
    
         
            +
                        point_array.hash
         
     | 
| 
      
 98 
     | 
    
         
            +
                      end
         
     | 
| 
      
 99 
     | 
    
         
            +
                                
         
     | 
| 
      
 100 
     | 
    
         
            +
                    end
         
     | 
| 
      
 101 
     | 
    
         
            +
                  end
         
     | 
| 
      
 102 
     | 
    
         
            +
                end
         
     | 
| 
      
 103 
     | 
    
         
            +
              end
         
     | 
| 
      
 104 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -73,7 +73,7 @@ module Glimmer 
     | 
|
| 
       73 
73 
     | 
    
         
             
                    Glimmer::SWT::DisplayProxy.instance.auto_exec do
         
     | 
| 
       74 
74 
     | 
    
         
             
                      result = if proxy_source_object&.respond_to?(attribute_setter(attribute_name))
         
     | 
| 
       75 
75 
     | 
    
         
             
                        swt_widget_operation = true
         
     | 
| 
       76 
     | 
    
         
            -
                        proxy_source_object&.send(attribute_setter(attribute_name), *args) unless proxy_source_object&.send(attribute_getter(attribute_name)) == args.first
         
     | 
| 
      
 76 
     | 
    
         
            +
                        proxy_source_object&.send(attribute_setter(attribute_name), *args) unless (proxy_source_object&.respond_to?(attribute_getter(attribute_name)) && proxy_source_object&.send(attribute_getter(attribute_name))) == args.first
         
     | 
| 
       77 
77 
     | 
    
         
             
                      elsif proxy_source_object&.respond_to?(ruby_attribute_setter(attribute_name))
         
     | 
| 
       78 
78 
     | 
    
         
             
                        swt_widget_operation = true
         
     | 
| 
       79 
79 
     | 
    
         
             
                        proxy_source_object&.send(ruby_attribute_setter(attribute_name), args)
         
     | 
| 
         @@ -379,7 +379,7 @@ class MandelbrotFractal 
     | 
|
| 
       379 
379 
     | 
    
         
             
                  image @mandelbrot_image
         
     | 
| 
       380 
380 
     | 
    
         
             
                }
         
     | 
| 
       381 
381 
     | 
    
         
             
                @canvas.set_size @mandelbrot_image.bounds.width, @mandelbrot_image.bounds.height
         
     | 
| 
       382 
     | 
    
         
            -
                @scrolled_composite. 
     | 
| 
      
 382 
     | 
    
         
            +
                @scrolled_composite.set_min_size(Point.new(@mandelbrot_image.bounds.width, @mandelbrot_image.bounds.height))
         
     | 
| 
       383 
383 
     | 
    
         
             
                if @location_x && @location_y
         
     | 
| 
       384 
384 
     | 
    
         
             
                  # center on mouse click location
         
     | 
| 
       385 
385 
     | 
    
         
             
                  factor = (zoom / last_zoom)
         
     | 
| 
         @@ -0,0 +1,223 @@ 
     | 
|
| 
      
 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 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
         
     | 
| 
      
 65 
     | 
    
         
            +
              
         
     | 
| 
      
 66 
     | 
    
         
            +
              include Glimmer::UI::CustomShell
         
     | 
| 
      
 67 
     | 
    
         
            +
              
         
     | 
| 
      
 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)
         
     | 
| 
      
 149 
     | 
    
         
            +
                  }
         
     | 
| 
      
 150 
     | 
    
         
            +
                }
         
     | 
| 
      
 151 
     | 
    
         
            +
              }
         
     | 
| 
      
 152 
     | 
    
         
            +
              
         
     | 
| 
      
 153 
     | 
    
         
            +
              body {
         
     | 
| 
      
 154 
     | 
    
         
            +
                shell {
         
     | 
| 
      
 155 
     | 
    
         
            +
                  fill_layout {
         
     | 
| 
      
 156 
     | 
    
         
            +
                    margin_width 15
         
     | 
| 
      
 157 
     | 
    
         
            +
                    margin_height 15
         
     | 
| 
      
 158 
     | 
    
         
            +
                  }
         
     | 
| 
      
 159 
     | 
    
         
            +
                  text 'Hello, Canvas Path!'
         
     | 
| 
      
 160 
     | 
    
         
            +
                  minimum_size 650, 650
         
     | 
| 
      
 161 
     | 
    
         
            +
                  background :white
         
     | 
| 
      
 162 
     | 
    
         
            +
                  
         
     | 
| 
      
 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
         
     | 
| 
      
 208 
     | 
    
         
            +
                  }
         
     | 
| 
      
 209 
     | 
    
         
            +
                
         
     | 
| 
      
 210 
     | 
    
         
            +
                  on_swt_show {
         
     | 
| 
      
 211 
     | 
    
         
            +
                    Stock.stock_price_min = 25
         
     | 
| 
      
 212 
     | 
    
         
            +
                    Stock.stock_price_max = @tabs.first[:canvas].bounds.height - 6
         
     | 
| 
      
 213 
     | 
    
         
            +
                  }
         
     | 
| 
      
 214 
     | 
    
         
            +
                  
         
     | 
| 
      
 215 
     | 
    
         
            +
                  on_widget_disposed {
         
     | 
| 
      
 216 
     | 
    
         
            +
                    @thread.kill # safe to kill as memory is in data only
         
     | 
| 
      
 217 
     | 
    
         
            +
                  }
         
     | 
| 
      
 218 
     | 
    
         
            +
                }
         
     | 
| 
      
 219 
     | 
    
         
            +
              }
         
     | 
| 
      
 220 
     | 
    
         
            +
            end
         
     | 
| 
      
 221 
     | 
    
         
            +
             
     | 
| 
      
 222 
     | 
    
         
            +
            HelloCanvasPath.launch
         
     | 
| 
      
 223 
     | 
    
         
            +
                    
         
     | 
    
        metadata
    CHANGED
    
    | 
         @@ -1,14 +1,14 @@ 
     | 
|
| 
       1 
1 
     | 
    
         
             
            --- !ruby/object:Gem::Specification
         
     | 
| 
       2 
2 
     | 
    
         
             
            name: glimmer-dsl-swt
         
     | 
| 
       3 
3 
     | 
    
         
             
            version: !ruby/object:Gem::Version
         
     | 
| 
       4 
     | 
    
         
            -
              version: 4.18. 
     | 
| 
      
 4 
     | 
    
         
            +
              version: 4.18.6.0
         
     | 
| 
       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-28 00:00:00.000000000 Z
         
     | 
| 
       12 
12 
     | 
    
         
             
            dependencies:
         
     | 
| 
       13 
13 
     | 
    
         
             
            - !ruby/object:Gem::Dependency
         
     | 
| 
       14 
14 
     | 
    
         
             
              requirement: !ruby/object:Gem::Requirement
         
     | 
| 
         @@ -434,13 +434,17 @@ files: 
     | 
|
| 
       434 
434 
     | 
    
         
             
            - lib/glimmer/swt/custom/radio_group.rb
         
     | 
| 
       435 
435 
     | 
    
         
             
            - lib/glimmer/swt/custom/shape.rb
         
     | 
| 
       436 
436 
     | 
    
         
             
            - lib/glimmer/swt/custom/shape/arc.rb
         
     | 
| 
      
 437 
     | 
    
         
            +
            - lib/glimmer/swt/custom/shape/cubic.rb
         
     | 
| 
       437 
438 
     | 
    
         
             
            - lib/glimmer/swt/custom/shape/focus.rb
         
     | 
| 
       438 
439 
     | 
    
         
             
            - lib/glimmer/swt/custom/shape/image.rb
         
     | 
| 
       439 
440 
     | 
    
         
             
            - lib/glimmer/swt/custom/shape/line.rb
         
     | 
| 
       440 
441 
     | 
    
         
             
            - lib/glimmer/swt/custom/shape/oval.rb
         
     | 
| 
      
 442 
     | 
    
         
            +
            - lib/glimmer/swt/custom/shape/path.rb
         
     | 
| 
      
 443 
     | 
    
         
            +
            - lib/glimmer/swt/custom/shape/path_segment.rb
         
     | 
| 
       441 
444 
     | 
    
         
             
            - lib/glimmer/swt/custom/shape/point.rb
         
     | 
| 
       442 
445 
     | 
    
         
             
            - lib/glimmer/swt/custom/shape/polygon.rb
         
     | 
| 
       443 
446 
     | 
    
         
             
            - lib/glimmer/swt/custom/shape/polyline.rb
         
     | 
| 
      
 447 
     | 
    
         
            +
            - lib/glimmer/swt/custom/shape/quad.rb
         
     | 
| 
       444 
448 
     | 
    
         
             
            - lib/glimmer/swt/custom/shape/rectangle.rb
         
     | 
| 
       445 
449 
     | 
    
         
             
            - lib/glimmer/swt/custom/shape/text.rb
         
     | 
| 
       446 
450 
     | 
    
         
             
            - lib/glimmer/swt/date_time_proxy.rb
         
     | 
| 
         @@ -499,6 +503,7 @@ files: 
     | 
|
| 
       499 
503 
     | 
    
         
             
            - samples/hello/hello_button.rb
         
     | 
| 
       500 
504 
     | 
    
         
             
            - samples/hello/hello_canvas.rb
         
     | 
| 
       501 
505 
     | 
    
         
             
            - samples/hello/hello_canvas_animation.rb
         
     | 
| 
      
 506 
     | 
    
         
            +
            - samples/hello/hello_canvas_path.rb
         
     | 
| 
       502 
507 
     | 
    
         
             
            - samples/hello/hello_canvas_transform.rb
         
     | 
| 
       503 
508 
     | 
    
         
             
            - samples/hello/hello_checkbox.rb
         
     | 
| 
       504 
509 
     | 
    
         
             
            - samples/hello/hello_checkbox_group.rb
         
     |