Class: Tuile::Component::PasswordField

Inherits:
TextField show all
Defined in:
lib/tuile/component/password_field.rb,
sig/tuile.rbs

Overview

A TextField that paints one mask glyph per character instead of the text. Editing, caret, clicks and horizontal scrolling are the field's, unchanged:

pf = Component::PasswordField.new
pf.rect  = Rect.new(0, 0, 20, 1)
pf.value                          # => the plaintext String
pf.mask_char = ""                # default "*"
pf.revealed  = true               # show the plaintext, e.g. behind a Checkbox

A password's value is its text, so this subclasses TextField rather than composing one the way IntegerField does — the delta is presentation only, and it lands entirely on TextField#display_text.

What it hides, and what it doesn't

The plaintext is an ordinary Ruby String: not pinned, not wiped, not kept out of GC. Anything stronger needs a frozen-buffer type and the cooperation of every consumer, which is out of scope for a widget.

The mask shows the text's length — accepted, since a caret has to sit somewhere. Its word structure is hidden: CTRL+LEFT / CTRL+RIGHT jump to the ends while masked instead of hopping the spaces a watcher could then read off the caret. They resume word-jumping when #revealed.

UI-thread-confined, like every component (see Screen).

Instance Attribute Summary collapse

Attributes inherited from TextField

#left_column, #max_text_length, #on_enter, #on_key_down, #on_key_up

Attributes inherited from AbstractStringField

#caret, #on_change, #on_escape, #on_key, #text

Attributes included from HasValue

#on_value_change

Instance Method Summary collapse

Methods inherited from TextField

#adjust_left_column, #column_at, #cursor_position, #handle_mouse, #handle_text_input_key, #index_at, #insert, #on_caret_mutated, #on_text_mutated, #on_width_changed, #repaint, #snap_to_glyph_start, #text_columns, #visible_text

Methods inherited from AbstractStringField

#background, #clear, #cluster_boundary_after, #cluster_boundary_before, #columns_of, #default_on_escape, #delete_at_caret, #delete_before_caret, #empty?, #empty_value, #focusable?, #handle_key, #handle_text_input_key, #on_caret_mutated, #on_text_mutated, #preprocess_text, #snap_to_cluster, #tab_stop?, #value, #value=

Methods included from HasValue

#clear, #empty?, #empty_value, #focusable?, #value, #value=

Constructor Details

#initializePasswordField

Returns a new instance of PasswordField.



31
32
33
34
35
# File 'lib/tuile/component/password_field.rb', line 31

def initialize
  super
  @mask_char = "*"
  @revealed = false
end

Instance Attribute Details

#mask_charString

@return — the glyph painted per character; "*" by default.

Returns:

  • (String)


38
39
40
# File 'lib/tuile/component/password_field.rb', line 38

def mask_char
  @mask_char
end

#revealedbool, Object

@return — whether the plaintext is shown; false by default.

Returns:

  • (bool, Object)


65
66
67
# File 'lib/tuile/component/password_field.rb', line 65

def revealed
  @revealed
end

Instance Method Details

#display_textString

@return — the mask, one glyph per character, unless #revealed.

Returns:

  • (String)


90
# File 'lib/tuile/component/password_field.rb', line 90

def display_text = revealed? ? super : @mask_char * @text.length

#revealed?Boolean

@return#revealed in predicate form.

Returns:

  • (Boolean)


68
# File 'lib/tuile/component/password_field.rb', line 68

def revealed? = @revealed

#single_cluster?(char) ⇒ Boolean

@param char

Parameters:

  • char (String)

Returns:

  • (Boolean)


96
# File 'lib/tuile/component/password_field.rb', line 96

def single_cluster?(char) = char.each_grapheme_cluster.take(2).size == 1

#word_leftInteger

@return — caret target for CTRL+LEFT: the start, while masked.

Returns:

  • (Integer)


99
# File 'lib/tuile/component/password_field.rb', line 99

def word_left = revealed? ? super : 0

#word_rightInteger

@return — caret target for CTRL+RIGHT: the end, while masked.

Returns:

  • (Integer)


102
# File 'lib/tuile/component/password_field.rb', line 102

def word_right = revealed? ? super : @text.length