Download CommonLua/UI/StdDialogs.lua from sirnii/myspace: direct link, hf CLI and curl.
- Browser
- Download file 21 kB
-
https://huggingface.co/spaces/sirnii/myspace/resolve/main/CommonLua/UI/StdDialogs.lua
- Command line
-
hf download hf://spaces/sirnii/myspace/CommonLua/UI/StdDialogs.lua
-
curl -L -o StdDialogs.lua https://huggingface.co/spaces/sirnii/myspace/resolve/main/CommonLua/UI/StdDialogs.lua
21 kB
| if FirstLoad then | |
| g_OpenMessageBoxes = {} | |
| end | |
| DefineClass.StdDialog = { | |
| __parents = { "XDialog", "XDarkModeAwareDialog" }, | |
| HAlign = "center", | |
| VAlign = "center", | |
| BorderWidth = 1, | |
| BorderColor = RGB(0, 0, 0), | |
| Background = RGBA(0, 0, 0, 255), | |
| MinWidth = 350, | |
| MinHeight = 150, | |
| Translate = true, | |
| } | |
| function StdDialog:Init(parent, context) | |
| context = context or empty_table | |
| if context.title then | |
| XLabel:new({ | |
| Id = "idTitle", | |
| Dock = "top", | |
| Margins = box(4, 4, 4, 0), | |
| TextStyle = "GedTitle", | |
| Translate = context.translate, | |
| }, self) | |
| self.idTitle:SetText(context.title) | |
| end | |
| XWindow:new({ | |
| Id = "idContainer", | |
| Background = RGB(240, 240, 240), | |
| BorderWidth = 1, | |
| BorderColor = RGB(160, 160, 160), | |
| Margins = box(6, 6, 6, 6), | |
| Padding = box(8, 8, 8, 8), | |
| MaxWidth = 900, | |
| }, self) | |
| XWindow:new({ | |
| Id = "idButtonContainer", | |
| Dock = "bottom", | |
| LayoutMethod = "HList", | |
| LayoutHSpacing = 4, | |
| HAlign = "center", | |
| Margins = box(0, 11, 0, 0), | |
| }, self.idContainer) | |
| self:SetModal() | |
| local dark_mode | |
| if context.dark_mode ~= nil then | |
| dark_mode = context.dark_mode | |
| else | |
| dark_mode = GetDarkModeSetting() | |
| end | |
| self:SetDarkMode(dark_mode) | |
| end | |
| function StdDialog:Open(...) | |
| RegisterMessageBox(self) | |
| XDialog.Open(self, ...) | |
| self:UpdateControlDarkMode(self) | |
| self:UpdateChildrenDarkMode(self) | |
| end | |
| function StdDialog:Close(...) | |
| UnregisterMessageBox(self) | |
| XDialog.Close(self, ...) | |
| end | |
| local list_bg = RGB(64, 64, 66) | |
| local list_focus = RGB(150, 150, 150) | |
| local l_list_bg = RGB(255, 255, 255) | |
| local l_list_focus = RGB(255, 255, 255) | |
| local item_selection = RGB(100, 100, 100) | |
| local l_item_selection = RGB(204, 232, 255) | |
| local btn_bg = RGB(100, 100, 100) | |
| local l_btn_bg = RGB(240, 240, 240) | |
| local btn_selected = RGB(150, 150, 150) | |
| local btn_rollover = RGB(120, 120, 120) | |
| local l_btn_selected = RGB(204, 232, 255) | |
| local l_btn_rollover = RGB(180, 180, 180) | |
| local scroll = RGB(128, 128, 128) | |
| local scroll_background = RGB(64, 64, 66) | |
| local l_scroll = RGB(169, 169, 169) | |
| local l_scroll_background = RGB(240, 240, 240) | |
| function StdDialog:UpdateChildrenDarkMode(win) | |
| if IsKindOf(win, "XSleekScroll") then | |
| return | |
| end | |
| XDarkModeAwareDialog.UpdateChildrenDarkMode(self, win) | |
| end | |
| function StdDialog:UpdateControlDarkMode(control) | |
| XDarkModeAwareDialog.UpdateControlDarkMode(self, control) | |
| local dark_mode = self.dark_mode | |
| if IsKindOf(control, "XList") then | |
| control:SetBackground(dark_mode and list_bg or l_list_bg) | |
| control:SetFocusedBackground(dark_mode and list_focus or l_list_focus) | |
| end | |
| if IsKindOf(control, "XListItem") then | |
| control:SetBackground(dark_mode and list_bg or l_list_bg) | |
| control:SetSelectionBackground(dark_mode and item_selection or l_item_selection) | |
| end | |
| if IsKindOf(control, "XTextButton") then | |
| if control:GetBackground() ~= RGBA(0,0,0,0) then | |
| control:SetBackground(dark_mode and btn_bg or l_btn_bg) | |
| control:SetRolloverBackground(dark_mode and btn_rollover or l_btn_rollover) | |
| control:SetPressedBackground(dark_mode and btn_selected or l_btn_selected) | |
| end | |
| end | |
| if IsKindOf(control, "XSleekScroll") then | |
| control.idThumb:SetBackground(dark_mode and scroll or l_scroll) | |
| control:SetBackground(dark_mode and scroll_background or l_scroll_background) | |
| end | |
| end | |
| ----- StdStatusDialog | |
| DefineClass.StdStatusDialog = { | |
| __parents = { "StdDialog" }, | |
| HandleMouse = false, | |
| MinWidth = 200, | |
| MinHeight = 50, | |
| DrawOnTop = true, | |
| } | |
| function StdStatusDialog:Init(parent, context) | |
| XText:new({ | |
| Id = "idText", | |
| TextHAlign = "center", | |
| TextVAlign = "center", | |
| Translate = context and context.translate, | |
| Margins = box(10, 7, 10, 7), | |
| }, self) | |
| self.idText:SetText(context and context.status or "") | |
| self:SetModal(false) | |
| end | |
| function StdStatusDialog:SetStatus(text) | |
| self.idText:SetText(text) | |
| WaitNextFrame(3) | |
| end | |
| ----- StdMessageDialog | |
| DefineClass.StdMessageDialog = { | |
| __parents = { "StdDialog" }, | |
| HandleKeyboard = true, | |
| DrawOnTop = true, | |
| } | |
| function StdMessageDialog:Init(parent, context) | |
| context = context or empty_table | |
| XScrollArea:new({ | |
| Id = "idScrollArea", | |
| VAlign = "top", | |
| LayoutMethod = "VList", | |
| VScroll = "idScroll", | |
| IdNode = false, | |
| }, self.idContainer) | |
| XSleekScroll:new({ | |
| Dock = "right", | |
| Target = "idScrollArea", | |
| Id = "idScroll", | |
| AutoHide = true, | |
| }, self.idContainer) | |
| XText:new({ | |
| Id = "idText", | |
| TextVAlign = "center", | |
| Translate = context.translate, | |
| }, self.idScrollArea) | |
| self.idText:SetText(context.text or "") | |
| if context.choices then | |
| for i=1,#context.choices do | |
| XTextButton:new({ | |
| Id = "idChoice" .. i, | |
| MinWidth = 100, | |
| Translate = context.translate, | |
| Text = context.choices[i], | |
| LayoutMethod = "VList", | |
| OnPress = function() self:Close(i) end, | |
| }, self.idButtonContainer) | |
| end | |
| else | |
| XTextButton:new({ | |
| Id = "idOKText", | |
| MinWidth = 100, | |
| Translate = context.translate, | |
| Text = context.ok_text or context.translate and T(325411474155, "OK") or "OK", | |
| LayoutMethod = "VList", | |
| ActionShortcut = "Enter", | |
| ActionGamepad = "ButtonA", | |
| OnPress = function() self:Close("ok") end, | |
| }, self.idButtonContainer) | |
| if context.question then | |
| XTextButton:new({ | |
| Id = "idCancelText", | |
| MinWidth = 100, | |
| Translate = context.translate, | |
| Text = context.cancel_text or context.translate and T(967444875712, "Cancel") or "Cancel", | |
| LayoutMethod = "VList", | |
| ActionShortcut = "Escape", | |
| ActionGamepad = "ButtonB", | |
| OnPress = function() self:Close("cancel") end, | |
| }, self.idButtonContainer) | |
| end | |
| end | |
| self:SetFocus() | |
| end | |
| function StdMessageDialog:PreventClose() | |
| if self:HasMember("idOKText") then | |
| self.idOKText:SetVisible(false) | |
| elseif self:HasMember("idCancelText") then | |
| self.idCancelText:SetVisible(false) | |
| end | |
| self.OnShortcut = empty_func | |
| end | |
| function StdMessageDialog:OnShortcut(shortcut, ...) | |
| if self:HasMember("idOKText") and self.idOKText:IsVisible() and (shortcut == "Enter" or shortcut == "ButtonA") then | |
| self:Close("ok", ...) | |
| return "break" | |
| elseif self:HasMember("idCancelText") and self.idCancelText:IsVisible() and (shortcut == "Escape" or shortcut == "ButtonB") then | |
| self:Close("cancel", ...) | |
| return "break" | |
| end | |
| end | |
| ----- StdInputDialog | |
| DefineClass.StdInputDialog = { | |
| __parents = { "StdDialog" }, | |
| FocusOnOpen = "", | |
| } | |
| function StdInputDialog:Init(parent, context) | |
| if context.free_input then | |
| XWindow:new({ | |
| Id = "idSubContainer", | |
| Dock = "top", | |
| }, self.idContainer) | |
| XText:new({ | |
| Id = "idFreeLabel", | |
| Dock = "left", | |
| Translate = true, | |
| }, self.idSubContainer):SetText(T(998885500683, "Input: ")) | |
| XEdit:new({ | |
| Id = "idFreeInput", | |
| Dock = "top", | |
| Margins = box(0, 0, 0, 7), | |
| Background = RGB(255, 255, 255), | |
| FocusedBackground = RGB(255, 255, 255), | |
| AutoSelectAll = true, | |
| AllowEscape = false, | |
| MaxLen = context.max_len, | |
| }, self.idSubContainer) | |
| end | |
| XTextButton:new({ | |
| Id = "idOKText", | |
| MinWidth = 100, | |
| Translate = true, | |
| Text = T(325411474155, "OK"), | |
| LayoutMethod = "VList", | |
| OnPress = function() self:SelectAndClose() end, | |
| }, self.idButtonContainer) | |
| XTextButton:new({ | |
| Id = "idCancelText", | |
| MinWidth = 100, | |
| Translate = true, | |
| Text = T(967444875712, "Cancel"), | |
| LayoutMethod = "VList", | |
| OnPress = function() self:Close() end, | |
| }, self.idButtonContainer) | |
| if context.items and context.combo then | |
| XCombo:new({ | |
| Id = "idInput", | |
| VAlign = "center", | |
| Background = RGB(255, 255, 255), | |
| FocusedBackground = RGB(255, 255, 255), | |
| Items = context.items, | |
| VirtualItems = true, | |
| }, self.idContainer) | |
| self.idInput:SetValue(context.items[context.default]) | |
| self.idInput:SetFocus() | |
| elseif context.items then | |
| if context.free_input then | |
| XWindow:new({ | |
| Id = "idSubContainer2", | |
| Dock = "top", | |
| }, self.idContainer) | |
| XText:new({ | |
| Id = "idFilterLabel", | |
| Dock = "left", | |
| Translate = true, | |
| }, self.idSubContainer2):SetText(T(173389874804, "Filter:")) | |
| end | |
| XEdit:new({ | |
| Id = "idFilter", | |
| Dock = "top", | |
| Margins = box(0, 0, 0, 7), | |
| AllowEscape = false, | |
| OnTextChanged = function(edit) | |
| self.idInput:Clear() | |
| local pattern = edit:GetText() | |
| local lower_pattern = string.lower(pattern) | |
| local sorted_items = {} | |
| for idx, item in ipairs(context.items) do | |
| local match, score, match_indices = string.fuzzy_match(pattern, item) | |
| if pattern == "" or match then | |
| local s, e = string.find(string.lower(item), lower_pattern, 1, true) | |
| if s then | |
| match_indices = {} | |
| for i = s, e do | |
| match_indices[#match_indices + 1] = i | |
| end | |
| sorted_items[#sorted_items + 1] = { | |
| idx = idx, | |
| text = HighlightFuzzyMatches(item, match_indices, "<style GedSearchHighlightPartial>", "</style>"), | |
| score = 1000000, | |
| } | |
| else | |
| sorted_items[#sorted_items + 1] = { | |
| idx = idx, | |
| text = match_indices and HighlightFuzzyMatches(item, match_indices, "<style GedSearchHighlight>", "</style>") or item, | |
| score = score, | |
| } | |
| end | |
| end | |
| end | |
| table.stable_sort(sorted_items, function(a, b) return a.score > b.score end) | |
| for k, v in ipairs(sorted_items) do | |
| local item = self.idInput:CreateTextItem(v.text, { selectable = true }) | |
| rawset(item, "choice_idx", v.idx) | |
| end | |
| self.idInput:SetSelection(1) | |
| Msg("XWindowRecreated", self.idInput) | |
| end, | |
| OnShortcut = function(edit, shortcut, ...) | |
| if shortcut == "Up" or shortcut == "Down" or shortcut == "Ctrl-Home" or shortcut == "Ctrl-End" or | |
| shortcut == "Pageup" or shortcut == "Pagedown" or shortcut == "DPadUp" or shortcut == "DPadDown" then | |
| return self.idInput:OnShortcut(shortcut, ...) | |
| end | |
| return XEdit.OnShortcut(edit, shortcut, ...) | |
| end, | |
| }, context.free_input and self.idSubContainer2 or self.idContainer) | |
| XWindow:new({ | |
| Id = "idListParent", | |
| BorderWidth = 1, | |
| }, self.idContainer) | |
| local list = XList:new({ | |
| Id = "idInput", | |
| VAlign = "center", | |
| WorkUnfocused = true, | |
| FocusedBackground = RGB(255, 255, 255), | |
| VScroll = "idScroll", | |
| MultipleSelection = context.multiple, | |
| BorderWidth = 0, | |
| OnDoubleClick = function(this, item_idx) | |
| local item = context.items[this[item_idx].choice_idx] | |
| self:Close(context.multiple and { item } or item) | |
| end, | |
| }, self.idListParent) | |
| XSleekScroll:new({ | |
| Id = "idScroll", | |
| Dock = "right", | |
| AutoHide = true, | |
| MinThumbSize = 30, | |
| FixedSizeThumb = false, | |
| Target = "idInput", | |
| }, self.idListParent) | |
| if context.multiple then | |
| XText:new({ Dock = "bottom", TextHAlign = "center" }, self.idContainer):SetText("(hold Ctrl or Shift to select multiple items)") | |
| end | |
| for k, v in ipairs(context.items) do | |
| local text = v | |
| if type(v) == "table" and v.text then | |
| text = v.text | |
| end | |
| local item = list:CreateTextItem(text, { selectable = true }) | |
| rawset(item, "choice_idx", k) | |
| end | |
| local itemHeight = #list > 0 and list[1][1]:GetFontHeight() or 0 | |
| local lCnt = Clamp(context.lines or 18, 5, 18) | |
| list:SetMaxHeight(lCnt * itemHeight) | |
| list:SetMinHeight(Min(lCnt, #list) * itemHeight) | |
| if context.multiple then | |
| list:SetSelection(context.multiple and context.default) | |
| else | |
| list:SetSelection(table.find(context.items, context.default) or 1) | |
| end | |
| if context.free_input then | |
| self.idFreeInput:SetFocus() | |
| else | |
| self.idFilter:SetFocus() | |
| end | |
| else | |
| XText:new({ | |
| Id = "idError", | |
| Dock = "bottom", | |
| Translate = true, | |
| HideOnEmpty = true, | |
| FoldWhenHidden = true, | |
| }, self.idContainer) | |
| if context.description and context.description ~= "" then | |
| local desc = XText:new({ | |
| Dock = "top", | |
| Translate = context.translate, | |
| TextHAlign = "center", | |
| }, self.idContainer) | |
| desc:SetText(context.description .. "\n\n") | |
| end | |
| XEdit:new({ | |
| Id = "idInput", | |
| VAlign = "center", | |
| Background = RGB(255, 255, 255), | |
| FocusedBackground = RGB(255, 255, 255), | |
| AutoSelectAll = true, | |
| AllowEscape = false, | |
| MaxLen = context.max_len, | |
| OnTextChanged = function(ctrl) | |
| if (self.idError:GetText() or "") ~= "" then | |
| self:VerifyInputText() | |
| end | |
| XEdit.OnTextChanged(ctrl) | |
| end | |
| }, self.idContainer) | |
| self.idInput:SetText(context.default) | |
| self.idInput:SetFocus() | |
| end | |
| end | |
| function StdInputDialog:VerifyInputText() | |
| local free_text = self.idFreeInput and self.idFreeInput:GetText() or "" | |
| local closeParam = (free_text ~= "") and free_text or self.idInput:GetText() | |
| local error_text = self.context.verifier and self.context.verifier(closeParam) or "" | |
| self.idError:SetText(error_text) | |
| return (error_text or "") == "" | |
| end | |
| function StdInputDialog:OpenControllerTextInput(title, description) | |
| if not self:IsThreadRunning("keyboard") then | |
| self:CreateThread("keyboard", function() | |
| local current_text = self.idInput and self.idInput:GetText() or "" | |
| local text, err, shown = WaitControllerTextInput(current_text, title, | |
| description, 256) | |
| if not err and self.window_state ~= "destroying" then | |
| text = text:trim_spaces() | |
| if text ~= current_text then | |
| self:OnControllerTextInput(text) | |
| end | |
| end | |
| end) | |
| end | |
| end | |
| function StdInputDialog:OnControllerTextInput(text) | |
| self.idInput:SetText(text) | |
| end | |
| function StdInputDialog:SelectAndClose(...) | |
| local input = self.idInput | |
| local closeParam = false | |
| local closeCond = true | |
| local free_text = self.idFreeInput and self.idFreeInput:GetText() or "" | |
| if free_text ~= "" then | |
| closeParam = free_text | |
| elseif input:IsKindOf("XCombo") then | |
| closeParam = input:GetValue() | |
| elseif input:IsKindOf("XList") then | |
| local list = self.idInput | |
| local items = self.context.items | |
| if self.context.multiple then | |
| local selection = input:GetSelection() | |
| closeParam = selection and table.map(selection, function(sel_idx) return items[list[sel_idx].choice_idx] end) | |
| else | |
| closeParam = input:GetFocusedItem() and items[list[input:GetFocusedItem()].choice_idx] | |
| end | |
| else | |
| closeParam = input:GetText() | |
| closeCond = self:VerifyInputText() | |
| end | |
| if closeCond then | |
| self:Close(closeParam, ...) | |
| end | |
| end | |
| function StdInputDialog:OnShortcut(shortcut, ...) | |
| if shortcut == "ButtonY" then | |
| if HasControllerTextInput() then | |
| self:OpenControllerTextInput(IsT(self.context.title) and self.context.title or Untranslated(self.context.title), "") | |
| end | |
| return | |
| end | |
| if self.idOKText:IsVisible() and (shortcut == "Enter" or shortcut == "ButtonA") then | |
| self:SelectAndClose(...) | |
| return "break" | |
| elseif self.idCancelText:IsVisible() and (shortcut == "Escape" or shortcut == "ButtonB") then | |
| self:Close(nil, ...) | |
| return "break" | |
| end | |
| end | |
| ----- StdChoiceDialog | |
| DefineClass.StdChoiceDialog = { | |
| __parents = {"StdDialog"}, | |
| MaxWidth = 900, | |
| } | |
| function StdChoiceDialog:Init(parent, context) | |
| XCameraLockLayer:new({}, self) | |
| XPauseLayer:new({}, self) | |
| XScrollArea:new({ | |
| Id = "idScrollArea", | |
| VAlign = "top", | |
| LayoutMethod = "VList", | |
| VScroll = "idScroll", | |
| IdNode = false, | |
| }, self.idContainer) | |
| XSleekScroll:new({ | |
| Dock = "right", | |
| Target = "idScrollArea", | |
| Id = "idScroll", | |
| AutoHide = true, | |
| }, self.idContainer) | |
| XText:new({ | |
| Id = "idText", | |
| TextVAlign = "center", | |
| Translate = context.translate, | |
| }, self.idScrollArea) | |
| self.idText:SetText(context.text or "") | |
| local i = 1 | |
| local disabled = context.disabled | |
| local buttons = self.idButtonContainer | |
| buttons:SetLayoutMethod("VList") | |
| buttons:SetLayoutVSpacing(5) | |
| while true do | |
| local choice = context["choice" .. i] | |
| if not choice and i == 1 then | |
| choice = T(325411474155, "OK") | |
| end | |
| if not choice then break end | |
| local res = i | |
| local button = XTextButton:new({ | |
| OnPress = function(self, gamepad) | |
| GetDialog(self):Close(res) | |
| end, | |
| Background = RGB(175,175,175), | |
| }, buttons) | |
| local text = XText:new({ | |
| Translate = context.translate, | |
| }, button) | |
| text:SetText(T{choice, context.params, context}) | |
| if disabled and disabled[i] then | |
| button:SetEnabled(false) | |
| end | |
| i = i + 1 | |
| end | |
| end | |
| function WaitPopupChoice(parent, context, id) | |
| local dialog = StdChoiceDialog:new({Id = id}, parent or terminal.desktop, context) | |
| dialog:Open() | |
| return dialog:Wait() | |
| end | |
| function WaitInputText(parent, caption, text, max_len, verifier, id, description) | |
| if not caption or caption == "" then caption = "Enter text:" end | |
| if not text or text == "" then text = "Text..." end | |
| local dialog = StdInputDialog:new({Id = id}, parent or terminal.desktop, { title = caption, default = text, max_len = max_len, verifier = verifier, description = description }) | |
| dialog:Open() | |
| if HasControllerTextInput() and GetUIStyleGamepad() then | |
| dialog:OpenControllerTextInput(IsT(caption) and caption or Untranslated(caption), "") | |
| end | |
| return dialog:Wait() | |
| end | |
| function WaitListChoice(parent, items, caption, start_selection, lines, free_input, id) | |
| if not caption or caption == "" then caption = "Please select:" end | |
| if not items or type(items) ~= "table" or #items == 0 then items = {""} end | |
| if not start_selection then start_selection = items[1] end | |
| local dialog = StdInputDialog:new({Id = id}, parent or terminal.desktop, { | |
| title = caption, default = start_selection, items = items, lines = lines, free_input = free_input}) | |
| dialog:Open() | |
| return dialog:Wait() | |
| end | |
| function WaitListMultipleChoice(parent, items, caption, start_selection, lines, id) | |
| if not caption or caption == "" then caption = "Please select one or more:" end | |
| if not items or type(items) ~= "table" or #items == 0 then items = {""} end | |
| if not start_selection then start_selection = {1} end | |
| local dialog = StdInputDialog:new({Id = id}, parent or terminal.desktop, { multiple = true, title = caption, default = start_selection, items = items, lines = lines } ) | |
| dialog:Open() | |
| return dialog:Wait() | |
| end | |
| -- Message Box functions --- | |
| function CreateMessageBox(parent, caption, text, ok_text, obj) | |
| if not caption or caption == "" then caption = Untranslated("Enter text:") end | |
| if not text then text = "" end | |
| ok_text = ok_text or T(325411474155, "OK") | |
| parent = parent or terminal.desktop | |
| local dialog = StdMessageDialog:new({}, parent, { title = caption, text = text, translate = true, obj = obj }) | |
| dialog.idOKText:SetText(ok_text) | |
| dialog:Open() | |
| return dialog | |
| end | |
| -- function should always be called in a thread | |
| function WaitMessage(parent, caption, text, ok_text, obj) | |
| local dialog = CreateMessageBox(parent, caption, text, ok_text, obj) | |
| local result, dataset, controller_id = dialog:Wait() | |
| return result, dataset, controller_id | |
| end | |
| -- Message Question Box functions --- | |
| function CreateQuestionBox(parent, caption, text, ok_text, cancel_text, obj) | |
| local dialog = StdMessageDialog:new({}, parent or terminal.desktop, { | |
| title = caption or "", | |
| text = text or "", | |
| ok_text = ok_text or T(325411474155, "OK"), | |
| cancel_text = cancel_text or T(967444875712, "Cancel"), | |
| translate = true, | |
| question = true, | |
| obj = obj | |
| }) | |
| dialog:Open() | |
| return dialog | |
| end | |
| function WaitQuestion(parent, caption, text, ok_text, cancel_text, obj) | |
| parent = parent or terminal.desktop | |
| if type(caption) == "string" then caption = Untranslated(caption) end | |
| if type(text) == "string" then text = Untranslated(text) end | |
| assert(type(parent) == "table" and parent.IsKindOf and parent:IsKindOf("XWindow"), "The first argument must be a parent window. Don't just create 'global' messages, attach them to the correct parent so they'd share their lifetimes.", 1) | |
| local dialog | |
| if IsKindOf(caption, "XDialog") then | |
| dialog = caption | |
| else | |
| dialog = CreateQuestionBox(parent, caption, text, ok_text, cancel_text, obj) | |
| end | |
| local result, dataset, controller_id = dialog:Wait() | |
| return result, dataset, controller_id | |
| end | |
| function CreateMultiChoiceQuestionBox(parent, caption, text, obj, ...) | |
| local dialog = StdMessageDialog:new({}, parent or terminal.desktop, { | |
| title = caption or "", | |
| text = text or "", | |
| choices = { ... }, | |
| translate = true, | |
| obj = obj | |
| }) | |
| dialog:Open() | |
| return dialog | |
| end | |
| function WaitMultiChoiceQuestion(parent, caption, text, obj, ...) | |
| assert(type(parent) == "table" and parent.IsKindOf and parent:IsKindOf("XWindow"), "The first argument must be a parent window. Don't just create 'global' messages, attach them to the correct parent so they'd share their lifetimes.", 1) | |
| local dialog | |
| if IsKindOf(caption, "XDialog") then | |
| dialog = caption | |
| else | |
| dialog = CreateMultiChoiceQuestionBox(parent, caption, text, obj, ...) | |
| end | |
| local result, dataset, controller_id = dialog:Wait() | |
| return result, dataset, controller_id | |
| end | |
| function RegisterMessageBox(message_box) | |
| g_OpenMessageBoxes[message_box] = true | |
| Msg("MessageBoxRegister", message_box) | |
| end | |
| function UnregisterMessageBox(message_box) | |
| g_OpenMessageBoxes[message_box] = nil | |
| Msg("MessageBoxUnregister", message_box) | |
| end | |
| function CloseAllMessagesAndQuestions() | |
| for window,dummy in pairs(g_OpenMessageBoxes) do | |
| if window.window_state ~= "destroying" then | |
| window:Close() | |
| end | |
| end | |
| end | |
| function AreMessageBoxesOpen() | |
| return next(g_OpenMessageBoxes) | |
| end | |
| function IsMessageBoxOpen(id_or_dlg) | |
| if g_OpenMessageBoxes[id_or_dlg] then return true end | |
| for message_box in pairs(g_OpenMessageBoxes) do | |
| if message_box.Id == id_or_dlg then | |
| return true | |
| end | |
| end | |
| end |