glimmer-dsl-libui 0.5.15 → 0.5.18

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 84de8d621093ee6e1a4a5f88743e05fe3bfc3f14d844b4dbe0c8633a25b3c4b5
4
- data.tar.gz: 6b92c7d5fe723d64aaf6f01c934d8404c055ab3154c40a1b3a1771d5a0007549
3
+ metadata.gz: a3fef2bd47b932369023cff0088adf0776892ce7a2ed0589cd20b89726320809
4
+ data.tar.gz: ffc0cf261ffce1b52f92b3e0aff18691f645115c2ba36bea420f51c5e2d9c873
5
5
  SHA512:
6
- metadata.gz: 5a87a6606123afd53a3ad2419734c845a57072a76c4b1b81e4725372d94ebead2ab47536b8d2f0d84d04cd2319f38f41143244b0a08189f6046de6edc3a7e1da
7
- data.tar.gz: 8d7d4d95c4841355211c1f8058977098103ce9ac2b2c44b5d31478117f8815ee4f41afbd90cca03646f8d82e0546c79004894aed989f725b93756d8ffc2dc1f2
6
+ metadata.gz: cc07cb97b4fe12778abfc6ccb104bb5b2a9990d5b8f4cfff31aecae72a069efb5151c3a47be234fdf675e3a8cdd046eb89e454c22d97fb40eb8a4d1df30b2774
7
+ data.tar.gz: 7b4eb6ed048b18ee79e1aa197a90c168f69ee9c316df50244ab41a343266461c2fb3be233015387182cf77adb6386c6973fd649f9140a84ad83a8ce1a60d5e2f
data/CHANGELOG.md CHANGED
@@ -1,5 +1,23 @@
1
1
  # Change Log
2
2
 
3
+ ## 0.5.18
4
+
5
+ - `CustomWindow.launch(...)` returns the launched application/custom-window (e.g. `PaginatedRefinedTable.launch` returns the `PaginatedRefinedTable` instance that was automatically constructed)
6
+ - `CustomWindow.launched_application`/`CustomWindow.launched_custom_window` returns the launched application of a previous `.launch` call. This can be useful for rescuing errors and performing cleanup on the view object attributes after `.launch` returned.
7
+
8
+ ## 0.5.17
9
+
10
+ - Ensure disabling pagination buttons in `refined_table` if page is at beginning or end
11
+ - Add a "of #{page_count} pages" label after the text control in `refined_table` pagination area
12
+ - Page count ("of #{page_count} pages" label) can be shown by setting `visible_page_count: true` in `refined_table` options
13
+ - Correct initial `page` option passed to `refined_table` if out of range
14
+ - If `refined_table` `model_array` has no more than a single page of data, then hide pagination buttons
15
+
16
+ ## 0.5.16
17
+
18
+ - `refined_table` custom control that renders a `table` with filtering and pagination, thus being able to handle a large data set (e.g. 50,000)
19
+ - New examples/paginated_refined_table.rb
20
+
3
21
  ## 0.5.15
4
22
 
5
23
  - Fix an issue with rendering table content changes when the number of rows changes with new content that is not a subset of the old content or a container of it
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.5.15
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.5.18
2
2
  ## Prerequisite-Free Ruby Desktop Development GUI Library
