diff options
| author | cursed22bc <admin@pixeldawn.org> | 2026-03-08 23:15:16 +0200 |
|---|---|---|
| committer | cursed22bc <admin@pixeldawn.org> | 2026-03-08 23:15:16 +0200 |
| commit | 97d0d1ecc0cfd5516cfad2d477faa4d35992e7ba (patch) | |
| tree | 5ba61a59723d5c9ceb8059388d35bdcb069af743 /textbox.lua | |
| parent | aeb596379bbf1bec84efb294ff5bbbee922364ba (diff) | |
liquid shader and basic text render
Diffstat (limited to 'textbox.lua')
| -rw-r--r-- | textbox.lua | 145 |
1 files changed, 145 insertions, 0 deletions
diff --git a/textbox.lua b/textbox.lua new file mode 100644 index 0000000..35b66a4 --- /dev/null +++ b/textbox.lua @@ -0,0 +1,145 @@ +local fonts = require("fonts") + +local Textbox = {} +Textbox.__index = Textbox + +function Textbox:new() + local self = setmetatable({}, Textbox) + self.active = false + self.text = "" + self.visibleText = "" + self.mode = "show" + self.x = 0 + self.y = 0 + self.align = "center" + self.maxLines = nil + self.maxChars = nil + self.charIndex = 0 + self.timer = 0 + self.speed = 0.03 + self.width = 0 + self.height = 0 + self.lines = {} + return self +end + +function Textbox:show(text, pos, mode, opts) + opts = opts or {} + self.text = text + self.mode = mode or "show" + self.x = pos[1] + self.y = pos[2] + self.align = pos[3] or "center" + self.maxLines = opts.maxLines + self.maxChars = opts.maxChars + self.fontSize = opts.fontSize + self.centeredText = opts.centeredText + self.wrapToFit = opts.wrapToFit + self.life = opts.life + self.lifeTimer = 0 + self.charIndex = 0 + self.visibleText = "" + self.timer = 0 + self.active = true + self:layout() +end + +function Textbox:layout() + self.maxLines = self.maxLines or 4 + self.maxChars = self.maxChars or 40 + self.font = self.fontSize and fonts.get(self.fontSize) or love.graphics.getFont() + local padding = 10 + if self.wrapToFit then + local tempWidth = self.font:getWidth(string.rep("A", self.maxChars)) + local _, lines = self.font:getWrap(self.text, tempWidth) + self.lines = lines or {} + self.lines = self.lines or {} + local maxW = 0 + for _, line in ipairs(self.lines) do + local w = self.font:getWidth(line) + if w > maxW then maxW = w end + end + local lineCount = math.max(1, #self.lines) + self.width = maxW + padding * 2 + self.height = self.font:getHeight() * lineCount + padding * 2 + else + self.width = self.font:getWidth(string.rep("A", self.maxChars)) + padding * 2 + self.height = self.font:getHeight() * self.maxLines + padding * 2 + end +end + +function Textbox:wrap(text) + local lines = {} + local line = "" + for word in text:gmatch("%S+") do + if line == "" then + line = word + elseif #line + #word + 1 <= self.maxChars then + line = line .. " " .. word + else + table.insert(lines, line) + line = word + end + end + if line ~= "" then + table.insert(lines, line) + end + return lines +end + +function Textbox:update(dt) + if not self.active then return end + if self.life then + self.lifeTimer = self.lifeTimer + dt + if self.lifeTimer >= self.life then + self:hide() + return + end + end + if self.mode == "write" then + self.timer = self.timer + dt + if self.timer > self.speed then + self.timer = 0 + self.charIndex = self.charIndex + 1 + self.visibleText = self.text:sub(1, self.charIndex) + end + else + self.visibleText = self.text + end +end + +function Textbox:draw() + if not self.active then return end + local x = self.x + local y = self.y + if self.align == "center" then + x = x - self.width / 2 + y = y - self.height / 2 + elseif self.align == "right" then + x = x - self.width + end + local padding = 10 + local textAlign = self.centeredText and "center" or "left" + local textX = x + padding + local textY = y + padding + if self.centeredText then + local _, wrappedLines = self.font:getWrap(self.visibleText, self.width - padding * 2) + local numLines = wrappedLines and #wrappedLines or 1 + local textHeight = self.font:getHeight() * numLines + local vertExtra = math.max(0, self.height - padding * 2 - textHeight) + textY = y + padding + vertExtra / 2 + end + local prevFont = love.graphics.getFont() + love.graphics.setFont(self.font) + love.graphics.setColor(0, 0, 0, 0.8) + love.graphics.rectangle("fill", x, y, self.width, self.height) + love.graphics.setColor(1, 1, 1, 1) + love.graphics.printf(self.visibleText, textX, textY, self.width - padding * 2, textAlign) + love.graphics.setFont(prevFont) +end + +function Textbox:hide() + self.active = false +end + +return Textbox |
