module BBS::Windows::ButtonBar
Lays out a row of buttons at the bottom of a window.
A button descriptor is a Hash:
- key
-
a name for looking the button up in the
by_keyresult - label
-
the button text; +&+ marks the hotkey letter
- on_click
-
called with the window
- primary
-
marks the button that should get the initial focus
- cancel
-
informational only
- align
-
:left,:rightor:center - keep_open
-
never close the window after the handler
on_click receives the BBS::Window as its only argument and may return :keep to keep the window open. Any other return value (or nil) causes the window to be closed after the handler.
primary: true gets initial focus on the button. cancel: true is informational only: ESC closes the window through the standard Window#close_key path. If you also want a cancel-specific side effect on ESC, set window.on_close = ... manually. align: :left | :right | :center: default is :center for a single button, :right otherwise. Left-aligned buttons stack from the left edge; right-aligned buttons stack flush against the right edge in declaration order (so the last right-aligned button sits closest to the edge).
Public Class Methods
# File lib/bbs/windows/button_bar.rb, line 46 def self.attach(window, app, descriptors) descriptors = Array(descriptors) widgets = descriptors.map { |d| Widgets::Button.new(label: d[:label], on_click: handler(window, app, d)) } place(window, widgets, descriptors) widgets.each { |w| window.add(w) } pairs = descriptors.zip(widgets) { widgets: widgets, primary: pairs.find { |d, _| d[:primary] }&.last, by_key: pairs.select { |d, _| d[:key] }.to_h { |d, w| [d[:key], w] } } end
Builds a BBS::Widgets::Button for each of descriptors, places them on the bottom row of window and adds them to it. A click runs the descriptor’s on_click and then closes the window on app unless it returned :keep or keep_open is set.
Returns { widgets:, primary:, by_key: }: the buttons in order, the primary button (or nil), and a Hash of descriptor key to button.
# File lib/bbs/windows/button_bar.rb, line 60 def self.place(window, widgets, descriptors) default = descriptors.length == 1 ? :center : :right groups = widgets.each_index.group_by { |i| descriptors[i][:align] || default } %i[left right center].each do |align| row = widgets.values_at(*groups.fetch(align, [])) lay_out(row, start(window.bounds, align, row), window.bounds.y + window.bounds.height - 2) end end
Positions (or re-positions) the bar’s widgets, built from descriptors, against the window’s current bounds: the left ones from the left edge, the right ones flush against the right edge, the centred ones in the middle. Used by ::attach and by window relayouts.