glimmer-dsl-libui 0.5.20 → 0.5.21
Sign up to get free protection for your applications and to get access to all the features.
- 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
|
[![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)
|
@@ -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
|