summaryrefslogtreecommitdiff
path: root/textbox.lua
diff options
context:
space:
mode:
Diffstat (limited to 'textbox.lua')
-rw-r--r--textbox.lua145
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