glimmer-dsl-libui 0.6.0 → 0.6.1
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 +5 -0
- data/README.md +6 -4
- data/VERSION +1 -1
- data/docs/examples/GLIMMER-DSL-LIBUI-ADVANCED-EXAMPLES.md +39 -116
- data/examples/lazy_table.rb +76 -0
- data/examples/lazy_table2.rb +71 -0
- data/examples/lazy_table3.rb +74 -0
- data/examples/lazy_table4.rb +69 -0
- data/glimmer-dsl-libui.gemspec +0 -0
- data/lib/glimmer/libui/control_proxy/table_proxy.rb +14 -10
- metadata +6 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: c6c85518c66987d793c3e2883d3053f0361a1b21f0f572961d4f92b5e99f8e21
|
4
|
+
data.tar.gz: f69cc3e77d0f95ea5f0e9261588cbc4039bcaafae7b9460ff0890f2210477f00
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: db79e052ef21f04e89d0afaa7672b49329370ce7ce4c908885d6eb19f3b715f1ab3c3a6f926d1b0ce3e12ae69a7d7202ba68609ddc1d3bc45cc27d38f5605272
|
7
|
+
data.tar.gz: '088b796cf6521383d92cdc37225e00cc4ef8c4528d0b24f9f92ad4bb552245616090d35f3ee3339d6ddf216f78dbcaa710ec823a040bd1fbf78dbbab853ccd97'
|
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,10 @@
|
|
1
1
|
# Change Log
|
2
2
|
|
3
|
+
## 0.6.1
|
4
|
+
|
5
|
+
- `examples/lazy_table.rb` (and `examples/lazy_table2.rb` variation)
|
6
|
+
- Support `table` `cell_rows` implicit data-binding to a collection of models (only supported an array of arrays before in implicit data-binding)
|
7
|
+
|
3
8
|
## 0.6.0
|
4
9
|
|
5
10
|
- Upgrade to `libui` Ruby gem version 0.1.0.pre.0, which includes a newer C libui alpha release (libui-ng Nov 13, 2022)
|
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 LibUI 0.6.
|
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 LibUI 0.6.1
|
2
2
|
## Prerequisite-Free Ruby Desktop Development GUI Library
|
3
3
|
### The Quickest Way From Zero To GUI
|
4
4
|
[](http://badge.fury.io/rb/glimmer-dsl-libui)
|
@@ -542,7 +542,7 @@ gem install glimmer-dsl-libui
|
|
542
542
|
Or install via Bundler `Gemfile`:
|
543
543
|
|
544
544
|
```ruby
|
545
|
-
gem 'glimmer-dsl-libui', '~> 0.6.
|
545
|
+
gem 'glimmer-dsl-libui', '~> 0.6.1'
|
546
546
|
```
|
547
547
|
|
548
548
|
Test that installation worked by running the [Meta-Example](#examples):
|
@@ -2000,8 +2000,10 @@ That is data-binding `entered_text` attribute on `self` to `entry` `text` proper
|
|
2000
2000
|
##### Table Data-Binding
|
2001
2001
|
|
2002
2002
|
One note about `table` `cell_rows` data-binding is that it works with either:
|
2003
|
-
- Raw data `Array` (rows) of `Array`s (column cells)
|
2004
|
-
- Model `Array` (rows) of objects having attributes (column cells) matching the underscored names of `table` columns by convention. Model attribute names can be overridden when needed by passing an `Array` enumerating all mapped model attributes in the order of `table` columns or alternatively a `Hash` mapping only the column names that have model attribute names different from their table column underscored version.
|
2003
|
+
- Raw data `Array` (rows) of `Array`s (column cells) (see [Form Table example versions 4-5](https://github.com/AndyObtiva/glimmer-dsl-libui/blob/master/docs/examples/GLIMMER-DSL-LIBUI-ADVANCED-EXAMPLES.md#form-table)).
|
2004
|
+
- Model `Array` (rows) of objects having attributes (column cells) matching the underscored names of `table` columns by convention. Model attribute names can be overridden when needed by passing an `Array` enumerating all mapped model attributes in the order of `table` columns or alternatively a `Hash` mapping only the column names that have model attribute names different from their table column underscored version (see [Form Table example versions 1-3](https://github.com/AndyObtiva/glimmer-dsl-libui/blob/master/docs/examples/GLIMMER-DSL-LIBUI-ADVANCED-EXAMPLES.md#form-table)).
|
2005
|
+
- Raw data `Enumerator` or `Enumerator::Lazy` that generates `Array`s (column cells). This option enables rendering a table instantly even if it contained millions of rows, before all its rows have been generated. Rows are gradually generated as the user scrolls through the table.
|
2006
|
+
- Model `Enumerator` or `Enumerator::Lazy` that generates objects having attributes (column cells) matching the underscored names of `table` columns. This option enables rendering a table instantly even if it contained millions of rows, before all its rows have been generated. Rows are gradually generated as the user scrolls through the table (see [Lazy Table](https://github.com/AndyObtiva/glimmer-dsl-libui/blob/master/docs/examples/GLIMMER-DSL-LIBUI-ADVANCED-EXAMPLES.md#lazy-table) example).
|
2005
2007
|
|
2006
2008
|
Example of `table` implicit data-binding of `cell_rows` to raw data `Array` of `Array`s (you may copy/paste in [`girb`](#girb-glimmer-irb)):
|
2007
2009
|
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.6.
|
1
|
+
0.6.1
|
@@ -13,6 +13,7 @@
|
|
13
13
|
- [Form Table](#form-table)
|
14
14
|
- [GPT2 Notepad](#gpt2-notepad)
|
15
15
|
- [Paginated Refined Table](#paginated-refined-table)
|
16
|
+
- [Lazy Table](#lazy-table)
|
16
17
|
- [Grid](#grid)
|
17
18
|
- [Histogram](#histogram)
|
18
19
|
- [Login](#login)
|
@@ -337,125 +338,47 @@ Mac | Windows | Linux
|
|
337
338
|
|
338
339
|
New [Glimmer DSL for LibUI](https://rubygems.org/gems/glimmer-dsl-libui) Version:
|
339
340
|
|
340
|
-
|
341
|
-
require 'glimmer-dsl-libui'
|
341
|
+
[examples/paginated_refined_table.rb](/examples/paginated_refined_table.rb)
|
342
342
|
|
343
|
-
|
344
|
-
|
345
|
-
|
346
|
-
|
347
|
-
|
348
|
-
|
349
|
-
|
350
|
-
|
351
|
-
|
352
|
-
|
353
|
-
|
354
|
-
|
355
|
-
|
356
|
-
|
357
|
-
|
358
|
-
Smith Johnson Williams Brown Jones Miller Davis Wilson Anderson Taylor George Harrington Iverson Jackson Korby Levinson
|
359
|
-
]
|
360
|
-
|
361
|
-
CITIES = [
|
362
|
-
'Bellesville', 'Lombardia', 'Steepleton', 'Deerenstein', 'Schwartz', 'Hollandia', 'Saint Pete', 'Grandville', 'London',
|
363
|
-
'Berlin', 'Elktown', 'Paris', 'Garrison', 'Muncy', 'St Louis',
|
364
|
-
]
|
365
|
-
|
366
|
-
STATES = [ 'AK', 'AL', 'AR', 'AZ', 'CA', 'CO', 'CT', 'DC', 'DE', 'FL', 'GA',
|
367
|
-
'HI', 'IA', 'ID', 'IL', 'IN', 'KS', 'KY', 'LA', 'MA', 'MD', 'ME',
|
368
|
-
'MI', 'MN', 'MO', 'MS', 'MT', 'NC', 'ND', 'NE', 'NH', 'NJ', 'NM',
|
369
|
-
'NV', 'NY', 'OH', 'OK', 'OR', 'PA', 'RI', 'SC', 'SD', 'TN', 'TX',
|
370
|
-
'UT', 'VA', 'VT', 'WA', 'WI', 'WV', 'WY']
|
371
|
-
|
372
|
-
attr_accessor :contacts, :name, :email, :phone, :city, :state, :filter_value, :index
|
373
|
-
|
374
|
-
before_body do
|
375
|
-
@contacts = 50_000.times.map do |n|
|
376
|
-
n += 1
|
377
|
-
first_name = NAMES_FIRST.sample
|
378
|
-
last_name = NAMES_LAST.sample
|
379
|
-
city = CITIES.sample
|
380
|
-
state = STATES.sample
|
381
|
-
Contact.new("#{first_name} #{last_name}", "#{first_name.downcase}#{n}@#{last_name.downcase}.com", '555-555-5555', city, state)
|
382
|
-
end
|
383
|
-
end
|
384
|
-
|
385
|
-
body {
|
386
|
-
window("50,000 Paginated Contacts", 600, 700) {
|
387
|
-
margined true
|
388
|
-
|
389
|
-
vertical_box {
|
390
|
-
form {
|
391
|
-
stretchy false
|
392
|
-
|
393
|
-
entry {
|
394
|
-
label 'Name'
|
395
|
-
text <=> [self, :name] # bidirectional data-binding between entry text and self.name
|
396
|
-
}
|
397
|
-
|
398
|
-
entry {
|
399
|
-
label 'Email'
|
400
|
-
text <=> [self, :email]
|
401
|
-
}
|
402
|
-
|
403
|
-
entry {
|
404
|
-
label 'Phone'
|
405
|
-
text <=> [self, :phone]
|
406
|
-
}
|
407
|
-
|
408
|
-
entry {
|
409
|
-
label 'City'
|
410
|
-
text <=> [self, :city]
|
411
|
-
}
|
412
|
-
|
413
|
-
entry {
|
414
|
-
label 'State'
|
415
|
-
text <=> [self, :state]
|
416
|
-
}
|
417
|
-
}
|
418
|
-
|
419
|
-
button('Save Contact') {
|
420
|
-
stretchy false
|
421
|
-
|
422
|
-
on_clicked do
|
423
|
-
new_row = [name, email, phone, city, state]
|
424
|
-
if new_row.map(&:to_s).include?('')
|
425
|
-
msg_box_error('Validation Error!', 'All fields are required! Please make sure to enter a value for all fields.')
|
426
|
-
else
|
427
|
-
@contacts << Contact.new(*new_row) # automatically inserts a row into the table due to explicit data-binding
|
428
|
-
@unfiltered_contacts = @contacts.dup
|
429
|
-
self.name = '' # automatically clears name entry through explicit data-binding
|
430
|
-
self.email = ''
|
431
|
-
self.phone = ''
|
432
|
-
self.city = ''
|
433
|
-
self.state = ''
|
434
|
-
end
|
435
|
-
end
|
436
|
-
}
|
437
|
-
|
438
|
-
refined_table(
|
439
|
-
model_array: contacts,
|
440
|
-
table_columns: {
|
441
|
-
'Name' => {text: {editable: false}},
|
442
|
-
'Email' => :text,
|
443
|
-
'Phone' => :text,
|
444
|
-
'City' => :text,
|
445
|
-
'State' => :text,
|
446
|
-
},
|
447
|
-
table_editable: true,
|
448
|
-
per_page: 20,
|
449
|
-
# page: 1, # initial page is 1
|
450
|
-
# visible_page_count: true, # page count can be shown if preferred
|
451
|
-
)
|
452
|
-
}
|
453
|
-
}
|
454
|
-
}
|
455
|
-
end
|
343
|
+
## Lazy Table
|
344
|
+
|
345
|
+
A lazy table is loaded with row data lazily via Ruby `Enumerator` or `Enumerator::Lazy`.
|
346
|
+
That enables starting the app and rendering the table instantly before generating/loading all data,
|
347
|
+
even if the table was to contain millions of rows.
|
348
|
+
|
349
|
+
[examples/lazy_table.rb](/examples/lazy_table.rb)
|
350
|
+
|
351
|
+
Run with this command from the root of the project if you cloned the project:
|
352
|
+
|
353
|
+
```
|
354
|
+
ruby -r './lib/glimmer-dsl-libui' examples/lazy_table.rb
|
355
|
+
```
|
356
|
+
|
357
|
+
Run with this command if you installed the [Ruby gem](https://rubygems.org/gems/glimmer-dsl-libui):
|
456
358
|
|
457
|
-
PaginatedRefinedTable.launch
|
458
359
|
```
|
360
|
+
ruby -r glimmer-dsl-libui -e "require 'examples/paginated_refined_table'"
|
361
|
+
```
|
362
|
+
|
363
|
+
Mac | Windows | Linux
|
364
|
+
----|---------|------
|
365
|
+
| | 
|
366
|
+
|
367
|
+
`Enumerator` Subclass [Glimmer DSL for LibUI](https://rubygems.org/gems/glimmer-dsl-libui) Version:
|
368
|
+
|
369
|
+
[examples/lazy_table.rb](/examples/lazy_table.rb)
|
370
|
+
|
371
|
+
`Enumerator` [Glimmer DSL for LibUI](https://rubygems.org/gems/glimmer-dsl-libui) Version 2:
|
372
|
+
|
373
|
+
[examples/lazy_table2.rb](/examples/lazy_table2.rb)
|
374
|
+
|
375
|
+
`Enumerator::Lazy` Subclass [Glimmer DSL for LibUI](https://rubygems.org/gems/glimmer-dsl-libui) Version 3:
|
376
|
+
|
377
|
+
[examples/lazy_table3.rb](/examples/lazy_table3.rb)
|
378
|
+
|
379
|
+
`Enumerator::Lazy` [Glimmer DSL for LibUI](https://rubygems.org/gems/glimmer-dsl-libui) Version 4:
|
380
|
+
|
381
|
+
[examples/lazy_table4.rb](/examples/lazy_table4.rb)
|
459
382
|
|
460
383
|
## Grid
|
461
384
|
|
@@ -0,0 +1,76 @@
|
|
1
|
+
require 'glimmer-dsl-libui'
|
2
|
+
|
3
|
+
class LazyTable
|
4
|
+
Contact = Struct.new(:name, :email, :phone, :city, :state)
|
5
|
+
|
6
|
+
# Extending Enumerator enables building a collection generator in an encapsulated maintainable fashion
|
7
|
+
class ContactGenerator < Enumerator
|
8
|
+
NAMES_FIRST = %w[
|
9
|
+
Liam Noah William James Oliver Benjamin Elijah Lucas Mason Logan Alexander Ethan Jacob Michael Daniel Henry Jackson Sebastian
|
10
|
+
Aiden Matthew Samuel David Joseph Carter Owen Wyatt John Jack Luke Jayden Dylan Grayson Levi Isaac Gabriel Julian Mateo
|
11
|
+
Anthony Jaxon Lincoln Joshua Christopher Andrew Theodore Caleb Ryan Asher Nathan Thomas Leo Isaiah Charles Josiah Hudson
|
12
|
+
Christian Hunter Connor Eli Ezra Aaron Landon Adrian Jonathan Nolan Jeremiah Easton Elias Colton Cameron Carson Robert Angel
|
13
|
+
Maverick Nicholas Dominic Jaxson Greyson Adam Ian Austin Santiago Jordan Cooper Brayden Roman Evan Ezekiel Xaviar Jose Jace
|
14
|
+
Jameson Leonardo Axel Everett Kayden Miles Sawyer Jason Emma Olivia Bartholomew Corey Danielle Eva Felicity
|
15
|
+
]
|
16
|
+
|
17
|
+
NAMES_LAST = %w[
|
18
|
+
Smith Johnson Williams Brown Jones Miller Davis Wilson Anderson Taylor George Harrington Iverson Jackson Korby Levinson
|
19
|
+
]
|
20
|
+
|
21
|
+
CITIES = [
|
22
|
+
'Bellesville', 'Lombardia', 'Steepleton', 'Deerenstein', 'Schwartz', 'Hollandia', 'Saint Pete', 'Grandville', 'London',
|
23
|
+
'Berlin', 'Elktown', 'Paris', 'Garrison', 'Muncy', 'St Louis',
|
24
|
+
]
|
25
|
+
|
26
|
+
STATES = [ 'AK', 'AL', 'AR', 'AZ', 'CA', 'CO', 'CT', 'DC', 'DE', 'FL', 'GA',
|
27
|
+
'HI', 'IA', 'ID', 'IL', 'IN', 'KS', 'KY', 'LA', 'MA', 'MD', 'ME',
|
28
|
+
'MI', 'MN', 'MO', 'MS', 'MT', 'NC', 'ND', 'NE', 'NH', 'NJ', 'NM',
|
29
|
+
'NV', 'NY', 'OH', 'OK', 'OR', 'PA', 'RI', 'SC', 'SD', 'TN', 'TX',
|
30
|
+
'UT', 'VA', 'VT', 'WA', 'WI', 'WV', 'WY']
|
31
|
+
|
32
|
+
def initialize(contact_count)
|
33
|
+
# Make sure to pass super constructor size argument as it gets used by Glimmer DSL for LibUI
|
34
|
+
# to determine the number of rows in the table before generating all its data
|
35
|
+
super(contact_count) do |yielder|
|
36
|
+
contact_count.times do |index|
|
37
|
+
# Data will get lazy loaded into the table as the user scrolls through.
|
38
|
+
# After data is built, it is cached long-term, till updating table `cell_rows`.
|
39
|
+
yielder << contact_for(index)
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
def contact_for(index)
|
45
|
+
number = index + 1
|
46
|
+
first_name = NAMES_FIRST.sample
|
47
|
+
last_name = NAMES_LAST.sample
|
48
|
+
phone = 10.times.map { rand(10) }.yield_self { |numbers| [numbers[0..2], numbers[3..5], numbers[6..9]].map(&:join).join('-') }
|
49
|
+
city = CITIES.sample
|
50
|
+
state = STATES.sample
|
51
|
+
Contact.new("#{first_name} #{last_name}", "#{first_name.downcase}#{number}@#{last_name.downcase}.com", phone, city, state)
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
include Glimmer::LibUI::Application
|
56
|
+
|
57
|
+
body {
|
58
|
+
window("1,000,000 Lazy Loaded Contacts", 600, 700) {
|
59
|
+
margined true
|
60
|
+
|
61
|
+
vertical_box {
|
62
|
+
table {
|
63
|
+
text_column('Name')
|
64
|
+
text_column('Email')
|
65
|
+
text_column('Phone')
|
66
|
+
text_column('City')
|
67
|
+
text_column('State')
|
68
|
+
|
69
|
+
cell_rows ContactGenerator.new(1_000_000)
|
70
|
+
}
|
71
|
+
}
|
72
|
+
}
|
73
|
+
}
|
74
|
+
end
|
75
|
+
|
76
|
+
LazyTable.launch
|
@@ -0,0 +1,71 @@
|
|
1
|
+
require 'glimmer-dsl-libui'
|
2
|
+
|
3
|
+
class LazyTable
|
4
|
+
Contact = Struct.new(:name, :email, :phone, :city, :state)
|
5
|
+
|
6
|
+
include Glimmer::LibUI::Application
|
7
|
+
|
8
|
+
NAMES_FIRST = %w[
|
9
|
+
Liam Noah William James Oliver Benjamin Elijah Lucas Mason Logan Alexander Ethan Jacob Michael Daniel Henry Jackson Sebastian
|
10
|
+
Aiden Matthew Samuel David Joseph Carter Owen Wyatt John Jack Luke Jayden Dylan Grayson Levi Isaac Gabriel Julian Mateo
|
11
|
+
Anthony Jaxon Lincoln Joshua Christopher Andrew Theodore Caleb Ryan Asher Nathan Thomas Leo Isaiah Charles Josiah Hudson
|
12
|
+
Christian Hunter Connor Eli Ezra Aaron Landon Adrian Jonathan Nolan Jeremiah Easton Elias Colton Cameron Carson Robert Angel
|
13
|
+
Maverick Nicholas Dominic Jaxson Greyson Adam Ian Austin Santiago Jordan Cooper Brayden Roman Evan Ezekiel Xaviar Jose Jace
|
14
|
+
Jameson Leonardo Axel Everett Kayden Miles Sawyer Jason Emma Olivia Bartholomew Corey Danielle Eva Felicity
|
15
|
+
]
|
16
|
+
|
17
|
+
NAMES_LAST = %w[
|
18
|
+
Smith Johnson Williams Brown Jones Miller Davis Wilson Anderson Taylor George Harrington Iverson Jackson Korby Levinson
|
19
|
+
]
|
20
|
+
|
21
|
+
CITIES = [
|
22
|
+
'Bellesville', 'Lombardia', 'Steepleton', 'Deerenstein', 'Schwartz', 'Hollandia', 'Saint Pete', 'Grandville', 'London',
|
23
|
+
'Berlin', 'Elktown', 'Paris', 'Garrison', 'Muncy', 'St Louis',
|
24
|
+
]
|
25
|
+
|
26
|
+
STATES = [ 'AK', 'AL', 'AR', 'AZ', 'CA', 'CO', 'CT', 'DC', 'DE', 'FL', 'GA',
|
27
|
+
'HI', 'IA', 'ID', 'IL', 'IN', 'KS', 'KY', 'LA', 'MA', 'MD', 'ME',
|
28
|
+
'MI', 'MN', 'MO', 'MS', 'MT', 'NC', 'ND', 'NE', 'NH', 'NJ', 'NM',
|
29
|
+
'NV', 'NY', 'OH', 'OK', 'OR', 'PA', 'RI', 'SC', 'SD', 'TN', 'TX',
|
30
|
+
'UT', 'VA', 'VT', 'WA', 'WI', 'WV', 'WY']
|
31
|
+
|
32
|
+
before_body do
|
33
|
+
contact_count = 1_000_000
|
34
|
+
# Make sure to pass Enumerator constructor size argument as it gets used by Glimmer DSL for LibUI
|
35
|
+
# to determine the number of rows in the table before generating all its data
|
36
|
+
@contacts = Enumerator.new(contact_count) do |yielder|
|
37
|
+
contact_count.times do |index|
|
38
|
+
number = index + 1
|
39
|
+
first_name = NAMES_FIRST.sample
|
40
|
+
last_name = NAMES_LAST.sample
|
41
|
+
phone = 10.times.map { rand(10) }.yield_self { |numbers| [numbers[0..2], numbers[3..5], numbers[6..9]].map(&:join).join('-') }
|
42
|
+
city = CITIES.sample
|
43
|
+
state = STATES.sample
|
44
|
+
|
45
|
+
# Data will get lazy loaded into the table as the user scrolls through.
|
46
|
+
# After data is built, it is cached long-term, till updating table `cell_rows`.
|
47
|
+
yielder << Contact.new("#{first_name} #{last_name}", "#{first_name.downcase}#{number}@#{last_name.downcase}.com", phone, city, state)
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
body {
|
53
|
+
window("1,000,000 Lazy Loaded Contacts", 600, 700) {
|
54
|
+
margined true
|
55
|
+
|
56
|
+
vertical_box {
|
57
|
+
table {
|
58
|
+
text_column('Name')
|
59
|
+
text_column('Email')
|
60
|
+
text_column('Phone')
|
61
|
+
text_column('City')
|
62
|
+
text_column('State')
|
63
|
+
|
64
|
+
cell_rows @contacts
|
65
|
+
}
|
66
|
+
}
|
67
|
+
}
|
68
|
+
}
|
69
|
+
end
|
70
|
+
|
71
|
+
LazyTable.launch
|
@@ -0,0 +1,74 @@
|
|
1
|
+
require 'glimmer-dsl-libui'
|
2
|
+
|
3
|
+
class LazyTable
|
4
|
+
Contact = Struct.new(:name, :email, :phone, :city, :state)
|
5
|
+
|
6
|
+
# Extending Enumerator::Lazy enables building a collection generator in an encapsulated maintainable fashion
|
7
|
+
class ContactGenerator < Enumerator::Lazy
|
8
|
+
NAMES_FIRST = %w[
|
9
|
+
Liam Noah William James Oliver Benjamin Elijah Lucas Mason Logan Alexander Ethan Jacob Michael Daniel Henry Jackson Sebastian
|
10
|
+
Aiden Matthew Samuel David Joseph Carter Owen Wyatt John Jack Luke Jayden Dylan Grayson Levi Isaac Gabriel Julian Mateo
|
11
|
+
Anthony Jaxon Lincoln Joshua Christopher Andrew Theodore Caleb Ryan Asher Nathan Thomas Leo Isaiah Charles Josiah Hudson
|
12
|
+
Christian Hunter Connor Eli Ezra Aaron Landon Adrian Jonathan Nolan Jeremiah Easton Elias Colton Cameron Carson Robert Angel
|
13
|
+
Maverick Nicholas Dominic Jaxson Greyson Adam Ian Austin Santiago Jordan Cooper Brayden Roman Evan Ezekiel Xaviar Jose Jace
|
14
|
+
Jameson Leonardo Axel Everett Kayden Miles Sawyer Jason Emma Olivia Bartholomew Corey Danielle Eva Felicity
|
15
|
+
]
|
16
|
+
|
17
|
+
NAMES_LAST = %w[
|
18
|
+
Smith Johnson Williams Brown Jones Miller Davis Wilson Anderson Taylor George Harrington Iverson Jackson Korby Levinson
|
19
|
+
]
|
20
|
+
|
21
|
+
CITIES = [
|
22
|
+
'Bellesville', 'Lombardia', 'Steepleton', 'Deerenstein', 'Schwartz', 'Hollandia', 'Saint Pete', 'Grandville', 'London',
|
23
|
+
'Berlin', 'Elktown', 'Paris', 'Garrison', 'Muncy', 'St Louis',
|
24
|
+
]
|
25
|
+
|
26
|
+
STATES = [ 'AK', 'AL', 'AR', 'AZ', 'CA', 'CO', 'CT', 'DC', 'DE', 'FL', 'GA',
|
27
|
+
'HI', 'IA', 'ID', 'IL', 'IN', 'KS', 'KY', 'LA', 'MA', 'MD', 'ME',
|
28
|
+
'MI', 'MN', 'MO', 'MS', 'MT', 'NC', 'ND', 'NE', 'NH', 'NJ', 'NM',
|
29
|
+
'NV', 'NY', 'OH', 'OK', 'OR', 'PA', 'RI', 'SC', 'SD', 'TN', 'TX',
|
30
|
+
'UT', 'VA', 'VT', 'WA', 'WI', 'WV', 'WY']
|
31
|
+
|
32
|
+
def initialize(contact_count)
|
33
|
+
# Make sure to pass super constructor size (2nd) argument as it gets used by Glimmer DSL for LibUI
|
34
|
+
# to determine the number of rows in the table before generating all its data
|
35
|
+
super(contact_count.times, contact_count) do |yielder, index|
|
36
|
+
# Data will get lazy loaded into the table as the user scrolls through.
|
37
|
+
# After data is built, it is cached long-term, till updating table `cell_rows`.
|
38
|
+
yielder << contact_for(index)
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
def contact_for(index)
|
43
|
+
number = index + 1
|
44
|
+
first_name = NAMES_FIRST.sample
|
45
|
+
last_name = NAMES_LAST.sample
|
46
|
+
phone = 10.times.map { rand(10) }.yield_self { |numbers| [numbers[0..2], numbers[3..5], numbers[6..9]].map(&:join).join('-') }
|
47
|
+
city = CITIES.sample
|
48
|
+
state = STATES.sample
|
49
|
+
Contact.new("#{first_name} #{last_name}", "#{first_name.downcase}#{number}@#{last_name.downcase}.com", phone, city, state)
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
include Glimmer::LibUI::Application
|
54
|
+
|
55
|
+
body {
|
56
|
+
window("1,000,000 Lazy Loaded Contacts", 600, 700) {
|
57
|
+
margined true
|
58
|
+
|
59
|
+
vertical_box {
|
60
|
+
table {
|
61
|
+
text_column('Name')
|
62
|
+
text_column('Email')
|
63
|
+
text_column('Phone')
|
64
|
+
text_column('City')
|
65
|
+
text_column('State')
|
66
|
+
|
67
|
+
cell_rows ContactGenerator.new(1_000_000)
|
68
|
+
}
|
69
|
+
}
|
70
|
+
}
|
71
|
+
}
|
72
|
+
end
|
73
|
+
|
74
|
+
LazyTable.launch
|
@@ -0,0 +1,69 @@
|
|
1
|
+
require 'glimmer-dsl-libui'
|
2
|
+
|
3
|
+
class LazyTable
|
4
|
+
Contact = Struct.new(:name, :email, :phone, :city, :state)
|
5
|
+
|
6
|
+
include Glimmer::LibUI::Application
|
7
|
+
|
8
|
+
NAMES_FIRST = %w[
|
9
|
+
Liam Noah William James Oliver Benjamin Elijah Lucas Mason Logan Alexander Ethan Jacob Michael Daniel Henry Jackson Sebastian
|
10
|
+
Aiden Matthew Samuel David Joseph Carter Owen Wyatt John Jack Luke Jayden Dylan Grayson Levi Isaac Gabriel Julian Mateo
|
11
|
+
Anthony Jaxon Lincoln Joshua Christopher Andrew Theodore Caleb Ryan Asher Nathan Thomas Leo Isaiah Charles Josiah Hudson
|
12
|
+
Christian Hunter Connor Eli Ezra Aaron Landon Adrian Jonathan Nolan Jeremiah Easton Elias Colton Cameron Carson Robert Angel
|
13
|
+
Maverick Nicholas Dominic Jaxson Greyson Adam Ian Austin Santiago Jordan Cooper Brayden Roman Evan Ezekiel Xaviar Jose Jace
|
14
|
+
Jameson Leonardo Axel Everett Kayden Miles Sawyer Jason Emma Olivia Bartholomew Corey Danielle Eva Felicity
|
15
|
+
]
|
16
|
+
|
17
|
+
NAMES_LAST = %w[
|
18
|
+
Smith Johnson Williams Brown Jones Miller Davis Wilson Anderson Taylor George Harrington Iverson Jackson Korby Levinson
|
19
|
+
]
|
20
|
+
|
21
|
+
CITIES = [
|
22
|
+
'Bellesville', 'Lombardia', 'Steepleton', 'Deerenstein', 'Schwartz', 'Hollandia', 'Saint Pete', 'Grandville', 'London',
|
23
|
+
'Berlin', 'Elktown', 'Paris', 'Garrison', 'Muncy', 'St Louis',
|
24
|
+
]
|
25
|
+
|
26
|
+
STATES = [ 'AK', 'AL', 'AR', 'AZ', 'CA', 'CO', 'CT', 'DC', 'DE', 'FL', 'GA',
|
27
|
+
'HI', 'IA', 'ID', 'IL', 'IN', 'KS', 'KY', 'LA', 'MA', 'MD', 'ME',
|
28
|
+
'MI', 'MN', 'MO', 'MS', 'MT', 'NC', 'ND', 'NE', 'NH', 'NJ', 'NM',
|
29
|
+
'NV', 'NY', 'OH', 'OK', 'OR', 'PA', 'RI', 'SC', 'SD', 'TN', 'TX',
|
30
|
+
'UT', 'VA', 'VT', 'WA', 'WI', 'WV', 'WY']
|
31
|
+
|
32
|
+
before_body do
|
33
|
+
contact_count = 1_000_000
|
34
|
+
# Make sure to pass Enumerator::Lazy constructor size (2nd) argument as it gets used by Glimmer DSL for LibUI
|
35
|
+
# to determine the number of rows in the table before generating all its data
|
36
|
+
@contacts = Enumerator::Lazy.new(contact_count.times, contact_count) do |yielder, index|
|
37
|
+
number = index + 1
|
38
|
+
first_name = NAMES_FIRST.sample
|
39
|
+
last_name = NAMES_LAST.sample
|
40
|
+
phone = 10.times.map { rand(10) }.yield_self { |numbers| [numbers[0..2], numbers[3..5], numbers[6..9]].map(&:join).join('-') }
|
41
|
+
city = CITIES.sample
|
42
|
+
state = STATES.sample
|
43
|
+
|
44
|
+
# Data will get lazy loaded into the table as the user scrolls through.
|
45
|
+
# After data is built, it is cached long-term, till updating table `cell_rows`.
|
46
|
+
yielder << Contact.new("#{first_name} #{last_name}", "#{first_name.downcase}#{number}@#{last_name.downcase}.com", phone, city, state)
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
body {
|
51
|
+
window("1,000,000 Lazy Loaded Contacts", 600, 700) {
|
52
|
+
margined true
|
53
|
+
|
54
|
+
vertical_box {
|
55
|
+
table {
|
56
|
+
text_column('Name')
|
57
|
+
text_column('Email')
|
58
|
+
text_column('Phone')
|
59
|
+
text_column('City')
|
60
|
+
text_column('State')
|
61
|
+
|
62
|
+
cell_rows @contacts
|
63
|
+
}
|
64
|
+
}
|
65
|
+
}
|
66
|
+
}
|
67
|
+
end
|
68
|
+
|
69
|
+
LazyTable.launch
|
data/glimmer-dsl-libui.gemspec
CHANGED
Binary file
|
@@ -38,7 +38,7 @@ module Glimmer
|
|
38
38
|
|
39
39
|
CUSTOM_LISTENER_NAMES = ['on_changed', 'on_edited']
|
40
40
|
|
41
|
-
attr_reader :model_handler, :model, :table_params, :columns
|
41
|
+
attr_reader :model_handler, :model, :table_params, :columns
|
42
42
|
|
43
43
|
def initialize(keyword, parent, args, &block)
|
44
44
|
@keyword = keyword
|
@@ -110,12 +110,12 @@ module Glimmer
|
|
110
110
|
|
111
111
|
def expand_cell_row(cell_row)
|
112
112
|
return cell_row if cell_row.nil?
|
113
|
-
cell_row = expand_cell_row_from_model(cell_row) if !cell_row.is_a?(Array) &&
|
113
|
+
cell_row = expand_cell_row_from_model(cell_row) if !cell_row.is_a?(Array) && column_attributes.any?
|
114
114
|
cell_row.flatten(1)
|
115
115
|
end
|
116
116
|
|
117
117
|
def expand_cell_row_from_model(cell_row)
|
118
|
-
|
118
|
+
column_attributes.to_a.map {|attribute| cell_row.send(attribute) }
|
119
119
|
end
|
120
120
|
|
121
121
|
def editable(value = nil)
|
@@ -129,6 +129,10 @@ module Glimmer
|
|
129
129
|
alias set_editable editable
|
130
130
|
alias editable? editable
|
131
131
|
|
132
|
+
def column_attributes
|
133
|
+
@column_attributes ||= columns.select {|column| column.is_a?(Column)}.map(&:name).map(&:underscore)
|
134
|
+
end
|
135
|
+
|
132
136
|
def data_bind_read(property, model_binding)
|
133
137
|
if model_binding.binding_options[:column_attributes].is_a?(Array)
|
134
138
|
@column_attributes = model_binding.binding_options[:column_attributes]
|
@@ -141,7 +145,7 @@ module Glimmer
|
|
141
145
|
new_value = model_binding.evaluate_property
|
142
146
|
if model_binding.binding_options[:column_attributes] || (!new_value.nil? && (!new_value.is_a?(String) || !new_value.empty?) && (!new_value.is_a?(Array) || !new_value.first.is_a?(Array)))
|
143
147
|
@model_attribute_array_observer_registration&.deregister
|
144
|
-
@model_attribute_array_observer_registration = model_attribute_observer.observe(new_value,
|
148
|
+
@model_attribute_array_observer_registration = model_attribute_observer.observe(new_value, column_attributes, ignore_frozen: true, attribute_writer_type: [:attribute=, :set_attribute])
|
145
149
|
model_attribute_observer.add_dependent(model_attribute_observer_registration => @model_attribute_array_observer_registration)
|
146
150
|
end
|
147
151
|
# TODO look if multiple notifications are happening as a result of observing array and observing model binding
|
@@ -326,7 +330,7 @@ module Glimmer
|
|
326
330
|
if cell_row.is_a?(Array)
|
327
331
|
cell_row[compound_column_index_for(column)] = -1
|
328
332
|
else
|
329
|
-
attribute =
|
333
|
+
attribute = column_attributes[column]
|
330
334
|
cell_row.send("#{attribute}=", -1)
|
331
335
|
end
|
332
336
|
::LibUI.new_table_value_int(old_value)
|
@@ -349,7 +353,7 @@ module Glimmer
|
|
349
353
|
if table_cell_row.is_a?(Array)
|
350
354
|
table_cell_row[column] = ::LibUI.table_value_string(val).to_s
|
351
355
|
else
|
352
|
-
attribute =
|
356
|
+
attribute = column_attributes[column]
|
353
357
|
table_cell_row.send("#{attribute}=", ::LibUI.table_value_string(val).to_s)
|
354
358
|
end
|
355
359
|
when Column::TextColorColumnProxy
|
@@ -358,7 +362,7 @@ module Glimmer
|
|
358
362
|
table_cell_row[column] ||= []
|
359
363
|
table_cell_row[column][0] = ::LibUI.table_value_string(val).to_s
|
360
364
|
else
|
361
|
-
attribute =
|
365
|
+
attribute = column_attributes[column]
|
362
366
|
table_cell_row.send("#{attribute}=", []) unless table_cell_row.send(attribute)
|
363
367
|
table_cell_row.send(attribute)[0] = ::LibUI.table_value_string(val).to_s
|
364
368
|
end
|
@@ -368,7 +372,7 @@ module Glimmer
|
|
368
372
|
table_cell_row[column] ||= []
|
369
373
|
table_cell_row[column][1] = ::LibUI.table_value_string(val).to_s
|
370
374
|
else
|
371
|
-
attribute =
|
375
|
+
attribute = column_attributes[column]
|
372
376
|
table_cell_row.send("#{attribute}=", []) unless table_cell_row.send(attribute)
|
373
377
|
table_cell_row.send(attribute)[1] = ::LibUI.table_value_string(val).to_s
|
374
378
|
end
|
@@ -379,7 +383,7 @@ module Glimmer
|
|
379
383
|
if table_cell_row.is_a?(Array)
|
380
384
|
table_cell_row[column] = ::LibUI.table_value_int(val).to_i == 1
|
381
385
|
else
|
382
|
-
attribute =
|
386
|
+
attribute = column_attributes[column]
|
383
387
|
table_cell_row.send("#{attribute}=", ::LibUI.table_value_int(val).to_i == 1)
|
384
388
|
end
|
385
389
|
when Column::CheckboxTextColumnProxy
|
@@ -388,7 +392,7 @@ module Glimmer
|
|
388
392
|
table_cell_row[column] ||= []
|
389
393
|
table_cell_row[column][0] = ::LibUI.table_value_int(val).to_i == 1
|
390
394
|
else
|
391
|
-
attribute =
|
395
|
+
attribute = column_attributes[column]
|
392
396
|
table_cell_row.send("#{attribute}=", []) unless table_cell_row.send(attribute)
|
393
397
|
table_cell_row.send(attribute)[0] = ::LibUI.table_value_int(val).to_i == 1
|
394
398
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: glimmer-dsl-libui
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.6.
|
4
|
+
version: 0.6.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: 2023-01-
|
11
|
+
date: 2023-01-11 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: glimmer
|
@@ -348,6 +348,10 @@ files:
|
|
348
348
|
- examples/grid.rb
|
349
349
|
- examples/histogram.rb
|
350
350
|
- examples/histogram2.rb
|
351
|
+
- examples/lazy_table.rb
|
352
|
+
- examples/lazy_table2.rb
|
353
|
+
- examples/lazy_table3.rb
|
354
|
+
- examples/lazy_table4.rb
|
351
355
|
- examples/login.rb
|
352
356
|
- examples/login2.rb
|
353
357
|
- examples/login3.rb
|