module BBS::Dialogs
Ready-made modal dialogs for a BBS::Application: a message, a yes/no confirmation, and a one-line input. Each opens a centred Window on app and returns it; the buttons close it.
BBS::Dialogs.confirm(app, 'Delete this post?', on_yes: -> { delete(post) })
Constants
- BUTTON_ROW
-
The button row, counted up from the bottom edge.
- BUTTON_WIDTH
-
Width of an OK, Yes or No button.
- CANCEL_WIDTH
-
Width of the Cancel button.
- CHROME_ROWS
-
Rows of a message or confirm box beside its text lines: the borders, the blank lines and the button row.
- CONFIRM_MIN_WIDTH
-
The narrowest confirm box.
- HALF_GAP
-
Columns between the middle of the window and each of two buttons side by side.
- INPUT_HEIGHT
-
The height of an input box.
- INPUT_ROW
-
The window row of the text field of an input box.
- INPUT_WIDTH
-
The default width of an input box.
- MESSAGE_MIN_WIDTH
-
The narrowest message box.
- PADDING
-
Columns between the windowโs left edge and its text, and between the text and the right edge.
- SCREEN_MARGIN
-
Cells kept free between a dialog and each screen edge.
- TEXT_CHROME
-
Columns of a message or confirm box beside its wrapped text.
- TEXT_TOP
-
The window row of the first text line, below the top border.
- WRAP_WIDTH
-
The width a message without a fixed width and a confirm text are wrapped at.
Public Class Methods
# File lib/bbs/dialogs.rb, line 52 def self.centred_window(app, width:, height:, title: nil) cols = app.cols rows = app.rows w = [width, cols - (2 * SCREEN_MARGIN)].min h = [height, rows - (2 * SCREEN_MARGIN)].min x = ((cols - w) / 2) + 1 y = ((rows - h) / 2) + 1 win = Window.new(title: title, modal: true) win.layout(x, y, w, h) win end
# File lib/bbs/dialogs.rb, line 80 def self.confirm(app, text, title: ' Confirm ', on_yes: nil, on_no: nil) lines = wrap(text, WRAP_WIDTH) window = text_box(app, lines, fit(lines, CONFIRM_MIN_WIDTH), title) pair(window, Widgets::Button.new(label: '&Yes', on_click: closer(app, window) { on_yes&.call }), Widgets::Button.new(label: '&No', on_click: closer(app, window) { on_no&.call }), BUTTON_WIDTH) show(app, window) end
Opens a Yes/No box with text. Each button closes the box, then calls on_yes or on_no when given.
Returns the Window.
# File lib/bbs/dialogs.rb, line 94 def self.input(app, prompt:, title: ' Input ', value: '', width: INPUT_WIDTH, on_submit: nil) window = centred_window(app, width: width, height: INPUT_HEIGHT, title: title) inner = window.bounds.width - (2 * PADDING) place(window, Widgets::Label.new(text: prompt, style_key: :window_text), PADDING, TEXT_TOP, inner) field = Widgets::TextInput.new(value: value) field.on_submit = closer(app, window) { on_submit&.call(field.value) } place(window, field, PADDING, INPUT_ROW, inner) pair(window, Widgets::Button.new(label: '&OK', on_click: field.on_submit), Widgets::Button.new(label: '&Cancel', on_click: closer(app, window)), CANCEL_WIDTH) show(app, window, focus: field) end
Opens a box with prompt, a text field holding value, and OK and Cancel buttons. OK, or Enter in the field, closes the box and calls on_submit with the entered text; Cancel only closes it. The field has the focus.
Returns the Window.
# File lib/bbs/dialogs.rb, line 68 def self.message(app, text, title: ' Message ', width: nil) lines = wrap(text, width ? width - TEXT_CHROME : WRAP_WIDTH) window = text_box(app, lines, width || fit(lines, MESSAGE_MIN_WIDTH), title) ok = Widgets::Button.new(label: '&OK', on_click: closer(app, window)) place(window, ok, (window.bounds.width - BUTTON_WIDTH) / 2, button_row(window), BUTTON_WIDTH) show(app, window) end
Opens a message box with text, word-wrapped, and an OK button that closes it. width fixes the box width; by default it fits the text.
Returns the Window.