Class: Typr::Line
Overview
A single-line UI element for displaying text and collecting input.
Example
line = Line.new( top: 5, left: 10, width: 40 )
line.show "Hello world"
line.append " more"
line.ask([ ["Name?", :line], ["Age?", :line] ])
Constant Summary
Constants included from Typr
ALT_SCREEN_OFF, ALT_SCREEN_ON, COLORS, COLOR_MAP, DEFAULT_KEYS, ERASE_LINE, INPUT, KEY_ALT_BACKSPACE, KEY_ALT_LEFT, KEY_ALT_RIGHT, KEY_BACK_TAB, KEY_ESCAPE, KEY_PAGEDOWN, KEY_PAGEUP, KEY_RETURN, KEY_TAB, MIMETYPES, MODES, MOUSE_OFF, MOUSE_ON, ORIG_COLORS, TERMINFO
Instance Attribute Summary collapse
-
#align ⇒ Object
Returns the value of attribute align.
-
#bindings ⇒ Object
Returns the value of attribute bindings.
-
#data ⇒ Object
Returns the value of attribute data.
-
#default ⇒ Object
Returns the value of attribute default.
-
#prompt ⇒ Object
Returns the value of attribute prompt.
-
#trim ⇒ Object
Returns the value of attribute trim.
Attributes inherited from Space
#borders, #bottom, #colors, #interval, #left, #margin, #right, #top
Instance Method Summary collapse
-
#append(str) ⇒ Object
(also: #<<)
Append
strto the current content and redraw. -
#ask(sentence) ⇒ Object
Prompt the user with a sequence of questions.
-
#data_at(x, y) ⇒ Object
The binding label under terminal (x, y) on this line, or nil when the click is outside the row or off the current bindings text (see Space#data_at).
-
#help ⇒ Object
Pick a keybinding from the list: click a row (or press its hint digit) to return the row id, Escape or Return to return nil.
-
#initialize(args) ⇒ Line
constructor
A new instance of Line.
-
#list ⇒ Object
The keybinding list as a clickable grid of the line's own bindings.
-
#reset ⇒ Object
Reset the line to its default text or prompt.
-
#show(msg = @data, align = @align) ⇒ Object
Render
msg(String, Proc, or Space) on this line.
Methods inherited from Space
#border=, #draw_border, #extract_key, #height, #start, #stop, #symbolize, #width
Methods included from Typr
#background, clear, #clip, #coerce_type, #color, #color_code, column, decode_mouse, #draw, exit, #fade, #foreground, #get_background, #get_foreground, height, init, #mode, #mode_code, #move, #move_code, on_resize, position, #prepare, read_key, read_line, #real_size, row, #sanitize, size, slice_width, text_width, width, word_next, word_prev
Constructor Details
#initialize(args) ⇒ Line
Returns a new instance of Line.
145 146 147 148 149 150 151 152 153 154 |
# File 'lib/line.rb', line 145 def initialize args @right= -1 @align = :left @trim = :right @prompt = ?> super @bottom = @top @colors = { question: :green, answer: :yellow }.merge @colors reset end |
Instance Attribute Details
#align ⇒ Object
Returns the value of attribute align.
15 16 17 |
# File 'lib/line.rb', line 15 def align @align end |
#bindings ⇒ Object
Returns the value of attribute bindings.
15 16 17 |
# File 'lib/line.rb', line 15 def bindings @bindings end |
#data ⇒ Object
Returns the value of attribute data.
15 16 17 |
# File 'lib/line.rb', line 15 def data @data end |
#default ⇒ Object
Returns the value of attribute default.
15 16 17 |
# File 'lib/line.rb', line 15 def default @default end |
#prompt ⇒ Object
Returns the value of attribute prompt.
15 16 17 |
# File 'lib/line.rb', line 15 def prompt @prompt end |
#trim ⇒ Object
Returns the value of attribute trim.
15 16 17 |
# File 'lib/line.rb', line 15 def trim @trim end |
Instance Method Details
#append(str) ⇒ Object Also known as: <<
Append str to the current content and redraw.
line.show "hello"
line.append " world" #=> "hello world"
line << "!" #=> "hello world!"
39 |
# File 'lib/line.rb', line 39 def append(str); show @data+str end |
#ask(sentence) ⇒ Object
Prompt the user with a sequence of questions.
sentence is an array of [question, type] pairs (or a hash of them).
Returns a single answer, or an array when there are multiple questions.
The type selects how the answer is collected:
Array - interactive pick via <>.pick(<type>); an optional third
element renders the chosen row's field into the line, and an
optional fourth element is passed as pick keyword arguments
(e.g. { column: 0 } to open the pick in / search mode)
:key - a single keypress via Typr.read_key
:line - interactive line editor via Typr.read_line at the cursor
Pressing the exit key (@keymap, Escape by default) aborts the remaining questions and returns nil.
line.ask(name: :line) #=> "Alice"
line.ask(keys: :key) #=> "a"
line.ask(open: [grid, :row, :name]) #=> 2 (picked row id)
line.ask([ ["Name?", :line], ["Ok?", :key] ]) #=> ["Alice", "a"]
107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 |
# File 'lib/line.rb', line 107 def ask sentence answer = [] move left, top Typr.clear :line saved = @trim @trim = :left begin @data = @prompt.to_s colored = color_code( @colors[:default] ).to_s + @data move left, top draw prepare( colored, width, @align, @trim ) for question, object in sentence text = " " + question.to_s + " " @data += text colored += color_code( @colors[:question] ).to_s + text move left, top draw prepare( colored, width, @align, @trim ) color( @colors[:answer] ) case object when Array then answer << object.first.pick( object[1], **(object[3] || {}) ) when :key then answer << Typr.read_key when :line then answer << Typr.read_line( colored + color_code( @colors[:answer] ), left: left, top: top ) end return if !answer.last or answer.last == @keymap[:exit] text = ( object.is_a?(Array) and object[2] ) ? object.first.data[answer.last][object[2]].to_s : answer.last.to_s @data += text colored += color_code( @colors[:answer] ).to_s + text move left, top draw prepare( colored, width, @align, @trim ) end ensure @trim = saved end return ( answer.one? ? answer.first : answer ) end |
#data_at(x, y) ⇒ Object
The binding label under terminal (x, y) on this line, or nil when the click is outside the row or off the current bindings text (see Space#data_at).
line.data_at 3, 8 # => "[h]elp"
69 70 71 72 73 74 75 76 77 78 79 |
# File 'lib/line.rb', line 69 def data_at x, y return unless x and y and y == top + 1 and x.between?( left, right ) and @bindings and @data == @bindings.join( ' ' ) pos = left @bindings.each do |b| width = real_size( b ) return b if x.between?( pos, pos + width - 1 ) pos += width + 1 end nil end |
#help ⇒ Object
Pick a keybinding from the list: click a row (or press its hint digit) to return the row id, Escape or Return to return nil.
line.help # => 0 (the picked row) or nil
60 |
# File 'lib/line.rb', line 60 def help; list.pick :row end |
#list ⇒ Object
The keybinding list as a clickable grid of the line's own bindings. It auto-sizes to its widest binding (floored to fit the header) and starts at column 1, so apps can align side panels at +list.right + 2+.
line.list # => a Grid whose rows are the bindings
48 49 50 51 52 53 |
# File 'lib/line.rb', line 48 def list Grid.new( input: @bindings, top: 2, left: 1, bottom: -3, header: "KEYBINDINGS", colors: { header: [:yellow,:black], border:[:white,:grey10] }, alternate: false, border: :light ) end |
#reset ⇒ Object
Reset the line to its default text or prompt.
line.reset
85 |
# File 'lib/line.rb', line 85 def reset; show( @default || ( @bindings || [@prompt] ).join(' ') ) end |
#show(msg = @data, align = @align) ⇒ Object
Render msg (String, Proc, or Space) on this line.
line.show "status: ok"
line.show Proc.new { show_time }
22 23 24 25 26 27 28 29 30 31 |
# File 'lib/line.rb', line 22 def show msg=@data, align=@align @data = msg move left, top color @colors[:default] case msg when Proc; msg.call when Space; msg.show when String; draw( prepare msg, width, align, @trim ) end end |