3
3
  [![Gem Version](https://badge.fury.io/rb/glimmer-dsl-libui.svg)](http://badge.fury.io/rb/glimmer-dsl-libui)
4
4
  [![Join the chat at https://gitter.im/AndyObtiva/glimmer](https://badges.gitter.im/AndyObtiva/glimmer.svg)](https://gitter.im/AndyObtiva/glimmer?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
@@ -418,6 +418,7 @@ DSL | Platforms | Native? | Vector Graphics? | Pros | Cons | Prereqs
418
418
  - [Editable Column Table](#editable-column-table)
419
419
  - [Editable Table](#editable-table)
420
420
  - [Form Table](#form-table)
421
+ - [Paginated Refined Table](#paginated-refined-table)
421
422
  - [Grid](#grid)
422
423
  - [Histogram](#histogram)
423
424
  - [Login](#login)
@@ -583,7 +584,7 @@ gem install glimmer-dsl-libui
583
584
  Or install via Bundler `Gemfile`:
584
585
 
585
586
  ```ruby
586
- gem 'glimmer-dsl-libui', '~> 0.5.15'
587
+ gem 'glimmer-dsl-libui', '~> 0.5.18'
587
588
  ```
588
589
 
589
590
  Test that installation worked by running the [Meta-Example](#examples):
@@ -765,6 +766,7 @@ Keyword(Args) | Properties | Listeners
765
766
  `quit_menu_item` | None | `on_clicked`
766
767
  `radio_buttons` | `selected` (`Integer`) | `on_selected`
767
768
  `rectangle(x as Numeric, y as Numeric, width as Numeric, height as Numeric)` | `x` (`Numeric`), `y` (`Numeric`), `width` (`Numeric`), `height` (`Numeric`) | None
769
+ `refined_table` | `model_array` (`Array`), `table_columns` (`Hash`), `table_editable` (Boolean), `per_page` (`Integer`), `page` (`Integer`), `visible_page_count` (Boolean) | (EARLY ALPHA UNSTABLE API / CHECK SOURCE CODE FOR DETAILS)
768
770
  `scrolling_area(width = main_window.width, height = main_window.height)` | `auto_draw_enabled` (Boolean), `size` (`Array` of `width` (`Numeric`) and `height` (`Numeric`)), `width` (`Numeric`), `height` (`Numeric`) | `on_draw(area_draw_params)`, `on_mouse_event(area_mouse_event)`, `on_mouse_down(area_mouse_event)`, `on_mouse_up(area_mouse_event)`, `on_mouse_drag_started(area_mouse_event)`, `on_mouse_dragged(area_mouse_event)`, `on_mouse_dropped(area_mouse_event)`, `on_mouse_entered`, `on_mouse_exited`, `on_key_event(area_key_event)`, `on_key_down(area_key_event)`, `on_key_up(area_key_event)`
769
771
  `search_entry` | `read_only` (Boolean), `text` (`String`) | `on_changed`
770
772
  `separator_menu_item` | None | None
@@ -992,6 +994,52 @@ Mac | Windows | Linux
992
994
 
993
995
  Learn more by checking out [examples](#examples).
994
996
 
997
+ #### Refined Table
998
+
999
+ [EARLY ALPHA FEATURE]
1000
+
1001
+ `refined_table` is a custom control provided exclusively by [Glimmer DSL for LibUI](https://rubygems.org/gems/glimmer-dsl-libui)
1002
+ that includes filtering and pagination support out of the box and can handle very large amounts of data (e.g. 50,000 rows).
1003
+
1004
+ It is currently an early alpha feature, so please test-drive and report issues if you encounter any.
1005
+ And, please keep in mind that the API might undergo big changes.
1006
+
1007
+ Options (passed as kwargs hash):
1008
+
1009
+ - `model_array` (`Array`): array of models for which attributes map to table columns
1010
+ - `table_columns` (`Hash`): this maps column types to symbols (e.g. `text_column` becomes `:text`) with hash options per column
1011
+ - `table_editable` (Boolean) [default: `false`]: this indicates if all table columns are editable or not.
1012
+ - `per_page` (`Integer`)
1013
+ - `page` (`Integer`)
1014
+ - `visible_page_count` (Boolean) [default: `false`]: shows "of PAGE_COUNT pages" after page `entry` field
1015
+
1016
+ If the initial `model_array` has no more than a single page of data, then pagination buttons are hidden (but, the filter field remains).
1017
+
1018
+ Example code:
1019
+
1020
+ ```ruby
1021
+ refined_table(
1022
+ model_array: contacts,
1023
+ table_columns: {
1024
+ 'Name' => {button: {on_clicked: ->(row) {puts row}}},
1025
+ 'Colored Email' => :text_color,
1026
+ 'Phone' => {text: {editable: true}},
1027
+ 'City' => :text,
1028
+ 'State' => :text,
1029
+ },
1030
+ table_editable: true, # default value is false
1031
+ per_page: 20, # row count per page
1032
+ # page: 1, # initial page is 1
1033
+ # visible_page_count: true, # page count can be shown if preferred
1034
+ )
1035
+ ```
1036
+
1037
+ Mac | Windows | Linux
1038
+ ----|---------|------
1039
+ ![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)
1040
+
1041
+ Learn more in the [Paginated Refined Table](#paginated-refined-table) example.
1042
+
995
1043
  ### Area API
996
1044
 
997
1045
  The `area` control is a canvas-like control for drawing paths that can be used in one of two ways:
@@ -7979,6 +8027,148 @@ window('Contacts', 600, 600) {
7979
8027
  }.show
7980
8028
  ```
7981
8029
 
8030
+ #### Paginated Refined Table
8031
+
8032
+ [examples/paginated_refined_table.rb](examples/paginated_refined_table.rb)
8033
+
8034
+ Run with this command from the root of the project if you cloned the project:
8035
+
8036
+ ```
8037
+ ruby -r './lib/glimmer-dsl-libui' examples/paginated_refined_table.rb
8038
+ ```
8039
+
8040
+ Run with this command if you installed the [Ruby gem](https://rubygems.org/gems/glimmer-dsl-libui):
8041
+
8042
+ ```
8043
+ ruby -r glimmer-dsl-libui -e "require 'examples/paginated_refined_table'"
8044
+ ```
8045
+
8046
+ Mac | Windows | Linux
8047
+ ----|---------|------
8048
+ ![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)
8049
+
8050
+ New [Glimmer DSL for LibUI](https://rubygems.org/gems/glimmer-dsl-libui) Version:
8051
+
8052
+ ```ruby
8053
+ require 'glimmer-dsl-libui'
8054
+
8055
+ class PaginatedRefinedTable
8056
+ Contact = Struct.new(:name, :email, :phone, :city, :state)
8057
+
8058
+ include Glimmer::LibUI::Application
8059
+
8060
+ NAMES_FIRST = %w[
8061
+ Liam Noah William James Oliver Benjamin Elijah Lucas Mason Logan Alexander Ethan Jacob Michael Daniel Henry Jackson Sebastian
8062
+ Aiden Matthew Samuel David Joseph Carter Owen Wyatt John Jack Luke Jayden Dylan Grayson Levi Isaac Gabriel Julian Mateo
8063
+ Anthony Jaxon Lincoln Joshua Christopher Andrew Theodore Caleb Ryan Asher Nathan Thomas Leo Isaiah Charles Josiah Hudson
8064
+ Christian Hunter Connor Eli Ezra Aaron Landon Adrian Jonathan Nolan Jeremiah Easton Elias Colton Cameron Carson Robert Angel
8065
+ Maverick Nicholas Dominic Jaxson Greyson Adam Ian Austin Santiago Jordan Cooper Brayden Roman Evan Ezekiel Xaviar Jose Jace
8066
+ Jameson Leonardo Axel Everett Kayden Miles Sawyer Jason Emma Olivia Bartholomew Corey Danielle Eva Felicity
8067
+ ]
8068
+
8069
+ NAMES_LAST = %w[
8070
+ Smith Johnson Williams Brown Jones Miller Davis Wilson Anderson Taylor George Harrington Iverson Jackson Korby Levinson
8071
+ ]
8072
+
8073
+ CITIES = [
8074
+ 'Bellesville', 'Lombardia', 'Steepleton', 'Deerenstein', 'Schwartz', 'Hollandia', 'Saint Pete', 'Grandville', 'London',
8075
+ 'Berlin', 'Elktown', 'Paris', 'Garrison', 'Muncy', 'St Louis',
8076
+ ]
8077
+
8078
+ STATES = [ 'AK', 'AL', 'AR', 'AZ', 'CA', 'CO', 'CT', 'DC', 'DE', 'FL', 'GA',
8079
+ 'HI', 'IA', 'ID', 'IL', 'IN', 'KS', 'KY', 'LA', 'MA', 'MD', 'ME',
8080
+ 'MI', 'MN', 'MO', 'MS', 'MT', 'NC', 'ND', 'NE', 'NH', 'NJ', 'NM',
8081
+ 'NV', 'NY', 'OH', 'OK', 'OR', 'PA', 'RI', 'SC', 'SD', 'TN', 'TX',
8082
+ 'UT', 'VA', 'VT', 'WA', 'WI', 'WV', 'WY']
8083
+
8084
+ attr_accessor :contacts, :name, :email, :phone, :city, :state, :filter_value, :index
8085
+
8086
+ before_body do
8087
+ @contacts = 50_000.times.map do |n|
8088
+ n += 1
8089
+ first_name = NAMES_FIRST.sample
8090
+ last_name = NAMES_LAST.sample
8091
+ city = CITIES.sample
8092
+ state = STATES.sample
8093
+ Contact.new("#{first_name} #{last_name}", "#{first_name.downcase}#{n}@#{last_name.downcase}.com", '555-555-5555', city, state)
8094
+ end
8095
+ end
8096
+
8097
+ body {
8098
+ window("50,000 Paginated Contacts", 600, 700) {
8099
+ margined true
8100
+
8101
+ vertical_box {
8102
+ form {
8103
+ stretchy false
8104
+
8105
+ entry {
8106
+ label 'Name'
8107
+ text <=> [self, :name] # bidirectional data-binding between entry text and self.name
8108
+ }
8109
+
8110
+ entry {
8111
+ label 'Email'
8112
+ text <=> [self, :email]
8113
+ }
8114
+
8115
+ entry {
8116
+ label 'Phone'
8117
+ text <=> [self, :phone]
8118
+ }
8119
+
8120
+ entry {
8121
+ label 'City'
8122
+ text <=> [self, :city]
8123
+ }
8124
+
8125
+ entry {
8126
+ label 'State'
8127
+ text <=> [self, :state]
8128
+ }
8129
+ }
8130
+
8131
+ button('Save Contact') {
8132
+ stretchy false
8133
+
8134
+ on_clicked do
8135
+ new_row = [name, email, phone, city, state]
8136
+ if new_row.map(&:to_s).include?('')
8137
+ msg_box_error('Validation Error!', 'All fields are required! Please make sure to enter a value for all fields.')
8138
+ else
8139
+ @contacts << Contact.new(*new_row) # automatically inserts a row into the table due to explicit data-binding
8140
+ @unfiltered_contacts = @contacts.dup
8141
+ self.name = '' # automatically clears name entry through explicit data-binding
8142
+ self.email = ''
8143
+ self.phone = ''
8144
+ self.city = ''
8145
+ self.state = ''
8146
+ end
8147
+ end
8148
+ }
8149
+
8150
+ refined_table(
8151
+ model_array: contacts,
8152
+ table_columns: {
8153
+ 'Name' => {text: {editable: false}},
8154
+ 'Email' => :text,
8155
+ 'Phone' => :text,
8156
+ 'City' => :text,
8157
+ 'State' => :text,
8158
+ },
8159
+ table_editable: true,
8160
+ per_page: 20,
8161
+ # page: 1, # initial page is 1
8162
+ # visible_page_count: true, # page count can be shown if preferred
8163
+ )
8164
+ }
8165
+ }
8166
+ }
8167
+ end
8168
+
8169
+ PaginatedRefinedTable.launch
8170
+ ```
8171
+
7982
8172
  #### Grid
7983
8173
 
7984
8174
  [examples/grid.rb](examples/grid.rb)
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.5.15
1
+ 0.5.18
@@ -0,0 +1,117 @@
1
+ require 'glimmer-dsl-libui'
2
+
3
+ class PaginatedRefinedTable
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
+ attr_accessor :contacts, :name, :email, :phone, :city, :state, :filter_value, :index
33
+
34
+ before_body do
35
+ @contacts = 50_000.times.map do |n|
36
+ n += 1
37
+ first_name = NAMES_FIRST.sample
38
+ last_name = NAMES_LAST.sample
39
+ city = CITIES.sample
40
+ state = STATES.sample
41
+ Contact.new("#{first_name} #{last_name}", "#{first_name.downcase}#{n}@#{last_name.downcase}.com", '555-555-5555', city, state)
42
+ end
43
+ end
44
+
45
+ body {
46
+ window("50,000 Paginated Contacts", 600, 700) {
47
+ margined true
48
+
49
+ vertical_box {
50
+ form {
51
+ stretchy false
52
+
53
+ entry {
54
+ label 'Name'
55
+ text <=> [self, :name] # bidirectional data-binding between entry text and self.name
56
+ }
57
+
58
+ entry {
59
+ label 'Email'
60
+ text <=> [self, :email]
61
+ }
62
+
63
+ entry {
64
+ label 'Phone'
65
+ text <=> [self, :phone]
66
+ }
67
+
68
+ entry {
69
+ label 'City'
70
+ text <=> [self, :city]
71
+ }
72
+
73
+ entry {
74
+ label 'State'
75
+ text <=> [self, :state]
76
+ }
77
+ }
78
+
79
+ button('Save Contact') {
80
+ stretchy false
81
+
82
+ on_clicked do
83
+ new_row = [name, email, phone, city, state]
84
+ if new_row.map(&:to_s).include?('')
85
+ msg_box_error('Validation Error!', 'All fields are required! Please make sure to enter a value for all fields.')
86
+ else
87
+ @contacts << Contact.new(*new_row) # automatically inserts a row into the table due to explicit data-binding
88
+ @unfiltered_contacts = @contacts.dup
89
+ self.name = '' # automatically clears name entry through explicit data-binding
90
+ self.email = ''
91
+ self.phone = ''
92
+ self.city = ''
93
+ self.state = ''
94
+ end
95
+ end
96
+ }
97
+
98
+ refined_table(
99
+ model_array: contacts,
100
+ table_columns: {
101
+ 'Name' => {text: {editable: false}},
102
+ 'Email' => :text,
103
+ 'Phone' => :text,
104
+ 'City' => :text,
105
+ 'State' => :text,
106
+ },
107
+ table_editable: true,
108
+ per_page: 20,
109
+ # page: 1, # initial page is 1
110
+ # visible_page_count: true, # page count can be hidden if preferred
111
+ )
112
+ }
113
+ }
114
+ }
115
+ end
116
+
117
+ PaginatedRefinedTable.launch
Binary file
@@ -129,7 +129,7 @@ module Glimmer
129
129
  model_attribute_observer = Glimmer::DataBinding::Observer.proc do
130
130
  new_value = model_binding.evaluate_property
131
131
  new_value = new_value.to_a if new_value.is_a?(Enumerator)
132
- if model_binding.binding_options[:column_attributes] || (!new_value.empty? && !new_value.first.is_a?(Array))
132
+ 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)))
133
133
  @model_attribute_array_observer_registration&.deregister
134
134
  @model_attribute_array_observer_registration = model_attribute_observer.observe(new_value, @column_attributes, ignore_frozen: true, attribute_writer_type: [:attribute=, :set_attribute])
135
135
  model_attribute_observer.add_dependent(model_attribute_observer_registration => @model_attribute_array_observer_registration)
@@ -0,0 +1,173 @@
1
+ class RefinedTable
2
+ include Glimmer::LibUI::CustomControl
3
+
4
+ option :model_array, default: []
5
+ option :table_columns, default: []
6
+ option :table_editable, default: false
7
+ option :per_page, default: 10
8
+ option :page, default: 1
9
+ option :visible_page_count, default: false
10
+
11
+ attr_accessor :filtered_model_array, :filter_query, :filter_query_page_stack, :paginated_model_array
12
+
13
+ before_body do
14
+ @filter_query = ''
15
+ @filter_query_page_stack = {}
16
+ @filtered_model_array = model_array.dup
17
+ @filtered_model_array_stack = {@filter_query => @filtered_model_array}
18
+ self.page = correct_page(page)
19
+ paginate_model_array
20
+ end
21
+
22
+ body {
23
+ vertical_box {
24
+ table_filter
25
+
26
+ table_paginator if page_count > 1
27
+
28
+ @table = table {
29
+ table_columns.each do |column_name, column_details|
30
+ editable_value = on_clicked_value = nil
31
+ if column_details.is_a?(Symbol) || column_details.is_a?(String)
32
+ column_type = column_details
33
+ elsif column_details.is_a?(Hash)
34
+ column_type = column_details.keys.first
35
+ editable_value = column_details.values.first[:editable] || column_details.values.first['editable']
36
+ on_clicked_value = column_details.values.first[:on_clicked] || column_details.values.first['on_clicked']
37
+ end
38
+
39
+ send("#{column_type}_column", column_name) {
40
+ editable editable_value unless editable_value.nil?
41
+ on_clicked(&on_clicked_value) unless on_clicked_value.nil?
42
+ }
43
+ end
44
+
45
+ editable table_editable
46
+ cell_rows <=> [self, :paginated_model_array]
47
+ }
48
+ }
49
+ }
50
+
51
+ def table_filter
52
+ search_entry {
53
+ stretchy false
54
+ text <=> [self, :filter_query,
55
+ before_write: ->(new_filter_query) {
56
+ if new_filter_query != filter_query
57
+ if !@filtered_model_array_stack.key?(new_filter_query)
58
+ @filtered_model_array_stack[new_filter_query] = model_array.dup.filter do |model|
59
+ @table.expand([model])[0].any? do |attribute_value|
60
+ attribute_value.to_s.downcase.include?(new_filter_query.downcase)
61
+ end
62
+ end
63
+ end
64
+ @filtered_model_array = @filtered_model_array_stack[new_filter_query]
65
+ if new_filter_query.size > filter_query.size
66
+ @filter_query_page_stack[filter_query] = page
67
+ end
68
+ self.page = @filter_query_page_stack[new_filter_query] || correct_page(page)
69
+ paginate_model_array
70
+ end
71
+ }
72
+ ]
73
+ }
74
+ end
75
+
76
+ def table_paginator
77
+ horizontal_box {
78
+ stretchy false
79
+
80
+ button('<<') {
81
+ enabled <= [self, :page, on_read: ->(val) {val > 1}]
82
+
83
+ on_clicked do
84
+ unless self.page == 0
85
+ self.page = 1
86
+ paginate_model_array
87
+ end
88
+ end
89
+ }
90
+
91
+ button('<') {
92
+ enabled <= [self, :page, on_read: ->(val) {val > 1}]
93
+
94
+ on_clicked do
95
+ unless self.page == 0
96
+ self.page = [page - 1, 1].max
97
+ paginate_model_array
98
+ end
99
+ end
100
+ }
101
+
102
+ entry {
103
+ text <=> [self, :page,
104
+ on_read: :to_s,
105
+ on_write: ->(val) { correct_page(val.to_i) },
106
+ after_write: ->(val) { paginate_model_array },
107
+ ]
108
+ }
109
+
110
+ if visible_page_count
111
+ label {
112
+ text <= [self, :paginated_model_array, on_read: ->(val) {"of #{page_count} pages"}]
113
+ }
114
+ end
115
+
116
+ button('>') {
117
+ enabled <= [self, :page, on_read: ->(val) {val < page_count}]
118
+
119
+ on_clicked do
120
+ unless self.page == 0
121
+ self.page = [page + 1, page_count].min
122
+ paginate_model_array
123
+ end
124
+ end
125
+ }
126
+
127
+ button('>>') {
128
+ enabled <= [self, :page, on_read: ->(val) {val < page_count}]
129
+
130
+ on_clicked do
131
+ unless self.page == 0
132
+ self.page = page_count
133
+ paginate_model_array
134
+ end
135
+ end
136
+ }
137
+ }
138
+ end
139
+
140
+ def paginate_model_array
141
+ self.paginated_model_array = filtered_model_array[index, limit]
142
+ end
143
+
144
+ def index
145
+ [per_page * (page - 1), 0].max
146
+ end
147
+
148
+ def limit
149
+ [(filtered_model_array.count - index), per_page].min
150
+ end
151
+
152
+ def page_count
153
+ (filtered_model_array.count.to_f / per_page.to_f).ceil
154
+ end
155
+
156
+ def correct_page(page)
157
+ [[page, 1].max, page_count].min
158
+ end
159
+
160
+ # Ensure proxying properties to @table if body_root (vertical_box) doesn't support them
161
+
162
+ def respond_to?(method_name, *args, &block)
163
+ super || @table&.respond_to?(method_name, *args, &block)
164
+ end
165
+
166
+ def method_missing(method_name, *args, &block)
167
+ if @table&.respond_to?(method_name, *args, &block)
168
+ @table&.send(method_name, *args, &block)
169
+ else
170
+ super
171
+ end
172
+ end
173
+ end
@@ -31,8 +31,17 @@ module Glimmer
31
31
 
32
32
  class << self
33
33
  def launch(*args, &content)
34
- launched_custom_shell = send(keyword, *args, &content)
35
- launched_custom_shell.show
34
+ @@launched_custom_window = send(keyword, *args, &content)
35
+ @@launched_custom_window.show
36
+ @@launched_custom_window
37
+ end
38
+
39
+ def launched_custom_window
40
+ @@launched_custom_window if defined?(@@launched_custom_window)
41
+ end
42
+
43
+ def launched_application
44
+ launched_custom_window
36
45
  end
37
46
  end
38
47
 
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.5.15
4
+ version: 0.5.18
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-07-30 00:00:00.000000000 Z
11
+ date: 2022-08-04 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: glimmer
@@ -356,6 +356,7 @@ files:
356
356
  - examples/midi_player.rb
357
357
  - examples/midi_player2.rb
358
358
  - examples/midi_player3.rb
359
+ - examples/paginated_refined_table.rb
359
360
  - examples/shape_coloring.rb
360
361
  - examples/simple_notepad.rb
361
362
  - examples/snake.rb
@@ -469,6 +470,7 @@ files:
469
470
  - lib/glimmer/libui/control_proxy/window_proxy.rb
470
471
  - lib/glimmer/libui/custom_control.rb
471
472
  - lib/glimmer/libui/custom_control/code_area.rb
473
+ - lib/glimmer/libui/custom_control/refined_table.rb
472
474
  - lib/glimmer/libui/custom_window.rb
473
475
  - lib/glimmer/libui/data_bindable.rb
474
476
  - lib/glimmer/libui/image_path_renderer.rb