mirror of
https://github.com/IgorTimofeev/MineOS.git
synced 2025-12-20 11:09:21 +01:00
554 lines
22 KiB
Lua
554 lines
22 KiB
Lua
|
||
local libraries = {
|
||
buffer = "doubleBuffering",
|
||
unicode = "unicode",
|
||
event = "event",
|
||
}
|
||
|
||
for library in pairs(libraries) do if not _G[library] then _G[library] = require(libraries[library]) end end; libraries = nil
|
||
local GUI = {}
|
||
|
||
---------------------------------------------------- Универсальные методы --------------------------------------------------------
|
||
|
||
GUI.alignment = {
|
||
verticalCenter = 0,
|
||
horizontalCenter = 1,
|
||
horizontalAndVerticalCenter = 3,
|
||
}
|
||
|
||
GUI.directions = {
|
||
horizontal = 0,
|
||
vertical = 1,
|
||
}
|
||
|
||
GUI.buttonTypes = {
|
||
default = 0,
|
||
adaptive = 1,
|
||
framedDefault = 2,
|
||
framedAdaptive = 3,
|
||
}
|
||
|
||
GUI.colors = {
|
||
disabled = 0x888888,
|
||
disabledText = 0xAAAAAA,
|
||
}
|
||
|
||
-- Универсальный метод для проверки клика на прямоугольный объект
|
||
local function objectClicked(object, x, y)
|
||
if x >= object.x and y >= object.y and x <= object.x + object.width - 1 and y <= object.y + object.height - 1 and not object.disabled and not object.invisible ~= false then return true end
|
||
return false
|
||
end
|
||
|
||
local function objectSetDisabled(object, state)
|
||
object.disabled = state
|
||
end
|
||
|
||
--Создание базового примитива-объекта
|
||
function GUI.object(x, y, width, height)
|
||
return {
|
||
x = x,
|
||
y = y,
|
||
width = width,
|
||
height = height,
|
||
isClicked = objectClicked,
|
||
}
|
||
end
|
||
|
||
---------------------------------------------------- Кнопки --------------------------------------------------------------------
|
||
|
||
-- Универсальынй метод-рисоватор кнопки
|
||
local function drawButton(buttonObject, isPressed)
|
||
local textLength = unicode.len(buttonObject.text)
|
||
if textLength > buttonObject.width then buttonObject.text = unicode.sub(buttonObject.text, 1, buttonObject.width) end
|
||
|
||
local xText = math.floor(buttonObject.x + buttonObject.width / 2 - textLength / 2)
|
||
local yText = math.floor(buttonObject.y + buttonObject.height / 2)
|
||
local buttonColor = buttonObject.disabled and buttonObject.colors.disabled.button or (isPressed and buttonObject.colors.pressed.button or buttonObject.colors.default.button)
|
||
local textColor = buttonObject.disabled and buttonObject.colors.disabled.text or (isPressed and buttonObject.colors.pressed.text or buttonObject.colors.default.text)
|
||
|
||
if buttonObject.type == GUI.buttonTypes.default or buttonObject.type == GUI.buttonTypes.adaptive then
|
||
buffer.square(buttonObject.x, buttonObject.y, buttonObject.width, buttonObject.height, buttonColor, textColor, " ")
|
||
buffer.text(xText, yText, textColor, buttonObject.text)
|
||
elseif buttonObject.type == GUI.buttonTypes.framedDefault or buttonObject.type == GUI.buttonTypes.framedAdaptive then
|
||
buffer.frame(buttonObject.x, buttonObject.y, buttonObject.width, buttonObject.height, buttonColor)
|
||
buffer.text(xText, yText, textColor, buttonObject.text)
|
||
end
|
||
end
|
||
|
||
-- Метод-нажиматор кнопки
|
||
local function pressButton(buttonObject, pressTime)
|
||
drawButton(buttonObject, true)
|
||
buffer.draw()
|
||
os.sleep(pressTime or 0.2)
|
||
drawButton(buttonObject, false)
|
||
buffer.draw()
|
||
end
|
||
|
||
-- Создание таблицы кнопки со всеми необходимыми параметрами
|
||
local function createButtonObject(buttonType, x, y, width, height, buttonColor, textColor, buttonPressedColor, textPressedColor, text, disabledState)
|
||
local buttonObject = GUI.object(x, y, width, height)
|
||
buttonObject.colors = {
|
||
default = {
|
||
button = buttonColor,
|
||
text = textColor
|
||
},
|
||
pressed = {
|
||
button = buttonPressedColor,
|
||
text = textPressedColor
|
||
},
|
||
disabled = {
|
||
button = GUI.colors.disabled,
|
||
text = GUI.colors.disabledText,
|
||
}
|
||
}
|
||
buttonObject.disabled = disabledState
|
||
buttonObject.setDisabled = objectSetDisabled
|
||
buttonObject.type = buttonType
|
||
buttonObject.text = text
|
||
buttonObject.press = pressButton
|
||
buttonObject.draw = drawButton
|
||
return buttonObject
|
||
end
|
||
|
||
-- Кнопка фиксированных размеров
|
||
function GUI.button(x, y, width, height, buttonColor, textColor, buttonPressedColor, textPressedColor, text, disabledState)
|
||
local buttonObject = createButtonObject(GUI.buttonTypes.default, x, y, width, height, buttonColor, textColor, buttonPressedColor, textPressedColor, text, disabledState)
|
||
buttonObject:draw()
|
||
return buttonObject
|
||
end
|
||
|
||
-- Кнопка, подстраивающаяся под размер текста
|
||
function GUI.adaptiveButton(x, y, xOffset, yOffset, buttonColor, textColor, buttonPressedColor, textPressedColor, text, disabledState)
|
||
local buttonObject = createButtonObject(GUI.buttonTypes.adaptive, x, y, xOffset * 2 + unicode.len(text), yOffset * 2 + 1, buttonColor, textColor, buttonPressedColor, textPressedColor, text, disabledState)
|
||
buttonObject:draw()
|
||
return buttonObject
|
||
end
|
||
|
||
-- Кнопка в рамке
|
||
function GUI.framedButton(x, y, width, height, buttonColor, textColor, buttonPressedColor, textPressedColor, text, disabledState)
|
||
local buttonObject = createButtonObject(GUI.buttonTypes.framedDefault, x, y, width, height, buttonColor, textColor, buttonPressedColor, textPressedColor, text, disabledState)
|
||
buttonObject:draw()
|
||
return buttonObject
|
||
end
|
||
|
||
-- Кнопка в рамке, подстраивающаяся под размер текста
|
||
function GUI.adaptiveFramedButton(x, y, xOffset, yOffset, buttonColor, textColor, buttonPressedColor, textPressedColor, text, disabledState)
|
||
local buttonObject = createButtonObject(GUI.buttonTypes.framedAdaptive, x, y, xOffset * 2 + unicode.len(text), yOffset * 2 + 1, buttonColor, textColor, buttonPressedColor, textPressedColor, text, disabledState)
|
||
buttonObject:draw()
|
||
return buttonObject
|
||
end
|
||
|
||
-- Вертикальный или горизонтальный ряд кнопок
|
||
-- Каждая кнопка - это массив вида {enum GUI.buttonTypes.default или GUI.buttonTypes.adaptive, int ширина/отступ, int высота/отступ, int цвет кнопки, int цвет текста, int цвет нажатой кнопки, int цвет нажатого текста, string текст}
|
||
-- Метод возвращает обычный массив кнопочных объектов (см. выше)
|
||
function GUI.buttons(x, y, direction, spaceBetweenButtons, ...)
|
||
local buttons = {...}
|
||
local buttonObjects = {}
|
||
|
||
local function drawCorrectButton(i)
|
||
if buttons[i][1] == GUI.buttonTypes.default then
|
||
return GUI.button(x, y, buttons[i][2], buttons[i][3], buttons[i][4], buttons[i][5], buttons[i][6], buttons[i][7], buttons[i][8])
|
||
elseif buttons[i][1] == GUI.buttonTypes.adaptive then
|
||
return GUI.adaptiveButton(x, y, buttons[i][2], buttons[i][3], buttons[i][4], buttons[i][5], buttons[i][6], buttons[i][7], buttons[i][8])
|
||
elseif buttons[i][1] == GUI.buttonTypes.framedDefault then
|
||
return GUI.framedButton(x, y, buttons[i][2], buttons[i][3], buttons[i][4], buttons[i][5], buttons[i][6], buttons[i][7], buttons[i][8])
|
||
elseif buttons[i][1] == GUI.buttonTypes.framedAdaptive then
|
||
return GUI.adaptiveFramedButton(x, y, buttons[i][2], buttons[i][3], buttons[i][4], buttons[i][5], buttons[i][6], buttons[i][7], buttons[i][8])
|
||
else
|
||
error("Неподдерживаемый тип кнопки: " .. tostring(buttons[i][1]))
|
||
end
|
||
end
|
||
|
||
for i = 1, #buttons do
|
||
buttonObjects[i] = drawCorrectButton(i)
|
||
if direction == GUI.directions.horizontal then
|
||
x = x + buttonObjects[i].width + spaceBetweenButtons
|
||
elseif direction == GUI.directions.vertical then
|
||
y = y + buttonObjects[i].height + spaceBetweenButtons
|
||
else
|
||
error("Неподдерживаемое направление: " .. tostring(buttons[i][1]))
|
||
end
|
||
end
|
||
|
||
return buttonObjects
|
||
end
|
||
|
||
function GUI.menu(x, y, width, menuColor, ...)
|
||
local buttons = {...}
|
||
buffer.square(x, y, width, 1, menuColor)
|
||
x = x + 1
|
||
local menuObjects = {}
|
||
for i = 1, #buttons do
|
||
menuObjects[i] = GUI.adaptiveButton(x, y, 1, 0, menuColor, buttons[i].textColor, buttons[i].buttonPressedColor or 0x3366CC, buttons[i].textPressedColor or 0xFFFFFF, buttons[i].text)
|
||
x = x + menuObjects[i].width
|
||
end
|
||
return menuObjects
|
||
end
|
||
|
||
function GUI.windowActionButtons(x, y, fatSymbol)
|
||
local symbol = fatSymbol and "⬤" or "●"
|
||
local windowActionButtons, background = {}
|
||
background = buffer.get(x, y); windowActionButtons.close = GUI.button(x, y, 1, 1, background, 0xFF4940, background, 0x992400, symbol); x = x + 2
|
||
background = buffer.get(x, y); windowActionButtons.minimize = GUI.button(x, y, 1, 1, background, 0xFFB640, background, 0x996D00, symbol); x = x + 2
|
||
background = buffer.get(x, y); windowActionButtons.maximize = GUI.button(x, y, 1, 1, background, 0x00B640, background, 0x006D40, symbol); x = x + 2
|
||
return windowActionButtons
|
||
end
|
||
|
||
function GUI.toolbar(x, y, width, height, spaceBetweenElements, currentElement, toolbarColor, elementTextColor, activeElementColor, activeElementTextColor, ...)
|
||
local elements, objects, elementLength, isCurrent, elementWidth = {...}, {}
|
||
local totalWidth = 0; for i = 1, #elements do totalWidth = totalWidth + unicode.len(elements[i]) + 2 + spaceBetweenElements end; totalWidth = totalWidth - spaceBetweenElements
|
||
buffer.square(x, y, width, height, toolbarColor)
|
||
x = math.floor(x + width / 2 - totalWidth / 2)
|
||
local yText = math.floor(y + height / 2)
|
||
|
||
for i = 1, #elements do
|
||
elementLength, isCurrent = unicode.len(elements[i]), i == currentElement
|
||
elementWidth = elementLength + 2
|
||
if isCurrent then buffer.square(x, y, elementWidth, height, activeElementColor) end
|
||
buffer.text(x + 1, yText, isCurrent and activeElementTextColor or elementTextColor, elements[i])
|
||
table.insert(objects, GUI.object(x, y, elementWidth, height))
|
||
x = x + elementWidth + spaceBetweenElements
|
||
end
|
||
|
||
return objects
|
||
end
|
||
|
||
function GUI.progressBar(x, y, width, height, firstColor, secondColor, value, maxValue, thin)
|
||
local percent = value / maxValue
|
||
local activeWidth = math.floor(percent * width)
|
||
if thin then
|
||
buffer.text(x, y, firstColor, string.rep("━", width))
|
||
buffer.text(x, y, secondColor, string.rep("━", activeWidth))
|
||
else
|
||
buffer.square(x, y, width, height, firstColor)
|
||
buffer.square(x, y, activeWidth, height, secondColor)
|
||
end
|
||
end
|
||
|
||
function GUI.windowShadow(x, y, width, height, transparency)
|
||
buffer.square(x + width, y + 1, 2, height, 0x000000, 0x000000, " ", transparency)
|
||
buffer.square(x + 2, y + height, width - 2, 1, 0x000000, 0x000000, " ", transparency)
|
||
end
|
||
|
||
------------------------------------------------- Окна -------------------------------------------------------------------
|
||
|
||
-- Красивое окошко для отображения сообщения об ошибке. Аргумент errorWindowParameters может принимать следующие значения:
|
||
-- local errorWindowParameters = {
|
||
-- backgroundColor = 0x262626,
|
||
-- textColor = 0xFFFFFF,
|
||
-- truncate = 50,
|
||
-- title = {color = 0xFF8888, text = "Ошибочка"}
|
||
-- noAnimation = true,
|
||
-- }
|
||
function GUI.error(text, errorWindowParameters)
|
||
--Всякие константы, бла-бла
|
||
local backgroundColor = (errorWindowParameters and errorWindowParameters.backgroundColor) or 0x1b1b1b
|
||
local errorPixMap = {
|
||
{{0xffdb40 , 0xffffff,"#"}, {0xffdb40 , 0xffffff, "#"}, {backgroundColor, 0xffdb40, "▟"}, {backgroundColor, 0xffdb40, "▙"}, {0xffdb40 , 0xffffff, "#"}, {0xffdb40 , 0xffffff, "#"}},
|
||
{{0xffdb40 , 0xffffff,"#"}, {backgroundColor, 0xffdb40, "▟"}, {0xffdb40 , 0xffffff, " "}, {0xffdb40 , 0xffffff, " "}, {backgroundColor, 0xffdb40, "▙"}, {0xffdb40 , 0xffffff, "#"}},
|
||
{{backgroundColor, 0xffdb40,"▟"}, {0xffdb40 , 0xffffff, "c"}, {0xffdb40 , 0xffffff, "y"}, {0xffdb40 , 0xffffff, "k"}, {0xffdb40 , 0xffffff, "a"}, {backgroundColor, 0xffdb40, "▙"}},
|
||
}
|
||
local textColor = (errorWindowParameters and errorWindowParameters.textColor) or 0xFFFFFF
|
||
local buttonWidth = 12
|
||
local verticalOffset = 2
|
||
local minimumHeight = verticalOffset * 2 + #errorPixMap
|
||
local height = 0
|
||
local widthOfText = math.floor(buffer.screen.width * 0.5)
|
||
|
||
--Ебемся с текстом, делаем его пиздатым во всех смыслах
|
||
if type(text) ~= "table" then
|
||
text = tostring(text)
|
||
text = (errorWindowParameters and errorWindowParameters.truncate) and unicode.sub(text, 1, errorWindowParameters.truncate) or text
|
||
text = { text }
|
||
end
|
||
text = GUI.stringWrap(text, widthOfText)
|
||
|
||
|
||
--Ебашим высоту правильнуюe
|
||
height = verticalOffset * 2 + #text + 1
|
||
if errorWindowParameters and errorWindowParameters.title then height = height + 2 end
|
||
if height < minimumHeight then height = minimumHeight end
|
||
|
||
--Ебашим стартовые коорды отрисовки
|
||
local x, y = math.ceil(buffer.screen.width / 2 - widthOfText / 2), math.ceil(buffer.screen.height / 2 - height / 2)
|
||
local OKButton = {}
|
||
local oldPixels = buffer.copy(1, y, buffer.screen.width, height)
|
||
|
||
--Отрисовочка
|
||
local function draw()
|
||
local yPos = y
|
||
--Подложка
|
||
buffer.square(1, yPos, buffer.screen.width, height, backgroundColor, 0x000000); yPos = yPos + verticalOffset
|
||
buffer.customImage(x - #errorPixMap[1] - 3, yPos, errorPixMap)
|
||
--Титл, епта!
|
||
if errorWindowParameters and errorWindowParameters.title then buffer.text(x, yPos, errorWindowParameters.title.color, errorWindowParameters.title.text); yPos = yPos + 2 end
|
||
--Текстус
|
||
for i = 1, #text do buffer.text(x, yPos, textColor, text[i]); yPos = yPos + 1 end; yPos = yPos + 1
|
||
--Кнопачка
|
||
OKButton = GUI.button(x + widthOfText - buttonWidth, y + height - 2, buttonWidth, 1, 0x3392FF, 0xFFFFFF, 0xFFFFFF, 0x262626, "OK")
|
||
--Атрисовачка
|
||
buffer.draw()
|
||
end
|
||
|
||
--Графонистый выход
|
||
local function quit()
|
||
OKButton:press(0.2)
|
||
buffer.paste(1, y, oldPixels)
|
||
buffer.draw()
|
||
end
|
||
|
||
--Онимацыя
|
||
if not (errorWindowParameters and errorWindowParameters.noAnimation) then for i = 1, height do buffer.setDrawLimit(1, math.floor(buffer.screen.height / 2) - i, buffer.screen.width, i * 2); draw(); os.sleep(0.05) end; buffer.resetDrawLimit() end
|
||
draw()
|
||
|
||
--Анализ говнища
|
||
while true do
|
||
local e = {event.pull()}
|
||
if e[1] == "key_down" then
|
||
if e[4] == 28 then
|
||
quit(); return
|
||
end
|
||
elseif e[1] == "touch" then
|
||
if OKButton:isClicked(e[3], e[4]) then
|
||
quit(); return
|
||
end
|
||
end
|
||
end
|
||
end
|
||
|
||
--------------------------------------------------------------------------------------------------------------------------------
|
||
|
||
-- local textFieldProperties = {
|
||
-- --Регурярное выражение, которому должны соответствовать вводимые данные. При несоответствии на выходе из функции выдается первоначальный текст, поданынй на выход функции
|
||
-- regex = "^%d+$",
|
||
-- --Отключает символ многоточия при выходе за пределы текстового поля
|
||
-- disableDots = true,
|
||
-- --Попросту отрисовывает всю необходимую информацию без активации нажатия на клавиши
|
||
-- justDrawNotEvent = true,
|
||
-- --Задержка между миганимем курсора
|
||
-- cursorBlinkDelay = 1.5,
|
||
-- --Цвет курсора
|
||
-- cursorColor = 0xFF7777,
|
||
-- --Символ, используемый для отрисовки курсора
|
||
-- cursorSymbol = "▌",
|
||
-- --Символ-маскировщик, на который будет визуально заменен весь вводимый текст. Полезно для полей ввода пароля
|
||
-- maskTextWithSymbol = "*",
|
||
-- }
|
||
|
||
function GUI.input(x, y, width, foreground, startText, textFieldProperties)
|
||
if not (y >= buffer.drawLimit.y and y <= buffer.drawLimit.y2) then return startText end
|
||
|
||
local text = startText
|
||
local textLength = unicode.len(text)
|
||
local cursorBlinkState = false
|
||
local cursorBlinkDelay = (textFieldProperties and textFieldProperties.cursorBlinkDelay) and textFieldProperties.cursorBlinkDelay or 0.5
|
||
local cursorColor = (textFieldProperties and textFieldProperties.cursorColor) and textFieldProperties.cursorColor or 0x00A8FF
|
||
local cursorSymbol = (textFieldProperties and textFieldProperties.cursorSymbol) and textFieldProperties.cursorSymbol or "┃"
|
||
|
||
local oldPixels = {}; for i = x, x + width - 1 do table.insert(oldPixels, { buffer.get(i, y) }) end
|
||
|
||
local function drawOldPixels()
|
||
for i = 1, #oldPixels do buffer.set(x + i - 1, y, oldPixels[i][1], oldPixels[i][2], oldPixels[i][3]) end
|
||
end
|
||
|
||
local function getTextLength()
|
||
textLength = unicode.len(text)
|
||
end
|
||
|
||
local function textFormat()
|
||
local formattedText = text
|
||
|
||
if textFieldProperties and textFieldProperties.maskTextWithSymbol then
|
||
formattedText = string.rep(textFieldProperties.maskTextWithSymbol or "*", textLength)
|
||
end
|
||
|
||
if textLength > width then
|
||
if textFieldProperties and textFieldProperties.disableDots then
|
||
formattedText = unicode.sub(formattedText, -width, -1)
|
||
else
|
||
formattedText = "…" .. unicode.sub(formattedText, -width + 1, -1)
|
||
end
|
||
end
|
||
|
||
return formattedText
|
||
end
|
||
|
||
local function draw()
|
||
drawOldPixels()
|
||
buffer.text(x, y, foreground, textFormat())
|
||
|
||
if cursorBlinkState then
|
||
local cursorPosition = textLength < width and x + textLength or x + width - 1
|
||
local bg = buffer.get(cursorPosition, y)
|
||
buffer.set(cursorPosition, y, bg, cursorColor, cursorSymbol)
|
||
end
|
||
|
||
if not (textFieldProperties and textFieldProperties.justDrawNotEvent) then buffer.draw() end
|
||
end
|
||
|
||
local function backspace()
|
||
if unicode.len(text) > 0 then text = unicode.sub(text, 1, -2); getTextLength(); draw() end
|
||
end
|
||
|
||
local function quit()
|
||
cursorBlinkState = false
|
||
if textFieldProperties and textFieldProperties.regex and not string.match(text, textFieldProperties.regex) then
|
||
text = startText
|
||
draw()
|
||
return startText
|
||
end
|
||
draw()
|
||
return text
|
||
end
|
||
|
||
draw()
|
||
|
||
if textFieldProperties and textFieldProperties.justDrawNotEvent then return startText end
|
||
|
||
while true do
|
||
local e = { event.pull(cursorBlinkDelay) }
|
||
if e[1] == "key_down" then
|
||
if e[4] == 14 then
|
||
backspace()
|
||
elseif e[4] == 28 then
|
||
return quit()
|
||
else
|
||
local symbol = unicode.char(e[3])
|
||
if not keyboard.isControl(e[3]) then
|
||
text = text .. symbol
|
||
getTextLength()
|
||
draw()
|
||
end
|
||
end
|
||
elseif e[1] == "clipboard" then
|
||
text = text .. e[3]
|
||
getTextLength()
|
||
draw()
|
||
elseif e[1] == "touch" then
|
||
return quit()
|
||
else
|
||
cursorBlinkState = not cursorBlinkState
|
||
draw()
|
||
end
|
||
end
|
||
end
|
||
|
||
local function drawTextField(object, isFocused)
|
||
if not object.invisible then
|
||
local background = object.disabled and object.colors.disabled.textField or (isFocused and object.colors.focused.textField or object.colors.default.textField)
|
||
local foreground = object.disabled and object.colors.disabled.text or (isFocused and object.colors.focused.text or object.colors.default.text)
|
||
local y = math.floor(object.y + object.height / 2)
|
||
local text = isFocused and (object.text or "") or (object.text or object.placeholderText or "")
|
||
|
||
if background then buffer.square(object.x, object.y, object.width, object.height, background, foreground, " ") end
|
||
local resultText = GUI.input(object.x + 1, y, object.width - 2, foreground, text, {justDrawNotEvent = not isFocused})
|
||
object.text = isFocused and resultText or object.text
|
||
end
|
||
end
|
||
|
||
local function textFieldBeginInput(object)
|
||
drawTextField(object, true)
|
||
if object.text == "" then object.text = nil; drawTextField(object, false); buffer.draw() end
|
||
end
|
||
|
||
function GUI.textField(x, y, width, height, textFieldColor, textColor, textFieldFocusedColor, textFocusedColor, text, placeholderText, disabledState, invisibleState)
|
||
local object = GUI.object(x, y, width, height)
|
||
object.invisible = invisibleState
|
||
object.disabled = disabledState
|
||
object.colors = {
|
||
default = {
|
||
textField = textFieldColor,
|
||
text = textColor
|
||
},
|
||
focused = {
|
||
textField = textFieldFocusedColor,
|
||
text = textFocusedColor
|
||
},
|
||
disabled = {
|
||
textField = GUI.colors.disabled,
|
||
text = GUI.colors.disabledText,
|
||
}
|
||
}
|
||
object.text = text
|
||
object.placeholderText = placeholderText
|
||
object.isClicked = objectClicked
|
||
object.draw = drawTextField
|
||
object.input = textFieldBeginInput
|
||
object:draw()
|
||
return object
|
||
end
|
||
|
||
--------------------------------------------------------------------------------------------------------------------------------
|
||
|
||
--Функция по переносу слов на новую строку в зависимости от ограничения по ширине
|
||
function GUI.stringWrap(strings, limit)
|
||
local currentString = 1
|
||
while currentString <= #strings do
|
||
local words = {}; for word in string.gmatch(tostring(strings[currentString]), "[^%s]+") do table.insert(words, word) end
|
||
|
||
local newStringThatFormedFromWords, oldStringThatFormedFromWords = "", ""
|
||
local word = 1
|
||
local overflow = false
|
||
while word <= #words do
|
||
oldStringThatFormedFromWords = oldStringThatFormedFromWords .. (word > 1 and " " or "") .. words[word]
|
||
if unicode.len(oldStringThatFormedFromWords) > limit then
|
||
--ЕБЛО
|
||
if unicode.len(words[word]) > limit then
|
||
local left = unicode.sub(oldStringThatFormedFromWords, 1, limit)
|
||
local right = unicode.sub(strings[currentString], unicode.len(left) + 1, -1)
|
||
overflow = true
|
||
strings[currentString] = left
|
||
if strings[currentString + 1] then
|
||
strings[currentString + 1] = right .. " " .. strings[currentString + 1]
|
||
else
|
||
strings[currentString + 1] = right
|
||
end
|
||
end
|
||
break
|
||
else
|
||
newStringThatFormedFromWords = oldStringThatFormedFromWords
|
||
end
|
||
word = word + 1
|
||
end
|
||
|
||
if word <= #words and not overflow then
|
||
local fuckToAdd = table.concat(words, " ", word, #words)
|
||
if strings[currentString + 1] then
|
||
strings[currentString + 1] = fuckToAdd .. " " .. strings[currentString + 1]
|
||
else
|
||
strings[currentString + 1] = fuckToAdd
|
||
end
|
||
strings[currentString] = newStringThatFormedFromWords
|
||
end
|
||
|
||
currentString = currentString + 1
|
||
end
|
||
|
||
return strings
|
||
end
|
||
|
||
--------------------------------------------------------------------------------------------------------------------------------
|
||
|
||
function GUI.centeredText(centrationENUM, coordinate, color, text)
|
||
local textLength, x, y = unicode.len(text)
|
||
if centrationENUM == GUI.alignment.verticalCenter then
|
||
x, y = math.floor(buffer.screen.width / 2 - textLength / 2), coordinate
|
||
elseif centrationENUM == GUI.alignment.horizontalCenter then
|
||
x, y = coordinate, math.floor(buffer.screen.height / 2)
|
||
else
|
||
x, y = math.floor(buffer.screen.width / 2 - textLength / 2), math.floor(buffer.screen.height / 2)
|
||
end
|
||
|
||
buffer.text(x, y, color, text)
|
||
end
|
||
|
||
--------------------------------------------------------------------------------------------------------------------------------
|
||
|
||
return GUI
|
||
|
||
|
||
|
||
|
||
|
||
|