glimmer-dsl-libui 0.5.15 → 0.5.16

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: 84de8d621093ee6e1a4a5f88743e05fe3bfc3f14d844b4dbe0c8633a25b3c4b5
4
- data.tar.gz: 6b92c7d5fe723d64aaf6f01c934d8404c055ab3154c40a1b3a1771d5a0007549
3
+ metadata.gz: 99ed9eb0a65da64d13717cf3f967ceadc36c4a0eed74fcbb385bd5d19c812db2
4
+ data.tar.gz: f24060ff8ef38a93c1f3174d3e01102d61d2c0c8d8466b1e0d32fedc8972c9ea
5
5
  SHA512:
6
- metadata.gz: 5a87a6606123afd53a3ad2419734c845a57072a76c4b1b81e4725372d94ebead2ab47536b8d2f0d84d04cd2319f38f41143244b0a08189f6046de6edc3a7e1da
7
- data.tar.gz: 8d7d4d95c4841355211c1f8058977098103ce9ac2b2c44b5d31478117f8815ee4f41afbd90cca03646f8d82e0546c79004894aed989f725b93756d8ffc2dc1f2
6
+ metadata.gz: def5540396a5cffc5f1271d3bb2664d008cf26db2f88207dc75bc23fa9915a2badfa45db8778e59644c99cbb0753147361556de25d118acd51e2dc211abd4bc8
7
+ data.tar.gz: 30ac47a92b4439aca5f3bc244514b400f810d8a9c855f64acf924544b448647d0d573d5218bc2e515ceb7bb469978b1e3e754d74d3ff86aea0b7d7247ee0e433
data/CHANGELOG.md CHANGED
@@ -1,5 +1,10 @@
1
1
  # Change Log
2
2
 
