natty-ui 0.26.0 → 0.28.0

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 93595f761b9be11457f8c8eac967c87f6c91f55d1145aca2f9aa3f35c81a442c
4
- data.tar.gz: fe3fa5b6844e6513ed9e03cbfdb5338bebf9a1f955f61611053b0b3807771aab
3
+ metadata.gz: db28cf57db8670d12ed258d70765447c08bd51462acc7907ea9072b64117f965
4
+ data.tar.gz: 36e9c43bf76fcb1e68b450a1289bcffa8b4cfb33fa2d575ed9b1b92dc6ecce69
5
5
  SHA512:
6
- metadata.gz: f19f64cc3898a51bffe330505ddf015790c456dfc765f078b4798fe06584ae803e20fade81f3981d07a25342598ecfbc4ce1ee525866cbc865a7ab5a21706c96
7
- data.tar.gz: 96ff67e741b3caf88472547c0c205d403fdaa2bb9f21f01d4d8c0eff5c984cb0c1e6c0a12fc70c17bbf7a5fda5cc764693e15de07093c617e889517c0f57a368
6
+ metadata.gz: e19e8e97300a844d294f61e9d4e6c43f5db5fe5a7122ff7c07c7bdd460e229ffffb0b6c943fe1e9f015bf91008824312746290098e10c7851ece75b7bfcb21bf
7
+ data.tar.gz: c6caff65104a42913c3f38ad53b0d628b11aff7517f6450d562c7f41e3b99234caaa48d8e266dd7abb6ca3a83546cd27a019612d0ee6f9e40e249717d26ecfd1
@@ -5,8 +5,8 @@ require_relative '../lib/natty-ui'
5
5
  ui.message '[b]​ᓚᕠᗢ NattyUI[/b] [i green]24-bit Color Support[/]' do
6
6
  bar = '█' * ui.columns
7
7
  rainbow =
8
- (7..17).map do |i|
9
- NattyUI::Ansi.rainbow(bar, seed: 3, spread: 3.25, frequency: i / 100.0)
8
+ (7..21).map do |i|
9
+ NattyUI::Ansi.rainbow(bar, seed: 3, spread: 3.25, frequency: i / 200.0)
10
10
  end
11
11
 
12
12
  ui.space
@@ -4,7 +4,7 @@ require_relative '../lib/natty-ui'
4
4
 
5
5
  ui.message '[b]​ᓚᕠᗢ NattyUI[/b] [i green]3/4bit Color Support[/]' do
6
6
  ui.space
7
- ui.puts <<~INFO, ignore_newline: true
7
+ ui.puts <<~INFO, eol: false
8
8
  Terminals may support colors. You can colorize foreground text and
9
9
  background. The very basic color palette consists of eight colors and may
10
10
  be extended with eight colors which are much brighter.
@@ -6,13 +6,13 @@ ui.message '[b]​ᓚᕠᗢ NattyUI[/b] [i green]8bit Color Support[/]' do
6
6
  color = ->(i) { "[bg#{i = i.to_s(16).rjust(2, '0')}] #{i} " }
7
7
 
8
8
  ui.space
