glimmer-dsl-libui 0.5.20 → 0.5.21
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +7 -0
- data/README.md +4 -3
- data/VERSION +1 -1
- data/glimmer-dsl-libui.gemspec +0 -0
- data/lib/glimmer/libui/custom_control/code_area.rb +87 -58
- data/lib/glimmer/libui/custom_control/refined_table.rb +250 -172
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 1d3ae4d7f5fd6c3c531509482ba3ef7711b91f8cf9ae2441b233d25bc9dc266e
|
4
|
+
data.tar.gz: 9232fe8d0f5a792f2410b8c49f9c6ee0261487c3fd144dce76a7aa3ef83d5571
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 79b089d01f618868dd6b18905564b03ccf883bbdbd577009b27a54cfb65ba23ef7de183890b63fe9eac6f2d837f8eae410d0e21d556cdf22e2b6175e32438724
|
7
|
+
data.tar.gz: cf4632a603e050ea8f06fe5fa6c53da4e65ab0998a3335ce34b428eaab876ddb8b0e364e474cdc8e24473d4d9c171aa217dd8c86da8af79fd3977303e41638c3
|
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,12 @@
|
|
1
1
|
# Change Log
|
2
2
|
|
3
|
+
## 0.5.21
|
4
|
+
|
5
|
+
- Support `refined_table` AND-based filtering by treating multiple words as WORD1 AND WORD2, etc...
|
6
|
+
- Support `refined_table` exact term filtering by surrounding word by double-quotes
|
7
|
+
- Support `refined_table` column-specific term (column_name:term) filtering by concatenating column name (with or without double quotes) with column value (with or without double quotes) using colon
|
8
|
+
- Support `refined_table` `filter` option that should be a `lambda` that accepts `text, query` args and returns `true` or `false` for whether the `text` matches the `query` (`Glimmer::LibUI::CustomControl::RefinedTable::FILTER_DEFAULT` is the default value)
|
9
|
+
|
3
10
|
## 0.5.20
|
4
11
|
|
5
12
|
- Fix issue with selecting a `radio_menu_item` causing a crash when included with other types of `menu_item` under a `menu`
|
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.
|
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.21
|
2
2
|
## Prerequisite-Free Ruby Desktop Development GUI Library
|
3
3
|
[](http://badge.fury.io/rb/glimmer-dsl-libui)
|
4
4
|
[](https://gitter.im/AndyObtiva/glimmer?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
|
@@ -538,7 +538,7 @@ gem install glimmer-dsl-libui
|
|
538
538
|
Or install via Bundler `Gemfile`:
|
539
539
|
|
540
540
|
```ruby
|
541
|
-
gem 'glimmer-dsl-libui', '~> 0.5.
|
541
|
+
gem 'glimmer-dsl-libui', '~> 0.5.21'
|
542
542
|
```
|
543
543
|
|
544
544
|
Test that installation worked by running the [Meta-Example](#examples):
|
@@ -720,7 +720,7 @@ Keyword(Args) | Properties | Listeners
|
|
720
720
|
`quit_menu_item` | None | `on_clicked`
|
721
721
|
`radio_buttons` | `selected` (`Integer`) | `on_selected`
|
722
722
|
`rectangle(x as Numeric, y as Numeric, width as Numeric, height as Numeric)` | `x` (`Numeric`), `y` (`Numeric`), `width` (`Numeric`), `height` (`Numeric`) | None
|
723
|
-
`refined_table` | `model_array` (`Array`), `table_columns` (`Hash`), `table_editable` (Boolean), `per_page` (`Integer`), `page` (`Integer`), `visible_page_count` (Boolean), `filter_query` (`String`) | (EARLY ALPHA UNSTABLE API / CHECK SOURCE CODE FOR DETAILS)
|
723
|
+
`refined_table` | `model_array` (`Array`), `table_columns` (`Hash`), `table_editable` (Boolean), `per_page` (`Integer`), `page` (`Integer`), `visible_page_count` (Boolean), `filter_query` (`String`), `filter` (Lambda) | (EARLY ALPHA UNSTABLE API / CHECK SOURCE CODE FOR DETAILS)
|
724
724
|
`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)`
|
725
725
|
`search_entry` | `read_only` (Boolean), `text` (`String`) | `on_changed`
|
726
726
|
`separator_menu_item` | None | None
|
@@ -967,6 +967,7 @@ Options (passed as kwargs hash):
|
|
967
967
|
- `per_page` (`Integer`)
|
968
968
|
- `page` (`Integer`)
|
969
969
|
- `visible_page_count` (Boolean) [default: `false`]: shows "of PAGE_COUNT pages" after page `entry` field
|
970
|
+
- `filter` (Lambda) [default: `Glimmer::LibUI::CustomControl::RefinedTable::FILTER_DEFAULT`]: enables setting custom filter that accepts `row_hash` (mapping table column names to row values) and `query` string as arguments, and it is supposed to return `true` or `false` for whether to show a row or filter it out.
|
970
971
|
|
971
972
|
API:
|
972
973
|
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.5.
|
1
|
+
0.5.21
|
data/glimmer-dsl-libui.gemspec
CHANGED
Binary file
|
@@ -1,65 +1,94 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
1
|
+
# Copyright (c) 2021-2022 Andy Maleh
|
2
|
+
#
|
3
|
+
# Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
# a copy of this software and associated documentation files (the
|
5
|
+
# "Software"), to deal in the Software without restriction, including
|
6
|
+
# without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
# distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
# permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
# the following conditions:
|
10
|
+
#
|
11
|
+
# The above copyright notice and this permission notice shall be
|
12
|
+
# included in all copies or substantial portions of the Software.
|
13
|
+
#
|
14
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
21
|
+
|
22
|
+
require 'glimmer/libui/custom_control'
|
23
|
+
|
24
|
+
module Glimmer
|
25
|
+
module LibUI
|
26
|
+
module CustomControl
|
27
|
+
class CodeArea
|
28
|
+
class << self
|
29
|
+
def languages
|
30
|
+
require 'rouge'
|
31
|
+
Rouge::Lexer.all.map {|lexer| lexer.tag}.sort
|
32
|
+
end
|
33
|
+
|
34
|
+
def lexers
|
35
|
+
require 'rouge'
|
36
|
+
Rouge::Lexer.all.sort_by(&:title)
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
include Glimmer::LibUI::CustomControl
|
41
|
+
|
42
|
+
REGEX_COLOR_HEX6 = /^#([0-9a-f]{2})([0-9a-f]{2})([0-9a-f]{2})$/
|
29
43
|
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
44
|
+
option :language, default: 'ruby'
|
45
|
+
option :theme, default: 'glimmer'
|
46
|
+
option :code
|
47
|
+
|
48
|
+
body {
|
49
|
+
area {
|
50
|
+
rectangle(0, 0, 8000, 8000) {
|
51
|
+
fill :white
|
52
|
+
}
|
53
|
+
text {
|
54
|
+
default_font family: OS.mac? ? 'Consolas' : 'Courier', size: 13, weight: :medium, italic: :normal, stretch: :normal
|
55
|
+
|
56
|
+
syntax_highlighting(code).each do |token|
|
57
|
+
style_data = Rouge::Theme.find(theme).new.style_for(token[:token_type])
|
58
|
+
|
59
|
+
string(token[:token_text]) {
|
60
|
+
color style_data[:fg] || :black
|
61
|
+
background style_data[:bg] || :white
|
62
|
+
}
|
63
|
+
end
|
64
|
+
}
|
36
65
|
}
|
66
|
+
}
|
67
|
+
|
68
|
+
def lexer
|
69
|
+
require 'rouge'
|
70
|
+
require 'glimmer-dsl-libui/ext/rouge/theme/glimmer'
|
71
|
+
# TODO Try to use Rouge::Lexer.find_fancy('guess', code) in the future to guess the language or otherwise detect it from file extension
|
72
|
+
@lexer ||= Rouge::Lexer.find_fancy(language)
|
73
|
+
@lexer ||= Rouge::Lexer.find_fancy('ruby') # default to Ruby if no lexer is found
|
74
|
+
end
|
75
|
+
|
76
|
+
def syntax_highlighting(text)
|
77
|
+
return [] if text.to_s.strip.empty?
|
78
|
+
@syntax_highlighting ||= {}
|
79
|
+
unless @syntax_highlighting.keys.include?(text)
|
80
|
+
lex = lexer.lex(text).to_a
|
81
|
+
text_size = 0
|
82
|
+
@syntax_highlighting[text] = lex.map do |pair|
|
83
|
+
{token_type: pair.first, token_text: pair.last}
|
84
|
+
end.each do |hash|
|
85
|
+
hash[:token_index] = text_size
|
86
|
+
text_size += hash[:token_text].size
|
87
|
+
end
|
88
|
+
end
|
89
|
+
@syntax_highlighting[text]
|
37
90
|
end
|
38
|
-
}
|
39
|
-
}
|
40
|
-
}
|
41
|
-
|
42
|
-
def lexer
|
43
|
-
require 'rouge'
|
44
|
-
require 'glimmer-dsl-libui/ext/rouge/theme/glimmer'
|
45
|
-
# TODO Try to use Rouge::Lexer.find_fancy('guess', code) in the future to guess the language or otherwise detect it from file extension
|
46
|
-
@lexer ||= Rouge::Lexer.find_fancy(language)
|
47
|
-
@lexer ||= Rouge::Lexer.find_fancy('ruby') # default to Ruby if no lexer is found
|
48
|
-
end
|
49
|
-
|
50
|
-
def syntax_highlighting(text)
|
51
|
-
return [] if text.to_s.strip.empty?
|
52
|
-
@syntax_highlighting ||= {}
|
53
|
-
unless @syntax_highlighting.keys.include?(text)
|
54
|
-
lex = lexer.lex(text).to_a
|
55
|
-
text_size = 0
|
56
|
-
@syntax_highlighting[text] = lex.map do |pair|
|
57
|
-
{token_type: pair.first, token_text: pair.last}
|
58
|
-
end.each do |hash|
|
59
|
-
hash[:token_index] = text_size
|
60
|
-
text_size += hash[:token_text].size
|
61
91
|
end
|
62
92
|
end
|
63
|
-
@syntax_highlighting[text]
|
64
93
|
end
|
65
94
|
end
|
@@ -1,192 +1,270 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
filter_model_array
|
22
|
-
|
23
|
-
observe(self, :model_array) do
|
24
|
-
init_model_array
|
25
|
-
end
|
26
|
-
|
27
|
-
observe(self, :filter_query) do
|
28
|
-
filter_model_array
|
29
|
-
end
|
30
|
-
end
|
31
|
-
|
32
|
-
body {
|
33
|
-
vertical_box {
|
34
|
-
table_filter
|
1
|
+
# Copyright (c) 2021-2022 Andy Maleh
|
2
|
+
#
|
3
|
+
# Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
# a copy of this software and associated documentation files (the
|
5
|
+
# "Software"), to deal in the Software without restriction, including
|
6
|
+
# without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
# distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
# permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
# the following conditions:
|
10
|
+
#
|
11
|
+
# The above copyright notice and this permission notice shall be
|
12
|
+
# included in all copies or substantial portions of the Software.
|
13
|
+
#
|
14
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
35
21
|
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
22
|
+
require 'csv'
|
23
|
+
require 'facets/string/underscore'
|
24
|
+
|
25
|
+
require 'glimmer/libui/custom_control'
|
26
|
+
|
27
|
+
module Glimmer
|
28
|
+
module LibUI
|
29
|
+
module CustomControl
|
30
|
+
class RefinedTable
|
31
|
+
include Glimmer::LibUI::CustomControl
|
32
|
+
|
33
|
+
FILTER_DEFAULT = lambda do |row_hash, query|
|
34
|
+
text = row_hash.values.map(&:downcase).join(' ')
|
35
|
+
if query != @last_query
|
36
|
+
@last_query = query
|
37
|
+
@query_words = []
|
38
|
+
query_text = query.strip
|
39
|
+
until query_text.empty?
|
40
|
+
exact_term_double_quoted_regexp = /"[^"]+"/
|
41
|
+
specific_column_double_quoted_column_name_regexp = /"[^":]+":[^": ]+/
|
42
|
+
specific_column_double_quoted_column_value_regexp = /[^": ]+:"[^":]+"/
|
43
|
+
specific_column_double_quoted_column_name_and_value_regexp = /"[^":]+":"[^":]+"/
|
44
|
+
single_word_regexp = /\S+/
|
45
|
+
query_match = (query_text + ' ').match(/^(#{exact_term_double_quoted_regexp}|#{specific_column_double_quoted_column_name_regexp}|#{specific_column_double_quoted_column_value_regexp}|#{specific_column_double_quoted_column_name_and_value_regexp}|#{single_word_regexp})\s+/)
|
46
|
+
if query_match && query_match[1]
|
47
|
+
query_word = query_match[1]
|
48
|
+
query_text = query_text.sub(query_word, '').strip
|
49
|
+
query_word = query_word.sub(/^"/, '').sub(/"$/, '') if query_word.start_with?('"') && query_word.end_with?('"') && !query_word.include?(':')
|
50
|
+
@query_words << query_word
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
@query_words.all? do |word|
|
55
|
+
if word.include?(':')
|
56
|
+
column_name, column_value = word.split(':')
|
57
|
+
column_value = column_value.to_s
|
58
|
+
column_name = column_name.sub(/^"/, '').sub(/"$/, '') if column_name.start_with?('"') && column_name.end_with?('"')
|
59
|
+
column_value = column_value.sub(/^"/, '').sub(/"$/, '') if column_value.start_with?('"') && column_value.end_with?('"')
|
60
|
+
column_human_name = row_hash.keys.find do |table_column_name|
|
61
|
+
table_column_name.underscore.start_with?(column_name.underscore)
|
62
|
+
end
|
63
|
+
if column_human_name
|
64
|
+
column_value_words = [column_value.downcase.split].flatten
|
65
|
+
column_value_words.all? do |column_value_word|
|
66
|
+
row_hash[column_human_name].downcase.include?(column_value_word)
|
67
|
+
end
|
68
|
+
else
|
69
|
+
text.downcase.include?(word.downcase)
|
70
|
+
end
|
71
|
+
else
|
72
|
+
text.downcase.include?(word.downcase)
|
73
|
+
end
|
47
74
|
end
|
48
|
-
|
49
|
-
send("#{column_type}_column", column_name) {
|
50
|
-
editable editable_value unless editable_value.nil?
|
51
|
-
on_clicked(&on_clicked_value) unless on_clicked_value.nil?
|
52
|
-
}
|
53
75
|
end
|
54
|
-
|
55
|
-
editable table_editable
|
56
|
-
cell_rows <=> [self, :refined_model_array]
|
57
|
-
}
|
58
|
-
}
|
59
|
-
}
|
60
|
-
|
61
|
-
def table_filter
|
62
|
-
search_entry {
|
63
|
-
stretchy false
|
64
|
-
text <=> [self, :filter_query]
|
65
|
-
}
|
66
|
-
end
|
67
|
-
|
68
|
-
def table_paginator
|
69
|
-
horizontal_box {
|
70
|
-
stretchy false
|
71
|
-
|
72
|
-
button('<<') {
|
73
|
-
enabled <= [self, :page, on_read: ->(val) {val > 1}]
|
74
76
|
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
77
|
+
option :model_array, default: []
|
78
|
+
option :table_columns, default: []
|
79
|
+
option :table_editable, default: false
|
80
|
+
option :per_page, default: 10
|
81
|
+
option :page, default: 1
|
82
|
+
option :visible_page_count, default: false
|
83
|
+
option :filter_query, default: ''
|
84
|
+
option :filter, default: FILTER_DEFAULT
|
85
|
+
|
86
|
+
attr_accessor :filtered_model_array # filtered model array (intermediary, non-paginated)
|
87
|
+
attr_accessor :refined_model_array # paginated filtered model array
|
88
|
+
attr_reader :table_proxy
|
89
|
+
|
90
|
+
before_body do
|
91
|
+
init_model_array
|
80
92
|
end
|
81
|
-
}
|
82
|
-
|
83
|
-
button('<') {
|
84
|
-
enabled <= [self, :page, on_read: ->(val) {val > 1}]
|
85
93
|
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
94
|
+
after_body do
|
95
|
+
filter_model_array
|
96
|
+
|
97
|
+
observe(self, :model_array) do
|
98
|
+
init_model_array
|
99
|
+
end
|
100
|
+
|
101
|
+
observe(self, :filter_query) do
|
102
|
+
filter_model_array
|
90
103
|
end
|
91
104
|
end
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
on_read: :to_s,
|
97
|
-
on_write: ->(val) { correct_page(val.to_i) },
|
98
|
-
after_write: ->(val) { paginate_model_array },
|
99
|
-
]
|
100
|
-
}
|
105
|
+
|
106
|
+
body {
|
107
|
+
vertical_box {
|
108
|
+
table_filter
|
101
109
|
|
102
|
-
|
103
|
-
|
104
|
-
|
110
|
+
table_paginator if page_count > 1
|
111
|
+
|
112
|
+
@table_proxy = table {
|
113
|
+
table_columns.each do |column_name, column_details|
|
114
|
+
editable_value = on_clicked_value = nil
|
115
|
+
if column_details.is_a?(Symbol) || column_details.is_a?(String)
|
116
|
+
column_type = column_details
|
117
|
+
elsif column_details.is_a?(Hash)
|
118
|
+
column_type = column_details.keys.first
|
119
|
+
editable_value = column_details.values.first[:editable] || column_details.values.first['editable']
|
120
|
+
on_clicked_value = column_details.values.first[:on_clicked] || column_details.values.first['on_clicked']
|
121
|
+
end
|
122
|
+
|
123
|
+
send("#{column_type}_column", column_name) {
|
124
|
+
editable editable_value unless editable_value.nil?
|
125
|
+
on_clicked(&on_clicked_value) unless on_clicked_value.nil?
|
126
|
+
}
|
127
|
+
end
|
128
|
+
|
129
|
+
editable table_editable
|
130
|
+
cell_rows <=> [self, :refined_model_array]
|
131
|
+
}
|
132
|
+
}
|
105
133
|
}
|
106
|
-
end
|
107
|
-
|
108
|
-
button('>') {
|
109
|
-
enabled <= [self, :page, on_read: ->(val) {val < page_count}]
|
110
134
|
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
135
|
+
def table_filter
|
136
|
+
search_entry {
|
137
|
+
stretchy false
|
138
|
+
text <=> [self, :filter_query]
|
139
|
+
}
|
116
140
|
end
|
117
|
-
}
|
118
|
-
|
119
|
-
button('>>') {
|
120
|
-
enabled <= [self, :page, on_read: ->(val) {val < page_count}]
|
121
141
|
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
142
|
+
def table_paginator
|
143
|
+
horizontal_box {
|
144
|
+
stretchy false
|
145
|
+
|
146
|
+
button('<<') {
|
147
|
+
enabled <= [self, :page, on_read: ->(val) {val > 1}]
|
148
|
+
|
149
|
+
on_clicked do
|
150
|
+
unless self.page == 0
|
151
|
+
self.page = 1
|
152
|
+
paginate_model_array
|
153
|
+
end
|
154
|
+
end
|
155
|
+
}
|
156
|
+
|
157
|
+
button('<') {
|
158
|
+
enabled <= [self, :page, on_read: ->(val) {val > 1}]
|
159
|
+
|
160
|
+
on_clicked do
|
161
|
+
unless self.page == 0
|
162
|
+
self.page = [page - 1, 1].max
|
163
|
+
paginate_model_array
|
164
|
+
end
|
165
|
+
end
|
166
|
+
}
|
167
|
+
|
168
|
+
entry {
|
169
|
+
text <=> [self, :page,
|
170
|
+
on_read: :to_s,
|
171
|
+
on_write: ->(val) { correct_page(val.to_i) },
|
172
|
+
after_write: ->(val) { paginate_model_array },
|
173
|
+
]
|
174
|
+
}
|
175
|
+
|
176
|
+
if visible_page_count
|
177
|
+
label {
|
178
|
+
text <= [self, :refined_model_array, on_read: ->(val) {"of #{page_count} pages"}]
|
179
|
+
}
|
180
|
+
end
|
181
|
+
|
182
|
+
button('>') {
|
183
|
+
enabled <= [self, :page, on_read: ->(val) {val < page_count}]
|
184
|
+
|
185
|
+
on_clicked do
|
186
|
+
unless self.page == 0
|
187
|
+
self.page = [page + 1, page_count].min
|
188
|
+
paginate_model_array
|
189
|
+
end
|
190
|
+
end
|
191
|
+
}
|
192
|
+
|
193
|
+
button('>>') {
|
194
|
+
enabled <= [self, :page, on_read: ->(val) {val < page_count}]
|
195
|
+
|
196
|
+
on_clicked do
|
197
|
+
unless self.page == 0
|
198
|
+
self.page = page_count
|
199
|
+
paginate_model_array
|
200
|
+
end
|
201
|
+
end
|
202
|
+
}
|
203
|
+
}
|
204
|
+
end
|
205
|
+
|
206
|
+
def init_model_array
|
207
|
+
@last_filter_query = nil
|
208
|
+
@filter_query_page_stack = {}
|
209
|
+
@filtered_model_array = model_array.dup
|
210
|
+
@filtered_model_array_stack = {'' => @filtered_model_array}
|
211
|
+
self.page = correct_page(page)
|
212
|
+
filter_model_array if @table_proxy
|
213
|
+
end
|
214
|
+
|
215
|
+
def filter_model_array
|
216
|
+
return unless (@last_filter_query.nil? || filter_query != @last_filter_query)
|
217
|
+
if !@filtered_model_array_stack.key?(filter_query)
|
218
|
+
table_column_names = @table_proxy.columns.map(&:name)
|
219
|
+
@filtered_model_array_stack[filter_query] = model_array.dup.filter do |model|
|
220
|
+
row_values = @table_proxy.expand([model])[0].map(&:to_s)
|
221
|
+
row_hash = Hash[table_column_names.zip(row_values)]
|
222
|
+
filter.call(row_hash, filter_query)
|
223
|
+
end
|
224
|
+
end
|
225
|
+
@filtered_model_array = @filtered_model_array_stack[filter_query]
|
226
|
+
if @last_filter_query.nil? || filter_query.size > @last_filter_query.size
|
227
|
+
@filter_query_page_stack[filter_query] = correct_page(page)
|
126
228
|
end
|
229
|
+
self.page = @filter_query_page_stack[filter_query] || correct_page(page)
|
230
|
+
paginate_model_array
|
231
|
+
@last_filter_query = filter_query
|
127
232
|
end
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
233
|
+
|
234
|
+
def paginate_model_array
|
235
|
+
self.refined_model_array = filtered_model_array[index, limit]
|
236
|
+
end
|
237
|
+
|
238
|
+
def index
|
239
|
+
[per_page * (page - 1), 0].max
|
240
|
+
end
|
241
|
+
|
242
|
+
def limit
|
243
|
+
[(filtered_model_array.count - index), per_page].min
|
244
|
+
end
|
245
|
+
|
246
|
+
def page_count
|
247
|
+
(filtered_model_array.count.to_f / per_page.to_f).ceil
|
248
|
+
end
|
249
|
+
|
250
|
+
def correct_page(page)
|
251
|
+
[[page, 1].max, page_count].min
|
252
|
+
end
|
253
|
+
|
254
|
+
# Ensure proxying properties to @table_proxy if body_root (vertical_box) doesn't support them
|
255
|
+
|
256
|
+
def respond_to?(method_name, *args, &block)
|
257
|
+
super || @table_proxy&.respond_to?(method_name, *args, &block)
|
258
|
+
end
|
259
|
+
|
260
|
+
def method_missing(method_name, *args, &block)
|
261
|
+
if @table_proxy&.respond_to?(method_name, *args, &block)
|
262
|
+
@table_proxy&.send(method_name, *args, &block)
|
263
|
+
else
|
264
|
+
super
|
265
|
+
end
|
147
266
|
end
|
148
267
|
end
|
149
268
|
end
|
150
|
-
@filtered_model_array = @filtered_model_array_stack[filter_query]
|
151
|
-
if @last_filter_query.nil? || filter_query.size > @last_filter_query.size
|
152
|
-
@filter_query_page_stack[filter_query] = correct_page(page)
|
153
|
-
end
|
154
|
-
self.page = @filter_query_page_stack[filter_query] || correct_page(page)
|
155
|
-
paginate_model_array
|
156
|
-
@last_filter_query = filter_query
|
157
|
-
end
|
158
|
-
|
159
|
-
def paginate_model_array
|
160
|
-
self.refined_model_array = filtered_model_array[index, limit]
|
161
|
-
end
|
162
|
-
|
163
|
-
def index
|
164
|
-
[per_page * (page - 1), 0].max
|
165
|
-
end
|
166
|
-
|
167
|
-
def limit
|
168
|
-
[(filtered_model_array.count - index), per_page].min
|
169
|
-
end
|
170
|
-
|
171
|
-
def page_count
|
172
|
-
(filtered_model_array.count.to_f / per_page.to_f).ceil
|
173
|
-
end
|
174
|
-
|
175
|
-
def correct_page(page)
|
176
|
-
[[page, 1].max, page_count].min
|
177
|
-
end
|
178
|
-
|
179
|
-
# Ensure proxying properties to @table_proxy if body_root (vertical_box) doesn't support them
|
180
|
-
|
181
|
-
def respond_to?(method_name, *args, &block)
|
182
|
-
super || @table_proxy&.respond_to?(method_name, *args, &block)
|
183
|
-
end
|
184
|
-
|
185
|
-
def method_missing(method_name, *args, &block)
|
186
|
-
if @table_proxy&.respond_to?(method_name, *args, &block)
|
187
|
-
@table_proxy&.send(method_name, *args, &block)
|
188
|
-
else
|
189
|
-
super
|
190
|
-
end
|
191
269
|
end
|
192
270
|
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.
|
4
|
+
version: 0.5.21
|
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-08-
|
11
|
+
date: 2022-08-14 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: glimmer
|