feat: added new discussion functionality, implemented textbox draw functionality, added first discussion with sumphore to the street
This commit is contained in:
@@ -46,36 +46,108 @@ function UI.update_menu(items, selected_item)
|
||||
return selected_item
|
||||
end
|
||||
|
||||
--- Draws a bordered textbox with scrolling text.
|
||||
--- @within UI
|
||||
--- @param text string The text to display (multi-line supported).<br/>
|
||||
--- @param box_x number The x-coordinate of the box.<br/>
|
||||
--- @param box_y number The y-coordinate of the box.<br/>
|
||||
--- @param box_w number The width of the box.<br/>
|
||||
--- @param box_h number The height of the box.<br/>
|
||||
--- @param scroll_y number The vertical scroll offset for the text (0 = top, increases to scroll up).<br/>
|
||||
--- @param[opt] color number The text color (default: Config.colors.white).<br/>
|
||||
--- @param[opt] bg_color number The background fill color (default: Config.colors.dark_grey).<br/>
|
||||
--- @param[opt] border_color number The border color (default: Config.colors.white).<br/>
|
||||
--- @param[opt] center_text boolean Whether to center each line inside the box. Defaults to false.<br/>
|
||||
function UI.draw_textbox(text, box_x, box_y, box_w, box_h, scroll_y, color, bg_color, border_color, center_text)
|
||||
color = color or Config.colors.white
|
||||
bg_color = bg_color or Config.colors.dark_grey
|
||||
border_color = border_color or Config.colors.white
|
||||
center_text = center_text or false
|
||||
|
||||
local padding = 4
|
||||
local line_height = 8
|
||||
local inner_x = box_x + padding
|
||||
local inner_y = box_y + padding
|
||||
local inner_center_x = box_x + (box_w / 2)
|
||||
local visible_height = box_h - padding * 2
|
||||
local lines = UI.word_wrap(text, 30)
|
||||
local text_height = #lines * line_height
|
||||
local base_y = inner_y
|
||||
|
||||
if center_text and text_height < visible_height then
|
||||
base_y = inner_y + math.floor((visible_height - text_height) / 2)
|
||||
end
|
||||
|
||||
rect(box_x, box_y, box_w, box_h, bg_color)
|
||||
|
||||
for i, line in ipairs(lines) do
|
||||
local ly = base_y + (i - 1) * line_height - scroll_y
|
||||
if ly >= inner_y and ly + line_height <= inner_y + visible_height then
|
||||
if center_text then
|
||||
Print.text_center(line, inner_center_x, ly, color)
|
||||
else
|
||||
Print.text(line, inner_x, ly, color)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
rectb(box_x, box_y, box_w, box_h, border_color)
|
||||
end
|
||||
|
||||
--- Wraps text.
|
||||
--- @within UI
|
||||
--- @param text string The text to wrap.<br/>
|
||||
--- @param max_chars_per_line number The maximum characters per line.<br/>
|
||||
--- @return result table A table of wrapped lines.
|
||||
function UI.word_wrap(text, max_chars_per_line)
|
||||
if text == nil then return {""} end
|
||||
local lines = {}
|
||||
for input_line in (text .. "\n"):gmatch("(.-)\n") do
|
||||
local current_line = ""
|
||||
local words_in_line = 0
|
||||
for word in input_line:gmatch("%S+") do
|
||||
words_in_line = words_in_line + 1
|
||||
if #current_line == 0 then
|
||||
current_line = word
|
||||
elseif #current_line + #word + 1 <= max_chars_per_line then
|
||||
current_line = current_line .. " " .. word
|
||||
else
|
||||
table.insert(lines, current_line)
|
||||
current_line = word
|
||||
end
|
||||
end
|
||||
if words_in_line > 0 then
|
||||
table.insert(lines, current_line)
|
||||
else
|
||||
table.insert(lines, "")
|
||||
end
|
||||
if text == nil then return {""} end
|
||||
|
||||
local lines = {}
|
||||
|
||||
local function trim(s)
|
||||
return (s:gsub("^%s+", ""):gsub("%s+$", ""))
|
||||
end
|
||||
|
||||
local function previous_whitespace_index(s, target)
|
||||
if s:sub(target, target):match("%s") then
|
||||
return target
|
||||
end
|
||||
if #lines == 0 then
|
||||
return {""}
|
||||
|
||||
for i = target - 1, 1, -1 do
|
||||
if s:sub(i, i):match("%s") then
|
||||
return i
|
||||
end
|
||||
end
|
||||
return lines
|
||||
|
||||
return nil
|
||||
end
|
||||
|
||||
for input_line in (text .. "\n"):gmatch("(.-)\n") do
|
||||
local remaining = trim(input_line)
|
||||
|
||||
if remaining == "" then
|
||||
table.insert(lines, "")
|
||||
else
|
||||
while #remaining > max_chars_per_line do
|
||||
local split_at = previous_whitespace_index(remaining, max_chars_per_line)
|
||||
local line = trim(remaining:sub(1, split_at))
|
||||
|
||||
if not split_at or line == "" then
|
||||
line = remaining:sub(1, max_chars_per_line)
|
||||
split_at = max_chars_per_line
|
||||
end
|
||||
|
||||
table.insert(lines, line)
|
||||
remaining = trim(remaining:sub(split_at + 1))
|
||||
end
|
||||
|
||||
table.insert(lines, remaining)
|
||||
end
|
||||
end
|
||||
|
||||
if #lines == 0 then
|
||||
return {""}
|
||||
end
|
||||
|
||||
return lines
|
||||
end
|
||||
|
||||
Reference in New Issue
Block a user