9
- ui.message('System Colors', <<~COLORS.chomp)
9
+ ui.message 'System Colors', <<~COLORS.chomp
10
10
  [#ff]#{0.upto(7).map(&color).join}
11
11
  [#00]#{8.upto(15).map(&color).join}
12
12
  COLORS
13
13
 
14
14
  ui.space
15
- ui.message('Grayscale', <<~GRAYSCALE.chomp)
15
+ ui.message 'Grayscale', <<~GRAYSCALE.chomp
16
16
  [#ff]#{0xe8.upto(0xf3).map(&color).join}
17
17
  [#ff]#{0xf4.upto(0xff).map(&color).join}
18
18
  GRAYSCALE
@@ -4,7 +4,7 @@ require_relative '../lib/natty-ui'
4
4
 
5
5
  ui.message '[b]​ᓚᕠᗢ NattyUI[/b] [i green]ANSI Attributes[/]' do
6
6
  ui.space
7
- ui.puts <<~INFO_1, <<~INFO_2, ignore_newline: true
7
+ ui.puts <<~INFO_1, <<~INFO_2, eol: false
8
8
  NattyUI supports all well known attributes like
9
9
  [b]bold[/b],
10
10
  [i]italic[/i],
data/examples/elements.rb CHANGED
@@ -4,16 +4,16 @@ require_relative '../lib/natty-ui'
4
4
 
5
5
  ui.message '[b]​ᓚᕠᗢ NattyUI[/b] [i green]Simple Elements[/]' do
6
6
  ui.space
7
- ui.h1('This is a [b]H1[/b] heading element')
7
+ ui.h1 'This is a [b]H1[/b] heading element'
8
8
 
9
9
  ui.space
10
- ui.h2('This is a [b]H2[/b] heading element')
10
+ ui.h2 'This is a [b]H2[/b] heading element'
11
11
 
12
12
  ui.space
13
13
  ui.quote "This is a\nmulti-line quotation"
14
14
 
15
15
  ui.space
16
- ui.h3('This is a [b]H3[/b] heading element')
16
+ ui.h3 'This is a [b]H3[/b] heading element'
17
17
  ui.mark(
18
18
  'This is a multi-line message',
19
19
  'with a leading checkmark.',
@@ -21,11 +21,11 @@ ui.message '[b]​ᓚᕠᗢ NattyUI[/b] [i green]Simple Elements[/]' do
21
21
  )
22
22
 
23
23
  ui.space
24
- ui.h4('This is a [b]H4[/b] heading element')
24
+ ui.h4 'This is a [b]H4[/b] heading element'
25
25
 
26
26
  ui.space
27
- ui.h5('This is a [b]H5[/b] heading element')
27
+ ui.h5 'This is a [b]H5[/b] heading element'
28
28
 
29
29
  ui.space
30
- ui.h6('This is a [b]H6[/b] heading element')
30
+ ui.h6 'This is a [b]H6[/b] heading element'
31
31
  end
data/examples/examples.rb CHANGED
@@ -3,6 +3,7 @@
3
3
  require_relative '../lib/natty-ui'
4
4
 
5
5
  EXAMPLES = {
6
+ 'info' => 'Terminal Information',
6
7
  'attributes' => 'ANSI Attributes',
7
8
  '3bit-colors' => '3/4bit Color Support',
8
9
  '8bit-colors' => '8bit Color Support',
@@ -12,6 +13,8 @@ EXAMPLES = {
12
13
  'ls' => 'Print Lists',
13
14
  'tables' => 'Print Tables',
14
15
  'cols' => 'Print Columns',
16
+ 'vbars' => 'Print Vertical Bars',
17
+ 'hbars' => 'Print Horizontal Bars',
15
18
  'sections' => 'Sections',
16
19
  'tasks' => 'Tasks'
17
20
  }.freeze
@@ -22,7 +25,7 @@ ui.space
22
25
 
23
26
  while true
24
27
  selected =
25
- ui.choice(**EXAMPLES, abortable: true) do
28
+ ui.choice(**EXAMPLES, abortable: true, selected: selected) do
26
29
  ui.cols(
27
30
  "[red] /\\_/\\\n( o.o )\n > ^ <",
28
31
  '[bright_green b]Select a natty example:',
data/examples/hbars.rb ADDED
@@ -0,0 +1,18 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative '../lib/natty-ui'
4
+
5
+ ui.message '[b]​ᓚᕠᗢ NattyUI[/b] [i green]Print Horizontal Bars[/]' do
6
+ values = [11.97, 14.35, 15.51, 12.39, 14.3, 10.6, 17.7].freeze
7
+
8
+ ui.space
9
+ ui.hbars values, style: :blue
10
+ ui.puts 'NattyUI can quick dump values as horizontal bars.'
11
+
12
+ ui.space
13
+ ui.hbars values, style: :green, normalize: true, width: 0.5
14
+ ui.puts(
15
+ 'These are the same values but [i]normalized[/i] ' \
16
+ 'and printed in half width.'
17
+ )
18
+ end
@@ -39,7 +39,7 @@ ui.message '[b]​ᓚᕠᗢ NattyUI[/b]' do
39
39
  table.add do |row|
40
40
  row.add 'Layout'
41
41
  row.add <<~TEXT.chomp
42
- 🎩 heading elements     📝 messages
42
+ 🎩 heading elements     📝 messages    📊 bar graphs
43
43
  📏 horizontal rulers    [blue]┼┼[/] tables
44
44
  📋 lists                [b green]✓✓[/] tasks
45
45
  TEXT
data/examples/info.rb ADDED
@@ -0,0 +1,31 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative '../lib/natty-ui'
4
+
5
+ def colors
6
+ return Terminal.colors.to_s if Terminal.colors < 8
7
+ colors = [
8
+ Terminal.true_color? ? 'true color' : Terminal.colors,
9
+ "#{(0..15).map { "[#{_1.to_s(16).rjust(2, '0')}]██" }.join}[/]"
10
+ ]
11
+ if Terminal.true_color?
12
+ colors << Terminal::Ansi.rainbow('████████████████████████████████')
13
+ end
14
+ colors.join("\n")
15
+ end
16
+
17
+ ui.message '[b]​ᓚᕠᗢ NattyUI[/b] [i green]Terminal Information[/]' do
18
+ ui.space
19
+ ui.table do |table|
20
+ table.add 'Identifier', Terminal.application || 'unidentified'
21
+ table.add 'ANSI support', Terminal.ansi? ? 'yes' : 'no'
22
+ table.add 'Input mode', Terminal.input_mode
23
+ table.add 'Colors', colors
24
+ table.add 'Screen size', Terminal.size.join(' x ')
25
+ fc = table.columns[0]
26
+ fc.width = 14
27
+ fc.padding_right = 2
28
+ fc.align = :right
29
+ table.columns[1].style = %i[bold bright_yellow]
30
+ end
31
+ end
@@ -2,27 +2,29 @@
2
2
 
3
3
  require_relative '../lib/natty-ui'
4
4
 
5
- raw = name = :start
6
- while name != 'Esc'
5
+ event = nil
6
+ while true
7
7
  ui.temporary do
8
8
  ui.message '[b]​ᓚᕠᗢ NattyUI[/b] [i green]Keyboard Key Codes[/]' do
9
9
  ui.puts(
10
- "\n#{
11
- case name
12
- when :start
13
- "Your terminal uses [i]#{
14
- Terminal.input_mode
15
- }[/i] mode. Press a key!"
16
- when nil
17
- "[green]#{raw.inspect}[/fg] → [bold bright_green][\\#{raw}]"
10
+ "
11
+ #{
12
+ if event
13
+ "#{event.to_a.size < 2 ? ' Key' : 'Keys'}: [bold bright_green]#{
14
+ event.to_a.map { "[\\#{_1}]" }.join(' ')
15
+ }[/]
16
+ Code: [bright_blue]#{event.raw.inspect}[/]"
18
17
  else
19
- "[green]#{raw.inspect}[/fg] [bold bright_green]#{
20
- name.split('+').map! { "[\\#{_1}]" }.join(' ')
21
- }"
18
+ "Your terminal uses [bright_blue]#{
19
+ Terminal.input_mode
20
+ }[/] mode. Press a key!"
22
21
  end
23
- }\n\n[bright_black](Exit with ESC)"
22
+ }
23
+
24
+ [faint](Exit with ESC)"
24
25
  )
25
26
  end
26
- raw, name = Terminal.read_key(mode: :both)
27
+ event = Terminal.read_key_event
28
+ exit if event.nil? || event.name == 'Esc'
27
29
  end
28
30
  end
data/examples/sections.rb CHANGED
@@ -5,7 +5,7 @@ require_relative '../lib/natty-ui'
5
5
  ui.message '[b]​ᓚᕠᗢ NattyUI[/b] [i green]Sections[/]' do
6
6
  ui.space
7
7
  ui.information 'Informative Message' do
8
- ui.puts <<~TEXT, ignore_newline: true
8
+ ui.puts <<~TEXT, eol: false
9
9
  Sections and messages are elements which support any other feature. This
10
10
  means they may contain text, other sections, titles, horizontal rules,
11
11
  lists, progress bars and much more!
data/examples/tables.rb CHANGED
@@ -46,10 +46,9 @@ ui.message '[b]​ᓚᕠᗢ NattyUI[/b] [i green]Print Tables[/]' do
46
46
  ui.space
47
47
  ui.table do |table|
48
48
  table.add do |row|
49
- row.add 'green', style: :on_green
50
- row.add 'blue', style: :on_blue
51
- row.add 'red', style: :on_red
52
- row.width = 15
49
+ row.add 'green', style: :on_green, max_width: 0.1
50
+ row.add 'blue', style: :on_blue, max_width: 0.25
51
+ row.add 'red', style: :on_red, max_width: 0.1
53
52
  row.align = :centered
54
53
  end
55
54
  table.add do |row|
data/examples/tasks.rb CHANGED
@@ -4,7 +4,7 @@ require_relative '../lib/natty-ui'
4
4
 
5
5
  ui.message '[b]​ᓚᕠᗢ NattyUI[/b] [i green]Tasks[/]' do
6
6
  ui.space
7
- ui.puts <<~TEXT, ignore_newline: true
7
+ ui.puts <<~TEXT, eol: false
8
8
  Tasks are sections that are closed either successfully or with an error message.
9
9
  If successful, their content is only displayed temporarily and can consist of all
10
10
  other features, in particular further (sub)tasks. As an exception to this, some
@@ -21,7 +21,7 @@ ui.message '[b]​ᓚᕠᗢ NattyUI[/b] [i green]Tasks[/]' do
21
21
 
22
22
  ui.task('Connect to Library') do
23
23
  foo
24
- ui.mark('Server Found', mark: :checkmark)
24
+ ui.mark 'Server Found', mark: :checkmark
25
25
  ui.task('Login...') { some }
26
26
  end
27
27
 
data/examples/vbars.rb ADDED
@@ -0,0 +1,39 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative '../lib/natty-ui'
4
+
5
+ ui.message '[b]​ᓚᕠᗢ NattyUI[/b] [i green]Print Vertical Bars[/]' do
6
+ values = [
7
+ 11.97,
8
+ 14.35,
9
+ 15.51,
10
+ 12.39,
11
+ 14.3,
12
+ 10.6,
13
+ 17.7,
14
+ 14.47,
15
+ 14.56,
16
+ 17.31,
17
+ 12.98,
18
+ 16.21,
19
+ 14.9,
20
+ 17.23,
21
+ 13.35,
22
+ 11.62,
23
+ 14.81,
24
+ 19.7,
25
+ 13.42,
26
+ 14.18
27
+ ].freeze
28
+
29
+ ui.space
30
+ ui.vbars values, style: :blue
31
+ ui.puts 'NattyUI can quick dump values as vertical bars.'
32
+
33
+ ui.space
34
+ ui.vbars values, style: :green, normalize: true, bar_width: 2
35
+ ui.puts(
36
+ 'These are the same values but [i]normalized[/i] and printed with ' \
37
+ 'a fixed bar width.'
38
+ )
39
+ end
@@ -11,19 +11,13 @@ module NattyUI
11
11
  end
12
12
 
13
13
  # @return [Attributes] itself
14
- def merge!(**attributes)
15
- attributes.empty? ? self : _assign(attributes)
16
- end
14
+ def merge!(**attributes) = attributes.empty? ? self : _assign(attributes)
17
15
 
18
16
  # @!visibility private
19
- def to_hash
20
- _store({})
21
- end
17
+ def to_hash = _store({})
22
18
 
23
19
  # @!visibility private
24
- def to_h(&block)
25
- block ? _store({}).to_h(&block) : _store({})
26
- end
20
+ def to_h(&block) = block ? _store({}).to_h(&block) : _store({})
27
21
 
28
22
  private
29
23
 
@@ -41,17 +35,22 @@ module NattyUI
41
35
 
42
36
  def as_wh(value)
43
37
  return unless value
44
- return (value = value.to_i) > 0 ? value : nil if value.is_a?(Numeric)
45
- value.is_a?(Range) ? wh_from(value.begin.to_i, value.end.to_i) : nil
38
+ return value > 0 ? value : nil if value.is_a?(Numeric)
39
+ value.is_a?(Range) ? wh_from(value.begin, value.end) : nil
46
40
  end
47
41
 
48
42
  def wh_from(min, max)
49
- min = nil if min < 1
50
- max = nil if max < 1
43
+ min = normalized(min)
44
+ max = normalized(max)
51
45
  return max ? (..max) : nil unless min
52
- return(min..) unless max
46
+ return Range.new(min, nil) unless max
53
47
  min == max ? min : Range.new(*[min, max].minmax)
54
48
  end
49
+
50
+ def normalized(value)
51
+ return value < 0 ? nil : value if value.is_a?(Float) && value < 1
52
+ (value = value.to_i) < 1 ? nil : value
53
+ end
55
54
  end
56
55
 
57
56
  module Align
@@ -83,6 +82,30 @@ module NattyUI
83
82
  end
84
83
  end
85
84
 
85
+ module Position
86
+ # Horizontal element position.
87
+ #
88
+ # @return [nil, :right, :centered]
89
+ attr_reader :position
90
+
91
+ # @attribute [w] position
92
+ def position=(value)
93
+ @position = Utils.position(value)
94
+ end
95
+
96
+ protected
97
+
98
+ def _assign(opt)
99
+ self.position = opt[:position] if opt.key?(:position)
100
+ super
101
+ end
102
+
103
+ def _store(opt)
104
+ opt[:position] = @position if @position
105
+ super
106
+ end
107
+ end
108
+
86
109
  module Vertical
87
110
  # Vertical element alignment.
88
111
  #
@@ -129,26 +152,22 @@ module NattyUI
129
152
  #
130
153
  # @attribute [r] min_width
131
154
  # @return [Integer, nil]
132
- def min_width
133
- width.is_a?(Range) ? @width.begin : @width
134
- end
155
+ def min_width = width.is_a?(Range) ? @width.begin : @width
135
156
 
136
157
  # @attribute [w] min_width
137
158
  def min_width=(value)
138
- @width = wh_from(value.to_i, max_width.to_i)
159
+ @width = wh_from(value, max_width)
139
160
  end
140
161
 
141
162
  # Maximum element width.
142
163
  #
143
164
  # @attribute [r] max_width
144
165
  # @return [Integer, nil]
145
- def max_width
146
- width.is_a?(Range) ? @width.end : @width
147
- end
166
+ def max_width = width.is_a?(Range) ? @width.end : @width
148
167
 
149
168
  # @attribute [w] max_width
150
169
  def max_width=(value)
151
- @width = wh_from(min_width.to_i, value.to_i)
170
+ @width = wh_from(min_width, value)
152
171
  end
153
172
 
154
173
  protected
@@ -183,9 +202,7 @@ module NattyUI
183
202
  #
184
203
  # @attribute [r] min_height
185
204
  # @return [Integer, nil]
186
- def min_height
187
- @height.is_a?(Range) ? @height.begin : @height
188
- end
205
+ def min_height = @height.is_a?(Range) ? @height.begin : @height
189
206
 
190
207
  # @attribute [w] min_height
191
208
  def min_height=(value)
@@ -196,9 +213,7 @@ module NattyUI
196
213
  #
197
214
  # @attribute [r] max_height
198
215
  # @return [Integer, nil]
199
- def max_height
200
- @height.is_a?(Range) ? @height.begin : @height
201
- end
216
+ def max_height = @height.is_a?(Range) ? @height.begin : @height
202
217
 
203
218
  # @attribute [w] max_height
204
219
  def max_height=(value)
@@ -464,30 +479,6 @@ module NattyUI
464
479
  end
465
480
  end
466
481
 
467
- module BorderAround
468
- # Whether the border is around an element.
469
- #
470
- # @return [true, false]
471
- attr_reader :border_around
472
-
473
- # @attribute [w] border_around
474
- def border_around=(value)
475
- @border_around = value ? true : false
476
- end
477
-
478
- protected
479
-
480
- def _assign(opt)
481
- @border_around = opt[:border_around]
482
- super
483
- end
484
-
485
- def _store(opt)
486
- opt[:border_around] = true if @border_around
487
- super
488
- end
489
- end
490
-
491
482
  module Border
492
483
  # Border type.
493
484
  #
@@ -568,10 +559,8 @@ module NattyUI
568
559
  attr_reader :text
569
560
 
570
561
  def empty? = @text.empty?
571
-
572
562
  alias _to_s to_s
573
563
  private :_to_s
574
-
575
564
  def to_str = @text.join("\n")
576
565
  alias to_s to_str
577
566
 
@@ -7,22 +7,24 @@ module NattyUI
7
7
  def select
8
8
  yield(self) if block_given?
9
9
  pin_line = NattyUI.lines_written
10
- draw(current = 0)
11
- while (key = Terminal.read_key)
12
- case key
10
+ draw(current = @ret.index(@selected) || 0)
11
+ while (event = Terminal.read_key_event)
12
+ case event.name
13
13
  when 'Esc', 'Ctrl+c'
14
14
  break nil if @abortable
15
15
  when 'Enter', ' '
16
16
  break @ret[current]
17
- when 'Up', 'Left', 'Back', 'Shift+Tab'
17
+ when 'Home'
18
+ current = 0
19
+ when 'End'
20
+ current = @texts.size - 1
21
+ when 'Up', 'Back', 'Shift+Tab', 'i'
18
22
  current = @texts.size - 1 if (current -= 1) < 0
19
- pin_line = NattyUI.back_to_line(pin_line, erase: false)
20
- draw(current)
21
- when 'Down', 'Right', 'Tab'
23
+ when 'Down', 'Tab', 'k'
22
24
  current = 0 if (current += 1) == @texts.size
23
- pin_line = NattyUI.back_to_line(pin_line, erase: false)
24
- draw(current)
25
25
  end
26
+ pin_line = NattyUI.back_to_line(pin_line, erase: false)
27
+ draw(current)
26
28
  end
27
29
  ensure
28
30
  NattyUI.back_to_line(@start_line)
@@ -30,12 +32,13 @@ module NattyUI
30
32
 
31
33
  private
32
34
 
33
- def initialize(parent, args, kwargs, abortable)
35
+ def initialize(parent, args, kwargs, abortable, selected)
34
36
  super(parent)
35
37
  @start_line = NattyUI.lines_written
36
38
  @texts = args + kwargs.values
37
39
  @ret = Array.new(args.size, &:itself) + kwargs.keys
38
40
  @abortable = abortable
41
+ @selected = selected
39
42
  theme = Theme.current
40
43
  @mark = [theme.mark(:choice), theme.choice_style]
41
44
  @mark_current = [theme.mark(:current_choice), theme.choice_current_style]
@@ -7,10 +7,10 @@ module NattyUI
7
7
  def select
8
8
  yield(self) if block_given?
9
9
  draw
10
- while (code = Terminal.read_key)
11
- return if @abortable && (code == 'Esc' || code == 'Ctrl+c')
12
- next if code.size > 1
13
- code = code[0].upcase
10
+ while (event = Terminal.read_key_event)
11
+ return if @abortable && %w[Esc Ctrl+c].include?(event.name)
12
+ next unless event.simple?
13
+ code = event.raw.upcase
14
14
  if @ret.size <= 9 && ('1'..'9').include?(code)
15
15
  code = @ret[code.ord - 49] and break code
16
16
  elsif ('A'..'Z').include?(code)