glimmer-dsl-swt 4.24.2.2 → 4.24.3.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +17 -0
- data/README.md +6 -6
- data/VERSION +1 -1
- data/docs/reference/GLIMMER_GUI_DSL_SYNTAX.md +102 -20
- data/docs/reference/GLIMMER_SAMPLES.md +24 -8
- data/glimmer-dsl-swt.gemspec +0 -0
- data/lib/glimmer/data_binding/table_items_binding.rb +141 -16
- data/lib/glimmer/dsl/swt/font_expression.rb +1 -1
- data/lib/glimmer/swt/custom/code_text.rb +40 -2
- data/lib/glimmer/swt/font_proxy.rb +13 -3
- data/lib/glimmer/swt/table_proxy.rb +8 -2
- data/samples/elaborate/meta_sample/tutorials.yml +1 -0
- data/samples/hello/hello_custom_shape.rb +10 -10
- data/samples/hello/hello_table.rb +73 -14
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 44c7406f9588caef592b17f889b509db88771e545300a916f44ea1a928a89937
|
4
|
+
data.tar.gz: 2933dfdf3e5e1479849793cec5bbfdf3558768bb34b4c828847339c95559242a
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 6d13f0eaa866f47c449caa5ce3e3ae652025940769b8f419c0b4b66df0e1e67b3a4e3494ab539cb81d21de79ac44d81e3982f59083c9bd0453201e1231073ee0
|
7
|
+
data.tar.gz: 53fe039d009a4d3476bbc2a5d96f11ca3ab4fdb442b790bafd0b9bc920943bb4cc6bc475522f1f040d355da8029cd693a76179d4e247fa9e4bd59fcd2637fe80
|
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,22 @@
|
|
1
1
|
# Change Log
|
2
2
|
|
3
|
+
## 4.24.3.1
|
4
|
+
|
5
|
+
- `code_text` default behavior support of zoom in (CMD+= on Mac, CTRL+= on Win/Linux), zoom out (CMD+- on Mac, CTRL+- on Win/Linux), and restore original font height (CMD+0 on Mac, CTRL+0 on Win/Linux).
|
6
|
+
|
7
|
+
## 4.24.3.0
|
8
|
+
|
9
|
+
- Support `table` `items` data-binding of table row cell `background`, `foreground`, `font`, `image` to model attributes by convention based on specified `column_properties` (e.g. for `column_properties` model `name` attribute, automatically assume model `name_background` provides `[r, g, b]` array of color)
|
10
|
+
- Update Hello, Table! sample to demonstrate data-binding `table` `items` `background`, `foreground`, `font`, `image` to model attributes by convention, and to add `booked` attribute on `BaseballGame` to disable Book button when already booked
|
11
|
+
- Update Hello, Table! sample to add `booked` attribute to `BaseballGame` to disable Book button when already booked
|
12
|
+
- Update Hello, Table! sample to enable booking by hitting the ENTER keyboard button
|
13
|
+
- Optimize `table` data-binding performance by not recreating table-items when the table grows or stays at the same size, and by not updating a table item (row) when no changes have occurred (detect through diffing)
|
14
|
+
- Update `font` keyword and `FontProxy` to support lightweight creation/caching/sharing following Flyweight Design Pattern
|
15
|
+
|
16
|
+
## 4.24.2.3
|
17
|
+
|
18
|
+
- Default `code_text` font name in Mac is changed back to `'Courier'`
|
19
|
+
|
3
20
|
## 4.24.2.2
|
4
21
|
|
5
22
|
- Upgrade to jruby-9.3.7.0
|
data/README.md
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
# [<img src="https://raw.githubusercontent.com/AndyObtiva/glimmer/master/images/glimmer-logo-hi-res.png" height=85 />](https://github.com/AndyObtiva/glimmer) Glimmer DSL for SWT 4.24.
|
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.24.3.1
|
2
2
|
## JRuby Desktop Development GUI Framework
|
3
3
|
[![Gem Version](https://badge.fury.io/rb/glimmer-dsl-swt.svg)](http://badge.fury.io/rb/glimmer-dsl-swt)
|
4
4
|
[![Travis CI](https://travis-ci.com/AndyObtiva/glimmer-dsl-swt.svg?branch=master)](https://travis-ci.com/github/AndyObtiva/glimmer-dsl-swt)
|
@@ -12,7 +12,7 @@
|
|
12
12
|
|
13
13
|
![Glimmer DSL for SWT Demo of Hello, World!](/images/glimmer-dsl-swt-demo-hello-world.gif)
|
14
14
|
|
15
|
-
[Glimmer](https://github.com/AndyObtiva/glimmer) DSL for [SWT](https://www.eclipse.org/swt/) is a native GUI (Graphical User Interface) cross-platform desktop development library written in [JRuby](https://www.jruby.org/), an OS-threaded faster [JVM](https://www.java.com/en/download/help/whatis_java.html) version of [Ruby](https://www.ruby-lang.org/en/). [Glimmer](https://github.com/AndyObtiva/glimmer)'s main innovation is a declarative [Ruby DSL](docs/reference/GLIMMER_GUI_DSL_SYNTAX.md#glimmer-dsl-syntax) (Domain Specific Language) that enables productive and efficient authoring of desktop application user-interfaces by relying on the robust [Eclipse SWT library](https://www.eclipse.org/swt/). [Glimmer](https://rubygems.org/gems/glimmer) additionally innovates by having built-in [data-binding](docs/reference/GLIMMER_GUI_DSL_SYNTAX.md#data-binding) support, which greatly facilitates synchronizing the GUI with domain models, thus achieving true decoupling of object oriented components and enabling developers to solve business problems (test-first) without worrying about GUI concerns, or alternatively drive development GUI-first, and then write clean business models afterwards. Not only does Glimmer provide a large set of GUI [widgets](docs/reference/GLIMMER_GUI_DSL_SYNTAX.md#widgets), but it also supports drawing Canvas Graphics like [Shapes](docs/reference/GLIMMER_GUI_DSL_SYNTAX.md#canvas-shape-dsl) and [Animations](docs/reference/GLIMMER_GUI_DSL_SYNTAX.md#canvas-animation-dsl). To get started quickly, [Glimmer](https://rubygems.org/gems/glimmer) offers [scaffolding](docs/reference/GLIMMER_COMMAND.md#scaffolding) options for [Apps](#in-production), [Gems](docs/reference/GLIMMER_COMMAND.md#custom-shell-gem), and [Custom Widgets](docs/reference/GLIMMER_GUI_DSL_SYNTAX.md#custom-widgets). [Glimmer](https://rubygems.org/gems/glimmer) also includes native-executable [packaging](docs/reference/GLIMMER_PACKAGING_AND_DISTRIBUTION.md) support, sorely lacking in other libraries, thus enabling the delivery of desktop apps written in [Ruby](https://www.ruby-lang.org/en/) as truly native DMG/PKG/APP files on the [Mac](https://www.apple.com/ca/macos), MSI/EXE files on [Windows](https://www.microsoft.com/en-ca/windows), and DEB/RPM files on [Linux](https://www.linux.org/). [Glimmer](https://github.com/AndyObtiva/glimmer) was the [first Ruby gem](https://rubygems.org/gems/glimmer) to bring [SWT](https://www.eclipse.org/swt/) (Standard Widget Toolkit) to [Ruby](https://www.ruby-lang.org/en/), thanks to creator [Andy Maleh](https://andymaleh.blogspot.com/), EclipseCon/EclipseWorld/RubyConf speaker.
|
15
|
+
[Glimmer](https://github.com/AndyObtiva/glimmer) DSL for [SWT](https://www.eclipse.org/swt/) (formerly [Glimmer](https://github.com/AndyObtiva/glimmer)) is a native GUI (Graphical User Interface) cross-platform desktop development library written in [JRuby](https://www.jruby.org/), an OS-threaded faster [JVM](https://www.java.com/en/download/help/whatis_java.html) version of [Ruby](https://www.ruby-lang.org/en/). [Glimmer](https://github.com/AndyObtiva/glimmer)'s main innovation is a declarative [Ruby DSL](docs/reference/GLIMMER_GUI_DSL_SYNTAX.md#glimmer-dsl-syntax) (Domain Specific Language) that enables productive and efficient authoring of desktop application user-interfaces by relying on the robust [Eclipse SWT library](https://www.eclipse.org/swt/). [Glimmer](https://rubygems.org/gems/glimmer) additionally innovates by having built-in [data-binding](docs/reference/GLIMMER_GUI_DSL_SYNTAX.md#data-binding) support, which greatly facilitates synchronizing the GUI with domain models, thus achieving true decoupling of object oriented components and enabling developers to solve business problems (test-first) without worrying about GUI concerns, or alternatively drive development GUI-first, and then write clean business models afterwards. Not only does Glimmer provide a large set of GUI [widgets](docs/reference/GLIMMER_GUI_DSL_SYNTAX.md#widgets), but it also supports drawing Canvas Graphics like [Shapes](docs/reference/GLIMMER_GUI_DSL_SYNTAX.md#canvas-shape-dsl) and [Animations](docs/reference/GLIMMER_GUI_DSL_SYNTAX.md#canvas-animation-dsl). To get started quickly, [Glimmer](https://rubygems.org/gems/glimmer) offers [scaffolding](docs/reference/GLIMMER_COMMAND.md#scaffolding) options for [Apps](#in-production), [Gems](docs/reference/GLIMMER_COMMAND.md#custom-shell-gem), and [Custom Widgets](docs/reference/GLIMMER_GUI_DSL_SYNTAX.md#custom-widgets). [Glimmer](https://rubygems.org/gems/glimmer) also includes native-executable [packaging](docs/reference/GLIMMER_PACKAGING_AND_DISTRIBUTION.md) support, sorely lacking in other libraries, thus enabling the delivery of desktop apps written in [Ruby](https://www.ruby-lang.org/en/) as truly native DMG/PKG/APP files on the [Mac](https://www.apple.com/ca/macos), MSI/EXE files on [Windows](https://www.microsoft.com/en-ca/windows), and DEB/RPM files on [Linux](https://www.linux.org/). [Glimmer](https://github.com/AndyObtiva/glimmer) was the [first Ruby gem](https://rubygems.org/gems/glimmer) to bring [SWT](https://www.eclipse.org/swt/) (Standard Widget Toolkit) to [Ruby](https://www.ruby-lang.org/en/), thanks to creator [Andy Maleh](https://andymaleh.blogspot.com/), EclipseCon/EclipseWorld/RubyConf speaker.
|
16
16
|
|
17
17
|
[<img src="https://covers.oreillystatic.com/images/9780596519650/lrg.jpg" width=105 /><br />
|
18
18
|
Featured in JRuby Cookbook](http://shop.oreilly.com/product/9780596519650.do) and [Chalmers/Gothenburg University Software Engineering Master's Lecture Material](http://www.cse.chalmers.se/~bergert/slides/guest_lecture_DSLs.pdf)
|
@@ -21,7 +21,7 @@ Featured in JRuby Cookbook](http://shop.oreilly.com/product/9780596519650.do) an
|
|
21
21
|
|
22
22
|
![Eclipse SWT RCP NASA Mars Rover](/images/glimmer-eclipse-swt-rcp-nasa-mars-rover.png)
|
23
23
|
|
24
|
-
[Glimmer DSL for SWT](https://rubygems.org/gems/glimmer-dsl-swt) 4.24.
|
24
|
+
[Glimmer DSL for SWT](https://rubygems.org/gems/glimmer-dsl-swt) 4.24.3.1 includes [SWT 4.24](https://download.eclipse.org/eclipse/downloads/drops4/R-4.24-202206070700/), which was released on June 7, 2022. 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.
|
25
25
|
|
26
26
|
**Starting in version 4.20.0.0, [Glimmer DSL for SWT](https://rubygems.org/gems/glimmer-dsl-swt) comes with the new [***Shine***](/docs/reference/GLIMMER_GUI_DSL_SYNTAX.md#shine) syntax** for highly intuitive and visually expressive View/Model Attribute Mapping, relying on `<=>` for bidirectional (two-way) data-binding and `<=` for unidirectional (one-way) data-binding, providing an alternative to the `bind` keyword. That was [originally conceived back in 2007](https://andymaleh.blogspot.com/2007/12/data-shining-in-glimmer.html).
|
27
27
|
|
@@ -338,7 +338,7 @@ jgem install glimmer-dsl-swt
|
|
338
338
|
|
339
339
|
Or this command if you want a specific version:
|
340
340
|
```
|
341
|
-
jgem install glimmer-dsl-swt -v 4.24.
|
341
|
+
jgem install glimmer-dsl-swt -v 4.24.3.1
|
342
342
|
```
|
343
343
|
|
344
344
|
`jgem` is JRuby's version of `gem` command.
|
@@ -366,7 +366,7 @@ Note: if you're using activerecord or activesupport, keep in mind that Glimmer u
|
|
366
366
|
|
367
367
|
Add the following to `Gemfile`:
|
368
368
|
```
|
369
|
-
gem 'glimmer-dsl-swt', '~> 4.24.
|
369
|
+
gem 'glimmer-dsl-swt', '~> 4.24.3.1'
|
370
370
|
```
|
371
371
|
|
372
372
|
And, then run:
|
@@ -389,7 +389,7 @@ glimmer
|
|
389
389
|
```
|
390
390
|
|
391
391
|
```
|
392
|
-
Glimmer (JRuby Desktop Development GUI Framework) - JRuby Gem: glimmer-dsl-swt v4.24.
|
392
|
+
Glimmer (JRuby Desktop Development GUI Framework) - JRuby Gem: glimmer-dsl-swt v4.24.3.1
|
393
393
|
|
394
394
|
Usage: glimmer [--bundler] [--pd] [--quiet] [--debug] [--log-level=VALUE] [[ENV_VAR=VALUE]...] [[-jruby-option]...] (application.rb or task[task_args]) [[application2.rb]...]
|
395
395
|
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
4.24.
|
1
|
+
4.24.3.1
|
@@ -3998,9 +3998,9 @@ The SWT Tree widget renders a multi-column data table, such as a contact listing
|
|
3998
3998
|
|
3999
3999
|
To data-bind a Table, you need the main model, the collection property, and the text display attribute for each table column.
|
4000
4000
|
|
4001
|
-
This involves using the
|
4001
|
+
This involves using the `<=>` operator in addition to a special `column_properties` kwarg that takes an array that maps table columns to model attributes.
|
4002
4002
|
|
4003
|
-
It assumes you have defined
|
4003
|
+
It assumes you have already defined table columns via the `table_column` `table`-nested widget.
|
4004
4004
|
|
4005
4005
|
Example:
|
4006
4006
|
|
@@ -4019,8 +4019,8 @@ shell {
|
|
4019
4019
|
text "Adult"
|
4020
4020
|
width 120
|
4021
4021
|
}
|
4022
|
-
items
|
4023
|
-
selection
|
4022
|
+
items <=> [group, :people, column_properties: [:name, :age, :adult]]
|
4023
|
+
selection <=> [group, :selected_person]
|
4024
4024
|
on_mouse_up do |event|
|
4025
4025
|
@table.edit_table_item(event.table_item, event.column_index)
|
4026
4026
|
end
|
@@ -4029,11 +4029,11 @@ shell {
|
|
4029
4029
|
```
|
4030
4030
|
|
4031
4031
|
The code above includes two data-bindings:
|
4032
|
-
- Table `items`, which first
|
4033
|
-
- Table `selection`, which binds the single table item selected by the user to the attribute denoted by
|
4032
|
+
- Table `items`, which first data-binds to the model collection property (group.people), and then maps each column property (name, age, adult) for displaying each table item column.
|
4033
|
+
- Table `selection`, which data-binds the single table item (row) selected by the user to the model attribute denoted by `<=>` (or data-binds multiple table items to a model attribute array value for a table with `:multi` SWT style)
|
4034
4034
|
- The `on_mouse_up` event handler invokes `@table.edit_table_item(event.table_item, event.column_index)` to start edit mode on the clicked table item cell, and then saves or cancel depending on whether the user hits ENTER or ESC once done editing (or focus-out after either making a change or not making any changes.)
|
4035
4035
|
|
4036
|
-
Additionally, Table `items` data-binding automatically stores each
|
4036
|
+
Additionally, Table `items` data-binding automatically stores each row model in the [SWT `TableItem`](https://help.eclipse.org/latest/topic/org.eclipse.platform.doc.isv/reference/api/org/eclipse/swt/widgets/TableItem.html) object representing it, by using the `set_data` method. This enables things like searchability.
|
4037
4037
|
|
4038
4038
|
The table widget in Glimmer is represented by a subclass of `WidgetProxy` called `TableProxy`.
|
4039
4039
|
TableProxy includes a `search` method that takes a block to look for a table item.
|
@@ -4044,13 +4044,31 @@ Example:
|
|
4044
4044
|
found_array = @table.search { |table_item| table_item.getData == company.owner }
|
4045
4045
|
```
|
4046
4046
|
|
4047
|
-
This finds a person. The array is a Java array. This enables easy passing of it to SWT `Table#setSelection` method, which expects a Java array of `TableItem` objects.
|
4047
|
+
This finds a person. The array is a Java array. This enables easy passing of it to SWT `Table#setSelection` method, which expects a Java array of [`TableItem`](https://help.eclipse.org/latest/topic/org.eclipse.platform.doc.isv/reference/api/org/eclipse/swt/widgets/TableItem.html) objects.
|
4048
4048
|
|
4049
4049
|
To edit a table, you must invoke `TableProxy#edit_selected_table_item(column_index, before_write: nil, after_write: nil, after_cancel: nil)` or `TableProxy#edit_table_item(table_item, column_index, before_write: nil, after_write: nil, after_cancel: nil)`.
|
4050
4050
|
This automatically leverages the SWT TableEditor custom class behind the scenes, displaying a text widget to the user to change the selected or
|
4051
4051
|
passed table item text into something else.
|
4052
4052
|
It automatically persists the change to `items` data-bound model on ENTER/FOCUS-OUT or cancels on ESC/NO-CHANGE.
|
4053
4053
|
|
4054
|
+
##### Table Item Properties
|
4055
|
+
|
4056
|
+
When data-binding a `table`'s `items`, extra [`TableItem` properties](https://help.eclipse.org/latest/topic/org.eclipse.platform.doc.isv/reference/api/org/eclipse/swt/widgets/TableItem.html) are data-bound automatically by convention for `background` color, `foreground` color, `font`, and `image` if corresponding properties (attributes) are available on the model.
|
4057
|
+
|
4058
|
+
That means that if `column_properties` were `[:name, :age, :adult]`, then the following [`TableItem` properties](https://help.eclipse.org/latest/topic/org.eclipse.platform.doc.isv/reference/api/org/eclipse/swt/widgets/TableItem.html) are also data-bound by convention:
|
4059
|
+
- `background` to `:name_background, :age_background, :adult_background` model attributes
|
4060
|
+
- `foreground` to `:name_foreground, :age_foreground, :adult_foreground` model attributes
|
4061
|
+
- `font` to `:name_font, :age_font, :adult_font` model attributes
|
4062
|
+
- `image` to `:name_image, :age_image, :adult_image` model attributes
|
4063
|
+
|
4064
|
+
Here are the expected values for each [`TableItem` property](https://help.eclipse.org/latest/topic/org.eclipse.platform.doc.isv/reference/api/org/eclipse/swt/widgets/TableItem.html):
|
4065
|
+
- `background`: Standard color symbol/string (e.g. `:red`), rgb array (e.g. `[24, 21, 239]`), or rgba array (e.g. `[128, 0, 128, 50]`)
|
4066
|
+
- `foreground`: Standard color symbol/string (e.g. `:red`), rgb array (e.g. `[24, 21, 239]`), or rgba array (e.g. `[128, 0, 128, 50]`)
|
4067
|
+
- `font`: font data hash having `:name`, `:height`, and/or `:style` keys (e.g. `{name: 'Courier New', height: 25, style: [:bold, :italic]}`)
|
4068
|
+
- `image`: image URL with or without image options (e.g. `'/usr/image1.png'` or `['/usr/image1.png', width: 20, height: 20]`)
|
4069
|
+
|
4070
|
+
![Hello Table game booked rows](/images/glimmer-hello-table-game-booked-rows.png)
|
4071
|
+
|
4054
4072
|
##### Table Selection
|
4055
4073
|
|
4056
4074
|
Table Selection data-binding is simply done via the `selection` property.
|
@@ -4807,32 +4825,93 @@ You may see another example at the [Hello, Radio Group!](/docs/reference/GLIMMER
|
|
4807
4825
|
|
4808
4826
|
##### Code Text Custom Widget
|
4809
4827
|
|
4810
|
-
`code_text` is a Glimmer built-in custom widget that displays syntax highlighted Ruby code
|
4828
|
+
`code_text` is a Glimmer built-in custom widget that displays syntax highlighted code (e.g. Ruby/JavaScript/HTML code) for 204 languages (see [options](#code-text-options) for the full list) by automating customizations for the SWT [StyledText](https://help.eclipse.org/2020-09/topic/org.eclipse.platform.doc.isv/reference/api/org/eclipse/swt/custom/StyledText.html) widget, including ability to zoom font in and out, or restore original font height (more details below).
|
4829
|
+
|
4830
|
+
To utilize, simply use `code_text` in place of the multi-line `text` and `styled_text` widgets. If you set the `code_text` `text` property value to multi-line code content (e.g. Ruby/JavaScript/HTML code), it automatically styles it with syntax highlighting.
|
4811
4831
|
|
4812
|
-
|
4813
|
-
1. Consolas
|
4814
|
-
2. Courier
|
4815
|
-
3.
|
4816
|
-
4.
|
4832
|
+
`code_text` attempts to use a monospace font if available, seeking font names in the following order (specified in `Glimmer::SWT::Custom::CodeText::FONT_NAMES_PREFERRED`):
|
4833
|
+
1. `'Consolas'`
|
4834
|
+
2. `'Courier'`
|
4835
|
+
3. `'Monospace'`
|
4836
|
+
4. `'Liberation Mono'`
|
4837
|
+
5. First available font that contains the word `mono` (case-insensitive)
|
4838
|
+
6. Default system font (if no other font in the list is found)
|
4817
4839
|
|
4818
4840
|
It is used in the [Glimmer Meta-Sample (The Sample of Samples)](#samples):
|
4819
4841
|
|
4820
4842
|
![Glimmer Meta-Sample](/images/glimmer-meta-sample.png)
|
4821
4843
|
|
4822
|
-
|
4844
|
+
Dark Mode:
|
4845
|
+
|
4846
|
+
![Glimmer Meta-Sample](/images/glimmer-meta-sample-dark-mode.png)
|
4847
|
+
|
4848
|
+
Code Text Simple Example (default language is Ruby):
|
4823
4849
|
|
4824
4850
|
```ruby
|
4825
|
-
|
4826
|
-
@code_text = code_text {
|
4851
|
+
code_text {
|
4827
4852
|
text bind(SampleDirectory, 'selected_sample.code', read_only: true)
|
4828
4853
|
editable bind(SampleDirectory, 'selected_sample.editable')
|
4829
4854
|
}
|
4830
|
-
# ...
|
4831
4855
|
```
|
4832
4856
|
|
4833
|
-
|
4857
|
+
Code Text Specified Language Example:
|
4858
|
+
|
4859
|
+
```ruby
|
4860
|
+
code_text(language: 'html') {
|
4861
|
+
text bind(SampleDirectory, 'selected_sample.code', read_only: true)
|
4862
|
+
editable bind(SampleDirectory, 'selected_sample.editable')
|
4863
|
+
}
|
4864
|
+
```
|
4865
|
+
|
4866
|
+
Code Text Lines and Margins Example:
|
4867
|
+
|
4868
|
+
```ruby
|
4869
|
+
code_text(lines: true) {
|
4870
|
+
text <=> [SampleDirectory, 'selected_sample.code']
|
4871
|
+
editable <= [SampleDirectory, 'selected_sample.editable']
|
4872
|
+
left_margin 7
|
4873
|
+
right_margin 7
|
4874
|
+
}
|
4875
|
+
```
|
4876
|
+
|
4877
|
+
Code Text Customized Lines Width and Background Example:
|
4878
|
+
|
4879
|
+
```ruby
|
4880
|
+
code_text(lines: {width: 3}) {
|
4881
|
+
line_numbers {
|
4882
|
+
background Display.system_dark_theme? ? :black : :white
|
4883
|
+
}
|
4884
|
+
text <=> [SampleDirectory, 'selected_sample.code']
|
4885
|
+
editable <= [SampleDirectory, 'selected_sample.editable']
|
4886
|
+
left_margin 7
|
4887
|
+
right_margin 7
|
4888
|
+
}
|
4889
|
+
```
|
4890
|
+
|
4891
|
+
Code Text Customized Root Composite Margins/Spacing Background Example:
|
4892
|
+
|
4893
|
+
```ruby
|
4894
|
+
code_text(lines: true) {
|
4895
|
+
root {
|
4896
|
+
grid_layout(2, false) {
|
4897
|
+
horizontal_spacing 0
|
4898
|
+
margin_left 0
|
4899
|
+
margin_right 0
|
4900
|
+
margin_top 0
|
4901
|
+
margin_bottom 0
|
4902
|
+
}
|
4903
|
+
}
|
4904
|
+
line_numbers {
|
4905
|
+
background Display.system_dark_theme? ? :black : :white
|
4906
|
+
}
|
4907
|
+
text <=> [SampleDirectory, 'selected_sample.code']
|
4908
|
+
editable <= [SampleDirectory, 'selected_sample.editable']
|
4909
|
+
left_margin 7
|
4910
|
+
right_margin 7
|
4911
|
+
}
|
4912
|
+
```
|
4834
4913
|
|
4835
|
-
###### Options
|
4914
|
+
###### Code Text Options
|
4836
4915
|
|
4837
4916
|
**lines**
|
4838
4917
|
(default: `false`)
|
@@ -5072,6 +5151,9 @@ This adds some default keyboard shortcuts:
|
|
5072
5151
|
- CMD+A (CTRL+A on Windows/Linux) to select all
|
5073
5152
|
- CTRL+A on Mac to jump to beginning of line
|
5074
5153
|
- CTRL+E on Mac to jump to end of line
|
5154
|
+
- CMD+= (CTRL+= on Windows/Linux) to zoom in (bump font height up by 1)
|
5155
|
+
- CMD+- (CTRL+- on Windows/Linux) to zoom out (bump font height down by 1)
|
5156
|
+
- CMD+0 (CTRL+0 on Windows/Linux) to restore to original font height
|
5075
5157
|
- Attempts to add proper indentation upon adding a new line when hitting ENTER (currently supporting Ruby only)
|
5076
5158
|
|
5077
5159
|
If you prefer it to be vanilla with no default key event listeners, then pass the `default_behavior: false` option.
|
@@ -730,7 +730,7 @@ Hello, Spinner!
|
|
730
730
|
|
731
731
|
#### Hello, Table!
|
732
732
|
|
733
|
-
This sample demonstrates the use of [table](#table) widget in Glimmer, including data-binding, multi-type editing, sorting, and filtering.
|
733
|
+
This sample demonstrates the use of [table](/docs/reference/GLIMMER_GUI_DSL_SYNTAX.md#table) widget in Glimmer, including data-binding, multi-type editing, sorting, and filtering.
|
734
734
|
|
735
735
|
Code:
|
736
736
|
|
@@ -768,13 +768,17 @@ Hello, Table! Playoff Type Changed
|
|
768
768
|
|
769
769
|
![Hello Table](/images/glimmer-hello-table-playoff-type-changed.png)
|
770
770
|
|
771
|
+
Hello, Table! Context Menu
|
772
|
+
|
773
|
+
![Hello Table](/images/glimmer-hello-table-context-menu.png)
|
774
|
+
|
771
775
|
Hello, Table! Game Booked
|
772
776
|
|
773
777
|
![Hello Table](/images/glimmer-hello-table-game-booked.png)
|
774
778
|
|
775
|
-
Hello, Table!
|
779
|
+
Hello, Table! Game Booked Rows
|
776
780
|
|
777
|
-
![Hello Table](/images/glimmer-hello-table-
|
781
|
+
![Hello Table game booked rows](/images/glimmer-hello-table-game-booked-rows.png)
|
778
782
|
|
779
783
|
#### Hello, Link!
|
780
784
|
|
@@ -810,23 +814,35 @@ Hello, Dialog! Open Dialog
|
|
810
814
|
|
811
815
|
#### Hello, Code Text!
|
812
816
|
|
813
|
-
This sample demonstrates the Glimmer Built-In [Code Text Custom Widget](#code-text-custom-widget).
|
817
|
+
This sample demonstrates the Glimmer Built-In [Code Text Custom Widget](/docs/reference/GLIMMER_GUI_DSL_SYNTAX.md#code-text-custom-widget).
|
814
818
|
|
815
819
|
Code:
|
816
820
|
|
817
821
|
[samples/hello/hello_code_text.rb](/samples/hello/hello_code_text.rb)
|
818
822
|
|
819
|
-
Hello, Code Text!
|
823
|
+
Hello, Code Text! HTML Language / GitHub Theme / No Line Numbers
|
820
824
|
|
821
|
-
![Hello Code Text
|
825
|
+
![Hello Code Text HTML](/images/glimmer-hello-code-text-html.png)
|
822
826
|
|
823
827
|
Hello, Code Text! JavaScript Language / Pastie Theme / Show Line Numbers (custom width of 2)
|
824
828
|
|
825
829
|
![Hello Code Text JavaScript](/images/glimmer-hello-code-text-javascript.png)
|
826
830
|
|
827
|
-
Hello, Code Text!
|
831
|
+
Hello, Code Text! Ruby Language / Glimmer Theme / Show Line Numbers (default width of 4)
|
828
832
|
|
829
|
-
![Hello Code Text
|
833
|
+
![Hello Code Text Ruby](/images/glimmer-hello-code-text-ruby.png)
|
834
|
+
|
835
|
+
Hello, Code Text! Zoom In (via keyboard shortcut CMD+= on Mac, CTRL+= on Win/Linux)
|
836
|
+
|
837
|
+
![Hello Code Text Zoom In](/images/glimmer-hello-code-text-zoom-in.png)
|
838
|
+
|
839
|
+
Hello, Code Text! Zoom Out (via keyboard shortcut CMD+- on Mac, CTRL+- on Win/Linux)
|
840
|
+
|
841
|
+
![Hello Code Text Zoom Out](/images/glimmer-hello-code-text-zoom-out.png)
|
842
|
+
|
843
|
+
Hello, Code Text! Restore Original Font Height (via keyboard shortcut CMD+0 on Mac, CTRL+0 on Win/Linux)
|
844
|
+
|
845
|
+
![Hello Code Text Restore Original Font Height](/images/glimmer-hello-code-text-ruby.png)
|
830
846
|
|
831
847
|
#### Hello, Canvas!
|
832
848
|
|
data/glimmer-dsl-swt.gemspec
CHANGED
Binary file
|
@@ -19,6 +19,8 @@
|
|
19
19
|
# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
20
|
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
21
21
|
|
22
|
+
require 'set'
|
23
|
+
|
22
24
|
require 'glimmer/data_binding/observable_array'
|
23
25
|
require 'glimmer/data_binding/observable_model'
|
24
26
|
require 'glimmer/data_binding/observable'
|
@@ -33,6 +35,8 @@ module Glimmer
|
|
33
35
|
include DataBinding::Observer
|
34
36
|
include_package 'org.eclipse.swt'
|
35
37
|
include_package 'org.eclipse.swt.widgets'
|
38
|
+
|
39
|
+
TABLE_ITEM_PROPERTIES = %w[background foreground font image]
|
36
40
|
|
37
41
|
def initialize(parent, model_binding, column_properties = nil)
|
38
42
|
@table = parent
|
@@ -56,40 +60,161 @@ module Glimmer
|
|
56
60
|
end
|
57
61
|
end
|
58
62
|
|
59
|
-
def call(
|
63
|
+
def call(*args)
|
64
|
+
options = args.last.is_a?(Hash) ? args.pop : {}
|
65
|
+
internal_sort = options[:internal_sort] || false
|
66
|
+
new_model_collection = args.first
|
60
67
|
Glimmer::SWT::DisplayProxy.instance.auto_exec(override_sync_exec: @model_binding.binding_options[:sync_exec], override_async_exec: @model_binding.binding_options[:async_exec]) do
|
61
68
|
new_model_collection = model_binding_evaluated_property = @model_binding.evaluate_property unless internal_sort # this ensures applying converters (e.g. :on_read)
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
69
|
+
return if same_table_data?(new_model_collection)
|
70
|
+
if same_model_collection?(new_model_collection)
|
71
|
+
new_model_collection_attribute_values = model_collection_attribute_values(new_model_collection)
|
72
|
+
@table.swt_widget.items.each_with_index do |table_item, row_index|
|
73
|
+
next if new_model_collection_attribute_values[row_index] == @last_model_collection_attribute_values[row_index]
|
74
|
+
model = table_item.get_data
|
75
|
+
(0..(@column_properties.size-1)).each do |column_index|
|
76
|
+
new_model_attribute_values_for_index = model_attribute_values_for_index(new_model_collection_attribute_values[row_index], column_index)
|
77
|
+
last_model_attribute_values_for_index = model_attribute_values_for_index(@last_model_collection_attribute_values[row_index], column_index)
|
78
|
+
next if new_model_attribute_values_for_index == last_model_attribute_values_for_index
|
79
|
+
model_attribute = @column_properties[column_index]
|
80
|
+
update_table_item_properties_from_model(table_item, row_index, column_index, model, model_attribute)
|
81
|
+
end
|
82
|
+
end
|
83
|
+
@last_model_collection_attribute_values = new_model_collection_attribute_values
|
84
|
+
else
|
85
|
+
if new_model_collection and new_model_collection.is_a?(Array)
|
86
|
+
remove_dependent(@table_observer_registration => @table_items_observer_registration) if @table_items_observer_registration
|
87
|
+
@table_items_observer_registration&.unobserve
|
88
|
+
# TODO observe and update table items piecemeal per model instead of passing @column_properties
|
89
|
+
# TODO ensure unobserving models when they are no longer part of the table
|
90
|
+
@table_items_observer_registration = observe(new_model_collection, @column_properties)
|
91
|
+
add_dependent(@table_observer_registration => @table_items_observer_registration)
|
92
|
+
@table_items_property_observer_registration ||= {}
|
93
|
+
if !same_model_collection_with_different_sort?(new_model_collection)
|
94
|
+
TABLE_ITEM_PROPERTIES.each do |table_item_property|
|
95
|
+
remove_dependent(@table_observer_registration => @table_items_property_observer_registration[table_item_property]) if @table_items_property_observer_registration[table_item_property]
|
96
|
+
@table_items_property_observer_registration[table_item_property]&.unobserve
|
97
|
+
property_properties = @column_properties.map {|property| "#{property}_#{table_item_property}" }
|
98
|
+
@table_items_property_observer_registration[table_item_property] = observe(new_model_collection, property_properties)
|
99
|
+
add_dependent(@table_observer_registration => @table_items_property_observer_registration[table_item_property])
|
100
|
+
end
|
101
|
+
end
|
102
|
+
@model_collection = new_model_collection
|
103
|
+
end
|
104
|
+
populate_table(@model_collection, @table, @column_properties, internal_sort: internal_sort)
|
70
105
|
end
|
71
|
-
populate_table(@model_collection, @table, @column_properties, internal_sort: internal_sort)
|
72
106
|
end
|
73
107
|
end
|
74
108
|
|
75
109
|
def populate_table(model_collection, parent, column_properties, internal_sort: false)
|
76
110
|
selected_table_item_models = parent.swt_widget.getSelection.map(&:get_data)
|
77
111
|
parent.finish_edit!
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
112
|
+
dispose_start_index = @last_model_collection_attribute_values &&
|
113
|
+
(model_collection.count < @last_model_collection_attribute_values.count) &&
|
114
|
+
(@last_model_collection_attribute_values.count - (@last_model_collection_attribute_values.count - model_collection.count))
|
115
|
+
if dispose_start_index
|
116
|
+
table_items_to_dispose = parent.swt_widget.items[dispose_start_index..-1]
|
117
|
+
parent.swt_widget.remove(dispose_start_index, (@last_model_collection_attribute_values.count-1))
|
118
|
+
table_items_to_dispose.each(&:dispose)
|
119
|
+
end
|
120
|
+
model_collection.each_with_index do |model, row_index|
|
121
|
+
table_item_exists = @last_model_collection_attribute_values &&
|
122
|
+
@last_model_collection_attribute_values.count > 0 &&
|
123
|
+
row_index < @last_model_collection_attribute_values.count
|
124
|
+
table_item = table_item_exists ? parent.swt_widget.items[row_index] : TableItem.new(parent.swt_widget, SWT::SWTProxy[:none])
|
125
|
+
(0..(column_properties.size-1)).each do |column_index|
|
126
|
+
model_attribute = column_properties[column_index]
|
127
|
+
update_table_item_properties_from_model(table_item, row_index, column_index, model, model_attribute)
|
84
128
|
end
|
85
129
|
table_item.set_data(model)
|
86
130
|
end
|
131
|
+
@last_model_collection_attribute_values = model_collection_attribute_values(model_collection)
|
87
132
|
selected_table_items = parent.search {|item| selected_table_item_models.include?(item.get_data) }
|
88
133
|
parent.swt_widget.setSelection(selected_table_items)
|
89
134
|
sorted_model_collection = parent.sort!(internal_sort: internal_sort)
|
90
135
|
call(sorted_model_collection, internal_sort: true) if @read_only_sort && !internal_sort && !sorted_model_collection.nil?
|
91
136
|
parent.swt_widget.redraw if parent&.swt_widget&.respond_to?(:redraw)
|
92
137
|
end
|
138
|
+
|
139
|
+
def update_table_item_properties_from_model(table_item, row_index, column_index, model, model_attribute)
|
140
|
+
Glimmer::SWT::DisplayProxy.instance.sync_exec do
|
141
|
+
old_table_item_values = @last_model_collection_attribute_values &&
|
142
|
+
@last_model_collection_attribute_values[row_index] &&
|
143
|
+
model_attribute_values_for_index(@last_model_collection_attribute_values[row_index], column_index)
|
144
|
+
text_value = model.send(model_attribute).to_s
|
145
|
+
old_table_item_value = old_table_item_values && old_table_item_values[0]
|
146
|
+
table_item.set_text(column_index, text_value) if old_table_item_value.nil? || text_value != old_table_item_value
|
147
|
+
TABLE_ITEM_PROPERTIES.each do |table_item_property|
|
148
|
+
if model.respond_to?("#{model_attribute}_#{table_item_property}")
|
149
|
+
table_item_value = model.send("#{model_attribute}_#{table_item_property}")
|
150
|
+
old_table_item_value = old_table_item_values && old_table_item_values[1 + TABLE_ITEM_PROPERTIES.index(table_item_property)]
|
151
|
+
if old_table_item_value.nil? || (table_item_value != old_table_item_value)
|
152
|
+
table_item_value = Glimmer::SWT::ColorProxy.create(*table_item_value).swt_color if table_item_value && %w[background foreground].include?(table_item_property.to_s)
|
153
|
+
table_item_value = Glimmer::SWT::FontProxy.create(table_item_value).swt_font if table_item_value && table_item_property.to_s == 'font'
|
154
|
+
table_item_value = Glimmer::SWT::ImageProxy.create(*table_item_value).swt_image if table_item_value && table_item_property.to_s == 'image'
|
155
|
+
table_item.send("set_#{table_item_property}", column_index, table_item_value)
|
156
|
+
end
|
157
|
+
end
|
158
|
+
end
|
159
|
+
end
|
160
|
+
end
|
161
|
+
|
162
|
+
def same_table_data?(new_model_collection)
|
163
|
+
(["text"] + TABLE_ITEM_PROPERTIES).all? do |table_item_property|
|
164
|
+
table_cells = @table.swt_widget.items.map do |item|
|
165
|
+
model = item.get_data
|
166
|
+
@table.column_properties.each_with_index.map do |column_property, i|
|
167
|
+
model_attribute = "#{column_property}"
|
168
|
+
model_attribute = "#{model_attribute}_#{table_item_property}" if TABLE_ITEM_PROPERTIES.include?(table_item_property)
|
169
|
+
item.send("get_#{table_item_property}", i) if model.respond_to?(model_attribute)
|
170
|
+
end
|
171
|
+
end
|
172
|
+
model_cells = new_model_collection.to_a.map do |m|
|
173
|
+
@table.cells_for(m, table_item_property: table_item_property)
|
174
|
+
end
|
175
|
+
model_cells = model_cells.map do |row|
|
176
|
+
row.map do |model_cell|
|
177
|
+
if model_cell
|
178
|
+
if %w[background foreground].include?(table_item_property.to_s)
|
179
|
+
Glimmer::SWT::ColorProxy.create(*model_cell).swt_color
|
180
|
+
elsif table_item_property.to_s == 'font'
|
181
|
+
Glimmer::SWT::FontProxy.create(model_cell).swt_font
|
182
|
+
elsif table_item_property.to_s == 'image'
|
183
|
+
Glimmer::SWT::ImageProxy.create(*model_cell).swt_image
|
184
|
+
else
|
185
|
+
model_cell
|
186
|
+
end
|
187
|
+
end
|
188
|
+
end
|
189
|
+
end
|
190
|
+
table_cells == model_cells
|
191
|
+
end
|
192
|
+
end
|
193
|
+
|
194
|
+
def same_model_collection?(new_model_collection)
|
195
|
+
new_model_collection == table_item_model_collection
|
196
|
+
end
|
197
|
+
|
198
|
+
def same_model_collection_with_different_sort?(new_model_collection)
|
199
|
+
Set.new(new_model_collection) == Set.new(table_item_model_collection)
|
200
|
+
end
|
201
|
+
|
202
|
+
def table_item_model_collection
|
203
|
+
@table.swt_widget.items.map(&:get_data)
|
204
|
+
end
|
205
|
+
|
206
|
+
def model_collection_attribute_values(model_collection)
|
207
|
+
model_collection.map do |model|
|
208
|
+
(["text"] + TABLE_ITEM_PROPERTIES).map do |table_item_property|
|
209
|
+
@table.cells_for(model, table_item_property: table_item_property)
|
210
|
+
end
|
211
|
+
end
|
212
|
+
end
|
213
|
+
|
214
|
+
def model_attribute_values_for_index(model_attribute_values, index)
|
215
|
+
model_attribute_values.map {|attribute_values| attribute_values[index]}
|
216
|
+
end
|
217
|
+
|
93
218
|
end
|
94
219
|
end
|
95
220
|
end
|
@@ -42,6 +42,7 @@ module Glimmer
|
|
42
42
|
|
43
43
|
REGEX_COLOR_HEX6 = /^#([0-9a-f]{2})([0-9a-f]{2})([0-9a-f]{2})$/
|
44
44
|
FONT_NAMES_PREFERRED = ['Consolas', 'Courier', 'Monospace', 'Liberation Mono']
|
45
|
+
SHORTCUT_KEY_COMMAND = OS.mac? ? :command : :ctrl
|
45
46
|
|
46
47
|
# TODO support auto language detection
|
47
48
|
|
@@ -145,7 +146,7 @@ module Glimmer
|
|
145
146
|
|
146
147
|
body {
|
147
148
|
if lines
|
148
|
-
composite {
|
149
|
+
@composite = composite {
|
149
150
|
grid_layout(2, false)
|
150
151
|
|
151
152
|
@line_numbers_styled_text_proxy = styled_text(swt(swt(swt_style), :h_scroll!, :v_scroll!)) {
|
@@ -204,12 +205,18 @@ module Glimmer
|
|
204
205
|
on_key_pressed { |event|
|
205
206
|
character = event.keyCode.chr rescue nil
|
206
207
|
case [event.stateMask, character]
|
207
|
-
when [
|
208
|
+
when [swt(SHORTCUT_KEY_COMMAND), 'a']
|
208
209
|
@styled_text_proxy.selectAll
|
209
210
|
when [(swt(:ctrl) if OS.mac?), 'a']
|
210
211
|
jump_to_beginning_of_line
|
211
212
|
when [(swt(:ctrl) if OS.mac?), 'e']
|
212
213
|
jump_to_end_of_line
|
214
|
+
when [swt(SHORTCUT_KEY_COMMAND), '=']
|
215
|
+
bump_font_height_up
|
216
|
+
when [swt(SHORTCUT_KEY_COMMAND), '-']
|
217
|
+
bump_font_height_down
|
218
|
+
when [swt(SHORTCUT_KEY_COMMAND), '0']
|
219
|
+
restore_font_height
|
213
220
|
end
|
214
221
|
}
|
215
222
|
on_verify_text { |verify_event|
|
@@ -326,12 +333,43 @@ module Glimmer
|
|
326
333
|
|
327
334
|
def select_best_font_name
|
328
335
|
all_font_names = display.get_font_list(nil, true).map(&:name)
|
336
|
+
@font_name = 'Courier' if OS.mac?
|
329
337
|
FONT_NAMES_PREFERRED.each do |font_name|
|
330
338
|
@font_name ||= font_name if all_font_names.include?(font_name)
|
331
339
|
end
|
332
340
|
@font_name ||= all_font_names.find {|font_name| font_name.downcase.include?('mono')}
|
333
341
|
@font_name
|
334
342
|
end
|
343
|
+
|
344
|
+
def bump_font_height_up
|
345
|
+
@original_font_height ||= font_datum.height
|
346
|
+
new_font_height = font_datum.height + 1
|
347
|
+
update_font_height(new_font_height)
|
348
|
+
end
|
349
|
+
|
350
|
+
def bump_font_height_down
|
351
|
+
@original_font_height ||= font_datum.height
|
352
|
+
new_font_height = font_datum.height - 1
|
353
|
+
update_font_height(new_font_height)
|
354
|
+
end
|
355
|
+
|
356
|
+
def restore_font_height
|
357
|
+
return if @original_font_height.nil?
|
358
|
+
update_font_height(@original_font_height)
|
359
|
+
@original_font_height = nil
|
360
|
+
end
|
361
|
+
|
362
|
+
def update_font_height(new_font_height)
|
363
|
+
return if new_font_height.nil?
|
364
|
+
@styled_text_proxy.font = {name: font_datum.name, height: new_font_height, style: font_datum.style}
|
365
|
+
@line_numbers_styled_text_proxy&.font = {name: font_datum.name, height: new_font_height, style: font_datum.style}
|
366
|
+
@body_root.shell_proxy.layout(true, true)
|
367
|
+
@body_root.shell_proxy.pack_same_size
|
368
|
+
end
|
369
|
+
|
370
|
+
def font_datum
|
371
|
+
@styled_text_proxy.font.font_data.first
|
372
|
+
end
|
335
373
|
end
|
336
374
|
end
|
337
375
|
end
|
@@ -36,14 +36,24 @@ module Glimmer
|
|
36
36
|
#
|
37
37
|
# Follows the Proxy Design Pattern
|
38
38
|
class FontProxy
|
39
|
-
|
40
|
-
|
39
|
+
class << self
|
40
|
+
def create(*args)
|
41
|
+
flyweight_font_proxies[args] ||= new(*args)
|
42
|
+
end
|
43
|
+
|
44
|
+
# Flyweight Design Pattern memoization cache. Can be cleared if memory is needed.
|
45
|
+
def flyweight_font_proxies
|
46
|
+
@flyweight_font_proxies ||= {}
|
47
|
+
end
|
48
|
+
end
|
41
49
|
|
42
50
|
include_package 'org.eclipse.swt.graphics'
|
51
|
+
|
52
|
+
ERROR_INVALID_FONT_STYLE = " is an invalid font style! Valid values are :normal, :bold, and :italic"
|
53
|
+
FONT_STYLES = [:normal, :bold, :italic]
|
43
54
|
|
44
55
|
attr_reader :widget_proxy, :swt_font, :font_properties
|
45
56
|
|
46
|
-
|
47
57
|
# Builds a new font proxy from passed in widget_proxy and font_properties hash,
|
48
58
|
#
|
49
59
|
# It begins with existing SWT widget font and amends it with font properties.
|
@@ -419,8 +419,14 @@ module Glimmer
|
|
419
419
|
@editor = args
|
420
420
|
end
|
421
421
|
|
422
|
-
def cells_for(model)
|
423
|
-
|
422
|
+
def cells_for(model, table_item_property: :text)
|
423
|
+
if table_item_property.to_s == 'text'
|
424
|
+
column_properties.map {|column_property| model.send(column_property)}
|
425
|
+
else
|
426
|
+
column_properties.map do |column_property|
|
427
|
+
model.send("#{column_property}_#{table_item_property}") if model.respond_to?("#{column_property}_#{table_item_property}")
|
428
|
+
end
|
429
|
+
end
|
424
430
|
end
|
425
431
|
|
426
432
|
def cells
|
@@ -25,17 +25,17 @@ require 'glimmer-dsl-swt'
|
|
25
25
|
class StickFigure
|
26
26
|
include Glimmer::UI::CustomShape
|
27
27
|
|
28
|
-
options :
|
28
|
+
options :figure_x, :figure_y, :figure_width, :figure_height
|
29
29
|
|
30
30
|
before_body do
|
31
|
-
@head_width =
|
32
|
-
@head_height =
|
33
|
-
@trunk_height =
|
34
|
-
@extremity_length =
|
31
|
+
@head_width = figure_width*0.2
|
32
|
+
@head_height = figure_height*0.2
|
33
|
+
@trunk_height = figure_height*0.4
|
34
|
+
@extremity_length = figure_height*0.4
|
35
35
|
end
|
36
36
|
|
37
37
|
body {
|
38
|
-
shape(
|
38
|
+
shape(figure_x + @head_width/2.0 + @extremity_length, figure_y) {
|
39
39
|
oval(0, 0, @head_width, @head_height)
|
40
40
|
line(@head_width/2.0, @head_height, @head_width/2.0, @head_height + @trunk_height)
|
41
41
|
line(@head_width/2.0, @head_height + @trunk_height, @head_width/2.0 + @extremity_length, @head_height + @trunk_height + @extremity_length)
|
@@ -47,7 +47,7 @@ class StickFigure
|
|
47
47
|
end
|
48
48
|
|
49
49
|
class HelloCustomShape
|
50
|
-
include Glimmer::UI::
|
50
|
+
include Glimmer::UI::Application
|
51
51
|
|
52
52
|
WIDTH = 220
|
53
53
|
HEIGHT = 235
|
@@ -60,12 +60,12 @@ class HelloCustomShape
|
|
60
60
|
@canvas = canvas {
|
61
61
|
background :white
|
62
62
|
|
63
|
-
15.times
|
63
|
+
15.times do |n|
|
64
64
|
x_location = (rand*WIDTH/2).to_i%WIDTH + (rand*15).to_i
|
65
65
|
y_location = (rand*HEIGHT/2).to_i%HEIGHT + (rand*15).to_i
|
66
66
|
foreground_color = rgb(rand*255, rand*255, rand*255)
|
67
67
|
|
68
|
-
a_stick_figure = stick_figure(
|
68
|
+
a_stick_figure = stick_figure(figure_x: x_location, figure_y: y_location, figure_width: 35+n*2, figure_height: 35+n*2) {
|
69
69
|
foreground foreground_color
|
70
70
|
drag_and_move true
|
71
71
|
|
@@ -74,7 +74,7 @@ class HelloCustomShape
|
|
74
74
|
a_stick_figure.foreground = rgb(rand*255, rand*255, rand*255)
|
75
75
|
end
|
76
76
|
}
|
77
|
-
|
77
|
+
end
|
78
78
|
}
|
79
79
|
}
|
80
80
|
}
|
@@ -89,6 +89,7 @@ class HelloTable
|
|
89
89
|
def playoff_type=(new_playoff_type)
|
90
90
|
@playoff_type = new_playoff_type
|
91
91
|
self.schedule=(all_playoff_games[@playoff_type])
|
92
|
+
self.selected_game = schedule.first unless selected_game.nil?
|
92
93
|
end
|
93
94
|
|
94
95
|
def playoff_type_options
|
@@ -118,15 +119,24 @@ class HelloTable
|
|
118
119
|
'St Louis Cardinals' => 'Busch Stadium',
|
119
120
|
}
|
120
121
|
|
121
|
-
|
122
|
+
ATTRIBUTES = [:game_date, :game_time, :home_team, :away_team, :ballpark, :promotion]
|
123
|
+
ATTRIBUTES_BACKGROUND = ATTRIBUTES.map {|attribute| "#{attribute}_background"}
|
124
|
+
ATTRIBUTES_FOREGROUND = ATTRIBUTES.map {|attribute| "#{attribute}_foreground"}
|
125
|
+
ATTRIBUTES_FONT = ATTRIBUTES.map {|attribute| "#{attribute}_font"}
|
126
|
+
ATTRIBUTES_IMAGE = ATTRIBUTES.map {|attribute| "#{attribute}_image"}
|
122
127
|
|
128
|
+
attr_accessor *([:booked, :date_time] + ATTRIBUTES + ATTRIBUTES_BACKGROUND + ATTRIBUTES_FOREGROUND + ATTRIBUTES_FONT + ATTRIBUTES_IMAGE)
|
129
|
+
alias booked? booked
|
130
|
+
|
123
131
|
def initialize(date_time, home_team, away_team, promotion = 'N/A')
|
124
132
|
self.date_time = date_time
|
125
133
|
self.home_team = home_team
|
126
134
|
self.away_team = away_team
|
127
135
|
self.promotion = promotion
|
136
|
+
self.ballpark_image = [File.expand_path('hello_table/baseball_park.png', __dir__), width: 20, height: 20]
|
137
|
+
self.booked = false
|
138
|
+
|
128
139
|
observe(self, :date_time) do |new_value|
|
129
|
-
notify_observers(:game_date)
|
130
140
|
notify_observers(:game_time)
|
131
141
|
end
|
132
142
|
end
|
@@ -177,8 +187,42 @@ class HelloTable
|
|
177
187
|
end
|
178
188
|
|
179
189
|
def book!
|
190
|
+
self.booked = true
|
191
|
+
self.background = :dark_green
|
192
|
+
self.foreground = :white
|
193
|
+
self.font = {style: :italic}
|
180
194
|
"Thank you for booking #{to_s}"
|
181
195
|
end
|
196
|
+
|
197
|
+
# Sets background for all attributes
|
198
|
+
def background=(color)
|
199
|
+
self.game_date_background = color
|
200
|
+
self.game_time_background = color
|
201
|
+
self.home_team_background = color
|
202
|
+
self.away_team_background = color
|
203
|
+
self.ballpark_background = color
|
204
|
+
self.promotion_background = color
|
205
|
+
end
|
206
|
+
|
207
|
+
# Sets foreground for all attributes
|
208
|
+
def foreground=(color)
|
209
|
+
self.game_date_foreground = color
|
210
|
+
self.game_time_foreground = color
|
211
|
+
self.home_team_foreground = color
|
212
|
+
self.away_team_foreground = color
|
213
|
+
self.ballpark_foreground = color
|
214
|
+
self.promotion_foreground = color
|
215
|
+
end
|
216
|
+
|
217
|
+
# Sets font for all attributes
|
218
|
+
def font=(font_properties)
|
219
|
+
self.game_date_font = font_properties
|
220
|
+
self.game_time_font = font_properties
|
221
|
+
self.home_team_font = font_properties
|
222
|
+
self.away_team_font = font_properties
|
223
|
+
self.ballpark_font = font_properties
|
224
|
+
self.promotion_font = font_properties
|
225
|
+
end
|
182
226
|
end
|
183
227
|
|
184
228
|
include Glimmer::UI::CustomShell
|
@@ -246,8 +290,27 @@ class HelloTable
|
|
246
290
|
# default text editor is used here
|
247
291
|
}
|
248
292
|
|
249
|
-
#
|
250
|
-
|
293
|
+
# This is a contextual pop up menu that shows up when right-clicking table rows
|
294
|
+
menu {
|
295
|
+
menu_item {
|
296
|
+
text 'Book'
|
297
|
+
|
298
|
+
on_widget_selected do
|
299
|
+
book_selected_game
|
300
|
+
end
|
301
|
+
}
|
302
|
+
}
|
303
|
+
|
304
|
+
# Data-bind table items (rows) to a model collection (BaseballGame.schedule),
|
305
|
+
# mapping columns in declaration order to row model properties (attributes)
|
306
|
+
# By convention, every column property can be accompanied by extra properties
|
307
|
+
# with the following suffixes: `_background`, `_foreground`, `_font`, and `_image`
|
308
|
+
# For example, for `game_date`, model could also implement these related properties:
|
309
|
+
# `game_date_background`, `game_date_foreground`, `game_date_font`, `game_date_image`
|
310
|
+
# That is done in order to let the table widget set extra properties if needed.
|
311
|
+
items <=> [BaseballGame, :schedule,
|
312
|
+
column_properties: [:game_date, :game_time, :ballpark, :home_team, :away_team, :promotion]
|
313
|
+
]
|
251
314
|
|
252
315
|
# Data-bind table selection
|
253
316
|
selection <=> [BaseballGame, :selected_game]
|
@@ -258,22 +321,16 @@ class HelloTable
|
|
258
321
|
# Sort by these additional properties after handling sort by the column the user clicked
|
259
322
|
additional_sort_properties :date, :time, :home_team, :away_team, :ballpark, :promotion
|
260
323
|
|
261
|
-
|
262
|
-
|
263
|
-
|
264
|
-
|
265
|
-
on_widget_selected do
|
266
|
-
book_selected_game
|
267
|
-
end
|
268
|
-
}
|
269
|
-
}
|
324
|
+
on_key_pressed do |key_event|
|
325
|
+
book_selected_game if key_event.keyCode == swt(:cr)
|
326
|
+
end
|
270
327
|
}
|
271
328
|
|
272
329
|
button {
|
273
330
|
text 'Book Selected Game'
|
274
331
|
layout_data :center, :center, true, false
|
275
332
|
font height: 14
|
276
|
-
enabled <= [BaseballGame, :
|
333
|
+
enabled <= [BaseballGame, 'selected_game.booked', on_read: ->(value) { value == false }]
|
277
334
|
|
278
335
|
on_widget_selected do
|
279
336
|
book_selected_game
|
@@ -283,6 +340,8 @@ class HelloTable
|
|
283
340
|
}
|
284
341
|
|
285
342
|
def book_selected_game
|
343
|
+
return if BaseballGame.selected_game.booked?
|
344
|
+
|
286
345
|
message_box {
|
287
346
|
text 'Baseball Game Booked!'
|
288
347
|
message BaseballGame.selected_game.book!
|
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.24.
|
4
|
+
version: 4.24.3.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Andy Maleh
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2022-08-
|
11
|
+
date: 2022-08-28 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
requirement: !ruby/object:Gem::Requirement
|