new framework
This commit is contained in:
114
lib/bbs/dialogs.rb
Normal file
114
lib/bbs/dialogs.rb
Normal file
@@ -0,0 +1,114 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require_relative 'window'
|
||||
require_relative 'widgets'
|
||||
|
||||
module BBS
|
||||
module Dialogs
|
||||
# Build a centred Window with the given inner size.
|
||||
def self.centred_window(app, width:, height:, title: nil)
|
||||
cols = app.cols
|
||||
rows = app.rows
|
||||
w = [width, cols - 4].min
|
||||
h = [height, rows - 4].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
|
||||
|
||||
# Show a one-line message with an OK button.
|
||||
def self.message(app, text, title: ' Message ', width: nil)
|
||||
lines = wrap(text, 50)
|
||||
w = (width || ([lines.map(&:length).max + 6, 30].max))
|
||||
h = lines.size + 5
|
||||
window = centred_window(app, width: w, height: h, title: title)
|
||||
|
||||
lines.each_with_index do |line, i|
|
||||
label = Widgets::Label.new(text: line, style_key: :window_text)
|
||||
label.layout(window.bounds.x + 2, window.bounds.y + 1 + i, w - 4, 1)
|
||||
window.add(label)
|
||||
end
|
||||
|
||||
btn = Widgets::Button.new(label: '&OK', on_click: ->(_) { app.close_window(window) })
|
||||
btn.layout(window.bounds.x + (w - 8) / 2, window.bounds.y + h - 2, 8, 1)
|
||||
window.add(btn)
|
||||
window.reset_focus
|
||||
app.open_window(window)
|
||||
window
|
||||
end
|
||||
|
||||
# Yes/No confirmation. Calls on_yes / on_no.
|
||||
def self.confirm(app, text, title: ' Confirm ', on_yes: nil, on_no: nil)
|
||||
lines = wrap(text, 50)
|
||||
w = [lines.map(&:length).max + 6, 36].max
|
||||
h = lines.size + 5
|
||||
window = centred_window(app, width: w, height: h, title: title)
|
||||
|
||||
lines.each_with_index do |line, i|
|
||||
label = Widgets::Label.new(text: line, style_key: :window_text)
|
||||
label.layout(window.bounds.x + 2, window.bounds.y + 1 + i, w - 4, 1)
|
||||
window.add(label)
|
||||
end
|
||||
|
||||
yes = Widgets::Button.new(label: '&Yes',
|
||||
on_click: ->(_) { app.close_window(window); on_yes&.call })
|
||||
no = Widgets::Button.new(label: '&No',
|
||||
on_click: ->(_) { app.close_window(window); on_no&.call })
|
||||
yes.layout(window.bounds.x + w / 2 - 9, window.bounds.y + h - 2, 8, 1)
|
||||
no.layout(window.bounds.x + w / 2 + 1, window.bounds.y + h - 2, 8, 1)
|
||||
window.add(yes)
|
||||
window.add(no)
|
||||
window.reset_focus
|
||||
app.open_window(window)
|
||||
window
|
||||
end
|
||||
|
||||
# Single-line text input dialog. Calls on_submit with the entered value.
|
||||
def self.input(app, prompt:, title: ' Input ', value: '', width: 50, on_submit: nil)
|
||||
w = width
|
||||
h = 7
|
||||
window = centred_window(app, width: w, height: h, title: title)
|
||||
|
||||
label = Widgets::Label.new(text: prompt, style_key: :window_text)
|
||||
label.layout(window.bounds.x + 2, window.bounds.y + 1, w - 4, 1)
|
||||
window.add(label)
|
||||
|
||||
input = Widgets::TextInput.new(value: value)
|
||||
input.layout(window.bounds.x + 2, window.bounds.y + 3, w - 4, 1)
|
||||
window.add(input)
|
||||
|
||||
ok = Widgets::Button.new(label: '&OK',
|
||||
on_click: ->(_) { app.close_window(window); on_submit&.call(input.value) })
|
||||
cancel = Widgets::Button.new(label: '&Cancel',
|
||||
on_click: ->(_) { app.close_window(window) })
|
||||
ok.layout(window.bounds.x + w / 2 - 9, window.bounds.y + h - 2, 8, 1)
|
||||
cancel.layout(window.bounds.x + w / 2 + 1, window.bounds.y + h - 2, 10, 1)
|
||||
window.add(ok)
|
||||
window.add(cancel)
|
||||
window.reset_focus
|
||||
window.focus_manager.focus(input)
|
||||
app.open_window(window)
|
||||
window
|
||||
end
|
||||
|
||||
def self.wrap(text, width)
|
||||
words = text.to_s.split
|
||||
lines = []
|
||||
cur = +''
|
||||
words.each do |w|
|
||||
if cur.empty?
|
||||
cur << w
|
||||
elsif cur.length + 1 + w.length <= width
|
||||
cur << ' ' << w
|
||||
else
|
||||
lines << cur.dup
|
||||
cur = +w
|
||||
end
|
||||
end
|
||||
lines << cur unless cur.empty?
|
||||
lines
|
||||
end
|
||||
end
|
||||
end
|
||||
Reference in New Issue
Block a user