Class: Typr::Line

Inherits:
Space
  • Object
show all
Defined in:
lib/line.rb

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

Attributes inherited from Space

#borders, #bottom, #colors, #interval, #left, #margin, #right, #top

Instance Method Summary collapse

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

#alignObject

Returns the value of attribute align.



15
16
17
# File 'lib/line.rb', line 15

def align
  @align
end

#bindingsObject

Returns the value of attribute bindings.



15
16
17
# File 'lib/line.rb', line 15

def bindings
  @bindings
end

#dataObject

Returns the value of attribute data.



15
16
17
# File 'lib/line.rb', line 15

def data
  @data
end

#defaultObject

Returns the value of attribute default.



15
16
17
# File 'lib/line.rb', line 15

def default
  @default
end

#promptObject

Returns the value of attribute prompt.



15
16
17
# File 'lib/line.rb', line 15

def prompt
  @prompt
end

#trimObject

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 <widget>.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

#helpObject

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

#listObject

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

#resetObject

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