Class: Tuile::Component::ListDropdown

Inherits:
Popup
  • Object
show all
Defined in:
lib/tuile/component/list_dropdown.rb,
sig/tuile.rbs

Overview

A borderless, tinted, non-focusable floating selection list — the dropdown a text input drops open, drives by forwarding movement keys, and commits a pick from: a non-modal Popup wrapping a List that never takes focus, so the caret stays in the driving input while the caller refills the rows, moves the highlight, and reads the pick.

drop = Component::ListDropdown.new
drop.on_item_chosen = ->(index, _line) { commit(index) } # caller commits
# …then, per keystroke in the driving input's key handler:
drop.lines = matches.map { |m| render(m) }  # caller filters + renders
drop.rect  = Rect.new(...)                   # caller anchors + sizes it
drop.open
return true if drop.move(key)  # Up/Down/PgUp/PgDn/^U/^D → list scroll
drop.choose if key == Keys::ENTER            # commit the highlight

It owns only what every such dropdown shares; everything that varies stays with the driver: geometry/anchoring, filtering, row rendering, the commit action, and ESC/Enter handling. ESC and Enter carry driver-specific tails (ESC may revert a query; Enter may commit via #choose or via a separate submit path), so #move claims neither — the driver calls #choose and Popup#close from its own branches.

Theming

Borderless, told apart from the content beneath by a background tint — Theme#input_bg_color by default, assigned as a live Theme::Ref so it tracks light/dark flips with no hook. Reassign #bg_color= for a different tint (a Theme.ref(:token) keeps the flip-tracking).

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

Defined Under Namespace

Classes: Menu

Constant Summary collapse

MOVE_KEYS =

Cursor-movement keys forwarded to the list by #move: the two vertical arrows, page up/down, and Ctrl+U/D half-page jumps. Deliberately excludes Home/End and j/k (they belong to the driving field — caret movement and typing) and Enter/ESC (they carry driver-specific tails — see the class docs).

Returns:

  • (Array<String>)
[Keys::UP_ARROW, Keys::DOWN_ARROW, Keys::PAGE_UP, Keys::PAGE_DOWN,
Keys::CTRL_U, Keys::CTRL_D].freeze

Instance Attribute Summary

Attributes inherited from Popup

#size

Attributes included from HasContent

#content

Instance Method Summary collapse

Methods inherited from Popup

#center, #close, #focusable?, #handle_key, #handle_mouse, #keyboard_hint, #layout, #modal?, #on_focus, #open, open, #open?, #rect=, #reposition

Methods included from HasContent

#handle_mouse, #on_focus, #rect=

Constructor Details

#initializeListDropdown

Returns a new instance of ListDropdown.



53
54
55
56
57
58
59
# File 'lib/tuile/component/list_dropdown.rb', line 53

def initialize
  @list = Menu.new
  @list.cursor = List::Cursor.new
  @list.show_cursor_when_inactive = true # highlight the selection though focus stays in the input
  super(content: @list, modal: false)
  self.bg_color = Theme.ref(:input_bg_color)
end

Instance Method Details

#chooseBoolean

Commits the highlighted row by firing Tuile::Component::List#on_item_chosen, exactly as pressing Enter on the focused list would — the driver calls this from its own Enter branch.

@return — true iff a row was chosen (false when the cursor is off-content).

Returns:

  • (Boolean)


103
# File 'lib/tuile/component/list_dropdown.rb', line 103

def choose = @list.handle_key(Keys::ENTER)

#cursorList::Cursor

@return — the list's cursor (the current highlight).

Returns:



83
# File 'lib/tuile/component/list_dropdown.rb', line 83

def cursor = @list.cursor

#cursor=(cursor) ⇒ void

This method returns an undefined value.

@param cursor — the highlight; see Tuile::Component::List#cursor=.

Parameters:



78
79
80
# File 'lib/tuile/component/list_dropdown.rb', line 78

def cursor=(cursor)
  @list.cursor = cursor
end

#lines::Array[StyledString]

@return — the current rows.

Returns:



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

def lines = @list.lines

#lines=(lines) ⇒ void

This method returns an undefined value.

@param lines — the rows to show; see Tuile::Component::List#lines=.

Parameters:

  • lines (::Array[untyped])


63
64
65
# File 'lib/tuile/component/list_dropdown.rb', line 63

def lines=(lines)
  @list.lines = lines
end

#move(key) ⇒ Boolean

Forwards a cursor-movement key to the list. The driver calls this from its own key handler; a truthy return means "consumed — stop here", falsy means "not mine — proceed with normal editing/dispatch". Only MOVE_KEYS are claimed, and only while open.

@param key

@return — true iff the key was consumed.

Parameters:

  • key (String)

Returns:

  • (Boolean)


91
92
93
94
95
96
# File 'lib/tuile/component/list_dropdown.rb', line 91

def move(key)
  return false unless open? && MOVE_KEYS.include?(key)

  @list.handle_key(key)
  true
end

#on_item_chosen=(proc) ⇒ void

This method returns an undefined value.

@param proc — commit callback; see Tuile::Component::List#on_item_chosen.

Parameters:

  • proc (Proc, Method, nil)


72
73
74
# File 'lib/tuile/component/list_dropdown.rb', line 72

def on_item_chosen=(proc)
  @list.on_item_chosen = proc
end