3
+ ## 0.5.16
4
+
5
+ - `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)
6
+ - New examples/paginated_refined_table.rb
7
+
3
8
  ## 0.5.15
4
9
 
5
10
  - 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.16
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.16'
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` | (EARLY ALPHA UNSTABLE API / CHECK SOURCE CODE FOR DETAILS) | (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,40 @@ 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 that includes filtering and pagination support out of the box and can handle very large amounts of data (e.g. 50,000 rows).
1002
+
1003
+ It is currently an early alpha feature, so please test-drive and report issues if you encounter any.
1004
+
1005
+ Also, the API might undergo big changes, so please keep that in mind.
1006
+
1007
+ Example code:
1008
+
1009
+ ```ruby
1010
+ refined_table(
1011
+ model_array: contacts,
1012
+ table_columns: {
1013
+ 'Name' => {button: {on_clicked: ->(row) {puts row}}},
1014
+ 'Colored Email' => :text_color,
1015
+ 'Phone' => {text: {editable: true}},
1016
+ 'City' => :text,
1017
+ 'State' => :text,
1018
+ },
1019
+ table_editable: true,
1020
+ per_page: 20, # row count per page
1021
+ page: 5, # initial page
1022
+ )
1023
+ ```
1024
+
1025
+ Mac | Windows | Linux
1026
+ ----|---------|------
1027
+ ![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)
1028
+
1029
+ Learn more in the [Paginated Refined Table](#paginated-refined-table) example.
1030
+
995
1031
  ### Area API
996
1032
 
997
1033
  The `area` control is a canvas-like control for drawing paths that can be used in one of two ways:
@@ -7979,6 +8015,273 @@ window('Contacts', 600, 600) {
7979
8015
  }.show
7980
8016
  ```
7981
8017
 
8018
+ #### Paginated Refined Table
8019
+
8020
+ [examples/paginated_refined_table.rb](examples/paginated_refined_table.rb)
8021
+
8022
+ Run with this command from the root of the project if you cloned the project:
8023
+
8024
+ ```
8025
+ ruby -r './lib/glimmer-dsl-libui' examples/paginated_refined_table.rb
8026
+ ```
8027
+
8028
+ Run with this command if you installed the [Ruby gem](https://rubygems.org/gems/glimmer-dsl-libui):
8029
+
8030
+ ```
8031
+ ruby -r glimmer-dsl-libui -e "require 'examples/paginated_refined_table'"
8032
+ ```
8033
+
8034
+ Mac | Windows | Linux
8035
+ ----|---------|------
8036
+ ![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)
8037
+
8038
+ New [Glimmer DSL for LibUI](https://rubygems.org/gems/glimmer-dsl-libui) Version:
8039
+
8040
+ ```ruby
8041
+ require 'glimmer-dsl-libui'
8042
+
8043
+ class PaginatedRefinedTable
8044
+ Contact = Struct.new(:name, :email, :phone, :city, :state)
8045
+
8046
+ include Glimmer::LibUI::Application
8047
+
8048
+ NAMES_FIRST = %w[
8049
+ Liam
8050
+ Noah
8051
+ William
8052
+ James
8053
+ Oliver
8054
+ Benjamin
8055
+ Elijah
8056
+ Lucas
8057
+ Mason
8058
+ Logan
8059
+ Alexander
8060
+ Ethan
8061
+ Jacob
8062
+ Michael
8063
+ Daniel
8064
+ Henry
8065
+ Jackson
8066
+ Sebastian
8067
+ Aiden
8068
+ Matthew
8069
+ Samuel
8070
+ David
8071
+ Joseph
8072
+ Carter
8073
+ Owen
8074
+ Wyatt
8075
+ John
8076
+ Jack
8077
+ Luke
8078
+ Jayden
8079
+ Dylan
8080
+ Grayson
8081
+ Levi
8082
+ Isaac
8083
+ Gabriel
8084
+ Julian
8085
+ Mateo
8086
+ Anthony
8087
+ Jaxon
8088
+ Lincoln
8089
+ Joshua
8090
+ Christopher
8091
+ Andrew
8092
+ Theodore
8093
+ Caleb
8094
+ Ryan
8095
+ Asher
8096
+ Nathan
8097
+ Thomas
8098
+ Leo
8099
+ Isaiah
8100
+ Charles
8101
+ Josiah
8102
+ Hudson
8103
+ Christian
8104
+ Hunter
8105
+ Connor
8106
+ Eli
8107
+ Ezra
8108
+ Aaron
8109
+ Landon
8110
+ Adrian
8111
+ Jonathan
8112
+ Nolan
8113
+ Jeremiah
8114
+ Easton
8115
+ Elias
8116
+ Colton
8117
+ Cameron
8118
+ Carson
8119
+ Robert
8120
+ Angel
8121
+ Maverick
8122
+ Nicholas
8123
+ Dominic
8124
+ Jaxson
8125
+ Greyson
8126
+ Adam
8127
+ Ian
8128
+ Austin
8129
+ Santiago
8130
+ Jordan
8131
+ Cooper
8132
+ Brayden
8133
+ Roman
8134
+ Evan
8135
+ Ezekiel
8136
+ Xaviar
8137
+ Jose
8138
+ Jace
8139
+ Jameson
8140
+ Leonardo
8141
+ Axel
8142
+ Everett
8143
+ Kayden
8144
+ Miles
8145
+ Sawyer
8146
+ Jason
8147
+ Emma
8148
+ Olivia
8149
+ Bartholomew
8150
+ Corey
8151
+ Danielle
8152
+ Eva
8153
+ Felicity
8154
+ ]
8155
+
8156
+ NAMES_LAST = %w[
8157
+ Smith
8158
+ Johnson
8159
+ Williams
8160
+ Brown
8161
+ Jones
8162
+ Miller
8163
+ Davis
8164
+ Wilson
8165
+ Anderson
8166
+ Taylor
8167
+ George
8168
+ Harrington
8169
+ Iverson
8170
+ Jackson
8171
+ Korby
8172
+ Levinson
8173
+ ]
8174
+
8175
+ CITIES = [
8176
+ 'Bellesville',
8177
+ 'Lombardia',
8178
+ 'Steepleton',
8179
+ 'Deerenstein',
8180
+ 'Schwartz',
8181
+ 'Hollandia',
8182
+ 'Saint Pete',
8183
+ 'Grandville',
8184
+ 'London',
8185
+ 'Berlin',
8186
+ 'Elktown',
8187
+ 'Paris',
8188
+ 'Garrison',
8189
+ 'Muncy',
8190
+ 'St Louis',
8191
+ ]
8192
+
8193
+ STATES = [ 'AK', 'AL', 'AR', 'AZ', 'CA', 'CO', 'CT', 'DC', 'DE', 'FL', 'GA',
8194
+ 'HI', 'IA', 'ID', 'IL', 'IN', 'KS', 'KY', 'LA', 'MA', 'MD', 'ME',
8195
+ 'MI', 'MN', 'MO', 'MS', 'MT', 'NC', 'ND', 'NE', 'NH', 'NJ', 'NM',
8196
+ 'NV', 'NY', 'OH', 'OK', 'OR', 'PA', 'RI', 'SC', 'SD', 'TN', 'TX',
8197
+ 'UT', 'VA', 'VT', 'WA', 'WI', 'WV', 'WY']
8198
+
8199
+ attr_accessor :contacts, :name, :email, :phone, :city, :state, :filter_value, :index
8200
+
8201
+ before_body do
8202
+ @contacts = 50_000.times.map do |n|
8203
+ n += 1
8204
+ first_name = NAMES_FIRST.sample
8205
+ last_name = NAMES_LAST.sample
8206
+ city = CITIES.sample
8207
+ state = STATES.sample
8208
+ Contact.new("#{first_name} #{last_name}", "#{first_name.downcase}#{n}@#{last_name.downcase}.com", '555-555-5555', city, state)
8209
+ end
8210
+ end
8211
+
8212
+ body {
8213
+ window("50,000 Paginated Contacts", 600, 700) {
8214
+ margined true
8215
+
8216
+ vertical_box {
8217
+ form {
8218
+ stretchy false
8219
+
8220
+ entry {
8221
+ label 'Name'
8222
+ text <=> [self, :name] # bidirectional data-binding between entry text and self.name
8223
+ }
8224
+
8225
+ entry {
8226
+ label 'Email'
8227
+ text <=> [self, :email]
8228
+ }
8229
+
8230
+ entry {
8231
+ label 'Phone'
8232
+ text <=> [self, :phone]
8233
+ }
8234
+
8235
+ entry {
8236
+ label 'City'
8237
+ text <=> [self, :city]
8238
+ }
8239
+
8240
+ entry {
8241
+ label 'State'
8242
+ text <=> [self, :state]
8243
+ }
8244
+ }
8245
+
8246
+ button('Save Contact') {
8247
+ stretchy false
8248
+
8249
+ on_clicked do
8250
+ new_row = [name, email, phone, city, state]
8251
+ if new_row.map(&:to_s).include?('')
8252
+ msg_box_error('Validation Error!', 'All fields are required! Please make sure to enter a value for all fields.')
8253
+ else
8254
+ @contacts << Contact.new(*new_row) # automatically inserts a row into the table due to explicit data-binding
8255
+ @unfiltered_contacts = @contacts.dup
8256
+ self.name = '' # automatically clears name entry through explicit data-binding
8257
+ self.email = ''
8258
+ self.phone = ''
8259
+ self.city = ''
8260
+ self.state = ''
8261
+ end
8262
+ end
8263
+ }
8264
+
8265
+ refined_table(
8266
+ model_array: contacts,
8267
+ table_columns: {
8268
+ 'Name' => :text,
8269
+ 'Email' => :text,
8270
+ 'Phone' => :text,
8271
+ 'City' => :text,
8272
+ 'State' => :text,
8273
+ },
8274
+ table_editable: true,
8275
+ per_page: 20,
8276
+ )
8277
+ }
8278
+ }
8279
+ }
8280
+ end
8281
+
8282
+ PaginatedRefinedTable.launch
8283
+ ```
8284
+
7982
8285
  #### Grid
7983
8286
 
7984
8287
  [examples/grid.rb](examples/grid.rb)
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.5.15
1
+ 0.5.16
@@ -0,0 +1,242 @@
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
10
+ Noah
11
+ William
12
+ James
13
+ Oliver
14
+ Benjamin
15
+ Elijah
16
+ Lucas
17
+ Mason
18
+ Logan
19
+ Alexander
20
+ Ethan
21
+ Jacob
22
+ Michael
23
+ Daniel
24
+ Henry
25
+ Jackson
26
+ Sebastian
27
+ Aiden
28
+ Matthew
29
+ Samuel
30
+ David
31
+ Joseph
32
+ Carter
33
+ Owen
34
+ Wyatt
35
+ John
36
+ Jack
37
+ Luke
38
+ Jayden
39
+ Dylan
40
+ Grayson
41
+ Levi
42
+ Isaac
43
+ Gabriel
44
+ Julian
45
+ Mateo
46
+ Anthony
47
+ Jaxon
48
+ Lincoln
49
+ Joshua
50
+ Christopher
51
+ Andrew
52
+ Theodore
53
+ Caleb
54
+ Ryan
55
+ Asher
56
+ Nathan
57
+ Thomas
58
+ Leo
59
+ Isaiah
60
+ Charles
61
+ Josiah
62
+ Hudson
63
+ Christian
64
+ Hunter
65
+ Connor
66
+ Eli
67
+ Ezra
68
+ Aaron
69
+ Landon
70
+ Adrian
71
+ Jonathan
72
+ Nolan
73
+ Jeremiah
74
+ Easton
75
+ Elias
76
+ Colton
77
+ Cameron
78
+ Carson
79
+ Robert
80
+ Angel
81
+ Maverick
82
+ Nicholas
83
+ Dominic
84
+ Jaxson
85
+ Greyson
86
+ Adam
87
+ Ian
88
+ Austin
89
+ Santiago
90
+ Jordan
91
+ Cooper
92
+ Brayden
93
+ Roman
94
+ Evan
95
+ Ezekiel
96
+ Xaviar
97
+ Jose
98
+ Jace
99
+ Jameson
100
+ Leonardo
101
+ Axel
102
+ Everett
103
+ Kayden
104
+ Miles
105
+ Sawyer
106
+ Jason
107
+ Emma
108
+ Olivia
109
+ Bartholomew
110
+ Corey
111
+ Danielle
112
+ Eva
113
+ Felicity
114
+ ]
115
+
116
+ NAMES_LAST = %w[
117
+ Smith
118
+ Johnson
119
+ Williams
120
+ Brown
121
+ Jones
122
+ Miller
123
+ Davis
124
+ Wilson
125
+ Anderson
126
+ Taylor
127
+ George
128
+ Harrington
129
+ Iverson
130
+ Jackson
131
+ Korby
132
+ Levinson
133
+ ]
134
+
135
+ CITIES = [
136
+ 'Bellesville',
137
+ 'Lombardia',
138
+ 'Steepleton',
139
+ 'Deerenstein',
140
+ 'Schwartz',
141
+ 'Hollandia',
142
+ 'Saint Pete',
143
+ 'Grandville',
144
+ 'London',
145
+ 'Berlin',
146
+ 'Elktown',
147
+ 'Paris',
148
+ 'Garrison',
149
+ 'Muncy',
150
+ 'St Louis',
151
+ ]
152
+
153
+ STATES = [ 'AK', 'AL', 'AR', 'AZ', 'CA', 'CO', 'CT', 'DC', 'DE', 'FL', 'GA',
154
+ 'HI', 'IA', 'ID', 'IL', 'IN', 'KS', 'KY', 'LA', 'MA', 'MD', 'ME',
155
+ 'MI', 'MN', 'MO', 'MS', 'MT', 'NC', 'ND', 'NE', 'NH', 'NJ', 'NM',
156
+ 'NV', 'NY', 'OH', 'OK', 'OR', 'PA', 'RI', 'SC', 'SD', 'TN', 'TX',
157
+ 'UT', 'VA', 'VT', 'WA', 'WI', 'WV', 'WY']
158
+
159
+ attr_accessor :contacts, :name, :email, :phone, :city, :state, :filter_value, :index
160
+
161
+ before_body do
162
+ @contacts = 50_000.times.map do |n|
163
+ n += 1
164
+ first_name = NAMES_FIRST.sample
165
+ last_name = NAMES_LAST.sample
166
+ city = CITIES.sample
167
+ state = STATES.sample
168
+ Contact.new("#{first_name} #{last_name}", "#{first_name.downcase}#{n}@#{last_name.downcase}.com", '555-555-5555', city, state)
169
+ end
170
+ end
171
+
172
+ body {
173
+ window("50,000 Paginated Contacts", 600, 700) {
174
+ margined true
175
+
176
+ vertical_box {
177
+ form {
178
+ stretchy false
179
+
180
+ entry {
181
+ label 'Name'
182
+ text <=> [self, :name] # bidirectional data-binding between entry text and self.name
183
+ }
184
+
185
+ entry {
186
+ label 'Email'
187
+ text <=> [self, :email]
188
+ }
189
+
190
+ entry {
191
+ label 'Phone'
192
+ text <=> [self, :phone]
193
+ }
194
+
195
+ entry {
196
+ label 'City'
197
+ text <=> [self, :city]
198
+ }
199
+
200
+ entry {
201
+ label 'State'
202
+ text <=> [self, :state]
203
+ }
204
+ }
205
+
206
+ button('Save Contact') {
207
+ stretchy false
208
+
209
+ on_clicked do
210
+ new_row = [name, email, phone, city, state]
211
+ if new_row.map(&:to_s).include?('')
212
+ msg_box_error('Validation Error!', 'All fields are required! Please make sure to enter a value for all fields.')
213
+ else
214
+ @contacts << Contact.new(*new_row) # automatically inserts a row into the table due to explicit data-binding
215
+ @unfiltered_contacts = @contacts.dup
216
+ self.name = '' # automatically clears name entry through explicit data-binding
217
+ self.email = ''
218
+ self.phone = ''
219
+ self.city = ''
220
+ self.state = ''
221
+ end
222
+ end
223
+ }
224
+
225
+ refined_table(
226
+ model_array: contacts,
227
+ table_columns: {
228
+ 'Name' => {text: {editable: false}},
229
+ 'Email' => :text,
230
+ 'Phone' => :text,
231
+ 'City' => :text,
232
+ 'State' => :text,
233
+ },
234
+ table_editable: true,
235
+ per_page: 20,
236
+ )
237
+ }
238
+ }
239
+ }
240
+ end
241
+
242
+ 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,153 @@
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
+
10
+ attr_accessor :filtered_model_array, :filter_query, :filter_query_page_stack, :paginated_model_array
11
+
12
+ before_body do
13
+ @filter_query = ''
14
+ @filter_query_page_stack = {}
15
+ @filtered_model_array = model_array.dup
16
+ @filtered_model_array_stack = {@filter_query => @filtered_model_array}
17
+ paginate_model_array
18
+ end
19
+
20
+ body {
21
+ vertical_box {
22
+ table_filter
23
+
24
+ table_paginator
25
+
26
+ @table = table {
27
+ table_columns.each do |column_name, column_details|
28
+ editable_value = on_clicked_value = nil
29
+ if column_details.is_a?(Symbol) || column_details.is_a?(String)
30
+ column_type = column_details
31
+ elsif column_details.is_a?(Hash)
32
+ column_type = column_details.keys.first
33
+ editable_value = column_details.values.first[:editable] || column_details.values.first['editable']
34
+ on_clicked_value = column_details.values.first[:on_clicked] || column_details.values.first['on_clicked']
35
+ end
36
+
37
+ send("#{column_type}_column", column_name) {
38
+ editable editable_value unless editable_value.nil?
39
+ on_clicked(&on_clicked_value) unless on_clicked_value.nil?
40
+ }
41
+ end
42
+
43
+ editable table_editable
44
+ cell_rows <=> [self, :paginated_model_array]
45
+ }
46
+ }
47
+ }
48
+
49
+ def table_filter
50
+ search_entry {
51
+ stretchy false
52
+ text <=> [self, :filter_query,
53
+ before_write: ->(new_filter_query) {
54
+ if new_filter_query != filter_query
55
+ if !@filtered_model_array_stack.key?(new_filter_query)
56
+ @filtered_model_array_stack[new_filter_query] = model_array.dup.filter do |model|
57
+ @table.expand([model])[0].any? do |attribute_value|
58
+ attribute_value.to_s.downcase.include?(new_filter_query.downcase)
59
+ end
60
+ end
61
+ end
62
+ @filtered_model_array = @filtered_model_array_stack[new_filter_query]
63
+ if new_filter_query.size > filter_query.size
64
+ @filter_query_page_stack[filter_query] = page
65
+ end
66
+ self.page = @filter_query_page_stack[new_filter_query] || correct_page(page)
67
+ paginate_model_array
68
+ end
69
+ }
70
+ ]
71
+ }
72
+ end
73
+
74
+ def table_paginator
75
+ horizontal_box {
76
+ stretchy false
77
+
78
+ button('<<') {
79
+ on_clicked do
80
+ unless self.page == 0
81
+ self.page = 1
82
+ paginate_model_array
83
+ end
84
+ end
85
+ }
86
+ button('<') {
87
+ on_clicked do
88
+ unless self.page == 0
89
+ self.page = [page - 1, 1].max
90
+ paginate_model_array
91
+ end
92
+ end
93
+ }
94
+ entry {
95
+ text <=> [self, :page,
96
+ on_read: :to_s,
97
+ on_write: ->(val) { correct_page(val.to_i) },
98
+ after_write: ->(val) { paginate_model_array },
99
+ ]
100
+ }
101
+ button('>') {
102
+ on_clicked do
103
+ unless self.page == 0
104
+ self.page = [page + 1, page_count].min
105
+ paginate_model_array
106
+ end
107
+ end
108
+ }
109
+ button('>>') {
110
+ on_clicked do
111
+ unless self.page == 0
112
+ self.page = page_count
113
+ paginate_model_array
114
+ end
115
+ end
116
+ }
117
+ }
118
+ end
119
+
120
+ def paginate_model_array
121
+ self.paginated_model_array = filtered_model_array[index, limit]
122
+ end
123
+
124
+ def index
125
+ [per_page * (page - 1), 0].max
126
+ end
127
+
128
+ def limit
129
+ [(filtered_model_array.count - index), per_page].min
130
+ end
131
+
132
+ def page_count
133
+ (filtered_model_array.count.to_f / per_page.to_f).ceil
134
+ end
135
+
136
+ def correct_page(page)
137
+ [[page, 1].max, page_count].min
138
+ end
139
+
140
+ # Ensure proxying properties to @table if body_root (vertical_box) doesn't support them
141
+
142
+ def respond_to?(method_name, *args, &block)
143
+ super || @table&.respond_to?(method_name, *args, &block)
144
+ end
145
+
146
+ def method_missing(method_name, *args, &block)
147
+ if @table&.respond_to?(method_name, *args, &block)
148
+ @table&.send(method_name, *args, &block)
149
+ else
150
+ super
151
+ end
152
+ end
153
+ 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.5.15
4
+ version: 0.5.16
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-07-31 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