SHOW:
|
|
- or go back to the newest paste.
| 1 | - | -- version: Unspeakable Crawling Sticky Tentacle |
| 1 | + | -- version: Unspeakable Crawling Rachis |
| 2 | ||
| 3 | Texter = {}
| |
| 4 | - | Texter._lastInputStr = "" |
| 4 | + | Texter._LastInputStr = "" |
| 5 | - | Texter._lastInputArgs = "1, 3" |
| 5 | + | Texter._LastInputArgs = "1, 3" |
| 6 | Texter._LastInputFont = "7px" | |
| 7 | Texter._Fonts = {}
| |
| 8 | ||
| 9 | - | if Texter._findFile("7px") ~= nil then
|
| 9 | + | |
| 10 | - | Texter.SetFont("7px")
|
| 10 | + | |
| 11 | Texter.LoadFont("TexterFonts")
| |
| 12 | - | Texter.SetFont("5px")
|
| 12 | + | tpt.register_keypress(Texter._HotkeyHandler) |
| 13 | end | |
| 14 | - | tpt.register_keypress(Texter._hotkeyHandler) |
| 14 | + | |
| 15 | -- Internal methods | |
| 16 | function Texter._IsFolder(path) | |
| 17 | local _isFolder = false | |
| 18 | - | function Texter._isFolder(path) |
| 18 | + | if(path ~= nil) then |
| 19 | -- API bug, not fixed right now (ver 85.0) | |
| 20 | - | if path ~= nil then |
| 20 | + | -- if( fs.isDirectory(path) ) then |
| 21 | - | -- if fs.isDirectory(path) then |
| 21 | + | |
| 22 | -- end | |
| 23 | if( fs.isDirectory(path) == fs.isDirectory(".") ) then
| |
| 24 | _isFolder = true | |
| 25 | - | if ( fs.isDirectory(path) == fs.isDirectory(".") ) then
|
| 25 | + | |
| 26 | end | |
| 27 | return _isFolder | |
| 28 | end | |
| 29 | function Texter._FindFileInCurrentDir(fileName, rootPath, optionalSuffix, optionalPrefix) | |
| 30 | local filePath = nil | |
| 31 | - | function Texter._findFileInCurrentDir(fileName, rootPath, optionalSuffix, optionalPrefix) |
| 31 | + | if( fs.exists(rootPath.."\\"..fileName)) then |
| 32 | filePath = rootPath.."\\"..fileName | |
| 33 | - | if fs.exists(rootPath.."\\"..fileName) then |
| 33 | + | else if( fs.exists(rootPath.."\\"..fileName..optionalSuffix)) then |
| 34 | filePath = rootPath.."\\"..fileName..optionalSuffix | |
| 35 | - | else if fs.exists(rootPath.."\\"..fileName..optionalSuffix) then |
| 35 | + | else if( fs.exists(rootPath.."\\"..optionalPrefix..fileName)) then |
| 36 | filePath = rootPath.."\\"..optionalPrefix..fileName | |
| 37 | - | else if fs.exists(rootPath.."\\"..optionalPrefix..fileName) then |
| 37 | + | else if( fs.exists(rootPath.."\\"..optionalPrefix..fileName..optionalSuffix)) then |
| 38 | filePath = rootPath.."\\"..optionalPrefix..fileName..optionalSuffix | |
| 39 | - | else if fs.exists(rootPath.."\\"..optionalPrefix..fileName..optionalSuffix) then |
| 39 | + | |
| 40 | end | |
| 41 | end | |
| 42 | end | |
| 43 | return filePath | |
| 44 | end | |
| 45 | function Texter._FindFile(fileName, rootPath, optionalSuffix, optionalPrefix, depth) | |
| 46 | if( rootPath == nil ) then | |
| 47 | - | function Texter._findFile(fileName, rootPath, optionalSuffix, optionalPrefix, depth) |
| 47 | + | |
| 48 | - | if rootPath == nil then |
| 48 | + | |
| 49 | if( optionalSuffix == nil ) then | |
| 50 | optionalSuffix = ".lua" | |
| 51 | - | if optionalSuffix == nil then |
| 51 | + | |
| 52 | if( optionalPrefix == nil ) then | |
| 53 | optionalPrefix = "" | |
| 54 | - | if optionalPrefix == nil then |
| 54 | + | |
| 55 | if( depth == nil ) then | |
| 56 | depth = 3 -- Find 3 level of subfolders in default | |
| 57 | - | if depth == nil then |
| 57 | + | |
| 58 | local subs = nil | |
| 59 | local filePath = Texter._FindFileInCurrentDir(fileName, rootPath, optionalSuffix, optionalPrefix) | |
| 60 | ||
| 61 | - | local filePath = Texter._findFileInCurrentDir(fileName, rootPath, optionalSuffix, optionalPrefix) |
| 61 | + | |
| 62 | if( filePath == nil ) then | |
| 63 | subs = fs.list(rootPath) | |
| 64 | - | if filePath == nil then |
| 64 | + | |
| 65 | if( Texter._IsFolder(rootPath.."\\"..subs[i]) and depth > 0 ) then | |
| 66 | filePath = Texter._FindFile(fileName, rootPath.."\\"..subs[i], optionalSuffix, optionalPrefix, depth - 1) | |
| 67 | - | if Texter._isFolder(rootPath.."\\"..subs[i]) and depth > 0 then |
| 67 | + | |
| 68 | - | filePath = Texter._findFile(fileName, rootPath.."\\"..subs[i], optionalSuffix, optionalPrefix, depth - 1) |
| 68 | + | if( filePath ~= nil ) then do break end end |
| 69 | end | |
| 70 | - | if filePath ~= nil then do break end end |
| 70 | + | |
| 71 | return filePath | |
| 72 | end | |
| 73 | function Texter._GetFontHeight(fontName) | |
| 74 | local height = 0 | |
| 75 | - | function Texter._getFontHeight() |
| 75 | + | if( Texter._Fontmatrix[fontName] ~=nil and Texter._Fontmatrix[fontName].height ~= nil ) then |
| 76 | height = Texter._Fontmatrix[fontName].height | |
| 77 | - | if fontmatrix.height ~= nil then |
| 77 | + | |
| 78 | - | height = fontmatrix.height |
| 78 | + | |
| 79 | end | |
| 80 | return height | |
| 81 | end | |
| 82 | function Texter._Input(eventHandler, fonts, paramsText, strText, fontText) | |
| 83 | local controlHeight = 17 | |
| 84 | if( paramsText == nil ) then paramsText = "" end | |
| 85 | if( strText == nil ) then strText = "" end | |
| 86 | - | -- Set the working font |
| 86 | + | if( fontText == nil ) then fontText = "" end |
| 87 | - | function Texter.SetFont(fontName, rootPath, optionalSuffix, optionalPrefix, depth) |
| 87 | + | if( fonts == nil ) then fonts = {} end
|
| 88 | - | local realPath = Texter._findFile(fontName, rootPath, optionalSuffix, optionalPrefix, depth) |
| 88 | + | |
| 89 | - | if realPath ~= nil then |
| 89 | + | local isContains = function(inTable, value) |
| 90 | local isContain = false | |
| 91 | - | tpt.log("Texter: Font file \""..realPath.."\" loaded.")
|
| 91 | + | for i=1, #inTable do |
| 92 | if( value == inTable[i] ) then | |
| 93 | isContain = true | |
| 94 | break | |
| 95 | end | |
| 96 | end | |
| 97 | return isContain | |
| 98 | end | |
| 99 | - | function Texter.Tchar(char, x, y, ptype) |
| 99 | + | |
| 100 | local TexterWin = Window:new(-1, -1, 500, 100) | |
| 101 | local paramsBox = Textbox:new(10, 32, 252, controlHeight, paramsText, "ptype, hspc, vspc") | |
| 102 | local paramsLabel = Label:new(11, 9, 232, controlHeight, "Enter the element name you want to use and\nthe spacing between letters (horizontal/vertical).") | |
| 103 | local stringBox = Textbox:new(10, 57, 480, controlHeight, strText, "Input text to create under mouse. Use \\n for new line, \\\\n for \\n. Sorry, you can't get \\\\n.") | |
| 104 | local fontBtn = Button:new(282, 32, 208, controlHeight, "No font available") | |
| 105 | local fontLabel = Label:new(283, 9, 150, controlHeight, "Select the font you want to use.") | |
| 106 | - | letter = fontmatrix[char] |
| 106 | + | local cancelBtn = Button:new(0, 83, 251, controlHeight, "Cancel") |
| 107 | - | if letter == nil then |
| 107 | + | cancelBtn:action(function(sender)interface.closeWindow(TexterWin)end) |
| 108 | - | letter = fontmatrix["nil"] |
| 108 | + | local okayBtn = Button:new(250, 83, 250, controlHeight, "Okay") |
| 109 | okayBtn:action( | |
| 110 | function(sender) | |
| 111 | - | if letter['voffset'] ~= nil then |
| 111 | + | if( eventHandler ~= nil and type(eventHandler) == "function" ) then |
| 112 | -- Use event because I can't make things like tpt.input | |
| 113 | eventHandler(paramsBox:text(), stringBox:text(), fontBtn:text()) | |
| 114 | - | if letter['hoffset'] ~= nil then |
| 114 | + | |
| 115 | interface.closeWindow(TexterWin) | |
| 116 | end | |
| 117 | ) | |
| 118 | ||
| 119 | if(#fonts > 0) then | |
| 120 | if( isContains(fonts, fontText) ) then | |
| 121 | - | if mtx[i] ~= nil then |
| 121 | + | fontBtn:text(fontText) |
| 122 | else | |
| 123 | fontBtn:text(fonts[1]) | |
| 124 | - | if mtx[i][j]==1 then |
| 124 | + | |
| 125 | - | tpt.create(x+j-1+hoffset, y+i-1+voffset, ptype) |
| 125 | + | fontBtn:action( |
| 126 | function(sender) | |
| 127 | local winX, winY = TexterWin:position() | |
| 128 | local btnX, btnY = fontBtn:position() | |
| 129 | local btnW, btnH = fontBtn:size() | |
| 130 | local listWin = Window:new(winX+btnX, winY+btnY-8*(#fonts-1), btnW, (btnH-1)*#fonts) | |
| 131 | for i=1, #fonts do | |
| 132 | local optionBtn = Button:new(0, (btnH-1)*(i-1), btnW, btnH, fonts[i]) | |
| 133 | optionBtn:action( | |
| 134 | - | function Texter.Tstr(str, x, y, ptype, hspacing, vspacing) |
| 134 | + | function(sender) |
| 135 | interface.closeWindow(listWin) | |
| 136 | fontBtn:text(optionBtn:text()) | |
| 137 | end | |
| 138 | - | local fontH = Texter._getFontHeight() |
| 138 | + | ) |
| 139 | - | if hspacing == nil then |
| 139 | + | listWin:addComponent(optionBtn) |
| 140 | end | |
| 141 | interface.showWindow(listWin) | |
| 142 | - | if vspacing == nil then |
| 142 | + | |
| 143 | ) | |
| 144 | end | |
| 145 | ||
| 146 | - | if string.sub(str, i, i) == "\n" then |
| 146 | + | TexterWin:addComponent(cancelBtn) |
| 147 | TexterWin:addComponent(okayBtn) | |
| 148 | TexterWin:addComponent(stringBox) | |
| 149 | TexterWin:addComponent(paramsBox) | |
| 150 | - | ox = hspacing + ox + Texter.Tchar(string.sub(str, i, i), x+ox, y+oy, ptype) |
| 150 | + | TexterWin:addComponent(paramsLabel) |
| 151 | TexterWin:addComponent(fontBtn) | |
| 152 | TexterWin:addComponent(fontLabel) | |
| 153 | ||
| 154 | interface.showWindow(TexterWin) | |
| 155 | end | |
| 156 | ||
| 157 | -- Load the working font | |
| 158 | - | function T(str, ptype, hspc, vspc) |
| 158 | + | function Texter.LoadFont(fontName, rootPath, optionalSuffix, optionalPrefix, depth) |
| 159 | - | if ptype == nil then |
| 159 | + | local realPath = Texter._FindFile(fontName, rootPath, optionalSuffix, optionalPrefix, depth) |
| 160 | if( realPath ~= nil ) then | |
| 161 | dofile(realPath) | |
| 162 | - | if str == nil then str = "" end |
| 162 | + | if(Texter._Fontmatrix ~= nil) then |
| 163 | - | if ptype == nil then |
| 163 | + | for fontName in pairs(Texter._Fontmatrix) do |
| 164 | table.insert(Texter._Fonts, fontName) | |
| 165 | end | |
| 166 | - | Texter.Tstr(str, tpt.mousex, tpt.mousey, ptype, hspc, vspc) |
| 166 | + | tpt.log("Texter: Font file \""..realPath.."\" loaded, "..#Texter._Fonts.." font(s) found.")
|
| 167 | else | |
| 168 | tpt.log("Texter: File \""..realPath.."\" loaded, invalid font file.")
| |
| 169 | end | |
| 170 | else | |
| 171 | - | function Texter._hotkeyHandler(key, keyNum, modifier, event) |
| 171 | + | |
| 172 | - | local str = "" |
| 172 | + | |
| 173 | - | local argsStr = "" |
| 173 | + | |
| 174 | end | |
| 175 | - | if event==1 and keyNum==116 and modifier==64 then -- Ctrl + t |
| 175 | + | |
| 176 | - | -- String to create |
| 176 | + | function Texter.Tchar(char, x, y, ptype, fontName) |
| 177 | - | str = tpt.input( |
| 177 | + | |
| 178 | - | "Input text to create under mouse", |
| 178 | + | |
| 179 | - | "[Format: text]\nUse \\n for new line, \\\\n for \\n.\nSorry, you can't get \\\\n.", |
| 179 | + | |
| 180 | - | Texter._lastInputStr |
| 180 | + | |
| 181 | -- if given font not available, use the first available one | |
| 182 | - | if string.len(str) > 0 then |
| 182 | + | if( fontName == nil or Texter._Fontmatrix[fontName] == nil ) then |
| 183 | - | Texter._lastInputStr = str |
| 183 | + | for font in pairs(Texter._Fontmatrix) do |
| 184 | - | str = string.gsub(str, "([^\\]?)\\n", "%1\n") -- Small trick |
| 184 | + | fontName = font |
| 185 | - | str = string.gsub(str, "([^\\]?)\\\\n", "%1\\n") |
| 185 | + | break |
| 186 | - | -- Additional settings |
| 186 | + | |
| 187 | - | local ptype = elements[tpt.selectedl] |
| 187 | + | |
| 188 | - | if ptype == nil then |
| 188 | + | -- if still not available, break |
| 189 | - | ptype = 1 --"DUST" |
| 189 | + | if( fontName == nil ) then return 0 end |
| 190 | ||
| 191 | - | argsStr = tpt.input( |
| 191 | + | |
| 192 | - | "Input parameters for creating text", |
| 192 | + | letter = Texter._Fontmatrix[fontName][char] |
| 193 | - | "[Format: ptype, hspc, vspc]\nptype is element used, e.g. DUST.\nh/vspc is horizontal/vertical spacing.", |
| 193 | + | if( letter == nil ) then |
| 194 | - | elements.property(ptype, "Name")..", "..Texter._lastInputArgs |
| 194 | + | letter = Texter._Fontmatrix[fontName]["nil"] |
| 195 | - | ) |
| 195 | + | |
| 196 | - | if string.len(argsStr) > 0 then Texter._lastInputArgs = string.gsub(argsStr, "%s*%w*%s*,%s*(.*)", "%1") end |
| 196 | + | |
| 197 | - | local i=1 |
| 197 | + | if( letter['voffset'] ~= nil ) then |
| 198 | - | for arg in string.gmatch(argsStr, "%s*(%w*)%s*,?") do |
| 198 | + | |
| 199 | - | args[i] = arg |
| 199 | + | |
| 200 | - | i = i+1 |
| 200 | + | if( letter['hoffset'] ~= nil ) then |
| 201 | voffset = letter['hoffset'] | |
| 202 | end | |
| 203 | - | if pcall(tpt.element, args[1]) == false then |
| 203 | + | |
| 204 | - | args[1] = "DUST" |
| 204 | + | |
| 205 | local width = 3 | |
| 206 | - | Texter.Tstr(str, tpt.mousex, tpt.mousey, args[1], args[2], args[3]) |
| 206 | + | |
| 207 | if( mtx[i] ~= nil ) then | |
| 208 | width = #mtx[i] | |
| 209 | for j=1,width do | |
| 210 | if( mtx[i][j]==1 ) then | |
| 211 | if( pcall(tpt.create, x+j-1+hoffset, y+i-1+voffset, ptype) == false ) then | |
| 212 | width = 0 | |
| 213 | end | |
| 214 | end | |
| 215 | end | |
| 216 | end | |
| 217 | end | |
| 218 | return width | |
| 219 | end | |
| 220 | -- Draw a string | |
| 221 | function Texter.Tstr(str, x, y, ptype, hspacing, vspacing, fontName) | |
| 222 | local ox = 0 | |
| 223 | local oy = 0 | |
| 224 | local oy = 0 | |
| 225 | local fontH = Texter._GetFontHeight(fontName) | |
| 226 | if( hspacing == nil ) then | |
| 227 | hspacing = 1 | |
| 228 | end | |
| 229 | if( vspacing == nil ) then | |
| 230 | vspacing = 3 | |
| 231 | end | |
| 232 | for i=1,string.len(str) do | |
| 233 | if( string.sub(str, i, i) == "\n" ) then | |
| 234 | oy = vspacing + oy + fontH | |
| 235 | ox = 0 | |
| 236 | else | |
| 237 | ox = hspacing + ox + Texter.Tchar(string.sub(str, i, i), x+ox, y+oy, ptype, fontName) | |
| 238 | end | |
| 239 | end | |
| 240 | return string.len(str) | |
| 241 | end | |
| 242 | ||
| 243 | -- Shortcut for better user experience | |
| 244 | function T(str, ptype, hspc, vspc, fontName) | |
| 245 | if( ptype == nil ) then | |
| 246 | ptype = elements[tpt.selectedl] -- elements.property(tpt.selectedl, "Name") | |
| 247 | end | |
| 248 | if( str == nil ) then str = "" end | |
| 249 | if( ptype == nil ) then | |
| 250 | ptype = "DUST" | |
| 251 | end | |
| 252 | Texter.Tstr(str, tpt.mousex, tpt.mousey, ptype, hspc, vspc, fontName) | |
| 253 | return string.len(str) | |
| 254 | end | |
| 255 | -- Hotkey handler | |
| 256 | function Texter._HotkeyHandler(key, keyNum, modifier, event) | |
| 257 | if( event==1 and keyNum==116 and modifier==64 ) then -- Ctrl + t | |
| 258 | -- Additional settings | |
| 259 | local ptype = elements[tpt.selectedl] | |
| 260 | if( ptype == nil ) then | |
| 261 | ptype = 1 --"DUST" | |
| 262 | end | |
| 263 | -- Prompt | |
| 264 | Texter._Input( | |
| 265 | Texter._InputHandler, | |
| 266 | Texter._Fonts, | |
| 267 | elements.property(ptype, "Name")..", "..Texter._LastInputArgs, | |
| 268 | Texter._LastInputStr, | |
| 269 | Texter._LastInputFont | |
| 270 | ) | |
| 271 | end | |
| 272 | end | |
| 273 | -- Input handler | |
| 274 | function Texter._InputHandler(params, str, fontName) | |
| 275 | local args = {}
| |
| 276 | if( string.len(str) > 0 ) then | |
| 277 | Texter._LastInputStr = str | |
| 278 | str = string.gsub(str, "([^\\]?)\\n", "%1\n") -- Small trick | |
| 279 | str = string.gsub(str, "([^\\]?)\\\\n", "%1\\n") | |
| 280 | end | |
| 281 | ||
| 282 | if( string.len(params) > 0 ) then Texter._LastInputArgs = string.gsub(params, "%s*%w*%s*,%s*(.*)", "%1") end | |
| 283 | local i=1 | |
| 284 | for arg in string.gmatch(params, "%s*(%w*)%s*,?") do | |
| 285 | args[i] = arg | |
| 286 | i = i+1 | |
| 287 | end | |
| 288 | Texter._LastInputFont = fontName | |
| 289 | ||
| 290 | if( pcall(tpt.element, args[1]) == false ) then | |
| 291 | args[1] = "DUST" | |
| 292 | end | |
| 293 | Texter.Tstr(str, tpt.mousex, tpt.mousey, args[1], args[2], args[3], fontName) | |
| 294 | end | |
| 295 | ||
| 296 | Texter.Init() |