autoConsole = autoConsole or {}
autoConsole.list = autoConsole.list or {}
autoConsole.bufferLinks = autoConsole.bufferLinks or {}
local meta = {__index = autoConsole}
autoConsole.create = function(name, x, y, w, h)
autoConsole.list[name] = {x = x, y = y, w = w, h = h}
createMiniConsole(name, 0, 0, 0, 0)
createBuffer(name.."_buffer")
autoConsole.refresh(name)
local self = {name = name, type = 'autoConsole', x = x, y = y, w = w, h = h}
setmetatable(self,meta)
return self
end
local function calcPixels(size, ref)
local ref = ref / 100
size = tostring(size)
local a, sign, b = string.match(size,"(-?%d+%%?)%s*([+-])%s*(%d+%%?)")
if not a then
a, sign, b = string.match(size,"(-?%d+%%?)"), "+", 0
end
local tonum = function(x)
if string.find(x,"%%") then
x = math.round(x:sub(1,#x-1) * ref)
end
return tonumber(x)
end
a = tonum(a)
b = tonum(b)
if sign == "+" then
return a + b
else
return a - b
end
end
local function calcWindow(x,y,w,h)
local mainw, mainh = getMainWindowSize()
x = calcPixels(x,mainw)
y = calcPixels(y,mainh)
w = calcPixels(w,mainw)
h = calcPixels(h,mainh)
if w < 0 then
x = mainw + w - x
w = -w
end
if h < 0 then
y = mainh + h - y
h = -h
end
return x,y,w,h
end
local function cleanText(str,style)
style = string.sub(style,1,1)
if style == "c" then
str = string.gsub(str,"<[%a_:]+>","")
elseif style == "h" then
str = string.gsub(str,
"%|c%w%w%w%w%w%w,[%da-fA-F][%da-fA-F][%da-fA-F][%da-fA-F][%da-fA-F][%da-fA-F]", "")
str = string.gsub(str,"%|c%w%w%w%w%w%w","")
str = string.gsub(str,"%|r","")
elseif style == "d" then
str = string.gsub(str,"<[%d,:]+>","")
str = string.gsub(str,"<r>","")
end
return str
end
autoConsole.refresh = function(name)
if type(name) == "table" then name = name.name end
if autoConsole.list[name] then
local buffer, list = name .. "_buffer", autoConsole.list[name]
local x, y, w, h = calcWindow(list.x,list.y,list.w,list.h)
resizeWindow(name,w,h)
moveWindow(name,x,y)
local wrap = math.floor(w / calcFontSize(name))
setWindowWrap(name,wrap)
clearWindow(name)
moveCursorEnd()
local line, moved = 0, moveCursor(buffer,0,0)
local links = autoConsole.bufferLinks[name] or {}
while moved do
moveCursorEnd(name)
local wline = getLineNumber(name)
selectCurrentLine(buffer)
copy(buffer)
appendBuffer(name)
if links[line] then
for _,info in ipairs(links[line]) do
moveCursor(name,0,wline)
local ctext = cleanText(info[2], info[3])
local index, max, pos = 0, getLineCount(name) - wline, -1
local bpos, col, match = 0, info[1], 1
repeat
moveCursor(name, 0, wline + index)
local cur_line = getCurrentLine(name)
bpos = selectString(buffer, cur_line, 1)
repeat
pos = selectString(name, ctext, match)
match = match + 1
until(pos == -1 or pos == col - bpos)
if pos == -1 and bpos + #cur_line > col then
selectSection(name, col - bpos, #cur_line - (col - bpos))
setLink(name,info[4],info[5])
moveCursor(name, 0, wline + index + 1)
cur_line = getCurrentLine(name)
bpos = selectString(buffer , cur_line, 1)
selectSection(name, 0, #ctext - (bpos - col))
pos = 1
end
index = index + 1
until(index >= max or pos ~= -1)
if pos ~= -1 then
setLink(name,info[4],info[5])
end
end
end
line = line + 1
moved = moveCursor(buffer,0,line)
end
else
error("autoConsole.refresh: no such autoConsole window",2)
end
end
autoConsole.refreshAll = function()
for k,v in pairs(autoConsole.list) do
autoConsole.refresh(k)
end
end
autoConsole.resizeWindow = function(name, width, height)
if type(name) == "table" then
name.w, name.h = width, height
name = name.name
end
if autoConsole.list[name] then
autoConsole.list[name].w = width
autoConsole.list[name].h = height
autoConsole.refresh(name)
else
error("autoConsole.resizeWindow: no such autoConsole window",2)
end
end
autoConsole.moveWindow = function(name, x, y)
if type(name) == "table" then
name.x, name.y = x, y
name = name.name
end
if autoConsole.list[name] then
autoConsole.list[name].x = x
autoConsole.list[name].y = y
autoConsole.refresh(name)
else
error("autoConsole.moveWindow: no such autoConsole window",2)
end
end
autoConsole.setFontSize = function(name, size)
if type(name) == "table" then name = name.name end
if autoConsole.list[name] then
setMiniConsoleFontSize(name,size)
autoConsole.refresh(name)
else
error("autoConsole.setFontSize: no such autoConsole window",2)
end
end
autoConsole.clearWindow = function(name)
if type(name) == "table" then name = name.name end
if autoConsole.list[name] then
clearWindow(name)
clearWindow(name.."_buffer")
autoConsole.bufferLinks[name] = nil
moveCursor(name,0,0)
moveCursor(name.."_buffer",0,0)
else
error("autoConsole.setFontSize: no such autoConsole window",2)
end
end
local make_link_func = function(func)
local f = function(name, text, ...)
if type(name) == "table" then name = name.name end
if autoConsole.list[name] then
local line, col = getLineNumber(name.."_buffer"), getColumnNumber(name.."_buffer")
if string.find(func,"echo") then
col = #getCurrentLine(name.."_buffer")
end
autoConsole.bufferLinks[name] = autoConsole.bufferLinks[name] or {}
autoConsole.bufferLinks[name][line] = autoConsole.bufferLinks[name][line] or {}
local ctext = cleanText(text,func)
for _,info in ipairs(autoConsole.bufferLinks[name][line]) do
if info[1] >= col then
info[1] = info[1] + #ctext
end
end
table.insert(autoConsole.bufferLinks[name][line],
{col, text, func, ...})
if _G[func] then
_G[func](name.."_buffer", text, ...)
else
_G[func:gsub("Link","Text")](name.."_buffer", text, ...)
end
autoConsole.refresh(name)
else
error("autoConsole."..func..": no such autoConsole window",2)
end
end
return f
end
local link_funcs = {"echoLink", "insertLink", "cechoLink", "cinsertLink", "dechoLink",
"dinsertLink", "hechoLink", "hinsertLink"}
for k,v in ipairs(link_funcs) do
autoConsole[v] = make_link_func(v)
end
local make_func = function(func,win,buf,ref)
local f = function(name,...)
if type(name) == "table" then name = name.name end
if autoConsole.list[name] then
local result
if win then result = {_G[func](name,...)} end
if buf then result = {_G[func](name.."_buffer",...)} end
if ref then autoConsole.refresh(name) end
return unpack(result)
else
error("autoConsole."..func..": no such autoConsole window",2)
end
end
return f
end
local dup_funcs = {'echo', 'cecho', 'hecho', 'decho', 'paste', 'appendBuffer', 'resetFormat'}
for k,v in ipairs(dup_funcs) do
autoConsole[v] = make_func(v,true,true,true)
end
local ref_funcs = {'insertText', 'cinsertText', 'bg', 'replace', 'deleteLine', 'fg',
'setBgColor', 'setFgColor', 'setStrikeOut', 'setHexFgColor', 'setHexBgColor',
'setBold', 'setUnderline', 'setItalics',}
for k,v in ipairs(ref_funcs) do
autoConsole[v] = make_func(v,false,true,true)
end
local buf_funcs = {'moveCursor', 'selectSection', 'selectString', 'selectCurrentLine',
'copy', 'getLineNumber', 'getColumNumber', 'getFont', 'deselect', 'getBgColor',
'getFgColor', 'getLastLineNumber', 'moveCursorEnd', 'getLineCount', 'getCurrentLine'}
for k,v in ipairs(buf_funcs) do
autoConsole[v] = make_func(v,false,true,false)
end
local win_funcs = {'hideWindow', 'showWindow', 'setTextFormat', 'getFont', 'getFontSize',
'enableScrollBar', 'disableScrollBar', 'lowerWindow', 'raiseWindow', 'getRowCount',
'getColumnCount', 'setBackgroundColor', 'setBackgroundImage',}
for k,v in ipairs(win_funcs) do
autoConsole[v] = make_func(v,true,false,false)
end
registerAnonymousEventHandler("sysWindowResizeEvent", "autoConsole.refreshAll")
local console = autoConsole.create("myConsole",0,0,300,250)
console:echo("This is a test, and I'm writing a lot just so the line is long enough to wrap.")
console:resizeWindow(200,250)
console:setFontSize(14)
console:clearWindow()
Edit: Added the capability to use insertLink and echoLink and their variations (including cinsertLink and the like, which don't exist normally) with the console windows. As a minor "issue", when using echoLink and insertLink, they will default to a background color of black, even if the background color of the console you see is a different color, this is because they don't apply formatting, and the text itself is drawn from a buffer, which can't have its background color set.