glimmer-dsl-swt 4.24.3.2 → 4.24.4.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +8 -0
- data/README.md +5 -5
- data/VERSION +1 -1
- data/docs/reference/GLIMMER_GUI_DSL_SYNTAX.md +50 -0
- data/docs/reference/GLIMMER_SAMPLES.md +13 -0
- data/glimmer-dsl-swt.gemspec +0 -0
- data/lib/glimmer/data_binding/table_items_binding.rb +31 -22
- data/lib/glimmer/data_binding/widget_binding.rb +26 -4
- data/lib/glimmer/dsl/swt/custom_widget_expression.rb +1 -0
- data/lib/glimmer/swt/custom/refined_table.rb +182 -0
- data/lib/glimmer/swt/widget_proxy.rb +6 -1
- data/lib/glimmer/ui/custom_widget.rb +8 -0
- data/samples/hello/hello_refined_table.rb +159 -0
- metadata +4 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 81eb61402ae45b2e3782b9c10dc6b0374e39fb7f74351d2ed940719fbd6e4ec3
|
4
|
+
data.tar.gz: dfa93b670ddc363dd2dc602920d5e24510202b179f7e7740ee8abc50fc91eee4
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 46bee26330ce88284c85f263b0db58dda6dfb76cd2d2f37938c881f6567d74cd0a514565625a6c21da53b91e119fd31185dda8b22626e357fb79612e9013f6fe
|
7
|
+
data.tar.gz: '049762158e8e4015ec1a157edd148212078a106b753b9ad4f6111ab49746fe2934471382b4c5c20d9ee00a9abca8d8c22866c1c3ecd7aa733ccc5aeb28eb6c7b'
|
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,13 @@
|
|
1
1
|
# Change Log
|
2
2
|
|
3
|
+
## 4.24.4.0
|
4
|
+
|
5
|
+
- Save `WidgetBinding` instances on `WidgetProxy` objects via `widget_bindings` attribute
|
6
|
+
- Support specifying `@children_owner` in any custom widget for which adding children will not add them under the `body_root` (e.g. a composite wrapping a table will designate the table as the `@children_owner` for adding `table_column`s)
|
7
|
+
- Add explicit `shell_proxy` method to `Glimmer::UI::CustomWidget` that delegates to `body_root` to avoid annoying false negative error every time that method is called
|
8
|
+
- Optimize `table` data-binding performance for single-model update scenarios
|
9
|
+
- Fix issue with data-binding a table as the body root of a custom widget when customizing column_attributes
|
10
|
+
|
3
11
|
## 4.24.3.2
|
4
12
|
|
5
13
|
- Have `table` data-binding infer model attribute names from column names by convention (no need to specify `column_properties`)
|
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.4.0
|
2
2
|
## JRuby Desktop Development GUI Framework
|
3
3
|
[![Gem Version](https://badge.fury.io/rb/glimmer-dsl-swt.svg)](http://badge.fury.io/rb/glimmer-dsl-swt)
|
4
4
|
[![Travis CI](https://travis-ci.com/AndyObtiva/glimmer-dsl-swt.svg?branch=master)](https://travis-ci.com/github/AndyObtiva/glimmer-dsl-swt)
|
@@ -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.4.0 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.4.0
|
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.4.0'
|
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.4.0
|
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.4.0
|
@@ -54,9 +54,11 @@ This guide should help you get started with Glimmer DSL for SWT. For more advanc
|
|
54
54
|
- [Combo](#combo)
|
55
55
|
- [List](#list)
|
56
56
|
- [Table](#table)
|
57
|
+
- [Table Item Properties](#table-item-properties)
|
57
58
|
- [Table Selection](#table-selection)
|
58
59
|
- [Table Editing](#table-editing)
|
59
60
|
- [Table Sorting](#table-sorting)
|
61
|
+
- [Refined Table with Pagination](#refined-table-with-pagination)
|
60
62
|
- [Tree](#tree)
|
61
63
|
- [DateTime](#datetime)
|
62
64
|
- [Observer](#observer)
|
@@ -4109,6 +4111,9 @@ This automatically leverages the SWT TableEditor custom class behind the scenes,
|
|
4109
4111
|
passed table item text into something else.
|
4110
4112
|
It automatically persists the change to `items` data-bound model on ENTER/FOCUS-OUT or cancels on ESC/NO-CHANGE.
|
4111
4113
|
|
4114
|
+
Note that `table` is designed to expect about 100 rows only, not more than that, or otherwise it will not offer a user-friendly experience due to requiring users to scroll through a lot of data.
|
4115
|
+
If you need to display a table with more than 100 rows, then you need to employ pagination. That is already supported in the [Refined Table (`refined_table`)](#refined-table-with-pagination) custom widget documented below.
|
4116
|
+
|
4112
4117
|
##### Table Item Properties
|
4113
4118
|
|
4114
4119
|
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.
|
@@ -4302,6 +4307,51 @@ Here is an explanation of the example above:
|
|
4302
4307
|
|
4303
4308
|
`<= [model, :property, read_only_sort: true]` could be used with items to make sorting not propagate sorting changes to model.
|
4304
4309
|
|
4310
|
+
##### Refined Table with Pagination
|
4311
|
+
|
4312
|
+
**(ALPHA FEATURE)**
|
4313
|
+
|
4314
|
+
`refined_table` is a custom widget that can handle very large amounts of data by applying pagination.
|
4315
|
+
|
4316
|
+
Just use like a standard `table`, but data-bind models to a `model_array` property instead of `items`. `refined_table` will take care of the rest.
|
4317
|
+
|
4318
|
+
Options:
|
4319
|
+
- `per_page` (default: `10`): specifies how many rows to display per page
|
4320
|
+
- `page` (default: `1` if table is filled and `0` otherwise): specifies initial page
|
4321
|
+
|
4322
|
+
Note that currently `refined_table` only supports displaying a **read-only** table (meaning it can read updates from the model, but it cannot write back to the model through table editing cells).
|
4323
|
+
|
4324
|
+
Example taken from [Hello, Refined Table!](/docs/reference/GLIMMER_SAMPLES.md#hello-refined-table):
|
4325
|
+
|
4326
|
+
![hello refined table](/images/glimmer-hello-refined-table.png)
|
4327
|
+
|
4328
|
+
```ruby
|
4329
|
+
#... more code precedes
|
4330
|
+
|
4331
|
+
refined_table(per_page: 20) {
|
4332
|
+
table_column {
|
4333
|
+
width 100
|
4334
|
+
text 'Date'
|
4335
|
+
}
|
4336
|
+
table_column {
|
4337
|
+
width 200
|
4338
|
+
text 'Ballpark'
|
4339
|
+
}
|
4340
|
+
table_column {
|
4341
|
+
width 150
|
4342
|
+
text 'Home Team'
|
4343
|
+
}
|
4344
|
+
table_column {
|
4345
|
+
width 150
|
4346
|
+
text 'Away Team'
|
4347
|
+
}
|
4348
|
+
|
4349
|
+
model_array <= [@baseball_season, :games, column_attributes: {'Home Team' => :home_team_name, 'Away Team' => :away_team_name}]
|
4350
|
+
}
|
4351
|
+
|
4352
|
+
#...more code follows
|
4353
|
+
```
|
4354
|
+
|
4305
4355
|
#### Tree
|
4306
4356
|
|
4307
4357
|
The SWT Tree widget visualizes a tree data-structure, such as an employment or composition hierarchy.
|
@@ -41,6 +41,7 @@
|
|
41
41
|
- [Hello, Slider!](#hello-slider)
|
42
42
|
- [Hello, Spinner!](#hello-spinner)
|
43
43
|
- [Hello, Table!](#hello-table)
|
44
|
+
- [Hello, Refined Table!](#hello-refined-table)
|
44
45
|
- [Hello, Link!](#hello-link)
|
45
46
|
- [Hello, Dialog!](#hello-dialog)
|
46
47
|
- [Hello, Code Text!](#hello-code-text)
|
@@ -780,6 +781,18 @@ Hello, Table! Game Booked Rows
|
|
780
781
|
|
781
782
|
![Hello Table game booked rows](/images/glimmer-hello-table-game-booked-rows.png)
|
782
783
|
|
784
|
+
#### Hello, Refined Table!
|
785
|
+
|
786
|
+
This sample demonstrates the use of the [`refined_table` widget](/docs/reference/GLIMMER_GUI_DSL_SYNTAX.md#refined-table-with-pagination), which provides a paginated `table` that can handle very large amounts of data.
|
787
|
+
|
788
|
+
Code:
|
789
|
+
|
790
|
+
[samples/hello/hello_refined_table.rb](/samples/hello/hello_refined_table.rb)
|
791
|
+
|
792
|
+
Hello, Refined Table!
|
793
|
+
|
794
|
+
![Hello Refined Table](/images/glimmer-hello-refined-table.png)
|
795
|
+
|
783
796
|
#### Hello, Link!
|
784
797
|
|
785
798
|
This sample demonstrates the use of the `link` widget in Glimmer, including identifying which link was clicked and performing an action (displaying help) based on its location.
|
data/glimmer-dsl-swt.gemspec
CHANGED
Binary file
|
@@ -39,18 +39,12 @@ module Glimmer
|
|
39
39
|
TABLE_ITEM_PROPERTIES = %w[background foreground font image]
|
40
40
|
|
41
41
|
def initialize(parent, model_binding, column_properties = nil)
|
42
|
-
@table = parent
|
42
|
+
@table = parent.is_a?(Glimmer::SWT::TableProxy) ? parent : parent.body_root # assume custom widget in latter case
|
43
43
|
@model_binding = model_binding
|
44
44
|
@read_only_sort = @model_binding.binding_options[:read_only_sort]
|
45
45
|
@table.editable = false if @model_binding.binding_options[:read_only]
|
46
|
-
column_properties = @model_binding.binding_options[:column_properties] || @model_binding.binding_options[:column_attributes] || column_properties
|
47
|
-
|
48
|
-
@table.column_properties = column_properties
|
49
|
-
@column_properties = @table.column_properties # normalized column properties
|
50
|
-
else # assume custom widget
|
51
|
-
@table.body_root.column_properties = @column_properties
|
52
|
-
@column_properties = @table.body_root.column_properties # normalized column properties
|
53
|
-
end
|
46
|
+
@table.column_properties = @model_binding.binding_options[:column_properties] || @model_binding.binding_options[:column_attributes] || column_properties
|
47
|
+
@column_properties = @table.column_properties # normalized column properties
|
54
48
|
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
|
55
49
|
@table.swt_widget.data = @model_binding
|
56
50
|
@table.swt_widget.set_data('table_items_binding', self)
|
@@ -69,6 +63,7 @@ module Glimmer
|
|
69
63
|
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
|
70
64
|
new_model_collection = model_binding_evaluated_property = @model_binding.evaluate_property unless internal_sort # this ensures applying converters (e.g. :on_read)
|
71
65
|
return if same_table_data?(new_model_collection)
|
66
|
+
|
72
67
|
if same_model_collection?(new_model_collection)
|
73
68
|
new_model_collection_attribute_values = model_collection_attribute_values(new_model_collection)
|
74
69
|
@table.swt_widget.items.each_with_index do |table_item, row_index|
|
@@ -85,24 +80,38 @@ module Glimmer
|
|
85
80
|
@last_model_collection_attribute_values = new_model_collection_attribute_values
|
86
81
|
else
|
87
82
|
if new_model_collection and new_model_collection.is_a?(Array)
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
83
|
+
@model_observer_registrations ||= {}
|
84
|
+
new_model_collection.each do |model|
|
85
|
+
@model_observer_registrations[model] ||= {}
|
86
|
+
@column_properties.each do |column_property|
|
87
|
+
old_model_observer_registration = @model_observer_registrations[model][column_property]
|
88
|
+
remove_dependent(@table_observer_registration => old_model_observer_registration) if old_model_observer_registration
|
89
|
+
old_model_observer_registration&.unobserve
|
90
|
+
model_observer_registration = observe(model, column_property)
|
91
|
+
@model_observer_registrations[model][column_property] = model_observer_registration
|
92
|
+
add_dependent(@table_observer_registration => model_observer_registration)
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
95
96
|
if !same_model_collection_with_different_sort?(new_model_collection)
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
97
|
+
new_model_collection.each do |model|
|
98
|
+
TABLE_ITEM_PROPERTIES.each do |table_item_property|
|
99
|
+
@column_properties.each do |column_property|
|
100
|
+
column_property = "#{column_property}_#{table_item_property}"
|
101
|
+
old_model_observer_registration = @model_observer_registrations[model][column_property]
|
102
|
+
remove_dependent(@table_observer_registration => old_model_observer_registration) if old_model_observer_registration
|
103
|
+
old_model_observer_registration&.unobserve
|
104
|
+
model_observer_registration = observe(model, column_property)
|
105
|
+
@model_observer_registrations[model][column_property] = model_observer_registration
|
106
|
+
add_dependent(@table_observer_registration => model_observer_registration)
|
107
|
+
end
|
108
|
+
end
|
102
109
|
end
|
103
110
|
end
|
111
|
+
|
104
112
|
@model_collection = new_model_collection
|
105
113
|
end
|
114
|
+
|
106
115
|
populate_table(@model_collection, @table, @column_properties, internal_sort: internal_sort)
|
107
116
|
end
|
108
117
|
end
|
@@ -31,7 +31,8 @@ module Glimmer
|
|
31
31
|
include Observable
|
32
32
|
include Observer
|
33
33
|
|
34
|
-
attr_reader :widget, :property
|
34
|
+
attr_reader :widget, :property, :model_binding
|
35
|
+
|
35
36
|
def initialize(widget, property, sync_exec: nil, async_exec: nil)
|
36
37
|
@widget = widget
|
37
38
|
@property = property
|
@@ -40,17 +41,35 @@ module Glimmer
|
|
40
41
|
SWT::DisplayProxy.instance.auto_exec(override_sync_exec: @sync_exec, override_async_exec: @async_exec) do
|
41
42
|
if @widget.is_a?(Glimmer::SWT::WidgetProxy) && @widget.respond_to?(:on_widget_disposed)
|
42
43
|
@widget.on_widget_disposed do |dispose_event|
|
43
|
-
|
44
|
+
unless @widget.shell_proxy.last_shell_closing?
|
45
|
+
@widget_proxy.widget_bindings.delete(self)
|
46
|
+
deregister_all_observables
|
47
|
+
end
|
44
48
|
end
|
45
49
|
end
|
46
50
|
# TODO look into hooking on_shape_disposed without slowing down shapes in samples like Tetris
|
47
51
|
end
|
52
|
+
# TODO try to come up with a more comprehensive and cleaner solution to miscallenous objects like MessageBoxProxy with regards to @widget_proxy
|
53
|
+
@widget_proxy = widget.is_a?(Glimmer::SWT::WidgetProxy) ? widget : (widget.respond_to?(:body_root) ? widget.body_root : widget)
|
54
|
+
end
|
55
|
+
|
56
|
+
def observe(*args)
|
57
|
+
if @widget_proxy.respond_to?(:widget_bindings)
|
58
|
+
# TODO try to come up with a more comprehensive and cleaner solution to miscallenous objects like MessageBoxProxy with regards to the following code
|
59
|
+
# assumes only one observation
|
60
|
+
@model_binding = args.first if args.size == 1
|
61
|
+
@widget_proxy.widget_bindings << self
|
62
|
+
end
|
63
|
+
super
|
48
64
|
end
|
49
65
|
|
50
66
|
def call(value)
|
51
67
|
SWT::DisplayProxy.instance.auto_exec(override_sync_exec: @sync_exec, override_async_exec: @async_exec) do
|
52
68
|
if @widget.respond_to?(:disposed?) && @widget.disposed?
|
53
|
-
|
69
|
+
unless @widget.shell_proxy.last_shell_closing?
|
70
|
+
@widget_proxy.widget_bindings.delete(self)
|
71
|
+
deregister_all_observables
|
72
|
+
end
|
54
73
|
return
|
55
74
|
end
|
56
75
|
# need the rescue false for a scenario with tree items not being equal to model objects raising an exception
|
@@ -62,7 +81,10 @@ module Glimmer
|
|
62
81
|
|
63
82
|
def evaluate_property
|
64
83
|
if @widget.respond_to?(:disposed?) && @widget.disposed?
|
65
|
-
|
84
|
+
unless @widget.shell_proxy.last_shell_closing?
|
85
|
+
@widget_proxy.widget_bindings.delete(self)
|
86
|
+
deregister_all_observables
|
87
|
+
end
|
66
88
|
return
|
67
89
|
end
|
68
90
|
@widget.get_attribute(@property)
|
@@ -26,6 +26,7 @@ require 'glimmer/dsl/top_level_expression'
|
|
26
26
|
require 'glimmer/ui/custom_widget'
|
27
27
|
require 'glimmer/ui/custom_shell'
|
28
28
|
require 'glimmer/swt/custom/code_text'
|
29
|
+
require 'glimmer/swt/custom/refined_table'
|
29
30
|
require 'glimmer/swt/custom/radio_group'
|
30
31
|
require 'glimmer/swt/custom/checkbox_group'
|
31
32
|
|
@@ -0,0 +1,182 @@
|
|
1
|
+
# Copyright (c) 2007-2022 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/ui/custom_widget'
|
23
|
+
|
24
|
+
module Glimmer
|
25
|
+
module SWT
|
26
|
+
module Custom
|
27
|
+
# RefinedTable is a customization of Table with support for Filtering/Pagination
|
28
|
+
class RefinedTable
|
29
|
+
include Glimmer::UI::CustomWidget
|
30
|
+
|
31
|
+
option :per_page, default: 10
|
32
|
+
option :page, default: 0
|
33
|
+
option :model_array
|
34
|
+
|
35
|
+
attr_accessor :refined_model_array
|
36
|
+
attr_reader :table_proxy, :page_text_proxy
|
37
|
+
|
38
|
+
before_body do
|
39
|
+
self.model_array ||= []
|
40
|
+
self.refined_model_array = []
|
41
|
+
end
|
42
|
+
|
43
|
+
after_body do
|
44
|
+
Glimmer::DataBinding::Observer.proc do |new_widget_bindings|
|
45
|
+
new_widget_bindings.each do |new_widget_binding|
|
46
|
+
if new_widget_binding.property.to_s == 'model_array' && !@data_bound
|
47
|
+
@data_bound = true
|
48
|
+
model_binding = new_widget_binding.model_binding
|
49
|
+
observe(self, :model_array) do
|
50
|
+
paginate
|
51
|
+
end
|
52
|
+
@table_proxy.content {
|
53
|
+
items(dsl: true) <=> [self, :refined_model_array, model_binding.binding_options.merge(read_only: true)]
|
54
|
+
}
|
55
|
+
paginate
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end.observe(body_root.widget_bindings)
|
59
|
+
end
|
60
|
+
|
61
|
+
body {
|
62
|
+
composite {
|
63
|
+
composite {
|
64
|
+
layout_data(:fill, :center, true, false)
|
65
|
+
|
66
|
+
fill_layout(:horizontal)
|
67
|
+
|
68
|
+
button {
|
69
|
+
text '<<'
|
70
|
+
|
71
|
+
on_widget_selected do
|
72
|
+
self.page = first_page
|
73
|
+
paginate
|
74
|
+
end
|
75
|
+
}
|
76
|
+
|
77
|
+
button {
|
78
|
+
text '<'
|
79
|
+
|
80
|
+
on_widget_selected do
|
81
|
+
self.page -= 1
|
82
|
+
paginate
|
83
|
+
end
|
84
|
+
}
|
85
|
+
|
86
|
+
@page_text_proxy = text(:border, :center) {
|
87
|
+
text <= [self, :page, on_read: ->(value) { "#{value} of #{page_count}" }]
|
88
|
+
|
89
|
+
on_focus_gained do
|
90
|
+
@page_text_proxy.select_all
|
91
|
+
end
|
92
|
+
|
93
|
+
on_focus_lost do
|
94
|
+
self.page = @page_text_proxy.text.to_i
|
95
|
+
paginate
|
96
|
+
end
|
97
|
+
|
98
|
+
on_key_pressed do |key_event|
|
99
|
+
if key_event.keyCode == swt(:cr)
|
100
|
+
self.page = @page_text_proxy.text.to_i
|
101
|
+
paginate
|
102
|
+
end
|
103
|
+
end
|
104
|
+
}
|
105
|
+
|
106
|
+
button {
|
107
|
+
text '>'
|
108
|
+
|
109
|
+
on_widget_selected do
|
110
|
+
self.page += 1
|
111
|
+
paginate
|
112
|
+
end
|
113
|
+
}
|
114
|
+
|
115
|
+
button {
|
116
|
+
text '>>'
|
117
|
+
|
118
|
+
on_widget_selected do
|
119
|
+
self.page = last_page
|
120
|
+
paginate
|
121
|
+
end
|
122
|
+
}
|
123
|
+
}
|
124
|
+
|
125
|
+
@children_owner = @table_proxy = table(swt_style)
|
126
|
+
}
|
127
|
+
}
|
128
|
+
|
129
|
+
def table_block=(block)
|
130
|
+
@table_proxy.content(&block)
|
131
|
+
end
|
132
|
+
|
133
|
+
def method_missing(method_name, *args, &block)
|
134
|
+
dsl_mode = @dsl_mode || args.last.is_a?(Hash) && args.last[:dsl]
|
135
|
+
if dsl_mode
|
136
|
+
args.pop if args.last.is_a?(Hash) && args.last[:dsl]
|
137
|
+
super(method_name, *args, &block)
|
138
|
+
elsif @table_proxy&.respond_to?(method_name, *args, &block)
|
139
|
+
@table_proxy&.send(method_name, *args, &block)
|
140
|
+
else
|
141
|
+
super
|
142
|
+
end
|
143
|
+
end
|
144
|
+
|
145
|
+
def respond_to?(method_name, *args, &block)
|
146
|
+
dsl_mode = @dsl_mode || args.last.is_a?(Hash) && args.last[:dsl]
|
147
|
+
if dsl_mode
|
148
|
+
args = args[0...-1] if args.last.is_a?(Hash) && args.last[:dsl]
|
149
|
+
super(method_name, *args, &block)
|
150
|
+
else
|
151
|
+
super || @table_proxy&.respond_to?(method_name, *args, &block)
|
152
|
+
end
|
153
|
+
end
|
154
|
+
|
155
|
+
def page_count
|
156
|
+
(model_array && (model_array.count / per_page.to_f).ceil) || 0
|
157
|
+
end
|
158
|
+
|
159
|
+
def corrected_page(initial_page_value = nil)
|
160
|
+
correct_page = initial_page_value || page
|
161
|
+
correct_page = [correct_page, page_count].min
|
162
|
+
correct_page = [correct_page, 1].max
|
163
|
+
correct_page = (model_array&.count.to_i > 0) ? (correct_page > 0 ? correct_page : 1) : 0
|
164
|
+
correct_page
|
165
|
+
end
|
166
|
+
|
167
|
+
def first_page
|
168
|
+
(model_array&.count.to_i > 0) ? 1 : 0
|
169
|
+
end
|
170
|
+
|
171
|
+
def last_page
|
172
|
+
page_count
|
173
|
+
end
|
174
|
+
|
175
|
+
def paginate
|
176
|
+
self.page = corrected_page(page)
|
177
|
+
self.refined_model_array = model_array[(page - 1) * per_page, per_page]
|
178
|
+
end
|
179
|
+
end
|
180
|
+
end
|
181
|
+
end
|
182
|
+
end
|
@@ -159,7 +159,8 @@ module Glimmer
|
|
159
159
|
@parent_proxy = parent
|
160
160
|
styles, extra_options = extract_args(underscored_widget_name, args)
|
161
161
|
swt_widget_class = self.class.swt_widget_class_for(underscored_widget_name)
|
162
|
-
|
162
|
+
swt_widget_producer = @parent_proxy.respond_to?(:children_owner) ? @parent_proxy.children_owner : @parent_proxy
|
163
|
+
@swt_widget = swt_widget_class.new(swt_widget_producer.swt_widget, style(underscored_widget_name, styles), *extra_options)
|
163
164
|
else
|
164
165
|
@swt_widget = swt_widget
|
165
166
|
underscored_widget_name = self.class.underscored_widget_name(@swt_widget)
|
@@ -769,6 +770,10 @@ module Glimmer
|
|
769
770
|
end
|
770
771
|
end
|
771
772
|
end
|
773
|
+
|
774
|
+
def widget_bindings
|
775
|
+
@widget_bindings ||= []
|
776
|
+
end
|
772
777
|
|
773
778
|
def content(&block)
|
774
779
|
auto_exec do
|
@@ -0,0 +1,159 @@
|
|
1
|
+
# Copyright (c) 2007-2022 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
|
+
require 'date'
|
24
|
+
|
25
|
+
class HelloRefinedTable
|
26
|
+
BaseballTeam = Struct.new(:name, :town, :ballpark, keyword_init: true) do
|
27
|
+
class << self
|
28
|
+
def all
|
29
|
+
@all ||= [
|
30
|
+
{town: 'Chicago', name: 'White Sox', ballpark: 'Guaranteed Rate Field'},
|
31
|
+
{town: 'Cleveland', name: 'Indians', ballpark: 'Progressive Field'},
|
32
|
+
{town: 'Detroit', name: 'Tigers', ballpark: 'Comerica Park'},
|
33
|
+
{town: 'Kansas City', name: 'Royals', ballpark: 'Kauffman Stadium'},
|
34
|
+
{town: 'Minnesota', name: 'Twins', ballpark: 'Target Field'},
|
35
|
+
{town: 'Baltimore', name: 'Orioles', ballpark: 'Oriole Park at Camden Yards'},
|
36
|
+
{town: 'Boston', name: 'Red Sox', ballpark: 'Fenway Park'},
|
37
|
+
{town: 'New York', name: 'Yankees', ballpark: 'Comerica Park'},
|
38
|
+
{town: 'Tampa Bay', name: 'Rays', ballpark: 'Tropicana Field'},
|
39
|
+
{town: 'Toronto', name: 'Blue Jays', ballpark: 'Rogers Centre'},
|
40
|
+
{town: 'Houston', name: 'Astros', ballpark: 'Minute Maid Park'},
|
41
|
+
{town: 'Los Angeles', name: 'Angels', ballpark: 'Angel Stadium'},
|
42
|
+
{town: 'Oakland', name: 'Athletics', ballpark: 'RingCentral Coliseum'},
|
43
|
+
{town: 'Seattle', name: 'Mariners', ballpark: 'T-Mobile Park'},
|
44
|
+
{town: 'Texas', name: 'Rangers', ballpark: 'Globe Life Field'},
|
45
|
+
{town: 'Chicago', name: 'Cubs', ballpark: 'Wrigley Field'},
|
46
|
+
{town: 'Cincinnati', name: 'Reds', ballpark: 'Great American Ball Park'},
|
47
|
+
{town: 'Milwaukee', name: 'Brewers', ballpark: 'American Family Field'},
|
48
|
+
{town: 'Pittsburgh', name: 'Pirates', ballpark: 'PNC Park'},
|
49
|
+
{town: 'St. Louis', name: 'Cardinals', ballpark: 'Busch Stadium'},
|
50
|
+
{town: 'Atlanta', name: 'Braves', ballpark: 'Truist Park'},
|
51
|
+
{town: 'Miami', name: 'Marlins', ballpark: 'LoanDepot Park'},
|
52
|
+
{town: 'New York', name: 'Mets', ballpark: 'Citi Field'},
|
53
|
+
{town: 'Philadelphia', name: 'Phillies', ballpark: 'Citizens Bank Park'},
|
54
|
+
{town: 'Washington', name: 'Nationals', ballpark: 'Nationals Park'},
|
55
|
+
{town: 'Arizona', name: 'Diamondbacks', ballpark: 'Chase Field'},
|
56
|
+
{town: 'Colorado', name: 'Rockies', ballpark: 'Coors Field'},
|
57
|
+
{town: 'Los Angeles', name: 'Dodgers', ballpark: 'Dodger Stadium'},
|
58
|
+
{town: 'San Diego', name: 'Padres', ballpark: 'Petco Park'},
|
59
|
+
{town: 'San Francisco', name: 'Giants', ballpark: 'Oracle Park'},
|
60
|
+
].map {|team_kwargs| new(team_kwargs)}
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
def complete_name
|
65
|
+
"#{town} #{name}"
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
BaseballGame = Struct.new(:date, :home_team, :away_team, keyword_init: true) do
|
70
|
+
def home_team_name
|
71
|
+
home_team.complete_name
|
72
|
+
end
|
73
|
+
|
74
|
+
def away_team_name
|
75
|
+
away_team.complete_name
|
76
|
+
end
|
77
|
+
|
78
|
+
def ballpark
|
79
|
+
home_team.ballpark
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
BaseballSeason = Struct.new(:year) do
|
84
|
+
def games
|
85
|
+
if @games.nil?
|
86
|
+
@games = []
|
87
|
+
baseball_team_combinations = BaseballTeam.all.combination(2).to_a
|
88
|
+
current_day = first_day
|
89
|
+
day_offset = 0
|
90
|
+
begin
|
91
|
+
if (day_offset % 7 != 6)
|
92
|
+
day_games = []
|
93
|
+
half_teams_count = BaseballTeam.all.count / 2
|
94
|
+
while day_games.uniq.count < half_teams_count
|
95
|
+
baseball_team_pair = baseball_team_combinations.sample
|
96
|
+
teams_played_so_far = day_games.map {|game| [game.home_team, game.away_team]}.flatten
|
97
|
+
unless teams_played_so_far.include?(baseball_team_pair.first) || teams_played_so_far.include?(baseball_team_pair.last)
|
98
|
+
baseball_game = BaseballGame.new(
|
99
|
+
date: current_day,
|
100
|
+
home_team: baseball_team_pair.first,
|
101
|
+
away_team: baseball_team_pair.last,
|
102
|
+
)
|
103
|
+
day_games << baseball_game
|
104
|
+
@games << baseball_game
|
105
|
+
end
|
106
|
+
end
|
107
|
+
end
|
108
|
+
day_offset += 1
|
109
|
+
current_day += 1
|
110
|
+
end while current_day != first_day_of_playoffs
|
111
|
+
end
|
112
|
+
@games
|
113
|
+
end
|
114
|
+
|
115
|
+
def first_day
|
116
|
+
@first_day ||= Date.new(year, 04, 01)
|
117
|
+
end
|
118
|
+
|
119
|
+
def first_day_of_playoffs
|
120
|
+
@last_day ||= Date.new(year, 10, 01)
|
121
|
+
end
|
122
|
+
end
|
123
|
+
|
124
|
+
include Glimmer::UI::Application
|
125
|
+
|
126
|
+
before_body do
|
127
|
+
@baseball_season = BaseballSeason.new(Time.now.year)
|
128
|
+
end
|
129
|
+
|
130
|
+
body {
|
131
|
+
shell {
|
132
|
+
text 'Hello, Refined Table!'
|
133
|
+
|
134
|
+
refined_table(per_page: 20) { # also `page: 1` by default
|
135
|
+
table_column {
|
136
|
+
width 100
|
137
|
+
text 'Date'
|
138
|
+
}
|
139
|
+
table_column {
|
140
|
+
width 200
|
141
|
+
text 'Ballpark'
|
142
|
+
}
|
143
|
+
table_column {
|
144
|
+
width 150
|
145
|
+
text 'Home Team'
|
146
|
+
}
|
147
|
+
table_column {
|
148
|
+
width 150
|
149
|
+
text 'Away Team'
|
150
|
+
}
|
151
|
+
|
152
|
+
model_array <= [@baseball_season, :games, column_attributes: {'Home Team' => :home_team_name, 'Away Team' => :away_team_name}]
|
153
|
+
}
|
154
|
+
}
|
155
|
+
}
|
156
|
+
|
157
|
+
end
|
158
|
+
|
159
|
+
HelloRefinedTable.launch
|
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.4.0
|
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-09-
|
11
|
+
date: 2022-09-05 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
requirement: !ruby/object:Gem::Requirement
|
@@ -472,6 +472,7 @@ files:
|
|
472
472
|
- lib/glimmer/swt/custom/code_text.rb
|
473
473
|
- lib/glimmer/swt/custom/drawable.rb
|
474
474
|
- lib/glimmer/swt/custom/radio_group.rb
|
475
|
+
- lib/glimmer/swt/custom/refined_table.rb
|
475
476
|
- lib/glimmer/swt/custom/shape.rb
|
476
477
|
- lib/glimmer/swt/custom/shape/arc.rb
|
477
478
|
- lib/glimmer/swt/custom/shape/cubic.rb
|
@@ -670,6 +671,7 @@ files:
|
|
670
671
|
- samples/hello/hello_progress_bar.rb
|
671
672
|
- samples/hello/hello_radio.rb
|
672
673
|
- samples/hello/hello_radio_group.rb
|
674
|
+
- samples/hello/hello_refined_table.rb
|
673
675
|
- samples/hello/hello_sash_form.rb
|
674
676
|
- samples/hello/hello_scale.rb
|
675
677
|
- samples/hello/hello_scrolled_composite.rb
|