#include "ui_defs.lua" function stringCapitalize(str) return str:gsub("^%l", string.upper) end function stringSplit(str, sep) sep = sep or "%s" local t = {} for s in string.gmatch(str, "([^"..sep.."]+)") do table.insert(t, s) end return t end Ui._DefaultIcon = function(obj) local dIco = Ui.Object:new { iconString = "default", draw = function(self) UiPush() UiColor(1,1,1,1) if LastInputDevice() == UI_DEVICE_MOUSE then UiTranslate(0, -5) end UiFont("regular.ttf", self.fH or self.h) UiText(self.iconString) UiPop() end } return dIco:new(obj) end local style = { white = { imagebox = "ui/common/box-solid-6.png", imageboxOutline = "ui/common/box-6-outline-1.png", textColor = { 0, 0, 0, 1 }, color = { 1, 1, 1, 1 }, }, transparent = { imageboxOutline = "ui/common/box-6-outline-1.png", textColor = { 1, 1, 1, 1 }, color = { 0, 0, 0, 1 }, } } Ui._KeyIcon = function(obj) local kIco = Ui.Object:new { key = "key", draw = function(self) local style = style[self.parent.style] UiFrameOccupy(self.w, self.h) local defaultFontSize = 21 local defaultIcoSize = 42 local padding = self.w / defaultIcoSize UiPush() UiAlign("top left") UiTranslate(padding, padding) UiColor(unpack(style.color)) if style.imagebox then UiImageBox(style.imagebox, self.w - 2 * padding, self.h - 2 * padding, 6, 6) end UiColor(unpack(style.textColor)) if (style.imageboxOutline) then UiImageBox(style.imageboxOutline, self.w - 2 * padding, self.h - 2 * padding, 6, 6) end UiTranslate(self.w / 2 - padding, self.h / 2 - padding) UiAlign("center middle") UiFont("regular.ttf", defaultFontSize * self.w / defaultIcoSize) UiFrameSkipItem(true) UiColor(unpack(style.textColor)) UiText(stringCapitalize(self.key)) UiPop() end } return kIco:new(obj) end Ui._Separator = function(obj) local s = Ui.Object:new { separator = "separator", draw = function(self) UiPush() UiColor(1,1,1,1) UiFont("regular.ttf", self.h) UiAlign("center middle") UiTranslate(self.w / 2, self.h / 2) UiScale(0.7,0.7) UiText(self.separator) UiPop() end } return s:new(obj) end Ui.Icon = function(obj) local basePath = "ui/common/key_icons/" local keyExceptions = { { key = "uparrow", path = "guparrow.png" }, { key = "downarrow", path = "downarrow.png" }, { key = "leftarrow", path = "leftarrow.png" }, { key = "rightarrow", path = "rightarrow.png" }, { key = "backspace", path = "backspace.png" }, { key = "return", path = "enter.png" }, { key = "space", path = "space.png" }, { key = "ctrl", path = "ctrl.png" }, { key = "tab", path = "tab.png" }, } local specialIcons = { { key = "lmb", path = "lmb.png" }, { key = "rmb", path = "rmb.png" }, { key = "mmb", path = "mmb.png" }, { key = "wheel", path = "wheel.png" }, { key = "wasd", path = "wasd.png" }, { key = "enter", path = "enter.png" }, { key = "space", path = "space.png" }, { key = "alt", path = "alt.png" }, { key = "del", path = "del.png" }, { key = "ctrl", path = "ctrl.png" }, { key = "shift", path = "shift.png" }, } local ico = Ui.HorizontalLayout { iconString = "", alignment = Ui.ContentLayout.Vertical.Middle, style = "transparent", -- default ico size for ingame UI w = 42, h = 42, onInputChanged = function(self) self:_updateDrawSequence() end, _updateDrawSequence = function(self) self.children = {} self.w = 0 local values = type(self.iconString) == "table" and self.iconString or { self.iconString } local inputDevice = LastInputDevice() if inputDevice == UI_DEVICE_GAMEPAD then local formatString = "" if #values == 1 then formatString = string.format("[[%s;iconsize=%i,%i]]", values[1], self.iW, self.iH) else for i = 1,(#values - 1) do local s1 = string.format("[[%s;iconsize=%i,%i]]", values[i], self.iW, self.iH) local s2 = string.format("[[%s;iconsize=%i,%i]]", values[i + 1], self.iW, self.iH) formatString = formatString .. s1 .. self._concatOps[i] .. s2 end end local w = GetTextSizeWithFont(formatString, "regular.ttf", self.iH) self:append(Ui._DefaultIcon{ iconString = formatString, w = w, h = self.iH, fH = self.iH * 0.7 }) self.w = self.w + w else if #values == 1 then local formatString, key = self:_getKeyBoardString(values[1]) if formatString ~= "" then self:append(Ui._DefaultIcon{ iconString = formatString, w = self.iW, h = self.iH }) self.w = self.w + self.iW else self:append(Ui._KeyIcon{ key = key, w = self.iW, h = self.iH }) self.w = self.w + self.iW end else for i = 1,(#values - 1) do local s1, k1 = self:_getKeyBoardString(values[i]) local s2, k2 = self:_getKeyBoardString(values[i + 1]) if s1 ~= "" then self:append(Ui._DefaultIcon{ iconString = s1, w = self.iW, h = self.iH }) self.w = self.w + self.iW else self:append(Ui._KeyIcon{ key = k1, w = self.iW, h = self.iH }) self.w = self.w + self.iW end local separator = self._concatOps[i] local separatorWidth = GetTextSizeWithFont(separator, "regular.ttf", self.iH) self:append(Ui._Separator { separator = separator, h = self.iH, w = separatorWidth}) self.w = self.w + separatorWidth if s2 ~= "" then self:append(Ui._DefaultIcon{ iconString = s2, w = self.iW, h = self.iH }) self.w = self.w + self.iW else self:append(Ui._KeyIcon{ key = k2, w = self.iW, h = self.iH }) self.w = self.w + self.iW end end end end end, _getKeyBoardString = function(self, value) local split = stringSplit(value, ":") local action = "" if #split > 1 then action = split[2] else action = split[1] end if split[1] == "key" then return "", split[2] end local key = GetKeyByAction(action) local isException, exceptionIco = tableContains(keyExceptions, function(it) return it.key == key end) local isSpecial, specialIco = tableContains(specialIcons, function(it) return it.key == action end) local formatString = "[[%s/%s/%s;iconsize=%i,%i]]" local path = isSpecial and specialIco.path or (isException and exceptionIco.path or nil) if path then local result = string.format(formatString, basePath, self.style, path, self.iW, self.iH) return result end return "", key end, _concatOps = {}, } -- combine onCreate to guarantee correct size update obj.iW = obj.w or ico.w obj.iH = obj.h or ico.h if obj.onCreate then local originOnCreate = obj.onCreate obj.onCreate = function(self) self:_updateDrawSequence() originOnCreate(self) end end if obj.onInputChanged then local originOnInputChanged = obj.onInputChanged obj.onInputChanged = function(self, dev) originOnInputChanged(self, dev) self:_updateDrawSequence() end end local instance = ico:new(obj) local mt = getmetatable(instance) mt.makeCombined = function(a, b, op) local it = Ui.Icon {style = a.style} local strings = {} if type(a.iconString) == "string" then table.insert(strings, a.iconString) else tableCombine(strings, a.iconString) end if type(b.iconString) == "string" then table.insert(strings, b.iconString) else tableCombine(strings, b.iconString) end local concatOps = {} tableCombine(concatOps, a._concatOps) table.insert(concatOps, op) tableCombine(concatOps, b._concatOps) it.iconString = strings it._concatOps = concatOps -- inherit icon size from the left object it.iW = a.w it.iH = a.h it:_updateDrawSequence() return it end mt.__div = function(a, b) return mt.makeCombined(a, b, "/") end mt.__add = function(a, b) return mt.makeCombined(a, b, "+") end mt.__mul = function(a, b) return mt.makeCombined(a, b, ",") end return instance end Ui.ActionIcons = {} Ui.ActionIcons.iconsCache = {} Ui.ActionIcons.mt = {} Ui.ActionIcons.mt.__index = function(table, key) if Ui.ActionIcons.iconsCache[key] ~= nil then return Ui.ActionIcons.iconsCache[key] else Ui.ActionIcons.iconsCache[key] = Ui.Icon { iconString = key } return Ui.ActionIcons.iconsCache[key] end end setmetatable(Ui.ActionIcons, Ui.ActionIcons.mt)