diff --git a/library/lua/gui/dialogs.lua b/library/lua/gui/dialogs.lua index 63f9990c1..6200de90a 100644 --- a/library/lua/gui/dialogs.lua +++ b/library/lua/gui/dialogs.lua @@ -5,6 +5,134 @@ local _ENV = mkmodule('gui.dialogs') local gui = require('gui') local widgets = require('gui.widgets') +--------------------------------- +-- DialogWindow and DialogScreen +-- + +DialogWindow = defclass(DialogWindow, widgets.Window) +DialogWindow.ATTRS { + frame={w=20, h=10}, + label_params=DEFAULT_NIL, + accept_label=DEFAULT_NIL, + on_accept=DEFAULT_NIL, + on_cancel=DEFAULT_NIL, +} + +function DialogWindow:init(info) + self:addviews{ + widgets.Label{ + view_id='label', + frame={t=0, l=0, b=3}, + text=self.label_params.text, + }, + widgets.HotkeyLabel{ + frame={b=0, l=0, r=0}, + label=self.accept_label, + key='SELECT', + auto_width=true, + on_activate=self:callback('accept'), + }, + } +end + +function DialogWindow:accept() + if self.on_accept then + self.on_accept() + end + self.parent_view:dismiss() +end + +function DialogWindow:cancel() + if self.on_cancel then + self.on_cancel() + end + self.parent_view:dismiss() +end + +function DialogWindow:computeFrame() + local min_width = math.max(self.frame.w or 0, 20, #(self.frame_title or '') + 4) + + local label = self.subviews.label + local text_area_width = label:getTextWidth() + 1 + local text_height = label:getTextHeight() + local sw, sh = dfhack.screen.getWindowSize() + if text_height >= sh - 6 then + -- account for scrollbar + text_area_width = text_area_width + 2 + end + + local fw, fh = math.max(min_width, text_area_width), text_height + 3 + return gui.compute_frame_body(sw, sh, {w=fw, h=fh}, 1, 1, true) +end + +function DialogWindow:onInput(keys) + if (keys.LEAVESCREEN or keys._MOUSE_R) and self.on_cancel then + self:cancel() + end + return DialogWindow.super.onInput(self, keys) +end + +DialogScreen = defclass(DialogScreen, gui.ZScreenModal) +DialogScreen.ATTRS { + focus_path='MessageBox', + title=DEFAULT_NIL, + label_params={}, + accept_label='Ok', + on_accept=DEFAULT_NIL, + on_cancel=DEFAULT_NIL, + on_close=DEFAULT_NIL, +} + +function DialogScreen:init() + self:addviews{ + DialogWindow{ + frame_title=self.title, + accept_label=self.accept_label, + label_params=self.label_params, + on_accept=self.on_accept, + on_cancel=self.on_cancel, + } + } +end + +function DialogScreen:onDismiss() + if self.on_close then + self.on_close() + end +end + +------------------------ +-- Convenience methods +-- + +function showMessage(title, text, tcolor, on_close) + return DialogScreen{ + title=title, + label_params={ + text=text, + text_pen=tcolor, + }, + on_close=on_close, + }:show() +end + +function showYesNoPrompt(title, text, tcolor, on_accept, on_cancel) + return DialogScreen{ + title=title, + label_params={ + text=text, + text_pen=tcolor, + }, + accept_label='Yes, proceed', + on_accept=on_accept, + on_cancel=on_cancel, + }:show() +end + +------------------------ +-- Legacy classes +-- + MessageBox = defclass(MessageBox, gui.FramedScreen) MessageBox.focus_path = 'MessageBox' @@ -70,29 +198,6 @@ function MessageBox:onInput(keys) return true end -function showMessage(title, text, tcolor, on_close) - local mb = MessageBox{ - frame_title = title, - text = text, - text_pen = tcolor, - on_close = on_close - } - mb:show() - return mb -end - -function showYesNoPrompt(title, text, tcolor, on_accept, on_cancel) - local mb = MessageBox{ - frame_title = title, - text = text, - text_pen = tcolor, - on_accept = on_accept, - on_cancel = on_cancel, - } - mb:show() - return mb -end - InputBox = defclass(InputBox, MessageBox) InputBox.focus_path = 'InputBox'