smigger22

sketch

Feb 17th, 2015
269
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 107.67 KB | None | 0 0
  1. if OneOS then
  2. --running under OneOS
  3. OneOS.ToolBarColour = colours.grey
  4. OneOS.ToolBarTextColour = colours.white
  5. end
  6.  
  7. colours.transparent = -1
  8. colors.transparent = -1
  9.  
  10. --APIS--
  11.  
  12. --This is my drawing API, is is pretty much identical to what drives OneOS, PearOS, etc.
  13. local _w, _h = term.getSize()
  14.  
  15. local round = function(num, idp)
  16. local mult = 10^(idp or 0)
  17. return math.floor(num * mult + 0.5) / mult
  18. end
  19.  
  20. Clipboard = {
  21. Content = nil,
  22. Type = nil,
  23. IsCut = false,
  24.  
  25. Empty = function()
  26. Clipboard.Content = nil
  27. Clipboard.Type = nil
  28. Clipboard.IsCut = false
  29. end,
  30.  
  31. isEmpty = function()
  32. return Clipboard.Content == nil
  33. end,
  34.  
  35. Copy = function(content, _type)
  36. Clipboard.Content = content
  37. Clipboard.Type = _type or 'generic'
  38. Clipboard.IsCut = false
  39. end,
  40.  
  41. Cut = function(content, _type)
  42. Clipboard.Content = content
  43. Clipboard.Type = _type or 'generic'
  44. Clipboard.IsCut = true
  45. end,
  46.  
  47. Paste = function()
  48. local c, t = Clipboard.Content, Clipboard.Type
  49. if Clipboard.IsCut then
  50. Clipboard.Empty()
  51. end
  52. return c, t
  53. end
  54. }
  55.  
  56. if OneOS and OneOS.Clipboard then
  57. Clipboard = OneOS.Clipboard
  58. end
  59.  
  60. Drawing = {
  61.  
  62. Screen = {
  63. Width = _w,
  64. Height = _h
  65. },
  66.  
  67. DrawCharacters = function (x, y, characters, textColour,bgColour)
  68. Drawing.WriteStringToBuffer(x, y, characters, textColour, bgColour)
  69. end,
  70.  
  71. DrawBlankArea = function (x, y, w, h, colour)
  72. Drawing.DrawArea (x, y, w, h, " ", 1, colour)
  73. end,
  74.  
  75. DrawArea = function (x, y, w, h, character, textColour, bgColour)
  76. --width must be greater than 1, other wise we get a stack overflow
  77. if w < 0 then
  78. w = w * -1
  79. elseif w == 0 then
  80. w = 1
  81. end
  82.  
  83. for ix = 1, w do
  84. local currX = x + ix - 1
  85. for iy = 1, h do
  86. local currY = y + iy - 1
  87. Drawing.WriteToBuffer(currX, currY, character, textColour, bgColour)
  88. end
  89. end
  90. end,
  91.  
  92. DrawImage = function(_x,_y,tImage, w, h)
  93. if tImage then
  94. for y = 1, h do
  95. if not tImage[y] then
  96. break
  97. end
  98. for x = 1, w do
  99. if not tImage[y][x] then
  100. break
  101. end
  102. local bgColour = tImage[y][x]
  103. local textColour = tImage.textcol[y][x] or colours.white
  104. local char = tImage.text[y][x]
  105. Drawing.WriteToBuffer(x+_x-1, y+_y-1, char, textColour, bgColour)
  106. end
  107. end
  108. elseif w and h then
  109. Drawing.DrawBlankArea(x, y, w, h, colours.green)
  110. end
  111. end,
  112. --using .nft
  113. LoadImage = function(path)
  114. local image = {
  115. text = {},
  116. textcol = {}
  117. }
  118. local _fs = fs
  119. if OneOS then
  120. _fs = OneOS.FS
  121. end
  122. if _fs.exists(path) then
  123. local _open = io.open
  124. if OneOS then
  125. _open = OneOS.IO.open
  126. end
  127. local file = _open(path, "r")
  128. local sLine = file:read()
  129. local num = 1
  130. while sLine do
  131. table.insert(image, num, {})
  132. table.insert(image.text, num, {})
  133. table.insert(image.textcol, num, {})
  134.  
  135. --As we're no longer 1-1, we keep track of what index to write to
  136. local writeIndex = 1
  137. --Tells us if we've hit a 30 or 31 (BG and FG respectively)- next char specifies the curr colour
  138. local bgNext, fgNext = false, false
  139. --The current background and foreground colours
  140. local currBG, currFG = nil,nil
  141. for i=1,#sLine do
  142. local nextChar = string.sub(sLine, i, i)
  143. if nextChar:byte() == 30 then
  144. bgNext = true
  145. elseif nextChar:byte() == 31 then
  146. fgNext = true
  147. elseif bgNext then
  148. currBG = Drawing.GetColour(nextChar)
  149. bgNext = false
  150. elseif fgNext then
  151. currFG = Drawing.GetColour(nextChar)
  152. fgNext = false
  153. else
  154. if nextChar ~= " " and currFG == nil then
  155. currFG = colours.white
  156. end
  157. image[num][writeIndex] = currBG
  158. image.textcol[num][writeIndex] = currFG
  159. image.text[num][writeIndex] = nextChar
  160. writeIndex = writeIndex + 1
  161. end
  162. end
  163. num = num+1
  164. sLine = file:read()
  165. end
  166. file:close()
  167. end
  168. return image
  169. end,
  170.  
  171. DrawCharactersCenter = function(x, y, w, h, characters, textColour,bgColour)
  172. w = w or Drawing.Screen.Width
  173. h = h or Drawing.Screen.Height
  174. x = x or 0
  175. y = y or 0
  176. x = math.ceil((w - #characters) / 2) + x
  177. y = math.floor(h / 2) + y
  178.  
  179. Drawing.DrawCharacters(x, y, characters, textColour, bgColour)
  180. end,
  181.  
  182. GetColour = function(hex)
  183. if hex == ' ' then
  184. return colours.transparent
  185. end
  186. local value = tonumber(hex, 16)
  187. if not value then return nil end
  188. value = math.pow(2,value)
  189. return value
  190. end,
  191.  
  192. Clear = function (_colour)
  193. _colour = _colour or colours.black
  194. Drawing.ClearBuffer()
  195. Drawing.DrawBlankArea(1, 1, Drawing.Screen.Width, Drawing.Screen.Height, _colour)
  196. end,
  197.  
  198. Buffer = {},
  199. BackBuffer = {},
  200.  
  201. DrawBuffer = function()
  202. for y,row in pairs(Drawing.Buffer) do
  203. for x,pixel in pairs(row) do
  204. local shouldDraw = true
  205. local hasBackBuffer = true
  206. if Drawing.BackBuffer[y] == nil or Drawing.BackBuffer[y][x] == nil or #Drawing.BackBuffer[y][x] ~= 3 then
  207. hasBackBuffer = false
  208. end
  209. if hasBackBuffer and Drawing.BackBuffer[y][x][1] == Drawing.Buffer[y][x][1] and Drawing.BackBuffer[y][x][2] == Drawing.Buffer[y][x][2] and Drawing.BackBuffer[y][x][3] == Drawing.Buffer[y][x][3] then
  210. shouldDraw = false
  211. end
  212. if shouldDraw then
  213. term.setBackgroundColour(pixel[3])
  214. term.setTextColour(pixel[2])
  215. term.setCursorPos(x, y)
  216. term.write(pixel[1])
  217. end
  218. end
  219. end
  220. Drawing.BackBuffer = Drawing.Buffer
  221. Drawing.Buffer = {}
  222. term.setCursorPos(1,1)
  223. end,
  224.  
  225. ClearBuffer = function()
  226. Drawing.Buffer = {}
  227. end,
  228.  
  229. WriteStringToBuffer = function (x, y, characters, textColour,bgColour)
  230. for i = 1, #characters do
  231. local character = characters:sub(i,i)
  232. Drawing.WriteToBuffer(x + i - 1, y, character, textColour, bgColour)
  233. end
  234. end,
  235.  
  236. WriteToBuffer = function(x, y, character, textColour,bgColour)
  237. x = round(x)
  238. y = round(y)
  239. if bgColour == colours.transparent then
  240. Drawing.Buffer[y] = Drawing.Buffer[y] or {}
  241. Drawing.Buffer[y][x] = Drawing.Buffer[y][x] or {"", colours.white, colours.black}
  242. Drawing.Buffer[y][x][1] = character
  243. Drawing.Buffer[y][x][2] = textColour
  244. else
  245. Drawing.Buffer[y] = Drawing.Buffer[y] or {}
  246. Drawing.Buffer[y][x] = {character, textColour, bgColour}
  247. end
  248. end,
  249. }
  250.  
  251. --Colour Deffitions--
  252. UIColours = {
  253. Toolbar = colours.grey,
  254. ToolbarText = colours.lightGrey,
  255. ToolbarSelected = colours.lightBlue,
  256. ControlText = colours.white,
  257. ToolbarItemTitle = colours.black,
  258. Background = colours.lightGrey,
  259. MenuBackground = colours.white,
  260. MenuText = colours.black,
  261. MenuSeparatorText = colours.grey,
  262. MenuDisabledText = colours.lightGrey,
  263. Shadow = colours.grey,
  264. TransparentBackgroundOne = colours.white,
  265. TransparentBackgroundTwo = colours.lightGrey,
  266. MenuBarActive = colours.white
  267. }
  268.  
  269. --Lists--
  270. Current = {
  271. Artboard = nil,
  272. Layer = nil,
  273. Tool = nil,
  274. ToolSize = 1,
  275. Toolbar = nil,
  276. Colour = colours.lightBlue,
  277. Menu = nil,
  278. MenuBar = nil,
  279. Window = nil,
  280. Input = nil,
  281. CursorPos = {1,1},
  282. CursorColour = colours.black,
  283. InterfaceVisible = true,
  284. Selection = {},
  285. SelectionDrawTimer = nil,
  286. HandDragStart = {},
  287. Modified = false,
  288. }
  289.  
  290. local isQuitting = false
  291.  
  292. function PrintCentered(text, y)
  293. local w, h = term.getSize()
  294. x = math.ceil(math.ceil((w / 2) - (#text / 2)), 0)+1
  295. term.setCursorPos(x, y)
  296. print(text)
  297. end
  298.  
  299. function DoVanillaClose()
  300. shell.run("index")
  301. end
  302.  
  303. function Close()
  304. if isQuitting or not Current.Artboard or not Current.Modified then
  305. if not OneOS then
  306. DoVanillaClose()
  307. end
  308. return true
  309. else
  310. local _w = ButtonDialougeWindow:Initialise('Quit Sketch?', 'You have unsaved changes, do you want to quit anyway?', 'Quit', 'Cancel', function(window, success)
  311. if success then
  312. if OneOS then
  313. OneOS.Close(true)
  314. else
  315. DoVanillaClose()
  316. end
  317. end
  318. window:Close()
  319. Draw()
  320. end):Show()
  321. --it's hacky but it works
  322. os.queueEvent('mouse_click', 1, _w.X, _w.Y)
  323. return false
  324. end
  325. end
  326.  
  327. if OneOS then
  328. OneOS.CanClose = function()
  329. return Close()
  330. end
  331. end
  332.  
  333. Lists = {
  334. Artboards = {},
  335. Interface = {
  336. Toolbars = {}
  337. }
  338. }
  339.  
  340. Events = {
  341.  
  342. }
  343.  
  344. --Setters--
  345.  
  346. function SetColour(colour)
  347. Current.Colour = colour
  348. Draw()
  349. end
  350.  
  351. function SetTool(tool)
  352. if tool and tool.Select and tool:Select() then
  353. Current.Input = nil
  354. Current.Tool = tool
  355. return true
  356. end
  357. return false
  358. end
  359.  
  360. function GetAbsolutePosition(object)
  361. local obj = object
  362. local i = 0
  363. local x = 1
  364. local y = 1
  365. while true do
  366. x = x + obj.X - 1
  367. y = y + obj.Y - 1
  368.  
  369. if not obj.Parent then
  370. return {X = x, Y = y}
  371. end
  372.  
  373. obj = obj.Parent
  374.  
  375. if i > 32 then
  376. return {X = 1, Y = 1}
  377. end
  378.  
  379. i = i + 1
  380. end
  381.  
  382. end
  383.  
  384. --Object Defintions--
  385.  
  386. Pixel = {
  387. TextColour = colours.black,
  388. BackgroundColour = colours.white,
  389. Character = " ",
  390. Layer = nil,
  391.  
  392. Draw = function(self, x, y)
  393. if self.BackgroundColour ~= colours.transparent or self.Character ~= ' ' then
  394. Drawing.WriteToBuffer(self.Layer.Artboard.X + x - 1, self.Layer.Artboard.Y + y - 1, self.Character, self.TextColour, self.BackgroundColour)
  395. end
  396. end,
  397.  
  398. Initialise = function(self, textColour, backgroundColour, character, layer)
  399. local new = {} -- the new instance
  400. setmetatable( new, {__index = self} )
  401. new.TextColour = textColour or self.TextColour
  402. new.BackgroundColour = backgroundColour or self.BackgroundColour
  403. new.Character = character or self.Character
  404. new.Layer = layer
  405. return new
  406. end,
  407.  
  408. Set = function(self, textColour, backgroundColour, character)
  409. self.TextColour = textColour or self.TextColour
  410. self.BackgroundColour = backgroundColour or self.BackgroundColour
  411. self.Character = character or self.Character
  412. end
  413. }
  414.  
  415. Layer = {
  416. Name = "",
  417. Pixels = {
  418.  
  419. },
  420. Artboard = nil,
  421. BackgroundColour = colours.white,
  422. Visible = true,
  423. Index = 1,
  424.  
  425. Draw = function(self)
  426. if self.Visible then
  427. for x = 1, self.Artboard.Width do
  428. for y = 1, self.Artboard.Height do
  429. self.Pixels[x][y]:Draw(x, y)
  430. end
  431. end
  432. end
  433. end,
  434.  
  435. Remove = function(self)
  436. for i, v in ipairs(self.Artboard.Layers) do
  437. if v == Current.Layer then
  438. Current.Artboard.Layers[i] = nil
  439. Current.Layer = Current.Artboard.Layers[1]
  440. ModuleNamed('Layers'):Update()
  441. end
  442. end
  443. end,
  444.  
  445. Initialise = function(self, name, backgroundColour, artboard, index, pixels)
  446. local new = {} -- the new instance
  447. setmetatable( new, {__index = self} )
  448. new.Name = name
  449. new.Pixels = {}
  450. new.BackgroundColour = backgroundColour
  451. new.Artboard = artboard
  452. new.Index = index or #artboard.Layers + 1
  453. if not pixels then
  454. new:MakeAllBlankPixels()
  455. else
  456. new:MakeAllBlankPixels()
  457. for x, col in ipairs(pixels) do
  458. for y, pixel in ipairs(col) do
  459. new:SetPixel(x, y, pixel.TextColour, pixel.BackgroundColour, pixel.Character)
  460. end
  461. end
  462. end
  463.  
  464. return new
  465. end,
  466.  
  467. SetPixel = function(self, x, y, textColour, backgroundColour, character)
  468. textColour = textColour or Current.Colour
  469. backgroundColour = backgroundColour or Current.Colour
  470. character = character or " "
  471.  
  472. if x < 1 or y < 1 or x > self.Artboard.Width or y > self.Artboard.Height then
  473. return
  474. end
  475.  
  476. if self.Pixels[x][y] then
  477. self.Pixels[x][y]:Set(textColour, backgroundColour, character)
  478. self.Pixels[x][y]:Draw(x,y)
  479. end
  480. end,
  481.  
  482. MakePixel = function(self, x, y, backgroundColour)
  483. backgroundColour = backgroundColour or self.BackgroundColour
  484. self.Pixels[x][y] = Pixel:Initialise(nil, backgroundColour, nil, self)
  485. end,
  486.  
  487. MakeColumn = function(self, x)
  488. self.Pixels[x] = {}
  489. end,
  490.  
  491. MakeAllBlankPixels = function(self)
  492. for x = 1, self.Artboard.Width do
  493. if not self.Pixels[x] then
  494. self:MakeColumn(x)
  495. end
  496.  
  497. for y = 1, self.Artboard.Height do
  498.  
  499. if not self.Pixels[x][y] then
  500. self:MakePixel(x, y)
  501. end
  502.  
  503. end
  504. end
  505. end,
  506.  
  507. PixelsInSelection = function(self, cut)
  508. local pixels = {}
  509. if Current.Selection and Current.Selection[1] and Current.Selection[2] ~= nil then
  510. local point1 = Current.Selection[1]
  511. local point2 = Current.Selection[2]
  512.  
  513. local size = point2 - point1
  514. local cornerX = point1.x
  515. local cornerY = point1.y
  516. for x = 1, size.x + 1 do
  517. for y = 1, size.y + 1 do
  518. if not pixels[x] then
  519. pixels[x] = {}
  520. end
  521. if not self.Pixels[cornerX + x - 1] or not self.Pixels[cornerX + x - 1][cornerY + y - 1] then
  522. break
  523. end
  524. local pixel = self.Pixels[cornerX + x - 1][cornerY + y - 1]
  525. pixels[x][y] = Pixel:Initialise(pixel.TextColour, pixel.BackgroundColour, pixel.Character, Current.Layer)
  526. if cut then
  527. Current.Layer:SetPixel(cornerX + x - 1, cornerY + y - 1, nil, Current.Layer.BackgroundColour, nil)
  528. end
  529. end
  530. end
  531. end
  532. return pixels
  533. end,
  534.  
  535. EraseSelection = function(self)
  536. if Current.Selection and Current.Selection[1] and Current.Selection[2] ~= nil then
  537. local point1 = Current.Selection[1]
  538. local point2 = Current.Selection[2]
  539.  
  540. local size = point2 - point1
  541. local cornerX = point1.x
  542. local cornerY = point1.y
  543. for x = 1, size.x + 1 do
  544. for y = 1, size.y + 1 do
  545. Current.Layer:SetPixel(cornerX + x - 1, cornerY + y - 1, nil, Current.Layer.BackgroundColour, nil)
  546. end
  547. end
  548. end
  549. end,
  550.  
  551. InsertPixels = function(self, pixels)
  552. local cornerX = Current.Selection[1].x
  553. local cornerY = Current.Selection[1].y
  554. for x, col in ipairs(pixels) do
  555. for y, pixel in ipairs(col) do
  556. Current.Layer:SetPixel(cornerX + x - 1, cornerY + y - 1, pixel.TextColour, pixel.BackgroundColour, pixel.Character)
  557. end
  558. end
  559. end
  560. }
  561.  
  562. Artboard = {
  563. X = 0,
  564. Y = 0,
  565. Name = "",
  566. Path = "",
  567. Width = 1,
  568. Height = 1,
  569. Layers = {},
  570. Format = nil,
  571. SelectionIsBlack = true,
  572.  
  573. Draw = function(self)
  574. Drawing.DrawBlankArea(self.X + 1, self.Y + 1, self.Width, self.Height, UIColours.Shadow)
  575.  
  576. local odd
  577. for x = 1, self.Width do
  578. odd = x % 2
  579. if odd == 1 then
  580. odd = true
  581. else
  582. odd = false
  583. end
  584. for y = 1, self.Height do
  585. if odd then
  586. Drawing.WriteToBuffer(self.X + x - 1, self.Y + y - 1, ":", UIColours.TransparentBackgroundTwo, UIColours.TransparentBackgroundOne)
  587. else
  588. Drawing.WriteToBuffer(self.X + x - 1, self.Y + y - 1, ":", UIColours.TransparentBackgroundOne, UIColours.TransparentBackgroundTwo)
  589. end
  590.  
  591. odd = not odd
  592. end
  593. end
  594.  
  595. for i, layer in ipairs(self.Layers) do
  596. layer:Draw()
  597. end
  598.  
  599. if Current.Selection and Current.Selection[1] and Current.Selection[2] ~= nil then
  600. local point1 = Current.Selection[1]
  601. local point2 = Current.Selection[2]
  602.  
  603. local size = point2 - point1
  604.  
  605. local isBlack = self.SelectionIsBlack
  606.  
  607. local function c()
  608. local c = colours.white
  609. if isBlack then
  610. c = colours.black
  611. end
  612. isBlack = not isBlack
  613. return c
  614. end
  615.  
  616. function horizontal(y)
  617. Drawing.WriteToBuffer(self.X - 1 + point1.x, self.Y - 1 + y, '+', c(), colours.transparent)
  618. if size.x > 0 then
  619. for i = 1, size.x - 1 do
  620. Drawing.WriteToBuffer(self.X - 1 + point1.x + i, self.Y - 1 + y, '-', c(), colours.transparent)
  621. end
  622. else
  623. for i = 1, (-1 * size.x) - 1 do
  624. Drawing.WriteToBuffer(self.X - 1 + point1.x - i, self.Y - 1 + y, '-', c(), colours.transparent)
  625. end
  626. end
  627.  
  628. Drawing.WriteToBuffer(self.X - 1 + point1.x + size.x, self.Y - 1 + y, '+', c(), colours.transparent)
  629. end
  630.  
  631. function vertical(x)
  632. if size.y < 0 then
  633. for i = 1, (-1 * size.y) - 1 do
  634. Drawing.WriteToBuffer(self.X - 1 + x, self.Y - 1 + point1.y - i, '|', c(), colours.transparent)
  635. end
  636. else
  637. for i = 1, size.y - 1 do
  638. Drawing.WriteToBuffer(self.X - 1 + x, self.Y - 1 + point1.y + i, '|', c(), colours.transparent)
  639. end
  640. end
  641. end
  642.  
  643. horizontal(point1.y)
  644. vertical(point1.x)
  645. horizontal(point1.y + size.y)
  646. vertical(point1.x + size.x)
  647. end
  648. end,
  649.  
  650. Initialise = function(self, name, path, width, height, format, backgroundColour, layers)
  651. local new = {} -- the new instance
  652. setmetatable( new, {__index = self} )
  653. new.Y = 3
  654. new.X = 2
  655. new.Name = name
  656. new.Path = path
  657. new.Width = width
  658. new.Height = height
  659. new.Format = format
  660. new.Layers = {}
  661. if not layers then
  662. new:MakeLayer('Background', backgroundColour)
  663. else
  664. for i, layer in ipairs(layers) do
  665. new:MakeLayer(layer.Name, layer.BackgroundColour, layer.Index, layer.Pixels)
  666. new.Layers[i].Visible = layer.Visible
  667. end
  668. Current.Layer = new.Layers[#new.Layers]
  669. end
  670. return new
  671. end,
  672.  
  673. Resize = function(self, top, bottom, left, right)
  674. self.Height = self.Height + top + bottom
  675. self.Width = self.Width + left + right
  676.  
  677. for i, layer in ipairs(self.Layers) do
  678.  
  679. if left < 0 then
  680. for x = 1, -left do
  681. table.remove(layer.Pixels, 1)
  682. end
  683. end
  684.  
  685. if right < 0 then
  686. for x = 1, -right do
  687. table.remove(layer.Pixels, #layer.Pixels)
  688. end
  689. end
  690.  
  691. for x = 1, left do
  692. table.insert(layer.Pixels, 1, {})
  693. for y = 1, self.Height do
  694. layer:MakePixel(1, y)
  695. end
  696. end
  697.  
  698. for x = 1, right do
  699. table.insert(layer.Pixels, {})
  700. for y = 1, self.Height do
  701. layer:MakePixel(#layer.Pixels, y)
  702. end
  703. end
  704.  
  705. for y = 1, top do
  706. for x = 1, self.Width do
  707. table.insert(layer.Pixels[x], 1, {})
  708. layer:MakePixel(x, 1)
  709. end
  710. end
  711.  
  712. for y = 1, bottom do
  713. for x = 1, self.Width do
  714. table.insert(layer.Pixels[x], {})
  715. layer:MakePixel(x, #layer.Pixels[x])
  716. end
  717. end
  718.  
  719. if top < 0 then
  720. for y = 1, -top do
  721. for x = 1, self.Width do
  722. table.remove(layer.Pixels[x], 1)
  723. end
  724. end
  725. end
  726.  
  727. if bottom < 0 then
  728. for y = 1, -bottom do
  729. for x = 1, self.Width do
  730. table.remove(layer.Pixels[x], #layer.Pixels[x])
  731. end
  732. end
  733. end
  734. end
  735. end,
  736.  
  737. MakeLayer = function(self, name, backgroundColour, index, pixels)
  738. backgroundColour = backgroundColour or colours.white
  739. name = name or "Layer"
  740. local layer = Layer:Initialise(name, backgroundColour, self, index, pixels)
  741. table.insert(self.Layers, layer)
  742. Current.Layer = layer
  743. ModuleNamed('Layers'):Update()
  744. return layer
  745. end,
  746.  
  747. New = function(self, name, path, width, height, format, backgroundColour, layers)
  748. local new = self:Initialise(name, path, width, height, format, backgroundColour, layers)
  749. table.insert(Lists.Artboards, new)
  750. Current.Artboard = new
  751. --new:Save()
  752. return new
  753. end,
  754.  
  755. Save = function(self, path)
  756. Current.Artboard = self
  757. path = path or self.Path
  758. local _open = io.open
  759. if OneOS then
  760. _open = OneOS.IO.open
  761. end
  762. local file = _open(path, "w", true)
  763. if self.Format == '.skch' then
  764. file:write(textutils.serialize(SaveSKCH()))
  765. else
  766. local lines = {}
  767. if self.Format == '.nfp' then
  768. lines = SaveNFP()
  769. elseif self.Format == '.nft' then
  770. lines = SaveNFT()
  771. end
  772.  
  773. for i, line in ipairs(lines) do
  774. file:write(line.."\n")
  775. end
  776. end
  777. file:close()
  778. Current.Modified = false
  779. end,
  780.  
  781. Click = function(self, side, x, y, drag)
  782. if Current.Tool and Current.Layer and Current.Layer.Visible then
  783. Current.Tool:Use(x, y, side, drag)
  784. Current.Modified = true
  785. return true
  786. end
  787. end
  788. }
  789.  
  790. Toolbar = {
  791. X = 0,
  792. Y = 0,
  793. Width = 0,
  794. ExpandedWidth = 14,
  795. ClosedWidth = 2,
  796. Height = 0,
  797. Expanded = true,
  798. ToolbarItems = {},
  799.  
  800. AbsolutePosition = function(self)
  801. return {X = self.X, Y = self.Y}
  802. end,
  803.  
  804. Draw = function(self)
  805. self:CalculateToolbarItemPositions()
  806. --Drawing.DrawArea(self.X - 1, self.Y, 1, self.Height, "|", UIColours.ToolbarText, UIColours.Background)
  807.  
  808.  
  809.  
  810. --if not Current.Window then
  811. Drawing.DrawBlankArea(self.X, self.Y, self.Width, self.Height, UIColours.Toolbar)
  812. --else
  813. -- Drawing.DrawArea(self.X, self.Y, self.Width, self.Height, '|', colours.lightGrey, UIColours.Toolbar)
  814. --end
  815. for i, toolbarItem in ipairs(self.ToolbarItems) do
  816. toolbarItem:Draw()
  817. end
  818. end,
  819.  
  820. Initialise = function(self, side, expanded)
  821. local new = {} -- the new instance
  822. setmetatable( new, {__index = self} )
  823. new.Expanded = expanded
  824.  
  825. if expanded then
  826. new.Width = new.ExpandedWidth
  827. else
  828. new.Width = new.ClosedWidth
  829. end
  830.  
  831. if side == 'right' then
  832. new.X = Drawing.Screen.Width - new.Width + 1
  833. end
  834.  
  835. if side == 'right' or side == 'left' then
  836. new.Height = Drawing.Screen.Width
  837. end
  838.  
  839. new.Y = 1
  840.  
  841. return new
  842. end,
  843.  
  844. AddToolbarItem = function(self, item)
  845. table.insert(self.ToolbarItems, item)
  846. self:CalculateToolbarItemPositions()
  847. end,
  848.  
  849. CalculateToolbarItemPositions = function(self)
  850. local currY = 1
  851. for i, toolbarItem in ipairs(self.ToolbarItems) do
  852. toolbarItem.Y = currY
  853. currY = currY + toolbarItem.Height
  854. end
  855. end,
  856.  
  857. Update = function(self)
  858. for i, toolbarItem in ipairs(self.ToolbarItems) do
  859. if toolbarItem.Module.Update then
  860. toolbarItem.Module:Update(toolbarItem)
  861. end
  862. end
  863. end,
  864.  
  865. New = function(self, side, expanded)
  866. local new = self:Initialise(side, expanded)
  867.  
  868. --new:AddToolbarItem(ToolbarItem:Initialise("Colours", nil, true, new))
  869. --new:AddToolbarItem(ToolbarItem:Initialise("IDK", true, new))
  870.  
  871. table.insert(Lists.Interface.Toolbars, new)
  872. return new
  873. end,
  874.  
  875. Click = function(self, side, x, y)
  876. return false
  877. end
  878. }
  879.  
  880. ToolbarItem = {
  881. X = 0,
  882. Y = 0,
  883. Width = 0,
  884. Height = 0,
  885. ExpandedHeight = 5,
  886. Expanded = true,
  887. Toolbar = nil,
  888. Title = "",
  889. MenuIcon = "=",
  890. ExpandedIcon = "+",
  891. ContractIcon = "-",
  892. ContentView = nil,
  893. Module = nil,
  894. MenuItems = nil,
  895.  
  896. Draw = function(self)
  897. Drawing.DrawBlankArea(self.X, self.Y, self.Width, 1, UIColours.ToolbarItemTitle)
  898. Drawing.DrawCharacters(self.X + 1, self.Y, self.Title, UIColours.ToolbarText, UIColours.ToolbarItemTitle)
  899.  
  900. Drawing.DrawCharacters(self.X + self.Width - 1, self.Y, self.MenuIcon, UIColours.ToolbarText, UIColours.ToolbarItemTitle)
  901.  
  902. local expandContractIcon = self.ContractIcon
  903. if not self.Expanded then
  904. expandContractIcon = self.ExpandedIcon
  905. end
  906.  
  907. if self.Expanded and self.ContentView then
  908. self.ContentView:Draw()
  909. end
  910.  
  911. Drawing.DrawCharacters(self.X + self.Width - 2, self.Y, expandContractIcon, UIColours.ToolbarText, UIColours.ToolbarItemTitle)
  912. end,
  913.  
  914. Initialise = function(self, module, height, expanded, toolbar, menuItems)
  915. local new = {} -- the new instance
  916. setmetatable( new, {__index = self} )
  917. new.Expanded = expanded
  918. new.Title = module.Title
  919. new.Width = toolbar.Width
  920. new.Height = height or 5
  921. new.Module = module
  922. new.MenuItems = menuItems or {}
  923. table.insert(new.MenuItems,
  924. {
  925. Title = 'Shrink',
  926. Click = function()
  927. new:ToggleExpanded()
  928. end
  929. })
  930. new.ExpandedHeight = height or 5
  931. new.Y = 1
  932. new.X = toolbar.X
  933. new.ContentView = ContentView:Initialise(1, 2, new.Width, new.Height - 1, nil, new)
  934. new.Toolbar = toolbar
  935.  
  936. return new
  937. end,
  938.  
  939. ToggleExpanded = function(self)
  940. self.Expanded = not self.Expanded
  941. if self.Expanded then
  942. self.Height = self.ExpandedHeight
  943. else
  944. self.Height = 1
  945. end
  946. end,
  947.  
  948. Click = function(self, side, x, y)
  949. local pos = GetAbsolutePosition(self)
  950. if x == self.Width and y == 1 then
  951. local expandContract = "Shrink"
  952.  
  953. if not self.Expanded then
  954. expandContract = "Expand"
  955. end
  956. self.MenuItems[#self.MenuItems].Title = expandContract
  957. Menu:New(pos.X + x, pos.Y + y, self.MenuItems, self)
  958. return true
  959. elseif x == self.Width - 1 and y == 1 then
  960. self:ToggleExpanded()
  961. return true
  962. elseif y ~= 1 then
  963. return self.ContentView:Click(side, x - self.ContentView.X + 1, y - self.ContentView.Y + 1)
  964. end
  965.  
  966. return false
  967. end
  968. }
  969.  
  970. ContentView = {
  971. X = 1,
  972. Y = 1,
  973. Width = 0,
  974. Height = 0,
  975. Parent = nil,
  976. Views = {},
  977.  
  978. AbsolutePosition = function(self)
  979. return self.Parent:AbsolutePosition()
  980. end,
  981.  
  982. Draw = function(self)
  983. for i, view in ipairs(self.Views) do
  984. view:Draw()
  985. end
  986. end,
  987.  
  988. Initialise = function(self, x, y, width, height, views, parent)
  989. local new = {} -- the new instance
  990. setmetatable( new, {__index = self} )
  991. new.Width = width
  992. new.Height = height
  993. new.Y = y
  994. new.X = x
  995. new.Views = views or {}
  996. new.Parent = parent
  997. return new
  998. end,
  999.  
  1000. Click = function(self, side, x, y)
  1001. for k, view in pairs(self.Views) do
  1002. if DoClick(view, side, x, y) then
  1003. return true
  1004. end
  1005. end
  1006. end
  1007. }
  1008.  
  1009. Button = {
  1010. X = 1,
  1011. Y = 1,
  1012. Width = 0,
  1013. Height = 0,
  1014. BackgroundColour = colours.lightGrey,
  1015. TextColour = colours.white,
  1016. ActiveBackgroundColour = colours.lightGrey,
  1017. Text = "",
  1018. Parent = nil,
  1019. _Click = nil,
  1020. Toggle = nil,
  1021.  
  1022. AbsolutePosition = function(self)
  1023. return self.Parent:AbsolutePosition()
  1024. end,
  1025.  
  1026. Draw = function(self)
  1027. local bg = self.BackgroundColour
  1028. local tc = self.TextColour
  1029. if type(bg) == 'function' then
  1030. bg = bg()
  1031. end
  1032.  
  1033. if self.Toggle then
  1034. tc = UIColours.MenuBarActive
  1035. bg = self.ActiveBackgroundColour
  1036. end
  1037.  
  1038. local pos = GetAbsolutePosition(self)
  1039. Drawing.DrawBlankArea(pos.X, pos.Y, self.Width, self.Height, bg)
  1040. Drawing.DrawCharactersCenter(pos.X, pos.Y, self.Width, self.Height, self.Text, tc, bg)
  1041. end,
  1042.  
  1043. Initialise = function(self, x, y, width, height, backgroundColour, parent, click, text, textColour, toggle, activeBackgroundColour)
  1044. local new = {} -- the new instance
  1045. setmetatable( new, {__index = self} )
  1046. height = height or 1
  1047. new.Width = width or #text + 2
  1048. new.Height = height
  1049. new.Y = y
  1050. new.X = x
  1051. new.Text = text or ""
  1052. new.BackgroundColour = backgroundColour or colours.lightGrey
  1053. new.TextColour = textColour or colours.white
  1054. new.ActiveBackgroundColour = activeBackgroundColour or colours.lightGrey
  1055. new.Parent = parent
  1056. new._Click = click
  1057. new.Toggle = toggle
  1058. return new
  1059. end,
  1060.  
  1061. Click = function(self, side, x, y)
  1062. if self._Click then
  1063. if self:_Click(side, x, y, not self.Toggle) ~= false and self.Toggle ~= nil then
  1064. self.Toggle = not self.Toggle
  1065. Draw()
  1066. end
  1067. return true
  1068. else
  1069. return false
  1070. end
  1071. end
  1072. }
  1073.  
  1074. TextBox = {
  1075. X = 1,
  1076. Y = 1,
  1077. Width = 0,
  1078. Height = 0,
  1079. BackgroundColour = colours.lightGrey,
  1080. TextColour = colours.black,
  1081. Parent = nil,
  1082. TextInput = nil,
  1083.  
  1084. AbsolutePosition = function(self)
  1085. return self.Parent:AbsolutePosition()
  1086. end,
  1087.  
  1088. Draw = function(self)
  1089. local pos = GetAbsolutePosition(self)
  1090. Drawing.DrawBlankArea(pos.X, pos.Y, self.Width, self.Height, self.BackgroundColour)
  1091. local text = self.TextInput.Value
  1092. if #text > (self.Width - 2) then
  1093. text = text:sub(#text-(self.Width - 3))
  1094. if Current.Input == self.TextInput then
  1095. Current.CursorPos = {pos.X + 1 + self.Width-2, pos.Y}
  1096. end
  1097. else
  1098. if Current.Input == self.TextInput then
  1099. Current.CursorPos = {pos.X + 1 + self.TextInput.CursorPos, pos.Y}
  1100. end
  1101. end
  1102. Drawing.DrawCharacters(pos.X + 1, pos.Y, text, self.TextColour, self.BackgroundColour)
  1103.  
  1104. term.setCursorBlink(true)
  1105.  
  1106. Current.CursorColour = self.TextColour
  1107. end,
  1108.  
  1109. Initialise = function(self, x, y, width, height, parent, text, backgroundColour, textColour, done, numerical)
  1110. local new = {} -- the new instance
  1111. setmetatable( new, {__index = self} )
  1112. height = height or 1
  1113. new.Width = width or #text + 2
  1114. new.Height = height
  1115. new.Y = y
  1116. new.X = x
  1117. new.TextInput = TextInput:Initialise(text or '', function(key)
  1118. if done then
  1119. done(key)
  1120. end
  1121. Draw()
  1122. end, numerical)
  1123. new.BackgroundColour = backgroundColour or colours.lightGrey
  1124. new.TextColour = textColour or colours.black
  1125. new.Parent = parent
  1126. return new
  1127. end,
  1128.  
  1129. Click = function(self, side, x, y)
  1130. Current.Input = self.TextInput
  1131. self:Draw()
  1132. end
  1133. }
  1134.  
  1135. TextInput = {
  1136. Value = "",
  1137. Change = nil,
  1138. CursorPos = nil,
  1139. Numerical = false,
  1140.  
  1141. Initialise = function(self, value, change, numerical)
  1142. local new = {} -- the new instance
  1143. setmetatable( new, {__index = self} )
  1144. new.Value = value
  1145. new.Change = change
  1146. new.CursorPos = #value
  1147. new.Numerical = numerical
  1148. return new
  1149. end,
  1150.  
  1151. Char = function(self, char)
  1152. if self.Numerical then
  1153. char = tostring(tonumber(char))
  1154. end
  1155. if char == 'nil' then
  1156. return
  1157. end
  1158. self.Value = string.sub(self.Value, 1, self.CursorPos ) .. char .. string.sub( self.Value, self.CursorPos + 1 )
  1159.  
  1160. self.CursorPos = self.CursorPos + 1
  1161. self.Change(key)
  1162. end,
  1163.  
  1164. Key = function(self, key)
  1165. if key == keys.enter then
  1166. self.Change(key)
  1167. elseif key == keys.left then
  1168. -- Left
  1169. if self.CursorPos > 0 then
  1170. self.CursorPos = self.CursorPos - 1
  1171. self.Change(key)
  1172. end
  1173.  
  1174. elseif key == keys.right then
  1175. -- Right
  1176. if self.CursorPos < string.len(self.Value) then
  1177. self.CursorPos = self.CursorPos + 1
  1178. self.Change(key)
  1179. end
  1180.  
  1181. elseif key == keys.backspace then
  1182. -- Backspace
  1183. if self.CursorPos > 0 then
  1184. self.Value = string.sub( self.Value, 1, self.CursorPos - 1 ) .. string.sub( self.Value, self.CursorPos + 1 )
  1185. self.CursorPos = self.CursorPos - 1
  1186. end
  1187. self.Change(key)
  1188. elseif key == keys.home then
  1189. -- Home
  1190. self.CursorPos = 0
  1191. self.Change(key)
  1192. elseif key == keys.delete then
  1193. if self.CursorPos < string.len(self.Value) then
  1194. self.Value = string.sub( self.Value, 1, self.CursorPos ) .. string.sub( self.Value, self.CursorPos + 2 )
  1195. self.Change(key)
  1196. end
  1197. elseif key == keys["end"] then
  1198. -- End
  1199. self.CursorPos = string.len(self.Value)
  1200. self.Change(key)
  1201. end
  1202. end
  1203. }
  1204.  
  1205. LayerItem = {
  1206. X = 1,
  1207. Y = 1,
  1208. Parent = nil,
  1209. Layer = nil,
  1210.  
  1211. Draw = function(self)
  1212. self.Y = self.Layer.Index
  1213.  
  1214. local pos = GetAbsolutePosition(self)
  1215.  
  1216. local tc = colours.lightGrey
  1217.  
  1218. if Current.Layer == self.Layer then
  1219. tc = colours.white
  1220. end
  1221.  
  1222. Drawing.DrawBlankArea(pos.X, pos.Y, self.Width, self.Height, UIColours.Toolbar)
  1223.  
  1224. Drawing.DrawCharacters(pos.X + 3, pos.Y, self.Layer.Name, tc, UIColours.Toolbar)
  1225.  
  1226. if self.Layer.Visible then
  1227. Drawing.DrawCharacters(pos.X + 1, pos.Y, "@", tc, UIColours.Toolbar)
  1228. else
  1229. Drawing.DrawCharacters(pos.X + 1, pos.Y, "X", tc, UIColours.Toolbar)
  1230. end
  1231.  
  1232. end,
  1233.  
  1234. Initialise = function(self, layer, parent)
  1235. local new = {} -- the new instance
  1236. setmetatable( new, {__index = self} )
  1237. new.Width = parent.Width
  1238. new.Height = 1
  1239. new.Y = 1
  1240. new.X = 1
  1241. new.Layer = layer
  1242. new.Parent = parent
  1243. return new
  1244. end,
  1245.  
  1246. Click = function(self, side, x, y)
  1247. if x == 2 then
  1248. self.Layer.Visible = not self.Layer.Visible
  1249. else
  1250. Current.Layer = self.Layer
  1251. end
  1252. return true
  1253. end
  1254. }
  1255.  
  1256. Menu = {
  1257. X = 0,
  1258. Y = 0,
  1259. Width = 0,
  1260. Height = 0,
  1261. Owner = nil,
  1262. Items = {},
  1263. RemoveTop = false,
  1264.  
  1265. Draw = function(self)
  1266. Drawing.DrawBlankArea(self.X + 1, self.Y + 1, self.Width, self.Height, UIColours.Shadow)
  1267. if not self.RemoveTop then
  1268. Drawing.DrawBlankArea(self.X, self.Y, self.Width, self.Height, UIColours.MenuBackground)
  1269. for i, item in ipairs(self.Items) do
  1270. if item.Separator then
  1271. Drawing.DrawArea(self.X, self.Y + i, self.Width, 1, '-', colours.grey, UIColours.MenuBackground)
  1272. else
  1273. local textColour = UIColours.MenuText
  1274. if (item.Enabled and type(item.Enabled) == 'function' and item.Enabled() == false) or item.Enabled == false then
  1275. textColour = UIColours.MenuDisabledText
  1276. end
  1277. Drawing.DrawCharacters(self.X + 1, self.Y + i, item.Title, textColour, UIColours.MenuBackground)
  1278. end
  1279. end
  1280. else
  1281. Drawing.DrawBlankArea(self.X, self.Y, self.Width, self.Height, UIColours.MenuBackground)
  1282. for i, item in ipairs(self.Items) do
  1283. if item.Separator then
  1284. Drawing.DrawArea(self.X, self.Y + i - 1, self.Width, 1, '-', colours.grey, UIColours.MenuBackground)
  1285. else
  1286. local textColour = UIColours.MenuText
  1287. if (item.Enabled and type(item.Enabled) == 'function' and item.Enabled() == false) or item.Enabled == false then
  1288. textColour = UIColours.MenuDisabledText
  1289. end
  1290. Drawing.DrawCharacters(self.X + 1, self.Y + i - 1, item.Title, textColour, UIColours.MenuBackground)
  1291.  
  1292. Drawing.DrawCharacters(self.X - 1 + self.Width-#item.KeyName, self.Y + i - 1, item.KeyName, textColour, UIColours.MenuBackground)
  1293. end
  1294. end
  1295. end
  1296. end,
  1297.  
  1298. NameForKey = function(self, key)
  1299. if key == keys.leftCtrl then
  1300. return '^'
  1301. elseif key == keys.tab then
  1302. return 'Tab'
  1303. elseif key == keys.delete then
  1304. return 'Delete'
  1305. elseif key == keys.n then
  1306. return 'N'
  1307. elseif key == keys.s then
  1308. return 'S'
  1309. elseif key == keys.o then
  1310. return 'O'
  1311. elseif key == keys.z then
  1312. return 'Z'
  1313. elseif key == keys.y then
  1314. return 'Y'
  1315. elseif key == keys.c then
  1316. return 'C'
  1317. elseif key == keys.x then
  1318. return 'X'
  1319. elseif key == keys.v then
  1320. return 'V'
  1321. elseif key == keys.r then
  1322. return 'R'
  1323. elseif key == keys.l then
  1324. return 'L'
  1325. elseif key == keys.t then
  1326. return 'T'
  1327. elseif key == keys.h then
  1328. return 'H'
  1329. elseif key == keys.e then
  1330. return 'E'
  1331. elseif key == keys.p then
  1332. return 'P'
  1333. elseif key == keys.f then
  1334. return 'F'
  1335. elseif key == keys.m then
  1336. return 'M'
  1337. else
  1338. return '?'
  1339. end
  1340. end,
  1341.  
  1342. Initialise = function(self, x, y, items, owner, removeTop)
  1343. local new = {} -- the new instance
  1344. setmetatable( new, {__index = self} )
  1345. if not owner then
  1346. return
  1347. end
  1348.  
  1349. local keyNames = {}
  1350.  
  1351. for i, v in ipairs(items) do
  1352. items[i].KeyName = ''
  1353. if v.Keys then
  1354. for _i, key in ipairs(v.Keys) do
  1355. items[i].KeyName = items[i].KeyName .. self:NameForKey(key)
  1356. end
  1357. end
  1358. if items[i].KeyName ~= '' then
  1359. table.insert(keyNames, items[i].KeyName)
  1360. end
  1361. end
  1362. local keysLength = LongestString(keyNames)
  1363. if keysLength > 0 then
  1364. keysLength = keysLength + 2
  1365. end
  1366.  
  1367. new.Width = LongestString(items, 'Title') + 2 + keysLength
  1368. if new.Width < 10 then
  1369. new.Width = 10
  1370. end
  1371. new.Height = #items + 2
  1372. new.RemoveTop = removeTop or false
  1373. if removeTop then
  1374. new.Height = new.Height - 1
  1375. end
  1376.  
  1377. if y < 1 then
  1378. y = 1
  1379. end
  1380. if x < 1 then
  1381. x = 1
  1382. end
  1383.  
  1384. if y + new.Height > Drawing.Screen.Height + 1 then
  1385. y = Drawing.Screen.Height - new.Height
  1386. end
  1387. if x + new.Width > Drawing.Screen.Width + 1 then
  1388. x = Drawing.Screen.Width - new.Width
  1389. end
  1390.  
  1391.  
  1392. new.Y = y
  1393. new.X = x
  1394. new.Items = items
  1395. new.Owner = owner
  1396. return new
  1397. end,
  1398.  
  1399. New = function(self, x, y, items, owner, removeTop)
  1400. if Current.Menu and Current.Menu.Owner == owner then
  1401. Current.Menu = nil
  1402. return
  1403. end
  1404.  
  1405. local new = self:Initialise(x, y, items, owner, removeTop)
  1406. Current.Menu = new
  1407. return new
  1408. end,
  1409.  
  1410. Click = function(self, side, x, y)
  1411. local i = y-1
  1412. if self.RemoveTop then
  1413. i = y
  1414. end
  1415. if i >= 1 and y < self.Height then
  1416. if not ((self.Items[i].Enabled and type(self.Items[i].Enabled) == 'function' and self.Items[i].Enabled() == false) or self.Items[i].Enabled == false) and self.Items[i].Click then
  1417. self.Items[i]:Click()
  1418. if Current.Menu.Owner and Current.Menu.Owner.Toggle then
  1419. Current.Menu.Owner.Toggle = false
  1420. end
  1421. Current.Menu = nil
  1422. self = nil
  1423. end
  1424. return true
  1425. end
  1426. end
  1427. }
  1428.  
  1429. MenuBar = {
  1430. X = 1,
  1431. Y = 1,
  1432. Width = Drawing.Screen.Width,
  1433. Height = 1,
  1434. MenuBarItems = {},
  1435.  
  1436. AbsolutePosition = function(self)
  1437. return {X = self.X, Y = self.Y}
  1438. end,
  1439.  
  1440. Draw = function(self)
  1441. --Drawing.DrawArea(self.X - 1, self.Y, 1, self.Height, "|", UIColours.ToolbarText, UIColours.Background)
  1442.  
  1443. Drawing.DrawBlankArea(self.X, self.Y, self.Width, self.Height, UIColours.Toolbar)
  1444. for i, button in ipairs(self.MenuBarItems) do
  1445. button:Draw()
  1446. end
  1447. end,
  1448.  
  1449. Initialise = function(self, items)
  1450. local new = {} -- the new instance
  1451. setmetatable( new, {__index = self} )
  1452. new.X = 1
  1453. new.Y = 1
  1454. new.MenuBarItems = items
  1455. return new
  1456. end,
  1457.  
  1458. AddToolbarItem = function(self, item)
  1459. table.insert(self.ToolbarItems, item)
  1460. self:CalculateToolbarItemPositions()
  1461. end,
  1462.  
  1463. CalculateToolbarItemPositions = function(self)
  1464. local currY = 1
  1465. for i, toolbarItem in ipairs(self.ToolbarItems) do
  1466. toolbarItem.Y = currY
  1467. currY = currY + toolbarItem.Height
  1468. end
  1469. end,
  1470.  
  1471. Click = function(self, side, x, y)
  1472. for i, item in ipairs(self.MenuBarItems) do
  1473. if item.X <= x and item.X + item.Width > x then
  1474. if item:Click(item, side, x - item.X + 1, 1) then
  1475. break
  1476. end
  1477. end
  1478. end
  1479. return false
  1480. end
  1481. }
  1482.  
  1483. --Modules--
  1484.  
  1485. Modules = {
  1486. {
  1487. Title = "Colours",
  1488. ToolbarItem = nil,
  1489. Initialise = function(self)
  1490. self.ToolbarItem = ToolbarItem:Initialise(self, nil, true, Current.Toolbar)
  1491.  
  1492. local buttons = {}
  1493.  
  1494. local i = 0
  1495.  
  1496. local coloursWidth = 8
  1497. local _colours = {
  1498. colours.brown,
  1499. colours.yellow,
  1500. colours.orange,
  1501. colours.red,
  1502. colours.green,
  1503. colours.lime,
  1504. colours.magenta,
  1505. colours.pink,
  1506. colours.purple,
  1507. colours.blue,
  1508. colours.cyan,
  1509. colours.lightBlue,
  1510. colours.lightGrey,
  1511. colours.grey,
  1512. colours.black,
  1513. colours.white
  1514. }
  1515.  
  1516. for k, colour in pairs(_colours) do
  1517. if type(colour) == 'number' and colour ~= -1 then
  1518. i = i + 1
  1519.  
  1520. local y = math.floor(i/(coloursWidth/2))
  1521.  
  1522. local x = (i%(coloursWidth/2))
  1523. if x == 0 then
  1524. x = (coloursWidth/2)
  1525. y = y -1
  1526. end
  1527.  
  1528. table.insert(buttons,
  1529. {
  1530. X = x*2 - 2 + self.ToolbarItem.Width - coloursWidth,
  1531. Y = y+1,
  1532. Width = 2,
  1533. Height = 1,
  1534. BackgroundColour = colour,
  1535. Click = function(self, side, x, y)
  1536. SetColour(self.BackgroundColour)
  1537. end
  1538. }
  1539. )
  1540. end
  1541. end
  1542.  
  1543. for i, button in ipairs(buttons) do
  1544. table.insert(self.ToolbarItem.ContentView.Views,
  1545. Button:Initialise(button.X, button.Y, button.Width, button.Height, button.BackgroundColour, self.ToolbarItem.ContentView, button.Click))
  1546. end
  1547.  
  1548. table.insert(self.ToolbarItem.ContentView.Views,
  1549. Button:Initialise(1, 1, 4, 3, function()return Current.Colour end, self.ToolbarItem.ContentView, nil))
  1550.  
  1551. Current.Toolbar:AddToolbarItem(self.ToolbarItem)
  1552. end
  1553. },
  1554.  
  1555. {
  1556. Title = "Tools",
  1557. ToolbarItem = nil,
  1558. Update = function(self)
  1559. for i, view in ipairs(self.ToolbarItem.ContentView.Views) do
  1560. if (Current.Tool and Current.Tool.Name == view.Text) then
  1561. view.TextColour = colours.white
  1562. else
  1563. view.TextColour = colours.lightGrey
  1564. end
  1565. end
  1566. self.ToolbarItem.ContentView.Views[1].Text = 'Size: '..Current.ToolSize
  1567. end,
  1568.  
  1569. Initialise = function(self)
  1570. self.ToolbarItem = ToolbarItem:Initialise(self, #Tools+2, true, Current.Toolbar,
  1571. {{
  1572. Title = "Change Tool Size",
  1573. Click = function()
  1574. DisplayToolSizeWindow()
  1575. end,
  1576. }})
  1577.  
  1578. table.insert(self.ToolbarItem.ContentView.Views, Button:Initialise(1, 1, self.ToolbarItem.Width, 1, UIColours.Toolbar, self.ToolbarItem.ContentView, DisplayToolSizeWindow, 'Size: '..Current.ToolSize))
  1579.  
  1580. local y = 2
  1581. for i, tool in ipairs(Tools) do
  1582. table.insert(self.ToolbarItem.ContentView.Views, Button:Initialise(1, y, self.ToolbarItem.Width, 1, UIColours.Toolbar, self.ToolbarItem.ContentView, function() SetTool(tool) self:Update(self.ToolbarItem) end, tool.Name))
  1583. y = y + 1
  1584. end
  1585.  
  1586. self:Update(self.ToolbarItem)
  1587.  
  1588. Current.Toolbar:AddToolbarItem(self.ToolbarItem)
  1589. end
  1590. },
  1591.  
  1592. {
  1593. Title = "Layers",
  1594. ToolbarItem = nil,
  1595. Update = function(self)
  1596. if Current.Artboard then
  1597. self.ToolbarItem.ContentView.Views = {}
  1598. for i = 1, #Current.Artboard.Layers do
  1599. table.insert(self.ToolbarItem.ContentView.Views, LayerItem:Initialise(Current.Artboard.Layers[#Current.Artboard.Layers-i+1], self.ToolbarItem.ContentView))
  1600. end
  1601. end
  1602. end,
  1603.  
  1604. Initialise = function(self)
  1605. self.ToolbarItem = ToolbarItem:Initialise(self, nil, true, Current.Toolbar,
  1606. {{
  1607. Title = "New Layer",
  1608. Click = function()
  1609. MakeNewLayer()
  1610. end,
  1611. Enabled = function()
  1612. return CheckOpenArtboard()
  1613. end
  1614. },
  1615. {
  1616. Title = 'Delete Layer',
  1617. Click = function()
  1618. DeleteLayer()
  1619. end,
  1620. Enabled = function()
  1621. return CheckSelectedLayer()
  1622. end
  1623. },
  1624. {
  1625. Title = 'Rename Layer...',
  1626. Click = function()
  1627. RenameLayer()
  1628. end,
  1629. Enabled = function()
  1630. return CheckSelectedLayer()
  1631. end
  1632. }})
  1633.  
  1634. self:Update()
  1635.  
  1636. Current.Toolbar:AddToolbarItem(self.ToolbarItem)
  1637. end
  1638. }
  1639.  
  1640. }
  1641.  
  1642. function ModuleNamed(name)
  1643. for i, v in ipairs(Modules) do
  1644. if v.Title == name then
  1645. return v
  1646. end
  1647. end
  1648. end
  1649.  
  1650. --Tools--
  1651.  
  1652. function ToolAffectedPixels(x, y)
  1653. if not CheckSelectedLayer() then
  1654. return {}
  1655. end
  1656. if Current.ToolSize == 1 then
  1657. if Current.Layer.Pixels[x] and Current.Layer.Pixels[x][y] then
  1658. return {{Current.Layer.Pixels[x][y], x, y}}
  1659. end
  1660. else
  1661. local pixels = {}
  1662. local cornerX = x - math.ceil(Current.ToolSize/2)
  1663. local cornerY = y - math.ceil(Current.ToolSize/2)
  1664. for _x = 1, Current.ToolSize do
  1665. for _y = 1, Current.ToolSize do
  1666. if Current.Layer.Pixels[cornerX + _x] and Current.Layer.Pixels[cornerX + _x][cornerY + _y] then
  1667. table.insert(pixels, {Current.Layer.Pixels[cornerX + _x][cornerY + _y], cornerX + _x, cornerY + _y})
  1668. end
  1669. end
  1670. end
  1671. return pixels
  1672. end
  1673. end
  1674. local moveStartPoint = {}
  1675. Tools = {
  1676. {
  1677. Name = "Hand",
  1678. Use = function(self, x, y, side, drag)
  1679. Current.Input = nil
  1680. if drag and Current.HandDragStart and Current.HandDragStart[1] and Current.HandDragStart[2] then
  1681. local deltaX = x - Current.HandDragStart[1]
  1682. local deltaY = y - Current.HandDragStart[2]
  1683. Current.Artboard.X = Current.Artboard.X + deltaX
  1684. Current.Artboard.Y = Current.Artboard.Y + deltaY
  1685. else
  1686. Current.HandDragStart = {x, y}
  1687. end
  1688. sleep(0)
  1689. end,
  1690. Select = function(self)
  1691. return true
  1692. end
  1693. },
  1694.  
  1695. {
  1696. Name = "Pencil",
  1697. Use = function(self, _x, _y, side, artboard)
  1698. Current.Input = nil
  1699. for i, pixel in ipairs(ToolAffectedPixels(_x, _y)) do
  1700. if side == 1 then
  1701. pixel[1].BackgroundColour = Current.Colour
  1702. elseif side == 2 then
  1703. pixel[1].TextColour = Current.Colour
  1704. end
  1705. pixel[1]:Draw(pixel[2], pixel[3])
  1706. end
  1707. end,
  1708. Select = function(self)
  1709. return true
  1710. end
  1711. },
  1712.  
  1713. {
  1714. Name = "Eraser",
  1715. Use = function(self, x, y, side)
  1716. Current.Input = nil
  1717. Current.Layer:SetPixel(x, y, nil, Current.Layer.BackgroundColour, nil)
  1718. for i, pixel in ipairs(ToolAffectedPixels(x, y)) do
  1719. Current.Layer:SetPixel(pixel[2], pixel[3], nil, Current.Layer.BackgroundColour, nil)
  1720. end
  1721. end,
  1722. Select = function(self)
  1723. return true
  1724. end
  1725. },
  1726.  
  1727. {
  1728. Name = "Fill Bucket",
  1729. Use = function(self, x, y, side)
  1730. local replaceColour = Current.Layer.Pixels[x][y].BackgroundColour
  1731. if side == 2 then
  1732. replaceColour = Current.Layer.Pixels[x][y].TextColour
  1733. end
  1734.  
  1735. local nodes = {{X = x, Y = y}}
  1736.  
  1737. while #nodes > 0 do
  1738. local node = nodes[1]
  1739. if Current.Layer.Pixels[node.X] and Current.Layer.Pixels[node.X][node.Y] then
  1740. local replacing = Current.Layer.Pixels[node.X][node.Y].BackgroundColour
  1741. if side == 2 then
  1742. replacing = Current.Layer.Pixels[node.X][node.Y].TextColour
  1743. end
  1744. if replacing == replaceColour and replacing ~= Current.Colour then
  1745. if side == 1 then
  1746. Current.Layer.Pixels[node.X][node.Y].BackgroundColour = Current.Colour
  1747. elseif side == 2 then
  1748. Current.Layer.Pixels[node.X][node.Y].TextColour = Current.Colour
  1749. end
  1750. table.insert(nodes, {X = node.X, Y = node.Y + 1})
  1751. table.insert(nodes, {X = node.X + 1, Y = node.Y})
  1752. if x > 1 then
  1753. table.insert(nodes, {X = node.X - 1, Y = node.Y})
  1754. end
  1755. if y > 1 then
  1756. table.insert(nodes, {X = node.X, Y = node.Y - 1})
  1757. end
  1758. end
  1759. end
  1760. table.remove(nodes, 1)
  1761. end
  1762. Draw()
  1763. end,
  1764. Select = function(self)
  1765. return true
  1766. end
  1767. },
  1768.  
  1769. {
  1770. Name = "Select",
  1771. Use = function(self, x, y, side, drag)
  1772. Current.Input = nil
  1773. if not drag then
  1774. Current.Selection[1] = vector.new(x, y, 0)
  1775. Current.Selection[2] = nil
  1776. else
  1777. Current.Selection[2] = vector.new(x, y, 0)
  1778. end
  1779. end,
  1780. Select = function(self)
  1781. return true
  1782. end
  1783. },
  1784.  
  1785. {
  1786. Name = "Move",
  1787. Use = function(self, x, y, side, drag)
  1788. Current.Input = nil
  1789.  
  1790. if Current.Selection and Current.Selection[1] and Current.Selection[2] ~= nil then
  1791. if drag and moveStartPoint then
  1792. local pixels = Current.Layer:PixelsInSelection(true)
  1793. local size = Current.Selection[1] - Current.Selection[2]
  1794. Current.Selection[1] = vector.new(x-moveStartPoint[1], y-moveStartPoint[2], 0)
  1795. Current.Selection[2] = vector.new(x-moveStartPoint[1]-size.x, y-moveStartPoint[2]-size.y, 0)
  1796. Current.Layer:InsertPixels(pixels)
  1797. else
  1798. moveStartPoint = {x-Current.Selection[1].x, y-Current.Selection[1].y}
  1799. end
  1800. end
  1801. end,
  1802. Select = function(self)
  1803. return true
  1804. end
  1805. },
  1806.  
  1807. {
  1808. Name = "Text",
  1809. Use = function(self, x, y)
  1810. Current.Input = TextInput:Initialise('', function(key)
  1811. if key == keys.delete or key == keys.backspace then
  1812. if #Current.Input.Value == 0 then
  1813. if Current.Layer.Pixels[x] and Current.Layer.Pixels[x][y] then
  1814. Current.Layer.Pixels[x][y]:Set(nil, nil, ' ')
  1815. local newPos = Current.CursorPos[1] - Current.Artboard.X
  1816. if newPos < Current.Artboard.X - 1 then
  1817. newPos = Current.Artboard.X - 1
  1818. end
  1819. Current.Tool:Use(newPos, Current.CursorPos[2] - Current.Artboard.Y + 1)
  1820. Draw()
  1821. end
  1822. return
  1823. else
  1824. if Current.Layer.Pixels[x+#Current.Input.Value] and Current.Layer.Pixels[x+#Current.Input.Value][y] then
  1825. Current.Layer.Pixels[x+#Current.Input.Value][y]:Set(nil, nil, ' ')
  1826. end
  1827. end
  1828. else
  1829. local i = #Current.Input.Value
  1830. if Current.Layer.Pixels[x+i-1] then
  1831. Current.Layer.Pixels[x+i-1][y]:Set(Current.Colour, nil, Current.Input.Value:sub(i,i))
  1832. Current.Layer.Pixels[x+i-1][y]:Draw(x+i-1, y)
  1833. end
  1834. end
  1835.  
  1836. local newPos = x+Current.Input.CursorPos
  1837.  
  1838. if newPos > Current.Artboard.Width then
  1839. Current.Input.CursorPos = Current.Input.CursorPos - 1
  1840. end
  1841.  
  1842. Current.CursorPos = {x+Current.Input.CursorPos + Current.Artboard.X - 1, y + Current.Artboard.Y - 1}
  1843. Current.CursorColour = Current.Colour
  1844. Draw()
  1845. end)
  1846.  
  1847. Current.CursorPos = {x + Current.Artboard.X - 1, y + Current.Artboard.Y - 1}
  1848. Current.CursorColour = Current.Colour
  1849. end,
  1850. Select = function(self)
  1851. if Current.Artboard.Format == '.nfp' then
  1852. ButtonDialougeWindow:Initialise('NFP does not support text!', 'The format you are using, NFP, does not support text. Use NFT or SKCH to use text.', 'Ok', nil, function(window)
  1853. window:Close()
  1854. end):Show()
  1855. return false
  1856. else
  1857. return true
  1858. end
  1859. end
  1860. }
  1861. }
  1862.  
  1863.  
  1864. function ToolNamed(name)
  1865. for i, v in ipairs(Tools) do
  1866. if v.Name == name then
  1867. return v
  1868. end
  1869. end
  1870. end
  1871.  
  1872. --Windows--
  1873.  
  1874. NewDocumentWindow = {
  1875. X = 1,
  1876. Y = 1,
  1877. Width = 0,
  1878. Height = 0,
  1879. CursorPos = 1,
  1880. Visible = true,
  1881. Return = nil,
  1882. OkButton = nil,
  1883. Format = '.skch',
  1884. ImageBackgroundColour = colours.white,
  1885. NameLabelHighlight = false,
  1886. SizeLabelHighlight = false,
  1887.  
  1888.  
  1889. AbsolutePosition = function(self)
  1890. return {X = self.X, Y = self.Y}
  1891. end,
  1892.  
  1893. Draw = function(self)
  1894. if not self.Visible then
  1895. return
  1896. end
  1897. Drawing.DrawBlankArea(self.X + 1, self.Y+1, self.Width, self.Height, colours.grey)
  1898. Drawing.DrawBlankArea(self.X, self.Y, self.Width, 1, colours.lightGrey)
  1899. Drawing.DrawBlankArea(self.X, self.Y+1, self.Width, self.Height-1, colours.white)
  1900. Drawing.DrawCharactersCenter(self.X, self.Y, self.Width, 1, self.Title, colours.black, colours.lightGrey)
  1901.  
  1902. local nameLabelColour = colours.black
  1903. if self.NameLabelHighlight then
  1904. nameLabelColour = colours.red
  1905. end
  1906.  
  1907. Drawing.DrawCharacters(self.X+1, self.Y+2, "Name", nameLabelColour, colours.white)
  1908. Drawing.DrawCharacters(self.X+1, self.Y+4, "Type", colours.black, colours.white)
  1909.  
  1910. local sizeLabelColour = colours.black
  1911. if self.SizeLabelHighlight then
  1912. sizeLabelColour = colours.red
  1913. end
  1914. Drawing.DrawCharacters(self.X+1, self.Y+6, "Size", sizeLabelColour, colours.white)
  1915. Drawing.DrawCharacters(self.X+11, self.Y+6, "x", colours.black, colours.white)
  1916. Drawing.DrawCharacters(self.X+1, self.Y+8, "Background", colours.black, colours.white)
  1917.  
  1918. self.OkButton:Draw()
  1919. self.CancelButton:Draw()
  1920. self.SKCHButton:Draw()
  1921. self.NFTButton:Draw()
  1922. self.NFPButton:Draw()
  1923. self.PathTextBox:Draw()
  1924. self.WidthTextBox:Draw()
  1925. self.HeightTextBox:Draw()
  1926. self.WhiteButton:Draw()
  1927. self.BlackButton:Draw()
  1928. self.TransparentButton:Draw()
  1929. end,
  1930.  
  1931. Initialise = function(self, returnFunc)
  1932. local new = {} -- the new instance
  1933. setmetatable( new, {__index = self} )
  1934. new.Width = 32
  1935. new.Height = 13
  1936. new.Return = returnFunc
  1937. new.X = math.ceil((Drawing.Screen.Width - new.Width) / 2)
  1938. new.Y = math.ceil((Drawing.Screen.Height - new.Height) / 2)
  1939. new.Title = 'New Document'
  1940. new.Visible = true
  1941. new.NameLabelHighlight = false
  1942. new.SizeLabelHighlight = false
  1943. new.Format = '.skch'
  1944. new.OkButton = Button:Initialise(new.Width - 4, new.Height - 1, nil, nil, colours.lightGrey, new, function(self, side, x, y, toggle)
  1945. local path = new.PathTextBox.TextInput.Value
  1946. local ok = true
  1947. new.NameLabelHighlight = false
  1948. new.SizeLabelHighlight = false
  1949. local _fs = fs
  1950. if OneOS then
  1951. _fs = OneOS.FS
  1952. end
  1953. if path:sub(-1) == '/' or _fs.isDir(path) or #path == 0 then
  1954. ok = false
  1955. new.NameLabelHighlight = true
  1956. end
  1957.  
  1958. if #new.WidthTextBox.TextInput.Value == 0 or tonumber(new.WidthTextBox.TextInput.Value) <= 0 then
  1959. ok = false
  1960. new.SizeLabelHighlight = true
  1961. end
  1962.  
  1963. if #new.HeightTextBox.TextInput.Value == 0 or tonumber(new.HeightTextBox.TextInput.Value) <= 0 then
  1964. ok = false
  1965. new.SizeLabelHighlight = true
  1966. end
  1967.  
  1968. if ok then
  1969. returnFunc(new, true, path, tonumber(new.WidthTextBox.TextInput.Value), tonumber(new.HeightTextBox.TextInput.Value), new.Format, new.ImageBackgroundColour)
  1970. else
  1971. Draw()
  1972. end
  1973. end, 'Ok', colours.black)
  1974. new.CancelButton = Button:Initialise(new.Width - 13, new.Height - 1, nil, nil, colours.lightGrey, new, function(self, side, x, y, toggle)returnFunc(new, false)end, 'Cancel', colours.black)
  1975.  
  1976. new.SKCHButton = Button:Initialise(7, 5, nil, nil, colours.lightGrey, new, function(self, side, x, y, toggle)
  1977. new.NFTButton.Toggle = false
  1978. new.NFPButton.Toggle = false
  1979. self.Toggle = false
  1980. new.Format = '.skch'
  1981. end, '.skch', colours.black, true, colours.lightBlue)
  1982. new.NFTButton = Button:Initialise(15, 5, nil, nil, colours.lightGrey, new, function(self, side, x, y, toggle)
  1983. new.SKCHButton.Toggle = false
  1984. new.NFPButton.Toggle = false
  1985. self.Toggle = false
  1986. new.Format = '.nft'
  1987. end, '.nft', colours.black, false, colours.lightBlue)
  1988. new.NFPButton = Button:Initialise(22, 5, nil, nil, colours.lightGrey, new, function(self, side, x, y, toggle)
  1989. new.SKCHButton.Toggle = false
  1990. new.NFTButton.Toggle = false
  1991. self.Toggle = false
  1992. new.Format = '.nfp'
  1993. end, '.nfp', colours.black, false, colours.lightBlue)
  1994.  
  1995. local path = ''
  1996. if OneOS then
  1997. path = '/Desktop/'
  1998. end
  1999. new.PathTextBox = TextBox:Initialise(7, 3, new.Width - 7, 1, new, path, nil, nil, function(key)
  2000. if key == keys.enter or key == keys.tab then
  2001. Current.Input = new.WidthTextBox.TextInput
  2002. end
  2003. end)
  2004. new.WidthTextBox = TextBox:Initialise(7, 7, 4, 1, new, tostring(15), nil, nil, function()
  2005. if key == keys.enter or key == keys.tab then
  2006. Current.Input = new.HeightTextBox.TextInput
  2007. end
  2008. end, true)
  2009. new.HeightTextBox = TextBox:Initialise(14, 7, 4, 1, new, tostring(10), nil, nil, function()
  2010. if key == keys.enter or key == keys.tab then
  2011. Current.Input = new.PathTextBox.TextInput
  2012. end
  2013. end, true)
  2014. Current.Input = new.PathTextBox.TextInput
  2015.  
  2016.  
  2017. new.WhiteButton = Button:Initialise(2, 10, nil, nil, colours.lightGrey, new, function(self, side, x, y, toggle)
  2018. new.TransparentButton.Toggle = false
  2019. new.BlackButton.Toggle = false
  2020. self.Toggle = false
  2021. new.ImageBackgroundColour = colours.white
  2022. end, 'White', colours.black, true, colours.lightBlue)
  2023. new.BlackButton = Button:Initialise(10, 10, nil, nil, colours.lightGrey, new, function(self, side, x, y, toggle)
  2024. new.TransparentButton.Toggle = false
  2025. new.WhiteButton.Toggle = false
  2026. self.Toggle = false
  2027. new.ImageBackgroundColour = colours.black
  2028. end, 'Black', colours.black, false, colours.lightBlue)
  2029. new.TransparentButton = Button:Initialise(18, 10, nil, nil, colours.lightGrey, new, function(self, side, x, y, toggle)
  2030. new.WhiteButton.Toggle = false
  2031. new.BlackButton.Toggle = false
  2032. self.Toggle = false
  2033. new.ImageBackgroundColour = colours.transparent
  2034. end, 'Transparent', colours.black, false, colours.lightBlue)
  2035.  
  2036. return new
  2037. end,
  2038.  
  2039. Show = function(self)
  2040. Current.Window = self
  2041. return self
  2042. end,
  2043.  
  2044. Close = function(self)
  2045. Current.Input = nil
  2046. Current.Window = nil
  2047. self = nil
  2048. end,
  2049.  
  2050. Flash = function(self)
  2051. self.Visible = false
  2052. Draw()
  2053. sleep(0.15)
  2054. self.Visible = true
  2055. Draw()
  2056. sleep(0.15)
  2057. self.Visible = false
  2058. Draw()
  2059. sleep(0.15)
  2060. self.Visible = true
  2061. Draw()
  2062. end,
  2063.  
  2064. ButtonClick = function(self, button, x, y)
  2065. if button.X <= x and button.Y <= y and button.X + button.Width > x and button.Y + button.Height > y then
  2066. button:Click()
  2067. end
  2068. end,
  2069.  
  2070. Click = function(self, side, x, y)
  2071. local items = {self.OkButton, self.CancelButton, self.SKCHButton, self.NFTButton, self.NFPButton, self.PathTextBox, self.WidthTextBox, self.HeightTextBox, self.WhiteButton, self.BlackButton, self.TransparentButton}
  2072. for i, v in ipairs(items) do
  2073. if CheckClick(v, x, y) then
  2074. v:Click(side, x, y)
  2075. end
  2076. end
  2077. return true
  2078. end
  2079. }
  2080.  
  2081. local TidyPath = function(path)
  2082. path = '/'..path
  2083. local _fs = fs
  2084. if OneOS then
  2085. _fs = OneOS.FS
  2086. end
  2087. if _fs.isDir(path) then
  2088. path = path .. '/'
  2089. end
  2090.  
  2091. path, n = path:gsub("//", "/")
  2092. while n > 0 do
  2093. path, n = path:gsub("//", "/")
  2094. end
  2095. return path
  2096. end
  2097.  
  2098. local WrapText = function(text, maxWidth)
  2099. local lines = {''}
  2100. for word, space in text:gmatch('(%S+)(%s*)') do
  2101. local temp = lines[#lines] .. word .. space:gsub('\n','')
  2102. if #temp > maxWidth then
  2103. table.insert(lines, '')
  2104. end
  2105. if space:find('\n') then
  2106. lines[#lines] = lines[#lines] .. word
  2107.  
  2108. space = space:gsub('\n', function()
  2109. table.insert(lines, '')
  2110. return ''
  2111. end)
  2112. else
  2113. lines[#lines] = lines[#lines] .. word .. space
  2114. end
  2115. end
  2116. return lines
  2117. end
  2118.  
  2119. OpenDocumentWindow = {
  2120. X = 1,
  2121. Y = 1,
  2122. Width = 0,
  2123. Height = 0,
  2124. CursorPos = 1,
  2125. Visible = true,
  2126. Return = nil,
  2127. OpenButton = nil,
  2128. PathTextBox = nil,
  2129. CurrentDirectory = '/',
  2130. Scroll = 0,
  2131. MaxScroll = 0,
  2132. GoUpButton = nil,
  2133. SelectedFile = '',
  2134. Files = {},
  2135. Typed = false,
  2136.  
  2137. AbsolutePosition = function(self)
  2138. return {X = self.X, Y = self.Y}
  2139. end,
  2140.  
  2141. Draw = function(self)
  2142. if not self.Visible then
  2143. return
  2144. end
  2145. Drawing.DrawBlankArea(self.X + 1, self.Y+1, self.Width, self.Height, colours.grey)
  2146. Drawing.DrawBlankArea(self.X, self.Y, self.Width, 3, colours.lightGrey)
  2147. Drawing.DrawBlankArea(self.X, self.Y+1, self.Width, self.Height-6, colours.white)
  2148. Drawing.DrawCharactersCenter(self.X, self.Y, self.Width, 1, self.Title, colours.black, colours.lightGrey)
  2149. Drawing.DrawBlankArea(self.X, self.Y + self.Height - 5, self.Width, 5, colours.lightGrey)
  2150. self:DrawFiles()
  2151.  
  2152. local _fs = fs
  2153. if OneOS then
  2154. _fs = OneOS.FS
  2155. end
  2156. if (_fs.exists(self.PathTextBox.TextInput.Value)) or (self.SelectedFile and #self.SelectedFile > 0 and _fs.exists(self.CurrentDirectory .. self.SelectedFile)) then
  2157. self.OpenButton.TextColour = colours.black
  2158. else
  2159. self.OpenButton.TextColour = colours.lightGrey
  2160. end
  2161.  
  2162. self.PathTextBox:Draw()
  2163. self.OpenButton:Draw()
  2164. self.CancelButton:Draw()
  2165. self.GoUpButton:Draw()
  2166. end,
  2167.  
  2168. DrawFiles = function(self)
  2169. local _fs = fs
  2170. if OneOS then
  2171. _fs = OneOS.FS
  2172. end
  2173. for i, file in ipairs(self.Files) do
  2174. if i > self.Scroll and i - self.Scroll <= 11 then
  2175. if file == self.SelectedFile then
  2176. Drawing.DrawCharacters(self.X + 1, self.Y + i - self.Scroll, file, colours.white, colours.lightBlue)
  2177. elseif string.find(file, '%.skch') or string.find(file, '%.nft') or string.find(file, '%.nfp') or _fs.isDir(self.CurrentDirectory .. file) then
  2178. Drawing.DrawCharacters(self.X + 1, self.Y + i - self.Scroll, file, colours.black, colours.white)
  2179. else
  2180. Drawing.DrawCharacters(self.X + 1, self.Y + i - self.Scroll, file, colours.grey, colours.white)
  2181. end
  2182. end
  2183. end
  2184. self.MaxScroll = #self.Files - 11
  2185. if self.MaxScroll < 0 then
  2186. self.MaxScroll = 0
  2187. end
  2188. end,
  2189.  
  2190. Initialise = function(self, returnFunc)
  2191. local new = {} -- the new instance
  2192. setmetatable( new, {__index = self} )
  2193. new.Width = 32
  2194. new.Height = 17
  2195. new.Return = returnFunc
  2196. new.X = math.ceil((Drawing.Screen.Width - new.Width) / 2)
  2197. new.Y = math.ceil((Drawing.Screen.Height - new.Height) / 2)
  2198. new.Title = 'Open Document'
  2199. new.Visible = true
  2200. new.CurrentDirectory = '/'
  2201. new.SelectedFile = nil
  2202. if OneOS then
  2203. new.CurrentDirectory = '/Desktop/'
  2204. end
  2205. local _fs = fs
  2206. if OneOS then
  2207. _fs = OneOS.FS
  2208. end
  2209. new.OpenButton = Button:Initialise(new.Width - 6, new.Height - 1, nil, nil, colours.white, new, function(self, side, x, y, toggle)
  2210. if _fs.exists(new.PathTextBox.TextInput.Value) and self.TextColour == colours.black and not _fs.isDir(new.PathTextBox.TextInput.Value) then
  2211. returnFunc(new, true, TidyPath(new.PathTextBox.TextInput.Value))
  2212. elseif new.SelectedFile and self.TextColour == colours.black and _fs.isDir(new.CurrentDirectory .. new.SelectedFile) then
  2213. new:GoToDirectory(new.CurrentDirectory .. new.SelectedFile)
  2214. elseif new.SelectedFile and self.TextColour == colours.black then
  2215. returnFunc(new, true, TidyPath(new.CurrentDirectory .. '/' .. new.SelectedFile))
  2216. end
  2217. end, 'Open', colours.black)
  2218. new.CancelButton = Button:Initialise(new.Width - 15, new.Height - 1, nil, nil, colours.white, new, function(self, side, x, y, toggle)
  2219. returnFunc(new, false)
  2220. end, 'Cancel', colours.black)
  2221. new.GoUpButton = Button:Initialise(2, new.Height - 1, nil, nil, colours.white, new, function(self, side, x, y, toggle)
  2222. local folderName = _fs.getName(new.CurrentDirectory)
  2223. local parentDirectory = new.CurrentDirectory:sub(1, #new.CurrentDirectory-#folderName-1)
  2224. new:GoToDirectory(parentDirectory)
  2225. end, 'Go Up', colours.black)
  2226. new.PathTextBox = TextBox:Initialise(2, new.Height - 3, new.Width - 2, 1, new, new.CurrentDirectory, colours.white, colours.black)
  2227. new:GoToDirectory(new.CurrentDirectory)
  2228. return new
  2229. end,
  2230.  
  2231. Show = function(self)
  2232. Current.Window = self
  2233. return self
  2234. end,
  2235.  
  2236. Close = function(self)
  2237. Current.Input = nil
  2238. Current.Window = nil
  2239. self = nil
  2240. end,
  2241.  
  2242. GoToDirectory = function(self, path)
  2243. path = TidyPath(path)
  2244. self.CurrentDirectory = path
  2245. self.Scroll = 0
  2246. self.SelectedFile = nil
  2247. self.Typed = false
  2248. self.PathTextBox.TextInput.Value = path
  2249. local _fs = fs
  2250. if OneOS then
  2251. _fs = OneOS.FS
  2252. end
  2253. self.Files = _fs.list(self.CurrentDirectory)
  2254. Draw()
  2255. end,
  2256.  
  2257. Flash = function(self)
  2258. self.Visible = false
  2259. Draw()
  2260. sleep(0.15)
  2261. self.Visible = true
  2262. Draw()
  2263. sleep(0.15)
  2264. self.Visible = false
  2265. Draw()
  2266. sleep(0.15)
  2267. self.Visible = true
  2268. Draw()
  2269. end,
  2270.  
  2271. Click = function(self, side, x, y)
  2272. local items = {self.OpenButton, self.CancelButton, self.PathTextBox, self.GoUpButton}
  2273. local found = false
  2274. for i, v in ipairs(items) do
  2275. if CheckClick(v, x, y) then
  2276. v:Click(side, x, y)
  2277. found = true
  2278. end
  2279. end
  2280.  
  2281. if not found then
  2282. if y <= 12 then
  2283. local _fs = fs
  2284. if OneOS then
  2285. _fs = OneOS.FS
  2286. end
  2287. self.SelectedFile = _fs.list(self.CurrentDirectory)[y-1]
  2288. self.PathTextBox.TextInput.Value = TidyPath(self.CurrentDirectory .. '/' .. self.SelectedFile)
  2289. Draw()
  2290. end
  2291. end
  2292. return true
  2293. end
  2294. }
  2295.  
  2296. ButtonDialougeWindow = {
  2297. X = 1,
  2298. Y = 1,
  2299. Width = 0,
  2300. Height = 0,
  2301. CursorPos = 1,
  2302. Visible = true,
  2303. CancelButton = nil,
  2304. OkButton = nil,
  2305. Lines = {},
  2306.  
  2307. AbsolutePosition = function(self)
  2308. return {X = self.X, Y = self.Y}
  2309. end,
  2310.  
  2311. Draw = function(self)
  2312. if not self.Visible then
  2313. return
  2314. end
  2315. Drawing.DrawBlankArea(self.X + 1, self.Y+1, self.Width, self.Height, colours.grey)
  2316. Drawing.DrawBlankArea(self.X, self.Y, self.Width, 1, colours.lightGrey)
  2317. Drawing.DrawBlankArea(self.X, self.Y+1, self.Width, self.Height-1, colours.white)
  2318. Drawing.DrawCharactersCenter(self.X, self.Y, self.Width, 1, self.Title, colours.black, colours.lightGrey)
  2319.  
  2320. for i, text in ipairs(self.Lines) do
  2321. Drawing.DrawCharacters(self.X + 1, self.Y + 1 + i, text, colours.black, colours.white)
  2322. end
  2323.  
  2324. self.OkButton:Draw()
  2325. if self.CancelButton then
  2326. self.CancelButton:Draw()
  2327. end
  2328. end,
  2329.  
  2330. Initialise = function(self, title, message, okText, cancelText, returnFunc)
  2331. local new = {} -- the new instance
  2332. setmetatable( new, {__index = self} )
  2333. new.Width = 28
  2334. new.Lines = WrapText(message, new.Width - 2)
  2335. new.Height = 5 + #new.Lines
  2336. new.Return = returnFunc
  2337. new.X = math.ceil((Drawing.Screen.Width - new.Width) / 2)
  2338. new.Y = math.ceil((Drawing.Screen.Height - new.Height) / 2)
  2339. new.Title = title
  2340. new.Visible = true
  2341. new.Visible = true
  2342. new.OkButton = Button:Initialise(new.Width - #okText - 2, new.Height - 1, nil, 1, nil, new, function()
  2343. returnFunc(new, true)
  2344. end, okText)
  2345. if cancelText then
  2346. new.CancelButton = Button:Initialise(new.Width - #okText - 2 - 1 - #cancelText - 2, new.Height - 1, nil, 1, nil, new, function()
  2347. returnFunc(new, false)
  2348. end, cancelText)
  2349. end
  2350.  
  2351. return new
  2352. end,
  2353.  
  2354. Show = function(self)
  2355. Current.Window = self
  2356. return self
  2357. end,
  2358.  
  2359. Close = function(self)
  2360. Current.Window = nil
  2361. self = nil
  2362. end,
  2363.  
  2364. Flash = function(self)
  2365. self.Visible = false
  2366. Draw()
  2367. sleep(0.15)
  2368. self.Visible = true
  2369. Draw()
  2370. sleep(0.15)
  2371. self.Visible = false
  2372. Draw()
  2373. sleep(0.15)
  2374. self.Visible = true
  2375. Draw()
  2376. end,
  2377.  
  2378. Click = function(self, side, x, y)
  2379. local items = {self.OkButton, self.CancelButton}
  2380. local found = false
  2381. for i, v in ipairs(items) do
  2382. if CheckClick(v, x, y) then
  2383. v:Click(side, x, y)
  2384. found = true
  2385. end
  2386. end
  2387. return true
  2388. end
  2389. }
  2390.  
  2391. TextDialougeWindow = {
  2392. X = 1,
  2393. Y = 1,
  2394. Width = 0,
  2395. Height = 0,
  2396. CursorPos = 1,
  2397. Visible = true,
  2398. CancelButton = nil,
  2399. OkButton = nil,
  2400. Lines = {},
  2401. TextInput = nil,
  2402.  
  2403. AbsolutePosition = function(self)
  2404. return {X = self.X, Y = self.Y}
  2405. end,
  2406.  
  2407. Draw = function(self)
  2408. if not self.Visible then
  2409. return
  2410. end
  2411. Drawing.DrawBlankArea(self.X + 1, self.Y+1, self.Width, self.Height, colours.grey)
  2412. Drawing.DrawBlankArea(self.X, self.Y, self.Width, 1, colours.lightGrey)
  2413. Drawing.DrawBlankArea(self.X, self.Y+1, self.Width, self.Height-1, colours.white)
  2414. Drawing.DrawCharactersCenter(self.X, self.Y, self.Width, 1, self.Title, colours.black, colours.lightGrey)
  2415.  
  2416. for i, text in ipairs(self.Lines) do
  2417. Drawing.DrawCharacters(self.X + 1, self.Y + 1 + i, text, colours.black, colours.white)
  2418. end
  2419.  
  2420.  
  2421. Drawing.DrawBlankArea(self.X + 1, self.Y + self.Height - 4, self.Width - 2, 1, colours.lightGrey)
  2422. Drawing.DrawCharacters(self.X + 2, self.Y + self.Height - 4, self.TextInput.Value, colours.black, colours.lightGrey)
  2423. Current.CursorPos = {self.X + 2 + self.TextInput.CursorPos, self.Y + self.Height - 4}
  2424. Current.CursorColour = colours.black
  2425.  
  2426. self.OkButton:Draw()
  2427. if self.CancelButton then
  2428. self.CancelButton:Draw()
  2429. end
  2430. end,
  2431.  
  2432. Initialise = function(self, title, message, okText, cancelText, returnFunc, numerical)
  2433. local new = {} -- the new instance
  2434. setmetatable( new, {__index = self} )
  2435. new.Width = 28
  2436. new.Lines = WrapText(message, new.Width - 2)
  2437. new.Height = 7 + #new.Lines
  2438. new.Return = returnFunc
  2439. new.X = math.ceil((Drawing.Screen.Width - new.Width) / 2)
  2440. new.Y = math.ceil((Drawing.Screen.Height - new.Height) / 2)
  2441. new.Title = title
  2442. new.Visible = true
  2443. new.Visible = true
  2444. new.OkButton = Button:Initialise(new.Width - #okText - 2, new.Height - 1, nil, 1, nil, new, function()
  2445. if #new.TextInput.Value > 0 then
  2446. returnFunc(new, true, new.TextInput.Value)
  2447. end
  2448. end, okText)
  2449. if cancelText then
  2450. new.CancelButton = Button:Initialise(new.Width - #okText - 2 - 1 - #cancelText - 2, new.Height - 1, nil, 1, nil, new, function()
  2451. returnFunc(new, false)
  2452. end, cancelText)
  2453. end
  2454. new.TextInput = TextInput:Initialise('', function(enter)
  2455. if enter then
  2456. new.OkButton:Click()
  2457. end
  2458. Draw()
  2459. end, numerical)
  2460.  
  2461. Current.Input = new.TextInput
  2462.  
  2463. return new
  2464. end,
  2465.  
  2466. Show = function(self)
  2467. Current.Window = self
  2468. return self
  2469. end,
  2470.  
  2471. Close = function(self)
  2472. Current.Window = nil
  2473. Current.Input = nil
  2474. self = nil
  2475. end,
  2476.  
  2477. Flash = function(self)
  2478. self.Visible = false
  2479. Draw()
  2480. sleep(0.15)
  2481. self.Visible = true
  2482. Draw()
  2483. sleep(0.15)
  2484. self.Visible = false
  2485. Draw()
  2486. sleep(0.15)
  2487. self.Visible = true
  2488. Draw()
  2489. end,
  2490.  
  2491. Click = function(self, side, x, y)
  2492. local items = {self.OkButton, self.CancelButton}
  2493. local found = false
  2494. for i, v in ipairs(items) do
  2495. if CheckClick(v, x, y) then
  2496. v:Click(side, x, y)
  2497. found = true
  2498. end
  2499. end
  2500. return true
  2501. end
  2502. }
  2503.  
  2504. ResizeDocumentWindow = {
  2505. X = 1,
  2506. Y = 1,
  2507. Width = 0,
  2508. Height = 0,
  2509. CursorPos = 1,
  2510. Visible = true,
  2511. Return = nil,
  2512. OkButton = nil,
  2513. AnchorPosition = 5,
  2514. WidthLabelHighlight = false,
  2515. HeightLabelHighlight = false,
  2516.  
  2517. AbsolutePosition = function(self)
  2518. return {X = self.X, Y = self.Y}
  2519. end,
  2520.  
  2521. Draw = function(self)
  2522. if not self.Visible then
  2523. return
  2524. end
  2525. Drawing.DrawBlankArea(self.X + 1, self.Y+1, self.Width, self.Height, colours.grey)
  2526. Drawing.DrawBlankArea(self.X, self.Y, self.Width, 1, colours.lightGrey)
  2527. Drawing.DrawBlankArea(self.X, self.Y+1, self.Width, self.Height-1, colours.white)
  2528. Drawing.DrawCharactersCenter(self.X, self.Y, self.Width, 1, self.Title, colours.black, colours.lightGrey)
  2529.  
  2530. Drawing.DrawCharacters(self.X+1, self.Y+2, "New Size", colours.lightGrey, colours.white)
  2531. if (#self.WidthTextBox.TextInput.Value > 0 and tonumber(self.WidthTextBox.TextInput.Value) < Current.Artboard.Width) or (#self.HeightTextBox.TextInput.Value > 0 and tonumber(self.HeightTextBox.TextInput.Value) < Current.Artboard.Height) then
  2532. Drawing.DrawCharacters(self.X+1, self.Y+8, "Clipping will occur!", colours.red, colours.white)
  2533. end
  2534.  
  2535. local widthLabelColour = colours.black
  2536. if self.WidthLabelHighlight then
  2537. widthLabelColour = colours.red
  2538. end
  2539.  
  2540. local heightLabelColour = colours.black
  2541. if self.HeightLabelHighlight then
  2542. heightLabelColour = colours.red
  2543. end
  2544.  
  2545. Drawing.DrawCharacters(self.X+1, self.Y+4, "Width", widthLabelColour, colours.white)
  2546. Drawing.DrawCharacters(self.X+1, self.Y+6, "Height", heightLabelColour, colours.white)
  2547.  
  2548. Drawing.DrawCharacters(self.X+14, self.Y+2, "Anchor", colours.lightGrey, colours.white)
  2549.  
  2550. self.WidthTextBox:Draw()
  2551. self.HeightTextBox:Draw()
  2552. self.OkButton:Draw()
  2553. self.Anchor1:Draw()
  2554. self.Anchor2:Draw()
  2555. self.Anchor3:Draw()
  2556. self.Anchor4:Draw()
  2557. self.Anchor5:Draw()
  2558. self.Anchor6:Draw()
  2559. self.Anchor7:Draw()
  2560. self.Anchor8:Draw()
  2561. self.Anchor9:Draw()
  2562. end,
  2563.  
  2564. Initialise = function(self, returnFunc)
  2565. local new = {} -- the new instance
  2566. setmetatable( new, {__index = self} )
  2567. new.Width = 27
  2568. new.Height = 10
  2569. new.Return = returnFunc
  2570. new.X = math.ceil((Drawing.Screen.Width - new.Width) / 2)
  2571. new.Y = math.ceil((Drawing.Screen.Height - new.Height) / 2)
  2572. new.Title = 'Resize Document'
  2573. new.Visible = true
  2574.  
  2575. new.WidthTextBox = TextBox:Initialise(9, 5, 4, 1, new, tostring(Current.Artboard.Width), nil, nil, function()
  2576. new:UpdateAnchorButtons()
  2577. end, true)
  2578. new.HeightTextBox = TextBox:Initialise(9, 7, 4, 1, new, tostring(Current.Artboard.Height), nil, nil, function()
  2579. new:UpdateAnchorButtons()
  2580. end, true)
  2581. new.OkButton = Button:Initialise(new.Width - 4, new.Height - 1, nil, nil, colours.lightGrey, new, function(self, side, x, y, toggle)
  2582. local ok = true
  2583. new.WidthLabelHighlight = false
  2584. new.HeightLabelHighlight = false
  2585.  
  2586. if #new.WidthTextBox.TextInput.Value == 0 or tonumber(new.WidthTextBox.TextInput.Value) <= 0 then
  2587. ok = false
  2588. new.WidthLabelHighlight = true
  2589. end
  2590.  
  2591. if #new.HeightTextBox.TextInput.Value == 0 or tonumber(new.HeightTextBox.TextInput.Value) <= 0 then
  2592. ok = false
  2593. new.HeightLabelHighlight = true
  2594. end
  2595.  
  2596. if ok then
  2597. returnFunc(new, tonumber(new.WidthTextBox.TextInput.Value), tonumber(new.HeightTextBox.TextInput.Value), new.AnchorPosition)
  2598. else
  2599. Draw()
  2600. end
  2601. end, 'Ok', colours.black)
  2602.  
  2603. local anchorX = 15
  2604. local anchorY = 5
  2605. new.Anchor1 = Button:Initialise(anchorX, anchorY, 1, 1, colours.lightGrey, new, function(self, side, x, y, toggle)new.AnchorPosition = 1 new:UpdateAnchorButtons() end, ' ', colours.black)
  2606. new.Anchor2 = Button:Initialise(anchorX+1, anchorY, 1, 1, colours.lightGrey, new, function(self, side, x, y, toggle)new.AnchorPosition = 2 new:UpdateAnchorButtons() end, '^', colours.black)
  2607. new.Anchor3 = Button:Initialise(anchorX+2, anchorY, 1, 1, colours.lightGrey, new, function(self, side, x, y, toggle)new.AnchorPosition = 3 new:UpdateAnchorButtons() end, ' ', colours.black)
  2608. new.Anchor4 = Button:Initialise(anchorX, anchorY+1, 1, 1, colours.lightGrey, new, function(self, side, x, y, toggle)new.AnchorPosition = 4 new:UpdateAnchorButtons() end, '<', colours.black)
  2609. new.Anchor5 = Button:Initialise(anchorX+1, anchorY+1, 1, 1, colours.lightGrey, new, function(self, side, x, y, toggle)new.AnchorPosition = 5 new:UpdateAnchorButtons() end, '#', colours.black)
  2610. new.Anchor6 = Button:Initialise(anchorX+2, anchorY+1, 1, 1, colours.lightGrey, new, function(self, side, x, y, toggle)new.AnchorPosition = 6 new:UpdateAnchorButtons() end, '>', colours.black)
  2611. new.Anchor7 = Button:Initialise(anchorX, anchorY+2, 1, 1, colours.lightGrey, new, function(self, side, x, y, toggle)new.AnchorPosition = 7 new:UpdateAnchorButtons() end, ' ', colours.black)
  2612. new.Anchor8 = Button:Initialise(anchorX+1, anchorY+2, 1, 1, colours.lightGrey, new, function(self, side, x, y, toggle)new.AnchorPosition = 8 new:UpdateAnchorButtons() end, 'v', colours.black)
  2613. new.Anchor9 = Button:Initialise(anchorX+2, anchorY+2, 1, 1, colours.lightGrey, new, function(self, side, x, y, toggle)new.AnchorPosition = 9 new:UpdateAnchorButtons() end, ' ', colours.black)
  2614.  
  2615. return new
  2616. end,
  2617.  
  2618. UpdateAnchorButtons = function(self)
  2619. local anchor1 = ' '
  2620. local anchor2 = ' '
  2621. local anchor3 = ' '
  2622. local anchor4 = ' '
  2623. local anchor5 = ' '
  2624. local anchor6 = ' '
  2625. local anchor7 = ' '
  2626. local anchor8 = ' '
  2627. local anchor9 = ' '
  2628. self.AnchorPosition = self.AnchorPosition or 5
  2629. if self.AnchorPosition == 1 then
  2630. anchor1 = '#'
  2631. anchor2 = '>'
  2632. anchor4 = 'v'
  2633. elseif self.AnchorPosition == 2 then
  2634. anchor1 = '<'
  2635. anchor2 = '#'
  2636. anchor3 = '>'
  2637. anchor5 = 'v'
  2638. elseif self.AnchorPosition == 3 then
  2639. anchor2 = '<'
  2640. anchor3 = '#'
  2641. anchor6 = 'v'
  2642. elseif self.AnchorPosition == 4 then
  2643. anchor1 = '^'
  2644. anchor4 = '#'
  2645. anchor5 = '>'
  2646. anchor7 = 'v'
  2647. elseif self.AnchorPosition == 5 then
  2648. anchor2 = '^'
  2649. anchor4 = '<'
  2650. anchor5 = '#'
  2651. anchor6 = '>'
  2652. anchor8 = 'v'
  2653. elseif self.AnchorPosition == 6 then
  2654. anchor3 = '^'
  2655. anchor6 = '#'
  2656. anchor5 = '<'
  2657. anchor9 = 'v'
  2658. elseif self.AnchorPosition == 7 then
  2659. anchor4 = '^'
  2660. anchor7 = '#'
  2661. anchor8 = '>'
  2662. elseif self.AnchorPosition == 8 then
  2663. anchor5 = '^'
  2664. anchor8 = '#'
  2665. anchor7 = '<'
  2666. anchor9 = '>'
  2667. elseif self.AnchorPosition == 9 then
  2668. anchor6 = '^'
  2669. anchor9 = '#'
  2670. anchor8 = '<'
  2671. end
  2672.  
  2673. if #self.HeightTextBox.TextInput.Value > 0 and Current.Artboard.Height > tonumber(self.HeightTextBox.TextInput.Value) then
  2674. local r = function(str)
  2675. if string.find(str, "%^") then
  2676. str = str:gsub('%^','v')
  2677. elseif string.find(str, "v") then
  2678. str = str:gsub('v','%^')
  2679. end
  2680. return str
  2681. end
  2682. anchor1 = r(anchor1)
  2683. anchor2 = r(anchor2)
  2684. anchor3 = r(anchor3)
  2685. anchor4 = r(anchor4)
  2686. anchor5 = r(anchor5)
  2687. anchor6 = r(anchor6)
  2688. anchor7 = r(anchor7)
  2689. anchor8 = r(anchor8)
  2690. anchor9 = r(anchor9)
  2691. end
  2692.  
  2693. if #self.WidthTextBox.TextInput.Value > 0 and Current.Artboard.Width > tonumber(self.WidthTextBox.TextInput.Value) then
  2694. local r = function(str)
  2695. if string.find(str, ">") then
  2696. str = str:gsub('>','<')
  2697. elseif string.find(str, "<") then
  2698. str = str:gsub('<','>')
  2699. end
  2700. return str
  2701. end
  2702. anchor1 = r(anchor1)
  2703. anchor2 = r(anchor2)
  2704. anchor3 = r(anchor3)
  2705. anchor4 = r(anchor4)
  2706. anchor5 = r(anchor5)
  2707. anchor6 = r(anchor6)
  2708. anchor7 = r(anchor7)
  2709. anchor8 = r(anchor8)
  2710. anchor9 = r(anchor9)
  2711. end
  2712.  
  2713. self.Anchor1.Text = anchor1
  2714. self.Anchor2.Text = anchor2
  2715. self.Anchor3.Text = anchor3
  2716. self.Anchor4.Text = anchor4
  2717. self.Anchor5.Text = anchor5
  2718. self.Anchor6.Text = anchor6
  2719. self.Anchor7.Text = anchor7
  2720. self.Anchor8.Text = anchor8
  2721. self.Anchor9.Text = anchor9
  2722. end,
  2723.  
  2724. Show = function(self)
  2725. Current.Window = self
  2726. return self
  2727. end,
  2728.  
  2729. Close = function(self)
  2730. Current.Input = nil
  2731. Current.Window = nil
  2732. self = nil
  2733. end,
  2734.  
  2735. Flash = function(self)
  2736. self.Visible = false
  2737. Draw()
  2738. sleep(0.15)
  2739. self.Visible = true
  2740. Draw()
  2741. sleep(0.15)
  2742. self.Visible = false
  2743. Draw()
  2744. sleep(0.15)
  2745. self.Visible = true
  2746. Draw()
  2747. end,
  2748.  
  2749. ButtonClick = function(self, button, x, y)
  2750. if button.X <= x and button.Y <= y and button.X + button.Width > x and button.Y + button.Height > y then
  2751. button:Click()
  2752. end
  2753. end,
  2754.  
  2755. Click = function(self, side, x, y)
  2756. local items = {self.OkButton, self.WidthTextBox, self.HeightTextBox, self.Anchor1, self.Anchor2, self.Anchor3, self.Anchor4, self.Anchor5, self.Anchor6, self.Anchor7, self.Anchor8, self.Anchor9}
  2757. for i, v in ipairs(items) do
  2758. if CheckClick(v, x, y) then
  2759. v:Click(side, x, y)
  2760. end
  2761. end
  2762. return true
  2763. end
  2764. }
  2765.  
  2766. ----------------------
  2767.  
  2768. function CheckOpenArtboard()
  2769. if Current.Artboard then
  2770. return true
  2771. else
  2772. return false
  2773. end
  2774. end
  2775.  
  2776. function CheckSelectedLayer()
  2777. if Current.Artboard and Current.Layer then
  2778. return true
  2779. else
  2780. return false
  2781. end
  2782. end
  2783.  
  2784. function DisplayNewDocumentWindow()
  2785. NewDocumentWindow:Initialise(function(self, success, path, width, height, format, backgroundColour)
  2786. if success then
  2787. if path:sub(-4) ~= format then
  2788. path = path .. format
  2789. end
  2790. local oldWindow = self
  2791. Current.Input = nil
  2792. Current.Window = nil
  2793. makeDocument = function()oldWindow:Close()NewDocument(path, width, height, format, backgroundColour)end
  2794. local _fs = fs
  2795. if OneOS then
  2796. _fs = OneOS.FS
  2797. end
  2798. if _fs.exists(path) then
  2799. ButtonDialougeWindow:Initialise('File Exists', path..' already exists! Use a different name and try again.', 'Ok', nil, function(window, ok)
  2800. window:Close()
  2801. oldWindow:Show()
  2802. end):Show()
  2803. elseif format == '.nfp' then
  2804. Current.Window = nil
  2805. ButtonDialougeWindow:Initialise('Use NFP?', 'The NFT format does not support text or layers, if you use it you will only be able to use 1 layer and not have any text.', 'Use NFP', 'Cancel', function(window, ok)
  2806. window:Close()
  2807. if ok then
  2808. makeDocument()
  2809. else
  2810. oldWindow:Show()
  2811. end
  2812. end):Show()
  2813. elseif format == '.nft' then
  2814. ButtonDialougeWindow:Initialise('Use NFT?', 'The NFT format does not support layers, if you use it you will only be able to use 1 layer.', 'Use NFT', 'Cancel', function(window, ok)
  2815. window:Close()
  2816. if ok then
  2817. makeDocument()
  2818. else
  2819. oldWindow:Show()
  2820. end
  2821. end):Show()
  2822. else
  2823. makeDocument()
  2824. end
  2825.  
  2826.  
  2827. else
  2828. self:Close()
  2829. end
  2830. end):Show()
  2831. end
  2832.  
  2833. function NewDocument(path, width, height, format, backgroundColour)
  2834. local _fs = fs
  2835. if OneOS then
  2836. _fs = OneOS.FS
  2837. end
  2838. ab = Artboard:New(_fs.getName(path), path, width, height, format, backgroundColour)
  2839. Current.Tool = Tools[2]
  2840. Current.Toolbar:Update()
  2841. Current.Modified = false
  2842. Draw()
  2843. end
  2844.  
  2845. function DisplayToolSizeWindow()
  2846. if not CheckOpenArtboard() then
  2847. return
  2848. end
  2849. TextDialougeWindow:Initialise('Change Tool Size', 'Enter the new tool size you\'d like to use.', 'Ok', 'Cancel', function(window, success, value)
  2850. if success then
  2851. Current.ToolSize = math.ceil(tonumber(value))
  2852. if Current.ToolSize < 1 then
  2853. Current.ToolSize = 1
  2854. elseif Current.ToolSize > 50 then
  2855. Current.ToolSize = 50
  2856. end
  2857. ModuleNamed('Tools'):Update()
  2858. end
  2859. window:Close()
  2860. end, true):Show()
  2861. end
  2862.  
  2863. --[[
  2864. Attempt to figure out what format the image is if it doesn't have an extension
  2865. ]]--
  2866. function GetFormat(path)
  2867. local _fs = fs
  2868. if OneOS then
  2869. _fs = OneOS.FS
  2870. end
  2871. local file = _fs.open(path, 'r')
  2872. local content = file.readAll()
  2873. file.close()
  2874. if type(textutils.unserialize(content)) == 'table' then
  2875. -- It's a serlized table, asume sketch
  2876. return '.skch'
  2877. elseif string.find(content, string.char(30)) or string.find(content, string.char(31)) then
  2878. -- Contains the characters that set colours, asume nft
  2879. return '.nft'
  2880. else
  2881. -- Otherwise asume nfp
  2882. return '.nfp'
  2883. end
  2884. end
  2885.  
  2886. function DisplayOpenDocumentWindow()
  2887. OpenDocumentWindow:Initialise(function(self, success, path)
  2888. self:Close()
  2889. if success then
  2890. OpenDocument(path)
  2891. end
  2892. end):Show()
  2893. end
  2894.  
  2895.  
  2896. local function Extension(path, addDot)
  2897. if not path then
  2898. return nil
  2899. elseif not string.find(fs.getName(path), '%.') then
  2900. if not addDot then
  2901. return fs.getName(path)
  2902. else
  2903. return ''
  2904. end
  2905. else
  2906. local _path = path
  2907. if path:sub(#path) == '/' then
  2908. _path = path:sub(1,#path-1)
  2909. end
  2910. local extension = _path:gmatch('\.[0-9a-z]+$')()
  2911. if extension then
  2912. extension = extension:sub(2)
  2913. else
  2914. --extension = nil
  2915. return ''
  2916. end
  2917. if addDot then
  2918. extension = '.'..extension
  2919. end
  2920. return extension:lower()
  2921. end
  2922. end
  2923.  
  2924. local RemoveExtension = function(path)
  2925. if path:sub(1,1) == '.' then
  2926. return path
  2927. end
  2928. local extension = Extension(path)
  2929. if extension == path then
  2930. return fs.getName(path)
  2931. end
  2932. return string.gsub(path, extension, ''):sub(1, -2)
  2933. end
  2934. --[[
  2935. Open a documet at a given path
  2936. ]]--
  2937. function OpenDocument(path)
  2938. local _fs = fs
  2939. if OneOS then
  2940. _fs = OneOS.FS
  2941. end
  2942. if _fs.exists(path) and not _fs.isDir(path) then
  2943. local format = Extension(path, true)
  2944. if (not format or format == '') and (format ~= '.nfp' and format ~= '.nft' and format ~= '.skch') then
  2945. format = GetFormat(path)
  2946. end
  2947. local layers = {}
  2948. if format == '.nfp' then
  2949. layers = ReadNFP(path)
  2950. elseif format == '.nft' then
  2951. layers = ReadNFT(path)
  2952. elseif format == '.skch' then
  2953. layers = ReadSKCH(path)
  2954. end
  2955.  
  2956. for i, layer in ipairs(layers) do
  2957. if layer.Visible == nil then
  2958. layer.Visible = true
  2959. end
  2960. if layer.Index == nil then
  2961. layer.Index = 1
  2962. end
  2963. if layer.Name == nil then
  2964. if layer.Index == 1 then
  2965. layer.Name = 'Background'
  2966. else
  2967. layer.Name = 'Layer'
  2968. end
  2969. end
  2970. if layer.BackgroundColour == nil then
  2971. layer.BackgroundColour = colours.white
  2972. end
  2973. end
  2974.  
  2975. if not layers[1] then
  2976. --log('File could not be read.')
  2977. return
  2978. end
  2979.  
  2980. local width = #layers[1].Pixels
  2981. local height = #layers[1].Pixels[1]
  2982.  
  2983. Current.Artboard = nil
  2984. local _fs = fs
  2985. if OneOS then
  2986. _fs = OneOS.FS
  2987. end
  2988. ab = Artboard:New(_fs.getName('Image'), path, width, height, format, nil, layers)
  2989. Current.Tool = Tools[2]
  2990. Current.Toolbar:Update()
  2991. Current.Modified = false
  2992. Draw()
  2993. end
  2994. end
  2995.  
  2996. function MakeNewLayer()
  2997. if not CheckOpenArtboard() then
  2998. return
  2999. end
  3000. if Current.Artboard.Format == '.skch' then
  3001. TextDialougeWindow:Initialise('New Layer Name', 'Enter the name you want for the next layer.', 'Ok', 'Cancel', function(window, success, value)
  3002. if success then
  3003. Current.Artboard:MakeLayer(value, colours.transparent)
  3004. end
  3005. window:Close()
  3006. end):Show()
  3007. else
  3008. local format = 'NFP'
  3009. if Current.Artboard.Format == '.nft' then
  3010. format = 'NFT'
  3011. end
  3012. ButtonDialougeWindow:Initialise(format..' does not support layers!', 'The format you are using, '..format..', does not support multiple layers. Use SKCH to have more than one layer.', 'Ok', nil, function(window)
  3013. window:Close()
  3014. end):Show()
  3015. end
  3016. end
  3017.  
  3018. function ResizeDocument()
  3019. if not CheckOpenArtboard() then
  3020. return
  3021. end
  3022. ResizeDocumentWindow:Initialise(function(window, width, height, anchor)
  3023. window:Close()
  3024. local topResize = 0
  3025. local rightResize = 0
  3026. local bottomResize = 0
  3027. local leftResize = 0
  3028.  
  3029. if anchor == 1 then
  3030. rightResize = 1
  3031. bottomResize = 1
  3032. elseif anchor == 2 then
  3033. rightResize = 0.5
  3034. leftResize = 0.5
  3035. bottomResize = 1
  3036. elseif anchor == 3 then
  3037. leftResize = 1
  3038. bottomResize = 1
  3039. elseif anchor == 4 then
  3040. rightResize = 1
  3041. bottomResize = 0.5
  3042. topResize = 0.5
  3043. elseif anchor == 5 then
  3044. rightResize = 0.5
  3045. leftResize = 0.5
  3046. bottomResize = 0.5
  3047. topResize = 0.5
  3048. elseif anchor == 6 then
  3049. leftResize = 1
  3050. bottomResize = 0.5
  3051. topResize = 0.5
  3052. elseif anchor == 7 then
  3053. rightResize = 1
  3054. topResize = 1
  3055. elseif anchor == 8 then
  3056. rightResize = 0.5
  3057. leftResize = 0.5
  3058. topResize = 1
  3059. elseif anchor == 9 then
  3060. leftResize = 1
  3061. topResize = 1
  3062. end
  3063.  
  3064. topResize = topResize * (height - Current.Artboard.Height)
  3065. if topResize > 0 then
  3066. topResize = math.floor(topResize)
  3067. else
  3068. topResize = math.ceil(topResize)
  3069. end
  3070.  
  3071. bottomResize = bottomResize * (height - Current.Artboard.Height)
  3072. if bottomResize > 0 then
  3073. bottomResize = math.ceil(bottomResize)
  3074. else
  3075. bottomResize = math.floor(bottomResize)
  3076. end
  3077.  
  3078. leftResize = leftResize * (width - Current.Artboard.Width)
  3079. if leftResize > 0 then
  3080. leftResize = math.floor(leftResize)
  3081. else
  3082. leftResize = math.ceil(leftResize)
  3083. end
  3084.  
  3085. rightResize = rightResize * (width - Current.Artboard.Width)
  3086. if rightResize > 0 then
  3087. rightResize = math.ceil(rightResize)
  3088. else
  3089. rightResize = math.floor(rightResize)
  3090. end
  3091.  
  3092. Current.Artboard:Resize(topResize, bottomResize, leftResize, rightResize)
  3093. end):Show()
  3094. end
  3095.  
  3096. function RenameLayer()
  3097. if not CheckOpenArtboard() then
  3098. return
  3099. end
  3100. if Current.Artboard.Format == '.skch' then
  3101. TextDialougeWindow:Initialise("Rename Layer '"..Current.Layer.Name.."'", 'Enter the new name you want the layer to be called.', 'Ok', 'Cancel', function(window, success, value)
  3102. if success then
  3103. Current.Layer.Name = value
  3104. end
  3105. window:Close()
  3106. end):Show()
  3107. else
  3108. local format = 'NFP'
  3109. if Current.Artboard.Format == '.nft' then
  3110. format = 'NFT'
  3111. end
  3112. ButtonDialougeWindow:Initialise(format..' does not support layers!', 'The format you are using, '..format..', does not support renaming layers. Use SKCH to rename layers.', 'Ok', nil, function(window)
  3113. window:Close()
  3114. end):Show()
  3115. end
  3116. end
  3117.  
  3118. function DeleteLayer()
  3119. if not CheckOpenArtboard() then
  3120. return
  3121. end
  3122. if Current.Artboard.Format == '.skch' then
  3123. if #Current.Artboard.Layers > 1 then
  3124. ButtonDialougeWindow:Initialise("Delete Layer '"..Current.Layer.Name.."'?", 'Are you sure you want delete the layer?', 'Ok', 'Cancel', function(window, success)
  3125. if success then
  3126. Current.Layer:Remove()
  3127. end
  3128. window:Close()
  3129. end):Show()
  3130. else
  3131. ButtonDialougeWindow:Initialise('Can not delete layer!', 'You can not delete the last layer of an image! Make another layer to delete this one.', 'Ok', nil, function(window)
  3132. window:Close()
  3133. end):Show()
  3134. end
  3135. else
  3136. local format = 'NFP'
  3137. if Current.Artboard.Format == '.nft' then
  3138. format = 'NFT'
  3139. end
  3140. ButtonDialougeWindow:Initialise(format..' does not support layers!', 'The format you are using, '..format..', does not support deleting layers. Use SKCH to deleting layers.', 'Ok', nil, function(window)
  3141. window:Close()
  3142. end):Show()
  3143. end
  3144. end
  3145.  
  3146. needsDraw = false
  3147. isDrawing = false
  3148. function Draw()
  3149. if isDrawing then
  3150. needsDraw = true
  3151. return
  3152. end
  3153. needsDraw = false
  3154. isDrawing = true
  3155. if not Current.Window then
  3156. Drawing.Clear(UIColours.Background)
  3157. else
  3158. Drawing.DrawArea(1, 2, Drawing.Screen.Width, Drawing.Screen.Height, '|', colours.black, colours.lightGrey)
  3159. end
  3160.  
  3161. if Current.Artboard then
  3162. ab:Draw()
  3163. end
  3164.  
  3165. if Current.InterfaceVisible then
  3166. Current.MenuBar:Draw()
  3167. Current.Toolbar.Width = Current.Toolbar.ExpandedWidth
  3168. Current.Toolbar:Draw()
  3169. else
  3170. Current.Toolbar.Width = Current.Toolbar.ExpandedWidth
  3171. end
  3172.  
  3173. if Current.InterfaceVisible and Current.Menu then
  3174. Current.Menu:Draw()
  3175. end
  3176.  
  3177. if Current.Window then
  3178. Current.Window:Draw()
  3179. end
  3180.  
  3181. if not Current.InterfaceVisible then
  3182. ShowInterfaceButton:Draw()
  3183. end
  3184.  
  3185. Drawing.DrawBuffer()
  3186. if Current.Input and not Current.Menu then
  3187. term.setCursorPos(Current.CursorPos[1], Current.CursorPos[2])
  3188. term.setCursorBlink(true)
  3189. term.setTextColour(Current.CursorColour)
  3190. else
  3191. term.setCursorBlink(false)
  3192. end
  3193.  
  3194. if Current.Selection and Current.Selection[1] and Current.Selection[2] ~= nil then
  3195. Current.SelectionDrawTimer = os.startTimer(0.5)
  3196. end
  3197. isDrawing = false
  3198. if needsDraw then
  3199. Draw()
  3200. end
  3201. end
  3202.  
  3203. function LoadMenuBar()
  3204. Current.MenuBar = MenuBar:Initialise({
  3205. Button:Initialise(1, 1, nil, nil, colours.grey, Current.MenuBar, function(self, side, x, y, toggle)
  3206. if toggle then
  3207. Menu:New(1, 2, {
  3208. {
  3209. Title = "New...",
  3210. Click = function()
  3211. DisplayNewDocumentWindow()
  3212. end,
  3213. Keys = {
  3214. keys.leftCtrl,
  3215. keys.n
  3216. }
  3217. },
  3218. {
  3219. Title = 'Open...',
  3220. Click = function()
  3221. DisplayOpenDocumentWindow()
  3222. end,
  3223. Keys = {
  3224. keys.leftCtrl,
  3225. keys.o
  3226. }
  3227. },
  3228. {
  3229. Separator = true
  3230. },
  3231. {
  3232. Title = 'Save...',
  3233. Click = function()
  3234. Current.Artboard:Save()
  3235. end,
  3236. Keys = {
  3237. keys.leftCtrl,
  3238. keys.s
  3239. },
  3240. Enabled = function()
  3241. return CheckOpenArtboard()
  3242. end
  3243. },
  3244. {
  3245. Separator = true
  3246. },
  3247. {
  3248. Title = 'Quit',
  3249. Click = function()
  3250. if Close() then
  3251. OneOS.Close()
  3252. end
  3253. end
  3254. },
  3255. --[[
  3256. {
  3257. Title = 'Save As...',
  3258. Click = function()
  3259.  
  3260. end
  3261. }
  3262. ]]--
  3263. }, self, true)
  3264. else
  3265. Current.Menu = nil
  3266. end
  3267. return true
  3268. end, 'File', colours.lightGrey, false),
  3269. Button:Initialise(7, 1, nil, nil, colours.grey, Current.MenuBar, function(self, side, x, y, toggle)
  3270. if not self.Toggle then
  3271. Menu:New(7, 2, {
  3272. --[[
  3273. {
  3274. Title = "Undo",
  3275. Click = function()
  3276. end,
  3277. Keys = {
  3278. keys.leftCtrl,
  3279. keys.z
  3280. },
  3281. Enabled = function()
  3282. return false
  3283. end
  3284. },
  3285. {
  3286. Title = 'Redo',
  3287. Click = function()
  3288.  
  3289. end,
  3290. Keys = {
  3291. keys.leftCtrl,
  3292. keys.y
  3293. },
  3294. Enabled = function()
  3295. return false
  3296. end
  3297. },
  3298. {
  3299. Separator = true
  3300. },
  3301. ]]--
  3302. {
  3303. Title = 'Cut',
  3304. Click = function()
  3305. Clipboard.Cut(Current.Layer:PixelsInSelection(true), 'sketchpixels')
  3306. end,
  3307. Keys = {
  3308. keys.leftCtrl,
  3309. keys.x
  3310. },
  3311. Enabled = function()
  3312. return Current.Selection and Current.Selection[1] and Current.Selection[2] ~= nil
  3313. end
  3314. },
  3315. {
  3316. Title = 'Copy',
  3317. Click = function()
  3318. Clipboard.Copy(Current.Layer:PixelsInSelection(), 'sketchpixels')
  3319. end,
  3320. Keys = {
  3321. keys.leftCtrl,
  3322. keys.c
  3323. },
  3324. Enabled = function()
  3325. return Current.Selection and Current.Selection[1] and Current.Selection[2] ~= nil
  3326. end
  3327. },
  3328. {
  3329. Title = 'Paste',
  3330. Click = function()
  3331. Current.Layer:InsertPixels(Clipboard.Paste())
  3332. end,
  3333. Keys = {
  3334. keys.leftCtrl,
  3335. keys.v
  3336. },
  3337. Enabled = function()
  3338. return (not Clipboard.isEmpty()) and Clipboard.Type == 'sketchpixels'
  3339. end
  3340. }
  3341. }, self, true)
  3342. else
  3343. Current.Menu = nil
  3344. end
  3345. return true
  3346. end, 'Edit', colours.lightGrey, false),
  3347. Button:Initialise(13, 1, nil, nil, colours.grey, Current.MenuBar, function(self, side, x, y, toggle)
  3348. if toggle then
  3349. Menu:New(13, 2, {
  3350. {
  3351. Title = "Resize...",
  3352. Click = function()
  3353. ResizeDocument()
  3354. end,
  3355. Keys = {
  3356. keys.leftCtrl,
  3357. keys.r
  3358. },
  3359. Enabled = function()
  3360. return CheckOpenArtboard()
  3361. end
  3362. },
  3363. {
  3364. Title = "Crop",
  3365. Click = function()
  3366. local top = 0
  3367. local left = 0
  3368. local bottom = 0
  3369. local right = 0
  3370. if Current.Selection[1].x < Current.Selection[2].x then
  3371. left = Current.Selection[1].x - 1
  3372. right = Current.Artboard.Width - Current.Selection[2].x
  3373. else
  3374. left = Current.Selection[2].x - 1
  3375. right = Current.Artboard.Width - Current.Selection[1].x
  3376. end
  3377. if Current.Selection[1].y < Current.Selection[2].y then
  3378. top = Current.Selection[1].y - 1
  3379. bottom = Current.Artboard.Height - Current.Selection[2].y
  3380. else
  3381. top = Current.Selection[2].y - 1
  3382. bottom = Current.Artboard.Height - Current.Selection[1].y
  3383. end
  3384. Current.Artboard:Resize(-1*top, -1*bottom, -1*left, -1*right)
  3385.  
  3386. Current.Selection[2] = nil
  3387. end,
  3388. Enabled = function()
  3389. if CheckSelectedLayer() and Current.Selection and Current.Selection[1] and Current.Selection[2] ~= nil then
  3390. return true
  3391. else
  3392. return false
  3393. end
  3394. end
  3395. },
  3396. {
  3397. Separator = true
  3398. },
  3399. {
  3400. Title = 'New Layer...',
  3401. Click = function()
  3402. MakeNewLayer()
  3403. end,
  3404. Keys = {
  3405. keys.leftCtrl,
  3406. keys.l
  3407. },
  3408. Enabled = function()
  3409. return CheckOpenArtboard()
  3410. end
  3411. },
  3412. {
  3413. Title = 'Delete Layer',
  3414. Click = function()
  3415. DeleteLayer()
  3416. end,
  3417. Enabled = function()
  3418. return CheckSelectedLayer()
  3419. end
  3420. },
  3421. {
  3422. Title = 'Rename Layer...',
  3423. Click = function()
  3424. RenameLayer()
  3425. end,
  3426. Enabled = function()
  3427. return CheckSelectedLayer()
  3428. end
  3429. },
  3430. {
  3431. Separator = true
  3432. },
  3433. {
  3434. Title = 'Erase Selection',
  3435. Click = function()
  3436. Current.Layer:EraseSelection()
  3437. end,
  3438. Keys = {
  3439. keys.delete
  3440. },
  3441. Enabled = function()
  3442. if CheckSelectedLayer() and Current.Selection and Current.Selection[1] and Current.Selection[2] ~= nil then
  3443. return true
  3444. else
  3445. return false
  3446. end
  3447. end
  3448. },
  3449. {
  3450. Separator = true
  3451. },
  3452. {
  3453. Title = 'Hide Interface',
  3454. Click = function()
  3455. Current.InterfaceVisible = not Current.InterfaceVisible
  3456. end,
  3457. Keys = {
  3458. keys.tab
  3459. }
  3460. }
  3461. }, self, true)
  3462. else
  3463. Current.Menu = nil
  3464. end
  3465. return true
  3466. end, 'Image', colours.lightGrey, false),
  3467.  
  3468. Button:Initialise(20, 1, nil, nil, colours.grey, Current.MenuBar, function(self, side, x, y, toggle)
  3469. if toggle then
  3470. local menuItems = {{
  3471. Title = "Change Size",
  3472. Click = function()
  3473. DisplayToolSizeWindow()
  3474. end,
  3475. Keys = {
  3476. keys.leftCtrl,
  3477. keys.t
  3478. }
  3479. },
  3480. {
  3481. Separator = true
  3482. }
  3483. }
  3484.  
  3485. local _keys = {'h','p','e','f','s','m','t'}
  3486. for i, tool in ipairs(Tools) do
  3487. table.insert(menuItems, {
  3488. Title = tool.Name,
  3489. Click = function()
  3490. SetTool(tool)
  3491. local m = ModuleNamed('Tools')
  3492. m:Update(m.ToolbarItem)
  3493. end,
  3494. Keys = {
  3495. keys[_keys[i]]
  3496. },
  3497. Enabled = function()
  3498. return CheckOpenArtboard()
  3499. end
  3500. })
  3501. end
  3502.  
  3503. Menu:New(20, 2, menuItems, self, true)
  3504. else
  3505. Current.Menu = nil
  3506. end
  3507. return true
  3508. end, 'Tools', colours.lightGrey, false),
  3509. })
  3510. end
  3511.  
  3512. function Timer(event, timer)
  3513. if timer == Current.ControlPressedTimer then
  3514. Current.ControlPressedTimer = nil
  3515. elseif timer == Current.SelectionDrawTimer then
  3516. if Current.Artboard then
  3517. Current.Artboard.SelectionIsBlack = not Current.Artboard.SelectionIsBlack
  3518. Draw()
  3519. end
  3520. end
  3521. end
  3522.  
  3523. function Initialise(arg)
  3524. if not OneOS then
  3525. SplashScreen()
  3526. end
  3527. EventRegister('mouse_click', TryClick)
  3528. EventRegister('mouse_drag', function(event, side, x, y)TryClick(event, side, x, y, true)end)
  3529. EventRegister('mouse_scroll', Scroll)
  3530. EventRegister('key', HandleKey)
  3531. EventRegister('char', HandleKey)
  3532. EventRegister('timer', Timer)
  3533. EventRegister('terminate', function(event) if Close() then error( "Terminated", 0 ) end end)
  3534.  
  3535.  
  3536. Current.Toolbar = Toolbar:New('right', true)
  3537.  
  3538. for k, v in pairs(Modules) do
  3539. v:Initialise()
  3540. end
  3541.  
  3542. --term.setBackgroundColour(UIColours.Background)
  3543. --term.clear()
  3544.  
  3545. LoadMenuBar()
  3546.  
  3547. local _fs = fs
  3548. if OneOS then
  3549. _fs = OneOS.FS
  3550. end
  3551. if arg and _fs.exists(arg) then
  3552. OpenDocument(arg)
  3553. else
  3554. DisplayNewDocumentWindow()
  3555. Current.Window.Visible = false
  3556. end
  3557.  
  3558. ShowInterfaceButton = Button:Initialise(Drawing.Screen.Width - 15, 1, nil, 1, colours.grey, nil, function(self)
  3559. Current.InterfaceVisible = true
  3560. Draw()
  3561. end, 'Show Interface')
  3562.  
  3563. Draw()
  3564. if Current.Window then
  3565. Current.Window.Visible = true
  3566. Draw()
  3567. end
  3568.  
  3569. EventHandler()
  3570. end
  3571.  
  3572. function SplashScreen()
  3573. local splashIcon = {{1,1,1,256,256,256,256,256,256,256,256,1,1,1,},{1,256,256,8,8,8,8,8,8,8,8,256,256,1,},{256,8,8,8,8,8,8,8,8,8,8,8,8,256,},{256,256,256,8,8,8,8,8,8,8,8,256,256,256,},{256,256,256,256,256,256,256,256,256,256,256,256,256,256,},{2048,2048,256,256,256,256,256,256,256,256,256,256,2048,2048,},{2048,2048,2048,2048,2048,2048,2048,2048,2048,2048,2048,2048,2048,2048,},{2048,2048,2048,2048,2048,2048,2048,2048,2048,2048,2048,2048,2048,2048,},{2048,2048,2048,2048,2048,2048,2048,2048,2048,2048,2048,2048,2048,2048,},{2048,2048,2048,2048,2048,2048,2048,2048,2048,2048,2048,2048,2048,2048,},{256,256,2048,2048,2048,2048,2048,2048,2048,2048,2048,2048,256,256,},{1,256,256,256,256,256,256,256,256,256,256,256,256,1,},{1,1,1,256,256,256,256,256,256,256,256,1,1,1,},["text"]={{" "," "," "," "," "," "," "," "," "," "," "," "," "," ",},{" "," "," "," "," "," "," "," "," "," "," "," "," "," ",},{" "," "," "," "," "," "," "," "," "," "," "," "," "," ",},{" "," "," "," "," "," "," "," "," "," "," "," "," "," ",},{" "," "," "," "," "," "," "," "," "," "," "," "," "," ",},{" "," "," "," "," "," "," "," "," "," "," "," "," "," ",},{" "," "," "," "," "," "," "," "," "," "," "," "," "," ",},{" "," "," "," ","S","k","e","t","c","h"," "," "," "," ",},{" "," "," "," "," "," ","b","y"," "," "," "," "," "," ",},{" "," "," "," "," ","o","e","e","d"," "," "," "," "," ",},{" "," "," "," "," "," "," "," "," "," "," "," "," "," ",},{" "," "," "," "," "," "," "," "," "," "," "," "," "," ",},{" "," "," "," "," "," "," "," "," "," "," "," "," "," ",},},["textcol"]={{32768,32768,32768,32768,32768,32768,32768,32768,32768,32768,32768,32768,32768,32768,},{32768,32768,32768,256,32768,32768,32768,32768,32768,32768,32768,32768,32768,32768,},{32768,32768,32768,32768,32768,32768,32768,32768,32768,32768,32768,32768,32768,32768,},{32768,32768,32768,32768,32768,32768,32768,32768,32768,32768,32768,32768,32768,32768,},{32768,32768,32768,32768,32768,32768,32768,32768,32768,32768,32768,32768,32768,32768,},{32768,32768,32768,32768,32768,32768,32768,32768,32768,32768,32768,32768,32768,32768,},{32768,32768,32768,32768,32768,32768,32768,32768,32768,32768,32768,32768,32768,32768,},{32768,32768,32768,32768,1,1,1,1,1,1,32768,32768,32768,32768,},{32768,32768,32768,32768,8,8,8,8,8,8,8,32768,32768,32768,},{32768,32768,32768,32768,1,1,1,1,1,32768,8,32768,32768,32768,},{32768,32768,32768,32768,32768,32768,32768,32768,32768,32768,32768,32768,32768,32768,},{32768,32768,32768,32768,32768,32768,32768,32768,32768,32768,32768,32768,32768,32768,},{32768,32768,32768,32768,32768,32768,32768,32768,32768,32768,32768,32768,32768,32768,},},}
  3574. Drawing.Clear(colours.white)
  3575. Drawing.DrawImage((Drawing.Screen.Width - 14)/2, (Drawing.Screen.Height - 13)/2, splashIcon, 14, 13)
  3576. Drawing.DrawBuffer()
  3577. parallel.waitForAny(function()sleep(1)end, function()os.pullEvent('mouse_click')end)
  3578. end
  3579.  
  3580. LongestString = function(input, key)
  3581. local length = 0
  3582. for i = 1, #input do
  3583. local value = input[i]
  3584. if key then
  3585. if value[key] then
  3586. value = value[key]
  3587. else
  3588. value = ''
  3589. end
  3590. end
  3591. local titleLength = string.len(value)
  3592. if titleLength > length then
  3593. length = titleLength
  3594. end
  3595. end
  3596. return length
  3597. end
  3598.  
  3599. function HandleKey(...)
  3600. local args = {...}
  3601. local event = args[1]
  3602. local keychar = args[2]
  3603. if event == 'key' and Current.Tool and Current.Tool.Name == 'Text' and Current.Input and (keychar == keys.up or keychar == keys.down or keychar == keys.left or keychar == keys.right) then
  3604. local currentPos = {Current.CursorPos[1] - Current.Artboard.X + 1, Current.CursorPos[2] - Current.Artboard.Y + 1}
  3605. if keychar == keys.up then
  3606. currentPos[2] = currentPos[2] - 1
  3607. elseif keychar == keys.down then
  3608. currentPos[2] = currentPos[2] + 1
  3609. elseif keychar == keys.left then
  3610. currentPos[1] = currentPos[1] - 1
  3611. elseif keychar == keys.right then
  3612. currentPos[1] = currentPos[1] + 1
  3613. end
  3614.  
  3615. if currentPos[1] < 1 then
  3616. currentPos[1] = 1
  3617. end
  3618.  
  3619. if currentPos[1] > Current.Artboard.Width then
  3620. currentPos[1] = Current.Artboard.Width
  3621. end
  3622.  
  3623. if currentPos[2] < 1 then
  3624. currentPos[2] = 1
  3625. end
  3626.  
  3627. if currentPos[2] > Current.Artboard.Height then
  3628. currentPos[2] = Current.Artboard.Height
  3629. end
  3630.  
  3631. Current.Tool:Use(currentPos[1], currentPos[2])
  3632. Current.Modified = true
  3633. Draw()
  3634. elseif Current.Input then
  3635. if event == 'char' then
  3636. Current.Input:Char(keychar)
  3637. elseif event == 'key' then
  3638. Current.Input:Key(keychar)
  3639. end
  3640. elseif event == 'key' then
  3641. CheckKeyboardShortcut(keychar)
  3642. end
  3643. end
  3644.  
  3645. function Scroll(event, direction, x, y)
  3646. if Current.Window and Current.Window.OpenButton then
  3647. Current.Window.Scroll = Current.Window.Scroll + direction
  3648. if Current.Window.Scroll < 0 then
  3649. Current.Window.Scroll = 0
  3650. elseif Current.Window.Scroll > Current.Window.MaxScroll then
  3651. Current.Window.Scroll = Current.Window.MaxScroll
  3652. end
  3653. end
  3654. Draw()
  3655. end
  3656.  
  3657. function CheckKeyboardShortcut(key)
  3658. local shortcuts = {}
  3659.  
  3660. if key == keys.leftCtrl then
  3661. Current.ControlPressedTimer = os.startTimer(0.5)
  3662. return
  3663. end
  3664. if Current.ControlPressedTimer then
  3665. shortcuts[keys.n] = function() DisplayNewDocumentWindow() end
  3666. shortcuts[keys.o] = function() DisplayOpenDocumentWindow() end
  3667. shortcuts[keys.s] = function() Current.Artboard:Save() end
  3668. shortcuts[keys.x] = function() if Current.Selection and Current.Selection[1] and Current.Selection[2] ~= nil then Clipboard.Cut(Current.Layer:PixelsInSelection(true), 'sketchpixels') end end
  3669. shortcuts[keys.c] = function() if Current.Selection and Current.Selection[1] and Current.Selection[2] ~= nil then Clipboard.Copy(Current.Layer:PixelsInSelection(), 'sketchpixels') end end
  3670. shortcuts[keys.v] = function() if (not Clipboard.isEmpty()) and Clipboard.Type == 'sketchpixels' then Current.Layer:InsertPixels(Clipboard.Paste()) end end
  3671. shortcuts[keys.r] = function() ResizeDocument() end
  3672. shortcuts[keys.l] = function() MakeNewLayer() end
  3673. end
  3674.  
  3675. shortcuts[keys.delete] = function() if CheckSelectedLayer() and Current.Selection and Current.Selection[1] and Current.Selection[2] ~= nil then Current.Layer:EraseSelection() Draw() end end
  3676. shortcuts[keys.backspace] = shortcuts[keys.delete]
  3677. shortcuts[keys.tab] = function() Current.InterfaceVisible = not Current.InterfaceVisible Draw() end
  3678.  
  3679. shortcuts[keys.h] = function() SetTool(ToolNamed('Hand')) ModuleNamed('Tools'):Update() Draw() end
  3680. shortcuts[keys.e] = function() SetTool(ToolNamed('Eraser')) ModuleNamed('Tools'):Update() Draw() end
  3681. shortcuts[keys.p] = function() SetTool(ToolNamed('Pencil')) ModuleNamed('Tools'):Update() Draw() end
  3682. shortcuts[keys.f] = function() SetTool(ToolNamed('Fill Bucket')) ModuleNamed('Tools'):Update() Draw() end
  3683. shortcuts[keys.m] = function() SetTool(ToolNamed('Move')) ModuleNamed('Tools'):Update() Draw() end
  3684. shortcuts[keys.s] = function() SetTool(ToolNamed('Select')) ModuleNamed('Tools'):Update() Draw() end
  3685. shortcuts[keys.t] = function() SetTool(ToolNamed('Text')) ModuleNamed('Tools'):Update() Draw() end
  3686.  
  3687. if shortcuts[key] then
  3688. shortcuts[key]()
  3689. return true
  3690. else
  3691. return false
  3692. end
  3693. end
  3694.  
  3695. --[[
  3696. Check if the given object falls under the click coordinates
  3697. ]]--
  3698. function CheckClick(object, x, y)
  3699. if object.X <= x and object.Y <= y and object.X + object.Width > x and object.Y + object.Height > y then
  3700. return true
  3701. end
  3702. end
  3703.  
  3704. --[[
  3705. Attempt to clicka given object
  3706. ]]--
  3707. function DoClick(object, side, x, y, drag)
  3708. if object and CheckClick(object, x, y) then
  3709. return object:Click(side, x - object.X + 1, y - object.Y + 1, drag)
  3710. end
  3711. end
  3712.  
  3713. --[[
  3714. Try to click at the given coordinates
  3715. ]]--
  3716. function TryClick(event, side, x, y, drag)
  3717. if Current.InterfaceVisible and Current.Menu then
  3718. if DoClick(Current.Menu, side, x, y, drag) then
  3719. Draw()
  3720. return
  3721. else
  3722. if Current.Menu.Owner and Current.Menu.Owner.Toggle then
  3723. Current.Menu.Owner.Toggle = false
  3724. end
  3725. Current.Menu = nil
  3726. Draw()
  3727. return
  3728. end
  3729. elseif Current.Window then
  3730. if DoClick(Current.Window, side, x, y, drag) then
  3731. Draw()
  3732. return
  3733. else
  3734. Current.Window:Flash()
  3735. return
  3736. end
  3737. end
  3738. local interfaceElements = {}
  3739.  
  3740. if Current.InterfaceVisible then
  3741. table.insert(interfaceElements, Current.MenuBar)
  3742. else
  3743. table.insert(interfaceElements, ShowInterfaceButton)
  3744. end
  3745.  
  3746. for i, v in ipairs(Lists.Interface.Toolbars) do
  3747. for i, v2 in ipairs(v.ToolbarItems) do
  3748. table.insert(interfaceElements, v2)
  3749. end
  3750. table.insert(interfaceElements, v)
  3751. end
  3752.  
  3753. table.insert(interfaceElements, Current.Artboard)
  3754.  
  3755. for i, object in ipairs(interfaceElements) do
  3756. if DoClick(object, side, x, y, drag) then
  3757. Draw()
  3758. return
  3759. end
  3760. end
  3761. Draw()
  3762. end
  3763.  
  3764. --[[
  3765. Registers functions to run on certain events
  3766. ]]--
  3767. function EventRegister(event, func)
  3768. if not Events[event] then
  3769. Events[event] = {}
  3770. end
  3771.  
  3772. table.insert(Events[event], func)
  3773. end
  3774.  
  3775. --[[
  3776. The main loop event handler, runs registered event functinos
  3777. ]]--
  3778. function EventHandler()
  3779. while true do
  3780. local event, arg1, arg2, arg3, arg4 = os.pullEventRaw()
  3781. if Events[event] then
  3782. for i, e in ipairs(Events[event]) do
  3783. e(event, arg1, arg2, arg3, arg4)
  3784. end
  3785. end
  3786. end
  3787. end
  3788.  
  3789. --[[
  3790. Thanks to NitrogenFingers for the colour functions and NFT + NFP read/write functions
  3791. ]]--
  3792.  
  3793. --[[
  3794. Gets the hex value from a colour
  3795. ]]--
  3796. local hexnums = { [10] = "a", [11] = "b", [12] = "c", [13] = "d", [14] = "e" , [15] = "f" }
  3797. local function getHexOf(colour)
  3798. if colour == colours.transparent or not colour or not tonumber(colour) then
  3799. return " "
  3800. end
  3801. local value = math.log(colour)/math.log(2)
  3802. if value > 9 then
  3803. value = hexnums[value]
  3804. end
  3805. return value
  3806. end
  3807.  
  3808. --[[
  3809. Gets the colour from a hex value
  3810. ]]--
  3811. local function getColourOf(hex)
  3812. if hex == ' ' then
  3813. return colours.transparent
  3814. end
  3815. local value = tonumber(hex, 16)
  3816. if not value then return nil end
  3817. value = math.pow(2,value)
  3818. return value
  3819. end
  3820.  
  3821. --[[
  3822. Saves the current artboard in .skch format
  3823. ]]--
  3824. function SaveSKCH()
  3825. local layers = {}
  3826. for i, l in ipairs(Current.Artboard.Layers) do
  3827. local pixels = SaveNFT(i)
  3828. local layer = {
  3829. Name = l.Name,
  3830. Pixels = pixels,
  3831. BackgroundColour = l.BackgroundColour,
  3832. Visible = l.Visible,
  3833. Index = l.Index,
  3834. }
  3835. table.insert(layers, layer)
  3836. end
  3837. return layers
  3838. end
  3839.  
  3840. --[[
  3841. Saves the current artboard in .nft format
  3842. ]]--
  3843. function SaveNFT(layer)
  3844. layer = layer or 1
  3845. local lines = {}
  3846. local width = Current.Artboard.Width
  3847. local height = Current.Artboard.Height
  3848. for y = 1, height do
  3849. local line = ''
  3850. local currentBackgroundColour = nil
  3851. local currentTextColour = nil
  3852. for x = 1, width do
  3853. local pixel = Current.Artboard.Layers[layer].Pixels[x][y]
  3854. if pixel.BackgroundColour ~= currentBackgroundColour then
  3855. line = line..string.char(30)..getHexOf(pixel.BackgroundColour)
  3856. currentBackgroundColour = pixel.BackgroundColour
  3857. end
  3858. if pixel.TextColour ~= currentTextColour then
  3859. line = line..string.char(31)..getHexOf(pixel.TextColour)
  3860. currentTextColour = pixel.TextColour
  3861. end
  3862. line = line .. pixel.Character
  3863. end
  3864. table.insert(lines, line)
  3865. end
  3866. return lines
  3867. end
  3868.  
  3869. --[[
  3870. Saves the current artboard in .nfp format
  3871. ]]--
  3872. function SaveNFP()
  3873. local lines = {}
  3874. local width = Current.Artboard.Width
  3875. local height = Current.Artboard.Height
  3876. for y = 1, height do
  3877. local line = ''
  3878. for x = 1, width do
  3879. line = line .. getHexOf(Current.Artboard.Layers[1].Pixels[x][y].BackgroundColour)
  3880. end
  3881. table.insert(lines, line)
  3882. end
  3883. return lines
  3884. end
  3885.  
  3886. --[[
  3887. Reads a .nfp file from the given path
  3888. ]]--
  3889. function ReadNFP(path)
  3890. local pixels = {}
  3891. local _fs = fs
  3892. if OneOS then
  3893. _fs = OneOS.FS
  3894. end
  3895. local file = _fs.open(path, 'r')
  3896. local line = file.readLine()
  3897. local y = 1
  3898. while line do
  3899. for x = 1, #line do
  3900. if not pixels[x] then
  3901. pixels[x] = {}
  3902. end
  3903. pixels[x][y] = {BackgroundColour = getColourOf(line:sub(x,x))}
  3904. end
  3905. y = y + 1
  3906. line = file.readLine()
  3907. end
  3908. file.close()
  3909. return {{Pixels = pixels}}
  3910. end
  3911.  
  3912. --[[
  3913. Reads a .nft file from the given path
  3914. ]]--
  3915. function ReadNFT(path)
  3916. local _fs = fs
  3917. if OneOS then
  3918. _fs = OneOS.FS
  3919. end
  3920. local file = _fs.open(path, 'r')
  3921. local line = file.readLine()
  3922. local lines = {}
  3923. while line do
  3924. table.insert(lines, line)
  3925. line = file.readLine()
  3926. end
  3927. file.close()
  3928. return {{Pixels = ParseNFT(lines)}}
  3929. end
  3930.  
  3931. --[[
  3932. Converts the lines of an .nft document to readble pixel data
  3933. ]]--
  3934. function ParseNFT(lines)
  3935. local pixels = {}
  3936. for y, line in ipairs(lines) do
  3937. local bgNext, fgNext = false, false
  3938. local currBG, currFG = nil,nil
  3939. local writePosition = 1
  3940. for x = 1, #line do
  3941. if not pixels[writePosition] then
  3942. pixels[writePosition] = {}
  3943. end
  3944.  
  3945. local nextChar = string.sub(line, x, x)
  3946. if nextChar:byte() == 30 then
  3947. bgNext = true
  3948. elseif nextChar:byte() == 31 then
  3949. fgNext = true
  3950. elseif bgNext then
  3951. currBG = getColourOf(nextChar)
  3952. if currBG == nil then
  3953. currBG = colours.transparent
  3954. end
  3955. bgNext = false
  3956. elseif fgNext then
  3957. currFG = getColourOf(nextChar)
  3958. fgNext = false
  3959. else
  3960. if nextChar ~= " " and currFG == nil then
  3961. currFG = colours.white
  3962. end
  3963. pixels[writePosition][y] = {BackgroundColour = currBG, TextColour = currFG, Character = nextChar}
  3964. writePosition = writePosition + 1
  3965. end
  3966. end
  3967. end
  3968. return pixels
  3969. end
  3970.  
  3971. --[[
  3972. Read a .skch file from the given path
  3973. ]]--
  3974. function ReadSKCH(path)
  3975. local _fs = fs
  3976. if OneOS then
  3977. _fs = OneOS.FS
  3978. end
  3979. local file = _fs.open(path, 'r')
  3980. local _layers = textutils.unserialize(file.readAll())
  3981. file.close()
  3982. local layers = {}
  3983.  
  3984. for i, l in ipairs(_layers) do
  3985. local layer = {
  3986. Name = l.Name,
  3987. Pixels = ParseNFT(l.Pixels),
  3988. BackgroundColour = l.BackgroundColour,
  3989. Visible = l.Visible,
  3990. Index = l.Index,
  3991. }
  3992. table.insert(layers, layer)
  3993. end
  3994. return layers
  3995. end
  3996.  
  3997. --[[
  3998. Start the program after all functions and tables are loaded
  3999. ]]--
  4000. if term.isColor and term.isColor() then
  4001. Initialise(...)
  4002. else
  4003. print('Sorry, but Sketch only works on Advanced (gold) Computers')
  4004. end
Advertisement
Add Comment
Please, Sign In to add comment