curses_menu 0.0.1 → 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,150 +1,151 @@
1
- class CursesMenu
2
-
3
- # Definition of a row that stores for each cell the string and color information to be displayed
4
- class CursesRow
5
-
6
- # Constructor
7
- #
8
- # Parameters::
9
- # * *cells* (Hash< Symbol, Hash<Symbol,Object> >): For each cell id (ordered), the cell info:
10
- # * *text* (String): Text associated to this cell
11
- # * *color_pair* (Integer): Associated color pair [optional]
12
- # * *begin_with* (String): String to prepend to the text [default: '']
13
- # * *end_with* (String): String to append to the text [default: '']
14
- # * *fixed_size* (Integer): Number of characters this cell will take, or nil if no limit. [default: nil]
15
- # * *justify* (Symbol): Text justification (only used when fixed_size is not nil). Values can be: [default: :left]
16
- # * *left*: Left justified
17
- # * *right*: Right justified
18
- # * *pad* (String): Text to be used to pad the cell content (only used when fixed_size is not nil) [default: ' ']
19
- # * *separator* (String): Separator used between cells [default: ' ']
20
- def initialize(cells, separator: ' ')
21
- @cells = cells
22
- @separator = separator
23
- end
24
-
25
- # Change the cells order
26
- #
27
- # Parameters::
28
- # * *cells* (Array<Symbol>): The ordered list of cells to filter
29
- # * *unknown_cells* (String or Hash<Symbol,Object>): Content to put in unknown cells (as a String or properties like in #initialize), or nil to not add them. [default: nil]
30
- def cells_order(cells, unknown_cells: nil)
31
- new_cells = {}
32
- cells.each do |cell_id|
33
- if @cells.key?(cell_id)
34
- new_cells[cell_id] = @cells[cell_id]
35
- elsif !unknown_cells.nil?
36
- new_cells[cell_id] = unknown_cells.is_a?(String) ? { text: unknown_cells } : unknown_cells
37
- end
38
- end
39
- @cells = new_cells
40
- end
41
-
42
- # Change properties of a set of cells
43
- #
44
- # Parameters::
45
- # * *cells* (Hash<Symbol, Hash<Symbol,Object> >): The cells properties to change, per cell id. Possible properties are the ones given in the #initialize method.
46
- def change_cells(cells)
47
- cells.each do |cell_id, cell_info|
48
- raise "Unknown cell #{cell_id}" unless @cells.key?(cell_id)
49
- @cells[cell_id].merge!(cell_info)
50
- @cells[cell_id].delete(:cache_rendered_text)
51
- end
52
- end
53
-
54
- # Get the size of the total string of such row.
55
- #
56
- # Parameters::
57
- # * *cells* (Array<Symbol>): The list of cells to consider for the size [default: @cells.keys]
58
- # Result::
59
- # * Integer: Row size
60
- def size(cells: @cells.keys)
61
- result = @separator.size * (cells.size - 1)
62
- cells.each do |cell_id|
63
- result += cell_text(cell_id).size
64
- end
65
- result
66
- end
67
-
68
- # Print this row into a window
69
- #
70
- # Parameters::
71
- # * *window* (Window): Curses window to print on
72
- # * *from* (Integer): From index to be displayed [default: 0]
73
- # * *to* (Integer): To index to be displayed [default: total size]
74
- # * *default_color_pair* (Integer): Default color pair to use if no color information is provided [default: COLORS_LINE]
75
- # * *force_color_pair* (Integer): Force color pair to use, or nil to not force [default: nil]
76
- # * *pad* (String or nil): Pad the line to the row extent with the given string, or nil for no padding. [default: nil]
77
- # * *add_nl* (Boolean): If true, then add a new line at the end [default: true]
78
- # * *single_line* (Boolean): If true, then make sure the print does not exceed the line [default: false]
79
- def print_on(window, from: 0, to: nil, default_color_pair: COLORS_LINE, force_color_pair: nil, pad: nil, add_nl: true, single_line: false)
80
- text_size = size
81
- from = text_size if from > text_size
82
- to = text_size - 1 if to.nil?
83
- to = window.maxx - window.curx + from - 2 if single_line && window.curx + to - from >= window.maxx - 1
84
- current_idx = 0
85
- @cells.each.with_index do |(cell_id, cell_info), cell_idx|
86
- text = cell_text(cell_id)
87
- full_substring_size = text.size + @separator.size
88
- if from < current_idx + full_substring_size
89
- # We have something to display from this substring
90
- window.color_set(
91
- if force_color_pair.nil?
92
- cell_info[:color_pair] ? cell_info[:color_pair] : default_color_pair
93
- else
94
- force_color_pair
95
- end
96
- )
97
- window << "#{text}#{cell_idx == @cells.size - 1 ? '' : @separator}"[(from < current_idx ? 0 : from - current_idx)..to - current_idx]
98
- end
99
- current_idx += full_substring_size
100
- break if current_idx > to
101
- end
102
- window.color_set(force_color_pair.nil? ? default_color_pair : force_color_pair)
103
- if pad && window.curx < window.maxx
104
- nbr_chars = window.maxx - window.curx - 1
105
- window << (pad * nbr_chars)[0..nbr_chars - 1]
106
- end
107
- window << "\n" if add_nl
108
- end
109
-
110
- private
111
-
112
- # Get a cell's text.
113
- # Cache it to not compute it several times.
114
- #
115
- # Parameters::
116
- # * *cell_id* (Symbol): Cell id to get text for
117
- # Result::
118
- # * String: The cell's text
119
- def cell_text(cell_id, cell_decorator: nil)
120
- unless @cells[cell_id].key?(:cache_rendered_text)
121
- begin_str = "#{@cells[cell_id][:begin_with] || ''}#{@cells[cell_id][:text]}"
122
- end_str = @cells[cell_id][:end_with] || ''
123
- @cells[cell_id][:cache_rendered_text] =
124
- if @cells[cell_id][:fixed_size]
125
- text = "#{begin_str[0..@cells[cell_id][:fixed_size] - end_str.size - 1]}#{end_str}"
126
- remaining_size = @cells[cell_id][:fixed_size] - text.size
127
- if remaining_size > 0
128
- padding = ((@cells[cell_id][:pad] || ' ') * remaining_size)[0..remaining_size - 1]
129
- justify = @cells[cell_id][:justify] || :left
130
- case justify
131
- when :left
132
- "#{text}#{padding}"
133
- when :right
134
- "#{padding}#{text}"
135
- else
136
- raise "Unknown justify decorator: #{justify}"
137
- end
138
- else
139
- text[0..@cells[cell_id][:fixed_size] - 1]
140
- end
141
- else
142
- "#{begin_str}#{end_str}"
143
- end
144
- end
145
- @cells[cell_id][:cache_rendered_text]
146
- end
147
-
148
- end
149
-
150
- end
1
+ class CursesMenu
2
+
3
+ # Definition of a row that stores for each cell the string and color information to be displayed
4
+ class CursesRow
5
+
6
+ # Constructor
7
+ #
8
+ # Parameters::
9
+ # * *cells* (Hash< Symbol, Hash<Symbol,Object> >): For each cell id (ordered), the cell info:
10
+ # * *text* (String): Text associated to this cell
11
+ # * *color_pair* (Integer): Associated color pair [optional]
12
+ # * *begin_with* (String): String to prepend to the text [default: '']
13
+ # * *end_with* (String): String to append to the text [default: '']
14
+ # * *fixed_size* (Integer): Number of characters this cell will take, or nil if no limit. [default: nil]
15
+ # * *justify* (Symbol): Text justification (only used when fixed_size is not nil). Values can be: [default: :left]
16
+ # * *left*: Left justified
17
+ # * *right*: Right justified
18
+ # * *pad* (String): Text to be used to pad the cell content (only used when fixed_size is not nil) [default: ' ']
19
+ # * *separator* (String): Separator used between cells [default: ' ']
20
+ def initialize(cells, separator: ' ')
21
+ @cells = cells
22
+ @separator = separator
23
+ end
24
+
25
+ # Change the cells order
26
+ #
27
+ # Parameters::
28
+ # * *cells* (Array<Symbol>): The ordered list of cells to filter
29
+ # * *unknown_cells* (String or Hash<Symbol,Object>): Content to put in unknown cells (as a String or properties like in #initialize), or nil to not add them. [default: nil]
30
+ def cells_order(cells, unknown_cells: nil)
31
+ new_cells = {}
32
+ cells.each do |cell_id|
33
+ if @cells.key?(cell_id)
34
+ new_cells[cell_id] = @cells[cell_id]
35
+ elsif !unknown_cells.nil?
36
+ new_cells[cell_id] = unknown_cells.is_a?(String) ? { text: unknown_cells } : unknown_cells
37
+ end
38
+ end
39
+ @cells = new_cells
40
+ end
41
+
42
+ # Change properties of a set of cells
43
+ #
44
+ # Parameters::
45
+ # * *cells* (Hash<Symbol, Hash<Symbol,Object> >): The cells properties to change, per cell id. Possible properties are the ones given in the #initialize method.
46
+ def change_cells(cells)
47
+ cells.each do |cell_id, cell_info|
48
+ raise "Unknown cell #{cell_id}" unless @cells.key?(cell_id)
49
+
50
+ @cells[cell_id].merge!(cell_info)
51
+ @cells[cell_id].delete(:cache_rendered_text)
52
+ end
53
+ end
54
+
55
+ # Get the size of the total string of such row.
56
+ #
57
+ # Parameters::
58
+ # * *cells* (Array<Symbol>): The list of cells to consider for the size [default: @cells.keys]
59
+ # Result::
60
+ # * Integer: Row size
61
+ def size(cells: @cells.keys)
62
+ result = @separator.size * (cells.size - 1)
63
+ cells.each do |cell_id|
64
+ result += cell_text(cell_id).size
65
+ end
66
+ result
67
+ end
68
+
69
+ # Print this row into a window
70
+ #
71
+ # Parameters::
72
+ # * *window* (Window): Curses window to print on
73
+ # * *from* (Integer): From index to be displayed [default: 0]
74
+ # * *to* (Integer): To index to be displayed [default: total size]
75
+ # * *default_color_pair* (Integer): Default color pair to use if no color information is provided [default: COLORS_LINE]
76
+ # * *force_color_pair* (Integer): Force color pair to use, or nil to not force [default: nil]
77
+ # * *pad* (String or nil): Pad the line to the row extent with the given string, or nil for no padding. [default: nil]
78
+ # * *add_nl* (Boolean): If true, then add a new line at the end [default: true]
79
+ # * *single_line* (Boolean): If true, then make sure the print does not exceed the line [default: false]
80
+ def print_on(window, from: 0, to: nil, default_color_pair: COLORS_LINE, force_color_pair: nil, pad: nil, add_nl: true, single_line: false)
81
+ text_size = size
82
+ from = text_size if from > text_size
83
+ to = text_size - 1 if to.nil?
84
+ to = window.maxx - window.curx + from - 2 if single_line && window.curx + to - from >= window.maxx - 1
85
+ current_idx = 0
86
+ @cells.each.with_index do |(cell_id, cell_info), cell_idx|
87
+ text = cell_text(cell_id)
88
+ full_substring_size = text.size + @separator.size
89
+ if from < current_idx + full_substring_size
90
+ # We have something to display from this substring
91
+ window.color_set(
92
+ if force_color_pair.nil?
93
+ cell_info[:color_pair] || default_color_pair
94
+ else
95
+ force_color_pair
96
+ end
97
+ )
98
+ window << "#{text}#{cell_idx == @cells.size - 1 ? '' : @separator}"[(from < current_idx ? 0 : from - current_idx)..to - current_idx]
99
+ end
100
+ current_idx += full_substring_size
101
+ break if current_idx > to
102
+ end
103
+ window.color_set(force_color_pair.nil? ? default_color_pair : force_color_pair)
104
+ if pad && window.curx < window.maxx
105
+ nbr_chars = window.maxx - window.curx - 1
106
+ window << (pad * nbr_chars)[0..nbr_chars - 1]
107
+ end
108
+ window << "\n" if add_nl
109
+ end
110
+
111
+ private
112
+
113
+ # Get a cell's text.
114
+ # Cache it to not compute it several times.
115
+ #
116
+ # Parameters::
117
+ # * *cell_id* (Symbol): Cell id to get text for
118
+ # Result::
119
+ # * String: The cell's text
120
+ def cell_text(cell_id)
121
+ unless @cells[cell_id].key?(:cache_rendered_text)
122
+ begin_str = "#{@cells[cell_id][:begin_with] || ''}#{@cells[cell_id][:text]}"
123
+ end_str = @cells[cell_id][:end_with] || ''
124
+ @cells[cell_id][:cache_rendered_text] =
125
+ if @cells[cell_id][:fixed_size]
126
+ text = "#{begin_str[0..@cells[cell_id][:fixed_size] - end_str.size - 1]}#{end_str}"
127
+ remaining_size = @cells[cell_id][:fixed_size] - text.size
128
+ if remaining_size.positive?
129
+ padding = ((@cells[cell_id][:pad] || ' ') * remaining_size)[0..remaining_size - 1]
130
+ justify = @cells[cell_id][:justify] || :left
131
+ case justify
132
+ when :left
133
+ "#{text}#{padding}"
134
+ when :right
135
+ "#{padding}#{text}"
136
+ else
137
+ raise "Unknown justify decorator: #{justify}"
138
+ end
139
+ else
140
+ text[0..@cells[cell_id][:fixed_size] - 1]
141
+ end
142
+ else
143
+ "#{begin_str}#{end_str}"
144
+ end
145
+ end
146
+ @cells[cell_id][:cache_rendered_text]
147
+ end
148
+
149
+ end
150
+
151
+ end
@@ -0,0 +1,5 @@
1
+ class CursesMenu
2
+
3
+ VERSION = '0.0.2'
4
+
5
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: curses_menu
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.1
4
+ version: 0.0.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Muriel Salvan
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2019-07-01 00:00:00.000000000 Z
11
+ date: 2021-08-15 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: curses
@@ -16,14 +16,70 @@ dependencies:
16
16
  requirements:
