glimmer-dsl-libui 0.5.15 → 0.5.18

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: 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