#include "ui_helpers.lua" #include "ui_extensions.lua" #include "script/common.lua" #include "components/buttons.lua" function isModDownloading(modId) if string.sub(modId,1,6) == "steam-" and HasKey("mods.pending.".. modId) then return GetBool("mods.pending."..modId..".downloading") end return false end Promo = {} Promo.selectedItem = nil function Promo.Item(obj) local i = Ui.Object:new { key = "", title = "", isSelected = false, image = { path = "", w = 0, h = 0 }, isSquare = false, isLarge = false, tileScale = 1, pad = 0, onCreate = function(self) self.image.w, self.image.h = UiGetImageSize(self.image.path) self.tileScale = self.h / self.image.h self.w = self.image.w * self.tileScale if self.isSquare then self.pad = (self.image.w - self.image.h) / 2 self.w = (self.image.w - self.pad * 2) * self.tileScale end end, draw = function(self) self.navId = UiNavComponent(self.w, self.h) self.x, self.y = UiGetCursorPos() UiPush() UiColor(1, 1, 1, 1) if UiIsMouseInRect(self.w, self.h) and UiReceivesInput() then local x, y = UiGetCanvasMousePos() if self.parent.window:IsInRect(x, y) and self.group.parent.window:IsInRect(x, y) then UiColor(0.8, 0.8, 0.8) if InputPressed("lmb") then self:selectSelf() if not self.parent.window:FullyVisible(self.x, self.y, self.w, self.h) then self.parent.state:scrollToItem(self.idx, true) end end end end UiPush() UiScale(self.tileScale) if self.isLarge then UiImageAlpha(self.image.path, "menu/339x200_rcorners-alpha.png", self.pad, 0, self.image.w - self.pad, self.image.h, 0, 0, 339, 200) else if self.isSquare then UiImageAlpha(self.image.path, "menu/200x200_rcorners-alpha.png", self.pad, 0, self.image.w - self.pad, self.image.h, 0, 0, 200, 200) else UiImageAlpha(self.image.path, "menu/339x200_rcorners-alpha.png", self.pad, 0, self.image.w - self.pad, self.image.h, 0, 0, 339, 200) end end UiPop() UiImageBox("common/item_preview_gradient.png", self.w, self.h, 8, 0) UiPop() if self.isSelected then UiPush() UiColor(1,1,1,1) UiImageBox("menu/promo_item_selection.png", self.w, self.h, 9, 9) UiPop() end UiPush() UiFont("medium.ttf", 27) if not self.isSelected then UiColor(1, 1, 1, 0.8) else UiColor(hexrgb(0xFFFF7F)) end UiAlign("top left") UiWordWrap(self.w) local _, th = UiGetTextSize(self.title) UiTranslate(10, self.h - 10 - th) UiText(self.title) UiPop() local tmp = splitString(self.key, ".") local modId = tmp[#tmp] local modKey = "mods.available."..modId if HasKey(modKey) then UiPush() UiTranslate(self.w - 46, 10) UiAlign("top left") UiColor(1, 1, 1, 1) if GetBool(modKey..".playable") then UiImage("menu/promo-play.png") elseif GetBool(modKey..".active") then UiImage("menu/promo-active.png") else UiImage("menu/promo-inactive.png") end UiPop() end end, selectSelf = function(self) if Promo.selectedItem then Promo.selectedItem.isSelected = false Promo.selectedItem.group.isSelected = false end self.isSelected = true self.group.isSelected = true Promo.selectedItem = self self.group.list.selected = self.idx Promo.Window.mainFrame.groupsList.selected = self.group.idx Promo.Window.mainFrame.groupsList.state:scrollToItem(self.group.idx, true) UiSound("terminal/message-select.ogg") end } return i:new(obj) end function Promo.Group(obj) local g = Ui.Frame { id = "", w = 1210, h = 325, key = "", title = "", tile = { h = 200, isLarge = false, isSquare = false }, hovered = false, isSelected = false, Ui.ImageBox { resizeToParent = true, path = "common/box-9.png", border = { width = 9, height = 9 }, color = 0x100000099 }, Ui.Text { margin = { top = 20, left = 20}, id = "title", font = { "medium.ttf", 27 }, color = 0xBFA65AFF, }, Ui.HorizontalLayout { margin = { top = 70 }, hAlign = Ui.ContentLayout.Horizontal.Center, alignment = Ui.ContentLayout.Vertical.Middle, Ui.Object:new { id = "leftScrollBtn", margin = { right = 20, bottom = 10 }, image = "menu/promo_new_arrow.png", hiden = false, draw = function(self) UiFrameOccupy(self.w, self.h) UiFrameSkipItem(true) UiPush() UiColorFilter(1, 1, 1, self.hidden and 0 or 1) UiAlign("top left") UiColor(1, 1, 1, 0.8) local hover = UiIsMouseInRect(self.w, self.h) if hover then UiColor(1,1,1,1) end UiTranslate(self.w, 0) UiScale(-1, 1) UiImage(self.image) UiPop() UiFrameSkipItem(false) end, onCreate = function(self) self.w, self.h = UiGetImageSize(self.image) end, onPressed = function(self) if not self.list then self.list = self.parent.parent:findById("itemsList") end InputClear() self.list:scroll(-(1 / #self.list.children)) end, }, Ui.HorizontalList { h = 200, w = 1070, id = "itemsList", selected = 1, state = { itemsPadding = 20, ignoreWheelScroll = true, scrollbarOffset = 20, holdFocusOnListEnd = true, thumb = { color = {1,1,1,1} }, background = { color = {1, 1, 1, 0.15 } } } }, Ui.Object:new { margin = { left = 20, bottom = 10 }, id = "rightScrollBtn", image = "menu/promo_new_arrow.png", hidden = false, draw = function(self) UiFrameOccupy(self.w, self.h) UiFrameSkipItem(true) UiPush() UiColorFilter(1, 1, 1, self.hidden and 0 or 1) UiAlign("top left") UiColor(1, 1, 1, 0.8) local hover = UiIsMouseInRect(self.w, self.h) if hover then UiColor(1,1,1,1) end UiImage(self.image) UiPop() UiFrameSkipItem(false) end, onCreate = function(self) self.w, self.h = UiGetImageSize(self.image) end, onPressed = function(self) if not self.list then self.list = self.parent.parent:findById("itemsList") end InputClear() self.list:scroll(1 / #self.list.children) end, } }, onCreate = function(self) self.list = self:findById("itemsList") self.list:clear() local items = ListKeys(self.key ..".items") for i=1, #items do local iKey = self.key .. ".items." .. items[i] local item = Promo.Item { key = iKey, image = { path = GetString(iKey .. ".image") }, title = GetString(iKey .. ".shorttitle"), isSquare = self.tile.isSquare, isLarge = self.tile.isLarge, h = self.tile.h, } item.group = self item.idx = i self.list:append(item) end self.titleTextBox = self:findById("title") self.titleTextBox.text = self.title self.rightScrollBtn = self:findById("rightScrollBtn") self.leftScrollBtn = self:findById("leftScrollBtn") end, onPreDraw = function(self) self.hovered = UiIsMouseInRect(self.w, self.h) if self.isSelected then local list = self.list local inputBeh = list.state.inputBehaviour inputBeh.disabled = false inputBeh:update() inputBeh.disabled = true if inputBeh.prevRequested then list.selected = clamp(list.selected - 1, 1, #list.children) list.children[list.selected]:selectSelf() list.state:scrollToItem(list.selected, true) elseif inputBeh.nextRequested then list.selected = clamp(list.selected + 1, 1, #list.children) list.children[list.selected]:selectSelf() list.state:scrollToItem(list.selected, true) end end end, onPostDraw = function(self) local listState = self.list.state self.rightScrollBtn.hidden = (listState.contentSpan < self.list.w) or (listState.thumbDelta == (listState.background.w - listState.thumb.w)) or (LastInputDevice() == UI_DEVICE_GAMEPAD) self.leftScrollBtn.hidden = self.list.state.thumbDelta == 0 or (LastInputDevice() == UI_DEVICE_GAMEPAD) if LastInputDevice() == UI_DEVICE_GAMEPAD then self.rightScrollBtn.visible = false self.leftScrollBtn.visible = false self.list.w = 1170 else self.rightScrollBtn.visible = true self.leftScrollBtn.visible = true self.list.w = 1070 end if self.isSelected then self.titleTextBox.color = 0xFFFF7FFF else self.titleTextBox.color = 0xFFFFFFCC end end, focusLeave = function(self) if not self.isSelected then return nil end self.isSelected = false return Promo.selectedItem end, focusEnter = function(self, curFocused) if not curFocused then self.list.selected = 1 self.list.children[1]:selectSelf() else local h = Promo.Helpers local curList = curFocused.group.list local curFocusedX = tableAccumulate( tableSlice(curList.children, 1, curList.selected - 1), function(a, b) return a + b.w + curList.state.itemsPadding end, 0) + curFocused.w / 2 local visibleItems = h.GetVisible(self.list) local isCloser = function(a, b) return math.abs(curFocusedX - (a.x + a.item.w / 2)) < math.abs(curFocusedX - (b.x + b.item.w / 2)) end local candidate = tableMin(visibleItems, isCloser) self.list.selected = candidate.idx candidate.item:selectSelf() end self.isSelected = true end } return g:new(obj) end Promo.Window = Ui.Window { w = 1920, h = 1080, visible=false, animator = { playTime = 0.25 }, ignoreNavigation = true, addHideAreas = function(self) local top = self.mainFrame.padding.top local left = self.mainFrame.padding.left local hideAreas = { { x = left, y = 0, w = self.w - 2 * left, h = top }, { x = left, y = self.h - top, w = self.w - 2 * left, h = top }, { x = 0, y = 0, w = left, h = self.h }, { x = self.w - left, y = 0, w = left, h = self.h }, } for i=1, #hideAreas do local area = hideAreas[i] area.colorFilter = { 0, 0, 0, 0 } function area:onPressed() Promo.Window:hide() end self:append(Ui.Rect{ id = "hideRect"..i, x = area.x, y = area.y, w = area.w, h = area.h, color = area.colorFilter, onPressed = area.onPressed, }) end end, Ui.Frame { id = "mainFrame", x = 0, y = 0, w = 1920, h = 1080, padding = { top = 40, bottom = 40, left = 60, right = 60 }, Ui.VerticalLayout { padding = 10, Ui.HorizontalLayout { margin = { bottom = 10 }, alignment = Ui.ContentLayout.Vertical.Middle, Ui.Text { font = { "bold.ttf", 40 }, text = "loc@UI_TEXT_FEATURED_MODS", margin = { right = 20 } }, Ui.Text { id = "moreInfoIco", text = "[[menu:pause;iconsize=42,42;color=255,255,255]]", }, Ui.Text { underline = true, font = { "medium.ttf", 22 }, color = 0xFFFFFFB2, text = "loc@UI_BUTTON_MORE_INFO", margin = { right = 10 }, onMouseEnter = function(self) self.color = 0xFFFF7F end, onMouseLeave = function(self) self.color = 0xFFFFFFB2 end, onPressed = function(self) Promo.LegalWindow:show() end, onPreDraw = function(self) if LastInputDevice() == UI_DEVICE_GAMEPAD and InputPressed("pause") then self:onPressed() end end }, onCreate = function(self) self.moreInfoIco = self:findById("moreInfoIco") end, onPreDraw = function(self) self.moreInfoIco.visible = LastInputDevice() == UI_DEVICE_GAMEPAD end }, Ui.Text { color = 0xFFFFFFB4, font = { "medium.ttf", 22 }, text = "loc@UI_TEXT_EXPERIENCE_SOME", wrapWidth = 1800 }, Ui.HorizontalLayout { margin = { top = 10 }, padding = 10, Ui.VerticalList { id = "groupsList", w = 1210, h = 780, selected = 1, state = { itemsPadding = 10, scrollbarOffset = 5, background = { w = 14, h = 780, color = {0, 0, 0, 0.8} }, thumb = { w = 10, color = {1, 1, 1, 0.9} } }, onPreDraw = function(self) local inputBeh = self.state.inputBehaviour inputBeh.disabled = false inputBeh:update() inputBeh.disabled = true if inputBeh.prevRequested then local prev = self.children[self.selected]:focusLeave() self.selected = clamp(self.selected - 1, 1, #self.children) self.children[self.selected]:focusEnter(prev) elseif inputBeh.nextRequested then local prev = self.children[self.selected]:focusLeave() self.selected = clamp(self.selected + 1, 1, #self.children) self.children[self.selected]:focusEnter(prev) end end }, Ui.Frame { id = "itemDetails", w = 560, h = 780, Ui.ImageBox { path = "common/box-9.png", border = { width = 9, height = 9 }, w = 560, h = 780, color = 0x100000099 }, Ui.VerticalLayout { id = "mainContent", padding = 10, Ui.Object:new { id = "itemImage", image = "", w = 560, h = 100, draw = function(self) local w, _ = UiGetImageSize(self.image) local _, hA = UiGetImageSize("menu/480x217_promo_preveiw_alpha.png") local scale = self.w / w self.h = hA * scale UiPush() UiScale(scale) UiColor(1, 1, 1, 1) UiImageAlpha(self.image, "menu/480x217_promo_preveiw_alpha.png", 0, 0, w, 217, 0, 0, w, 217) UiPop() end, }, Ui.VerticalLayout { margin = { left = 10 }, padding = 15, Ui.Text { id = "title", text = "title", font = { "medium.ttf", 27 }, color = 0xFFFF7F, fixedSize = true, wrapWidth = 530 }, Ui.Text { id = "author", text = "by someone", color = 0xFFFFFFCC, font = { "medium.ttf", 22 }, fixedSize = true, wrapWidth = 530 }, Ui.Text { id = "tags", text = "tags", color = 0xFFFFFFCC, font = { "medium.ttf", 22 }, fixedSize = true, wrapWidth = 530 }, Ui.ScrollableArea { id = "descriptionArea", w = 540, h = 100, Ui.Text { id = "description", text = "description", color = 0xFFFFFF99, font = { "medium.ttf", 22 }, fixedSize = true, wrapWidth = 530 } }, Ui.HorizontalLayout { alignment = Ui.ContentLayout.Vertical.Middle, Ui.Text { id = "moreDetailsIco", text = "[[menu:interact;iconsize=42,42;color=255,255,255]]" }, Ui.Text { id = "moreDetails", text = "loc@UI_BUTTON_MORE_DETAILS", color = 0xFFFFFF99, font = { "medium.ttf", 22 }, wrapWidth = 530, underline = true, onPressed = function(self) local steam_active = GetBool("game.steam.active") and GetBool("game.workshop") if steam_active then Command("mods.browse", self.modId) end end, onMouseEnter = function(self) self.color = 0xFFFF7F end, onMouseLeave = function(self) self.color = 0xFFFFFFB2 end, onPreDraw = function(self) if LastInputDevice() == UI_DEVICE_GAMEPAD and InputPressed("interact") then self:onPressed() end end } } } }, Ui.HorizontalLayout { padding = 20, vAlign = Ui.ContentLayout.Vertical.Bottom, hAlign = Ui.ContentLayout.Horizontal.Center, alignment = Ui.ContentLayout.Vertical.Middle, margin = { bottom = 30 }, Teardown.GenericButton { id = "playBtn", w = 250, h = 50, fontSize = 36, rawText = "", onPressed = function(self) if self.hasMod then if self.canPlay then Command("mods.play", self.modId) elseif self.canEnable and self.modEnabled then Command("mods.deactivate", self.modId) elseif self.canEnable and not self.modEnabled then Command("mods.activate", self.modId) end elseif not self.isLoading and self.steamActive then Command("mods.subscribe", self.modId) end end, onPreDraw = function(self) local ico = "" if LastInputDevice() == UI_DEVICE_GAMEPAD then ico = "[[menu:menu_accept;iconsize=42,42;color=255,255,255]]" elseif self.hasMod then if self.canPlay then ico = "[[menu/promo-play-btn.png;iconsize=42,42;color=255,255,255]]" elseif self.canEnable and self.modEnabled then ico = "[[menu/promo-active-btn.png;iconsize=42,42;color=255,255,127]]" elseif self.canEnable and not self.modEnabled then ico = "[[menu/promo-active-btn.png;iconsize=42,42;color=217,217,217]]" end end self.text = ico .. GetTranslatedStringByKey(self.rawText) if InputPressed("menu_accept") then self:onPressed() end end }, Teardown.GenericButton { id = "optionsBtn", w = 250, h = 50, fontSize = 36, text = "loc@UI_BUTTON_OPTIONS", onPressed = function(self) Command("mods.options", self.modId) end, onPreDraw = function(self) if LastInputDevice() == UI_DEVICE_GAMEPAD then self.text = "[[mmb;iconsize=42,42;color=255,255,255]]" .. GetTranslatedStringByKey("UI_BUTTON_OPTIONS") else self.text = "loc@UI_BUTTON_OPTIONS" end if InputPressed("mmb") then self:onPressed() end end } }, onCreate = function(self) self.itemImage = self:findById("itemImage") self.title = self:findById("title") self.author = self:findById("author") self.tags = self:findById("tags") self.desc = self:findById("description") self.details = self:findById("moreDetails") self.detailsIco = self:findById("moreDetailsIco") self.playBtn = self:findById("playBtn") self.optionsBtn = self:findById("optionsBtn") self.mainContent = self:findById("mainContent") self.descriptionArea = self:findById("descriptionArea") end, onPreDraw = function(self) if not Promo.selectedItem then return end if self.itemKey ~= Promo.selectedItem.key then self.descriptionArea.scrollBar:reset() end self:updateItemDetails() local availableH = 660 if self.mainContent.h + (self.desc.h - self.descriptionArea.h) > availableH then if InputDown("up") then self.descriptionArea.scrollBar:addOffset(InputValue("up") * 4, availableH, self.desc.h, true) end if InputDown("down") then self.descriptionArea.scrollBar:addOffset(-InputValue("down") * 4, availableH, self.desc.h, true) end local newH = self.descriptionArea.h - (self.mainContent.h - availableH) self.descriptionArea.h = newH < 0 and 100 or newH self.descriptionArea.w = 520 self.desc.wrapWidth = 510 else self.descriptionArea.h = self.desc.h self.descriptionArea.w = 540 self.desc.wrapWidth = 530 end end, updateItemDetails = function(self) self.itemKey = Promo.selectedItem.key local key = Promo.selectedItem.key self.itemImage.image = GetString(key .. ".image") self.title.text = GetString(key .. ".title") self.author.text = GetTranslatedStringByKey("loc@UI_TEXT_AUTHOR") .. ": " .. GetString(key .. ".author") self.desc.text = GetString(key .. ".desc") self.tags.text = GetTranslatedStringByKey("loc@UI_TEXT_TAGS") .. " " .. GetString(key .. ".tags") local tmp = splitString(key, ".") local modId = tmp[#tmp] local modKey = "mods.available."..modId local hasMod = HasKey(modKey) local canPlay = hasMod and GetBool(modKey..".playable") local canEnable = hasMod and GetBool(modKey..".override") local hasOptions = hasMod and GetBool(modKey..".options") local isLoading = (hasMod==false and isModDownloading(modId)) local steam_active = GetBool("game.steam.active") and GetBool("game.workshop") if not steam_active then self.details.colorFilter = {0.8, 0.8, 0.8, 0.8} end self.details.modId = modId self.detailsIco.visible = LastInputDevice() == UI_DEVICE_GAMEPAD self.optionsBtn.visible = hasOptions self.optionsBtn.modId = modId self.playBtn.modId = modId self.playBtn.hasMod = false self.playBtn.canPlay = false self.playBtn.canEnable = false self.playBtn.modEnabled = false self.playBtn.isLoading = false self.playBtn.steamActive = false if hasMod then self.playBtn.hasMod = true if canPlay then self.playBtn.rawText = "loc@UI_BUTTON_PLAY" self.playBtn.canPlay = true elseif canEnable then self.playBtn.canEnable = true self.playBtn.modEnabled = GetBool(modKey..".active") self.playBtn.rawText = self.playBtn.modEnabled and "loc@UI_BUTTON_ENABLED" or "loc@UI_BUTTON_DISABLED" else self.playBtn.rawText = "loc@UI_TEXT_INSTALLED" end elseif isLoading then self.playBtn.isLoading = true local l = GetTranslatedStringByKey("L_DOWNLOADING") local t = math.fmod(GetTime(), 4.0) if t > 1 then l = l.."." end if t > 2 then l = l.."." end if t > 3 then l = l.."." end self.playBtn.rawText = l else if steam_active then self.playBtn.steamActive = true self.playBtn.rawText = "loc@UI_BUTTON_SUBSCRIBE" end end end } }, Ui.Frame { w = 1800, h = 58, margin = { top = 10 }, Ui.ImageBox { path = "common/box-9.png", border = { width = 9, height = 9 }, w = 1800, h = 58, color = 0x100000099 }, Ui.HorizontalLayout { margin = { left = 20 }, vAlign = Ui.ContentLayout.Vertical.Middle, alignment = Ui.ContentLayout.Vertical.Middle, padding = 5, colorFilter = { 1, 1, 1, 0.6 }, onPressed = function(self) local isSteamActive = GetBool("game.steam.active") and GetBool("game.workshop") if isSteamActive then Command("mods.browse", "") end end, onMouseEnter = function(self) self.colorFilter = { 1, 1, 0.5, 1 } end, onMouseLeave = function(self) self.colorFilter = { 1, 1, 1, 0.6 } end, Ui.Icon { iconString = "zoom", onInputChanged = function(self, dev) if dev == UI_DEVICE_GAMEPAD then self.iconString = "zoom" else self.iconString = "crouch" end end }, Ui.Text { text = "loc@UI_BUTTON_MORE_MODS", font = { "medium.ttf", 22 }, onPressed = function(self) Command("mods.browse", "") end, onPreDraw = function(self) local isSteamActive = GetBool("game.steam.active") and GetBool("game.workshop") if not isSteamActive then self.colorFilter = { 0.8, 0.8, 0.8, 0.7 } end if LastInputDevice() == UI_DEVICE_GAMEPAD then if InputPressed("zoom") and isSteamActive then Command("mods.browse", "") end else if InputPressed("ctrl") and isSteamActive then Command("mods.browse", "") end end end }, Ui.Text { text = "[[gamepad_right_stick_up;iconsize=42,42]][[gamepad_right_stick_down;iconsize=42,42]]", font = { "medium.ttf", 22 }, onPreDraw = function (self) if LastInputDevice() == UI_DEVICE_GAMEPAD then self.text = "[[gamepad_right_stick_up;iconsize=42,42]][[gamepad_right_stick_down;iconsize=42,42]]"..GetTranslatedStringByKey("UI_MOD_SCROLL_DESCRIPTION") else self.text = nil end end }, }, Ui.HorizontalLayout { vAlign = Ui.ContentLayout.Vertical.Middle, hAlign = Ui.ContentLayout.Horizontal.Right, alignment = Ui.ContentLayout.Vertical.Middle, margin = { right = 20 }, padding = 5, colorFilter = { 1, 1, 1, 0.6 }, onInputChanged = function(self, curDev) self.padding = curDev == UI_DEVICE_GAMEPAD and 0 or 5 end, onPressed = function(self) Promo.Window:hide() end, onMouseEnter = function(self) self.colorFilter = { 1, 1, 0.5, 1 } end, onMouseLeave = function(self) self.colorFilter = { 1, 1, 1, 0.6 } end, Ui.Icon { iconString = "menu:menu_cancel" }, Ui.Text { text = "loc@UI_BUTTON_EXIT", font = { "medium.ttf", 22 }, } } } }, onCreate = function(self) self.groupsList = self:findById("groupsList") end, reload = function(self) self.groupsList:clear() local groups = ListKeys("promo.groups") for i=1, #groups do local groupKey = "promo.groups.".. groups[i] local g = Promo.Group { key = groupKey, title = GetString(groupKey .. ".title"), tile = { isLarge = GetString(groupKey .. ".size") == "large", isSquare = GetString(groupKey .. ".format") == "square"} } g.idx = i self.groupsList:append(g) end self.groupsList.selected = 1 self.groupsList.children[1]:focusEnter() end }, onInit = function(self) self.mainFrame = self:findById("mainFrame") self:addHideAreas() end, onShow = function(self) SetBool("savegame.promoupdated", false) local canvas = UiCanvasSize() self.x = canvas.w / 2 - self.w / 2 self.y = canvas.h / 2 - self.h / 2 self.mainFrame:reload() end, onClose = function(self) local groups = ListKeys("promo.groups") for i=1, #groups do local groupKey = "promo.groups."..groups[i] local items = ListKeys(groupKey.. ".items") for j=1, #items do local key = groupKey..".items."..items[j] local image = GetString(key .. ".image") local img = GetString(image) UiUnloadImage(img) end end end, onLogicUpdate = function(self) if not GetBool("savegame.legalnoticeshown") then Promo.LegalWindow:show() end end } Promo.LegalWindow = Ui.Window { fitToContent = true, animator = { playTime = 0.25 }, Ui.ImageBox { resizeToParent = true, path = "common/box-9.png", border = { width = 9, height = 9 }, color = 0x100000099 }, Ui.VerticalLayout { Ui.VerticalLayout { margin = { top = 30, left = 30, right = 30, bottom = 20 }, padding = 20, alignment = Ui.ContentLayout.Horizontal.Left, Ui.Text { hAlign = Ui.ContentLayout.Horizontal.Center, font = { "bold.ttf", 30 }, text = "loc@UI_TEXT_NOTICE_UPPERCASE" }, Ui.Text { font = { "regular.ttf", 20 }, text = "loc@UI_TEXT_THIS_WINDOW", wrapWidth = 800, color = 0xFFFFFF99 }, Ui.Text { font = { "regular.ttf", 20 }, text = "loc@UI_TEXT_PLEASE_BE", wrapWidth = 800, color = 0xFFFFFF99 }, Ui.Text { font = { "regular.ttf", 20 }, text = "loc@UI_TEXT_IF_YOU", wrapWidth = 800, color = 0xFFFFFF99 }, Ui.Text { font = { "regular.ttf", 20 }, text = "loc@UI_TEXT_IF_YOU_2", wrapWidth = 800, color = 0xFFFFFF99 }, Teardown.GenericButton { id = "acceptBtn", hAlign = Ui.ContentLayout.Horizontal.Center, text = "loc@UI_BUTTON_OK", w = 230, h = 40, fontSize = 27, onPressed = function(self) Promo.LegalWindow:hide() end }, Ui.Text { id = "acceptHint", hAlign = Ui.ContentLayout.Horizontal.Center, font = { "regular.ttf", 20 }, color = 0xFFFFFF99, text = "[[menu:menu_accept;iconsize=42,42]]" .. GetTranslatedStringByKey("loc@UI_BUTTON_OK"), onPreDraw = function(self) if InputPressed("menu_accept") then Promo.LegalWindow:hide() end end } }, }, onCreate = function(self) self.acceptBtn = self:findById("acceptBtn") self.acceptHint = self:findById("acceptHint") end, onPreDraw = function(self) local canvas = UiCanvasSize() self.x = canvas.w / 2 - self.w / 2 self.y = canvas.h / 2 - self.h / 2 self.acceptBtn.visible = LastInputDevice() ~= UI_DEVICE_GAMEPAD self.acceptHint.visible = LastInputDevice() == UI_DEVICE_GAMEPAD end, onShow = function(self) if not GetBool("savegame.legalnoticeshown") then SetBool("savegame.legalnoticeshown", true) end end } Promo.Helpers = {} function Promo.Helpers.GetVisible(list) local visibleItems = {} local isHorizontal = list.state.isHorizontal local listSpan = isHorizontal and list.w or list.h local scrollOffset = list.state:getOffset() local visibleBegin = -scrollOffset local visibleEnd = visibleBegin + listSpan local itemBegin = 0 for i=1,#list.children do local itemSize = isHorizontal and list.children[i].w or list.children[i].h local itemEnd = itemBegin + itemSize local isVisible = (not (itemBegin > visibleEnd)) and (not (itemEnd < visibleBegin)) if isVisible then visibleItems[#visibleItems + 1] = { item = list.children[i], idx = i, x = itemBegin + scrollOffset } end itemBegin = itemBegin + itemSize + list.state.itemsPadding end return visibleItems end