17
17
  - - "~>"
18
18
  - !ruby/object:Gem::Version
19
- version: '1.3'
19
+ version: '1.4'
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
24
  - - "~>"
25
25
  - !ruby/object:Gem::Version
26
- version: '1.3'
26
+ version: '1.4'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rspec
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '3.10'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '3.10'
41
+ - !ruby/object:Gem::Dependency
42
+ name: sem_ver_components
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '0.3'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '0.3'
55
+ - !ruby/object:Gem::Dependency
56
+ name: rubocop
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: '1.19'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: '1.19'
69
+ - !ruby/object:Gem::Dependency
70
+ name: rubocop-rspec
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - "~>"
74
+ - !ruby/object:Gem::Version
75
+ version: '2.4'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - "~>"
81
+ - !ruby/object:Gem::Version
82
+ version: '2.4'
27
83
  description:
28
84
  email:
29
85
  - muriel@x-aeon.com
@@ -41,11 +97,12 @@ files:
41
97
  - examples/sub_menus.rb
42
98
  - lib/curses_menu.rb
43
99
  - lib/curses_menu/curses_row.rb
44
- homepage: http://x-aeon.com
100
+ - lib/curses_menu/version.rb
101
+ homepage: https://github.com/Muriel-Salvan/curses_menu
45
102
  licenses:
46
103
  - BSD-3-Clause
47
104
  metadata:
48
- homepage_uri: http://x-aeon.com
105
+ homepage_uri: https://github.com/Muriel-Salvan/curses_menu
49
106
  post_install_message:
50
107
  rdoc_options: []
51
108
  require_paths:
@@ -54,15 +111,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
54
111
  requirements:
55
112
  - - ">="
56
113
  - !ruby/object:Gem::Version
57
- version: '0'
114
+ version: '2.6'
58
115
  required_rubygems_version: !ruby/object:Gem::Requirement
59
116
  requirements:
60
117
  - - ">="
61
118
  - !ruby/object:Gem::Version
62
119
  version: '0'
63
120
  requirements: []
64
- rubyforge_project:
65
- rubygems_version: 2.7.6
121
+ rubygems_version: 3.1.6
66
122
  signing_key:
67
123
  specification_version: 4
68
124
  summary: Simple menu offering choices with navigation keys using curses