glimmer-dsl-libui 0.6.0 → 0.6.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: cd6518993a36f3108798c6e510e7e8b4cf948738106d78320e3c50a0537d6046
4
- data.tar.gz: a06bd741f0900f8311a771cd5acdabefa22e7f7d07f7a2878cc85e03a086c916
3
+ metadata.gz: c6c85518c66987d793c3e2883d3053f0361a1b21f0f572961d4f92b5e99f8e21
4
+ data.tar.gz: f69cc3e77d0f95ea5f0e9261588cbc4039bcaafae7b9460ff0890f2210477f00
5
5
  SHA512:
6
- metadata.gz: b42863592aeff2f871c596bbe8e43fd74646d4a3b7b413ead62bd07f8baf1a40f3109a73e23709441eb32403edac51088211c0c373ea0fa5c29c1f97c6581ff3
7
- data.tar.gz: cb642dc20da632413d2fc7a29900158120d9d4146401c334a8681044a048e7a925ed05d7f845ecaf6e75f05a5fbdabc055c5bac28c7713228c466ef116f9db01
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.0
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
  [![Gem Version](https://badge.fury.io/rb/glimmer-dsl-libui.svg)](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.0'
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.0
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
- ```ruby
341
- require 'glimmer-dsl-libui'
341
+ [examples/paginated_refined_table.rb](/examples/paginated_refined_table.rb)
342
342
 
343
- class PaginatedRefinedTable
344
- Contact = Struct.new(:name, :email, :phone, :city, :state)
345
-
346
- include Glimmer::LibUI::Application
347
-
348
- NAMES_FIRST = %w[
349
- Liam Noah William James Oliver Benjamin Elijah Lucas Mason Logan Alexander Ethan Jacob Michael Daniel Henry Jackson Sebastian
350
- Aiden Matthew Samuel David Joseph Carter Owen Wyatt John Jack Luke Jayden Dylan Grayson Levi Isaac Gabriel Julian Mateo
351
- Anthony Jaxon Lincoln Joshua Christopher Andrew Theodore Caleb Ryan Asher Nathan Thomas Leo Isaiah Charles Josiah Hudson
352
- Christian Hunter Connor Eli Ezra Aaron Landon Adrian Jonathan Nolan Jeremiah Easton Elias Colton Cameron Carson Robert Angel
353
- Maverick Nicholas Dominic Jaxson Greyson Adam Ian Austin Santiago Jordan Cooper Brayden Roman Evan Ezekiel Xaviar Jose Jace
354
- Jameson Leonardo Axel Everett Kayden Miles Sawyer Jason Emma Olivia Bartholomew Corey Danielle Eva Felicity
355
- ]
356
-
357
- NAMES_LAST = %w[
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
+ ![glimmer-dsl-libui-mac-paginated-refined-table.png](/images/glimmer-dsl-libui-mac-paginated-refined-table.png)| ![glimmer-dsl-libui-windows-paginated-refined-table.png](/images/glimmer-dsl-libui-windows-paginated-refined-table.png)| ![glimmer-dsl-libui-linux-paginated-refined-table.png](/images/glimmer-dsl-libui-linux-paginated-refined-table.png)
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
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, :column_attributes
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) && @column_attributes&.any?
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
- @column_attributes.to_a.map {|attribute| cell_row.send(attribute) }
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, @column_attributes, ignore_frozen: true, attribute_writer_type: [:attribute=, :set_attribute])
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 = @column_attributes[column]
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 = @column_attributes[column]
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 = @column_attributes[column]
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 = @column_attributes[column]
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 = @column_attributes[column]
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 = @column_attributes[column]
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.0
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-09 00:00:00.000000000 Z
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