main.lua 7.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295
  1. --love.filesystem.setRequirePath("?.lua;?/init.lua;main/?.lua;main/?/init.lua")
  2. local Runner = require("main.runner")
  3. local BOXUI = require("boxui")
  4. -- extra modules
  5. BOXUI.require("main.lexer") -- used by codeviewer
  6. BOXUI.require("main.codeviewer")
  7. BOXUI.require("main.filelist")
  8. BOXUI.require("main.logger")
  9. -- standard
  10. local utils = BOXUI.utils
  11. local Container = BOXUI.container
  12. local Panel = BOXUI.panel
  13. local List = BOXUI.list
  14. local Button = BOXUI.button
  15. local Slider = BOXUI.slider
  16. -- extra
  17. local Codeviewer = BOXUI.codeviewer
  18. local Filelist = BOXUI.filelist
  19. local Logger = BOXUI.logger
  20. local fl -- filelist
  21. local cv -- codeviewer
  22. local opl -- option list
  23. local log -- log list
  24. local mgr -- manager
  25. local ASSETS_DIR = "main/assets/"
  26. local addIcon = function(t, icon)
  27. if type(icon) == "table" then
  28. for i, v in ipairs(icon) do
  29. t[v] = love.graphics.newImage(ASSETS_DIR .. v .. ".png")
  30. end
  31. return
  32. end
  33. t[icon] = love.graphics.newImage(ASSETS_DIR .. icon .. ".png")
  34. end
  35. local icons = {}
  36. addIcon(icons, {"folder", "file", "credits", "run", "clear", "copy", "help",
  37. "warn", "ok"})
  38. local cursor = love.mouse.newCursor( ASSETS_DIR .. 'cursor.png', 7, 7 )
  39. local EXTS = {["lua"] = true, ["txt"] = true}
  40. local INFOFILE_NAME = "info.txt"
  41. local DEFAULT_INFOFILE = "examples/info.txt"
  42. local DEFAULT_DIR = "examples"
  43. local fl_onClick = function(item)
  44. local ctx = item.context
  45. if not ctx then return end
  46. local activeFile = nil
  47. if ctx.type == "directory" then
  48. fl:setPath(ctx.name)
  49. if fl.path:find(DEFAULT_DIR, 1, true) == 1 then
  50. local fname = fl.path .. '/' .. INFOFILE_NAME
  51. local info = love.filesystem.getInfo(fname)
  52. if info and info.type == "file" then activeFile = fname
  53. else activeFile = DEFAULT_INFOFILE end
  54. else
  55. activeFile = cv.filename
  56. end
  57. elseif ctx.type == "file" then
  58. activeFile = ctx.name
  59. end
  60. if cv.filename ~= activeFile then
  61. cv:loadFile(activeFile, true)
  62. log:add("Loaded: " .. cv.filename)
  63. elseif ctx.type == "file" then
  64. log:add("Already loaded: " .. cv.filename, "warn")
  65. end
  66. end
  67. local oplOn = {}
  68. local loveCalls
  69. local opl_onRun = function()
  70. local filename, ext = cv.filename, cv.extension
  71. if not filename or ext ~= "lua" or filename:find(DEFAULT_DIR, 1, true) ~= 1 then
  72. log:add("Cannot run " .. (filename or "nothing"), "warn")
  73. return
  74. end
  75. Runner.run(filename, loveCalls, filename:match("(.-/?)[^/]*$"))
  76. end
  77. local opl_onClear = function()
  78. if cv.filename == nil then
  79. log:add("Nothing to be cleared", "warn")
  80. return
  81. end
  82. log:add("Cleared: " .. cv.filename)
  83. cv:clear()
  84. end
  85. local opl_onCopy = function()
  86. if not cv.filename then
  87. log:add("Nothing to be copied", "warn")
  88. return
  89. end
  90. love.system.setClipboardText(love.filesystem.read(cv.filename))
  91. log:add("Copied to clipboard: " .. cv.filename)
  92. end
  93. local _opl_onFile = function(filename)
  94. if filename == cv.filename then
  95. log:add("Already loaded: " .. cv.filename, "warn")
  96. return
  97. end
  98. cv:loadFile(filename, true)
  99. log:add("Loaded: " .. cv.filename)
  100. end
  101. local opl_onCredits = function()
  102. _opl_onFile("main/text/credits.txt")
  103. end
  104. local opl_onHelp = function()
  105. _opl_onFile("main/text/help.txt")
  106. end
  107. local opl_onLog = function(item)
  108. local found = mgr:find(log)
  109. local mgrobjects = mgr.objects
  110. if found then
  111. mgr:remove(found)
  112. item.icon = icons.warn
  113. else
  114. mgr:insert(log)
  115. item.icon = icons.ok
  116. end
  117. opl.list:redraw()
  118. end
  119. local opl_items = {
  120. {text = "Run", context = opl_onRun, icon = icons.run},
  121. {text = "Clear", context = opl_onClear, icon = icons.clear},
  122. {text = "Copy", context = opl_onCopy, icon = icons.copy},
  123. {text = "Help", context = opl_onHelp, icon = icons.help},
  124. {text = "Credits", context = opl_onCredits, icon = icons.credits},
  125. {text = "Log", context = opl_onLog, icon = icons.warn},
  126. }
  127. local opl_onClick = function(item)
  128. local fn = item.context
  129. if fn then fn(item) end
  130. end
  131. love.load = function()
  132. local smallfont = love.graphics.newFont(10)
  133. local normalfont = love.graphics.newFont(12)
  134. local bigfont = love.graphics.newFont(14)
  135. -- if we keep it nil, it resets love2d instead of restoring
  136. -- loveCalls = Runner.backupCallbacks()
  137. love.graphics.setBackgroundColor(0.0, 0.1, 0.2)
  138. love.mouse.setCursor(cursor)
  139. fl = Filelist.new(10, 10, 180, 420)
  140. utils.addprops(fl, {
  141. hasHandle = true, hasShade = true, movable = true,
  142. diricon = icons["folder"], fileicon = icons["file"],
  143. extensions = EXTS
  144. })
  145. utils.addprops(fl.list, {font = normalfont, onClick = fl_onClick})
  146. fl:setPath(DEFAULT_DIR)
  147. opl = List.new(10, 440, 180, 200)
  148. utils.addprops(opl, {title = "Menu", wrapVert = true})
  149. utils.addprops(opl.list, {font = normalfont, onClick = opl_onClick})
  150. opl:setItems(opl_items)
  151. opl:refresh(true)
  152. opl.y = 590 - opl.height
  153. cv = Codeviewer.new(15, 15, 500, 420)
  154. cv.wrapVert = true
  155. cv.scalable = true
  156. cv:loadFile("main/text/help.txt")
  157. cv:refresh(true)
  158. --[[]]
  159. local test = Container.new(200, 25, 590, 500, List.template_theme)
  160. test.scalable = true
  161. local panel = Panel.new(0,0,586, 476)
  162. local button1 = Button.new(10, 10, 100, 30)
  163. local button2 = Button.new(10, 50, 100, 30)
  164. local button3 = Button.new(10, 90, 100, 30)
  165. local radiogroup = {button1, button2, button3}
  166. for k,v in pairs(radiogroup) do
  167. v.radiogroup = radiogroup
  168. panel:insert(v)
  169. end
  170. local slider1 = Slider.new(10, 130, 120, 30)
  171. slider1:refresh()
  172. panel:insert(slider1)
  173. local slider2 = Slider.new(140, 130, 30, 120)
  174. slider2.vertical = true
  175. slider2:refresh()
  176. panel:insert(slider2)
  177. panel:insert(cv)
  178. cv.theme = utils.freshenprops(utils.deepcopy(BOXUI.theme), {
  179. itemBack = cv.scheme.back, itemPadVert = 1,
  180. --itemForeActive = cv.scheme.activeline,
  181. borderBack = cv.scheme.padding,
  182. itemHeight = cv.fonts["big"]:getHeight() + 2
  183. })
  184. cv.list.theme = cv.theme
  185. test.hasHandle = true; test.hasShade = true; test.movable = true;
  186. --test.canvas = nil
  187. test.content = panel
  188. --cv.parent = test
  189. cv.hasHandle = true; cv.movable = true; cv.hasExpand = true; cv.hasShade = true;
  190. cv:refresh(true)
  191. test:refresh(true)
  192. --[[]]
  193. log = Logger.new(200, 540, 590, 200)
  194. utils.addprops( log, { hasHandle = true, hasShade = true, movable = true,
  195. title = "Log Window", wrapVert = false, wrapHori = false,
  196. slideDown = true, icons = icons})
  197. log.list.font = smallfont
  198. log.list.theme = utils.freshenprops(utils.deepcopy(BOXUI.theme), {
  199. itemBack = {.9,.9,1}, itemPadVert = 1,
  200. itemFore = {0,0,1}, itemForeActive = {1,.1,.1},
  201. --borderBack = cv.scheme.padding,
  202. itemHeight = smallfont:getHeight() + 2
  203. })
  204. log:add("Hello", "warn")
  205. mgr = Panel.new()
  206. mgr:insert(fl)
  207. mgr:insert(opl)
  208. mgr:insert(test)
  209. end
  210. love.wheelmoved = function(x, y)
  211. mgr:wheelmoved(x, y)
  212. end
  213. love.mousemoved = function(x, y, dx, dy)
  214. mgr:mousemoved(x, y, dx, dy)
  215. end
  216. love.mousepressed = function(x, y, button)
  217. mgr:mousepressed(x, y, button)
  218. end
  219. love.mousereleased = function(x, y, button)
  220. mgr:mousereleased(x, y, button)
  221. end
  222. love.update = function(dt)
  223. mgr:update(dt)
  224. end
  225. love.draw = function()
  226. love.graphics.setColor(1, 1, 1)
  227. mgr:draw()
  228. love.graphics.setColor(0, 0, 1)
  229. love.graphics.rectangle("fill", 0, 0, 40, 20)
  230. love.graphics.setColor(1, 1, 1)
  231. love.graphics.print(love.timer.getFPS(), 0, 0)
  232. end
  233. local mountno = 1
  234. local mounted = {}
  235. love.directorydropped = function(path)
  236. if not mounted[path] then
  237. local mountpoint = ("%s/ext_%0.2i"):format(DEFAULT_DIR, mountno)
  238. local appendToPath = false
  239. local success = love.filesystem.mount(path, mountpoint, appendToPath)
  240. if not success then
  241. log:add("Cannot mount " .. (path or "nothing"))
  242. return
  243. end
  244. mounted[path] = mountpoint
  245. mountno = mountno + 1
  246. log:add("Mounted: " .. path .. " to " .. mountpoint)
  247. end
  248. fl:setPath(mounted[path])
  249. end