SHARE
TWEET

Ink

Oeed Jul 12th, 2014 5,027 Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. tArgs = {...}
  2.  
  3. if OneOS then
  4.         --running under OneOS
  5.         OneOS.ToolBarColour = colours.grey
  6.         OneOS.ToolBarTextColour = colours.white
  7. end
  8.  
  9. local _w, _h = term.getSize()
  10.  
  11. local round = function(num, idp)
  12.         local mult = 10^(idp or 0)
  13.         return math.floor(num * mult + 0.5) / mult
  14. end
  15.  
  16. UIColours = {
  17.         Toolbar = colours.grey,
  18.         ToolbarText = colours.lightGrey,
  19.         ToolbarSelected = colours.lightBlue,
  20.         ControlText = colours.white,
  21.         ToolbarItemTitle = colours.black,
  22.         Background = colours.lightGrey,
  23.         MenuBackground = colours.white,
  24.         MenuText = colours.black,
  25.         MenuSeparatorText = colours.grey,
  26.         MenuDisabledText = colours.lightGrey,
  27.         Shadow = colours.grey,
  28.         TransparentBackgroundOne = colours.white,
  29.         TransparentBackgroundTwo = colours.lightGrey,
  30.         MenuBarActive = colours.white
  31. }
  32.  
  33. local getNames = peripheral.getNames or function()
  34.         local tResults = {}
  35.         for n,sSide in ipairs( rs.getSides() ) do
  36.                 if peripheral.isPresent( sSide ) then
  37.                         table.insert( tResults, sSide )
  38.                         local isWireless = false
  39.                         if not pcall(function()isWireless = peripheral.call(sSide, 'isWireless') end) then
  40.                                 isWireless = true
  41.                         end    
  42.                         if peripheral.getType( sSide ) == "modem" and not isWireless then
  43.                                 local tRemote = peripheral.call( sSide, "getNamesRemote" )
  44.                                 for n,sName in ipairs( tRemote ) do
  45.                                         table.insert( tResults, sName )
  46.                                 end
  47.                         end
  48.                 end
  49.         end
  50.         return tResults
  51. end
  52.  
  53. Peripheral = {
  54.         GetPeripheral = function(_type)
  55.                 for i, p in ipairs(Peripheral.GetPeripherals()) do
  56.                         if p.Type == _type then
  57.                                 return p
  58.                         end
  59.                 end
  60.         end,
  61.  
  62.         Call = function(type, ...)
  63.                 local tArgs = {...}
  64.                 local p = Peripheral.GetPeripheral(type)
  65.                 peripheral.call(p.Side, unpack(tArgs))
  66.         end,
  67.  
  68.         GetPeripherals = function(filterType)
  69.                 local peripherals = {}
  70.                 for i, side in ipairs(getNames()) do
  71.                         local name = peripheral.getType(side):gsub("^%l", string.upper)
  72.                         local code = string.upper(side:sub(1,1))
  73.                         if side:find('_') then
  74.                                 code = side:sub(side:find('_')+1)
  75.                         end
  76.  
  77.                         local dupe = false
  78.                         for i, v in ipairs(peripherals) do
  79.                                 if v[1] == name .. ' ' .. code then
  80.                                         dupe = true
  81.                                 end
  82.                         end
  83.  
  84.                         if not dupe then
  85.                                 local _type = peripheral.getType(side)
  86.                                 local isWireless = false
  87.                                 if _type == 'modem' then
  88.                                         if not pcall(function()isWireless = peripheral.call(sSide, 'isWireless') end) then
  89.                                                 isWireless = true
  90.                                         end    
  91.                                         if isWireless then
  92.                                                 _type = 'wireless_modem'
  93.                                                 name = 'W '..name
  94.                                         end
  95.                                 end
  96.                                 if not filterType or _type == filterType then
  97.                                         table.insert(peripherals, {Name = name:sub(1,8) .. ' '..code, Fullname = name .. ' ('..side:sub(1, 1):upper() .. side:sub(2, -1)..')', Side = side, Type = _type, Wireless = isWireless})
  98.                                 end
  99.                         end
  100.                 end
  101.                 return peripherals
  102.         end,
  103.  
  104.         PresentNamed = function(name)
  105.                 return peripheral.isPresent(name)
  106.         end,
  107.  
  108.         CallType = function(type, ...)
  109.                 local tArgs = {...}
  110.                 local p = GetPeripheral(type)
  111.                 return peripheral.call(p.Side, unpack(tArgs))
  112.         end,
  113.  
  114.         CallNamed = function(name, ...)
  115.                 local tArgs = {...}
  116.                 return peripheral.call(name, unpack(tArgs))
  117.         end
  118. }
  119.  
  120. TextLine = {
  121.         Text = "",
  122.         Alignment = AlignmentLeft,
  123.  
  124.         Initialise = function(self, text, alignment)
  125.                 local new = {}    -- the new instance
  126.                 setmetatable( new, {__index = self} )
  127.                 new.Text = text
  128.                 new.Alignment = alignment or AlignmentLeft
  129.                 return new
  130.         end
  131. }
  132.  
  133. local StripColours = function(str)
  134.         return str:gsub('['..string.char(14)..'-'..string.char(29)..']','')
  135. end
  136.  
  137. Printer = {
  138.         Name = nil,
  139.         PeripheralType = 'printer',
  140.  
  141.         paperLevel = function(self)
  142.                 return Peripheral.CallNamed(self.Name, 'getPaperLevel')
  143.         end,
  144.  
  145.         newPage = function(self)
  146.                 return Peripheral.CallNamed(self.Name, 'newPage')
  147.         end,
  148.  
  149.         endPage = function(self)
  150.                 return Peripheral.CallNamed(self.Name, 'endPage')
  151.         end,
  152.  
  153.         pageWrite = function(self, text)
  154.                 return Peripheral.CallNamed(self.Name, 'write', text)
  155.         end,
  156.  
  157.         setPageTitle = function(self, title)
  158.                 return Peripheral.CallNamed(self.Name, 'setPageTitle', title)
  159.         end,
  160.  
  161.         inkLevel = function(self)
  162.                 return Peripheral.CallNamed(self.Name, 'getInkLevel')
  163.         end,
  164.  
  165.         getCursorPos = function(self)
  166.                 return Peripheral.CallNamed(self.Name, 'getCursorPos')
  167.         end,
  168.  
  169.         setCursorPos = function(self, x, y)
  170.                 return Peripheral.CallNamed(self.Name, 'setCursorPos', x, y)
  171.         end,
  172.  
  173.         pageSize = function(self)
  174.                 return Peripheral.CallNamed(self.Name, 'getPageSize')
  175.         end,
  176.  
  177.         Present = function()
  178.                 if Peripheral.GetPeripheral(Printer.PeripheralType) == nil then
  179.                         return false
  180.                 else
  181.                         return true
  182.                 end
  183.         end,
  184.  
  185.         PrintLines = function(self, lines, title, copies)
  186.                 local pages = {}
  187.                 local pageLines = {}
  188.                 for i, line in ipairs(lines) do
  189.                         table.insert(pageLines, TextLine:Initialise(StripColours(line)))
  190.                         if i % 25 == 0 then
  191.                                 table.insert(pages, pageLines)
  192.                                 pageLines = {}
  193.                         end
  194.                 end
  195.                 if #pageLines ~= 0 then
  196.                                 table.insert(pages, pageLines)
  197.                 end
  198.                 return self:PrintPages(pages, title, copies)
  199.         end,
  200.  
  201.         PrintPages = function(self, pages, title, copies)
  202.                 copies = copies or 1
  203.                 for c = 1, copies do
  204.                         for p, page in ipairs(pages) do
  205.                                 if self:paperLevel() < #pages * copies then
  206.                                         return 'Add more paper to the printer'
  207.                                 end
  208.                                 if self:inkLevel() < #pages * copies then
  209.                                         return 'Add more ink to the printer'
  210.                                 end
  211.                                 self:newPage()
  212.                                 for i, line in ipairs(page) do
  213.                                         self:setCursorPos(1, i)
  214.                                         self:pageWrite(StripColours(line.Text))
  215.                                 end
  216.                                 if title then
  217.                                         self:setPageTitle(title)
  218.                                 end
  219.                                 self:endPage()
  220.                         end
  221.                 end
  222.         end,
  223.  
  224.         Initialise = function(self, name)
  225.                 if Printer.Present() then --fix
  226.                         local new = {}    -- the new instance
  227.                         setmetatable( new, {__index = self} )
  228.                         if name and Peripheral.PresentNamed(name) then
  229.                                 new.Name = name
  230.                         else
  231.                                 new.Name = Peripheral.GetPeripheral(Printer.PeripheralType).Side
  232.                         end
  233.                         return new
  234.                 end
  235.         end
  236. }
  237.  
  238. Clipboard = {
  239.         Content = nil,
  240.         Type = nil,
  241.         IsCut = false,
  242.  
  243.         Empty = function()
  244.                 Clipboard.Content = nil
  245.                 Clipboard.Type = nil
  246.                 Clipboard.IsCut = false
  247.         end,
  248.  
  249.         isEmpty = function()
  250.                 return Clipboard.Content == nil
  251.         end,
  252.  
  253.         Copy = function(content, _type)
  254.                 Clipboard.Content = content
  255.                 Clipboard.Type = _type or 'generic'
  256.                 Clipboard.IsCut = false
  257.         end,
  258.  
  259.         Cut = function(content, _type)
  260.                 Clipboard.Content = content
  261.                 Clipboard.Type = _type or 'generic'
  262.                 Clipboard.IsCut = true
  263.         end,
  264.  
  265.         Paste = function()
  266.                 local c, t = Clipboard.Content, Clipboard.Type
  267.                 if Clipboard.IsCut then
  268.                         Clipboard.Empty()
  269.                 end
  270.                 return c, t
  271.         end
  272. }
  273.  
  274. if OneOS and OneOS.Clipboard then
  275.         Clipboard = OneOS.Clipboard
  276. end
  277.  
  278. Drawing = {
  279.        
  280.         Screen = {
  281.                 Width = _w,
  282.                 Height = _h
  283.         },
  284.  
  285.         DrawCharacters = function (x, y, characters, textColour,bgColour)
  286.                 Drawing.WriteStringToBuffer(x, y, characters, textColour, bgColour)
  287.         end,
  288.        
  289.         DrawBlankArea = function (x, y, w, h, colour)
  290.                 Drawing.DrawArea (x, y, w, h, " ", 1, colour)
  291.         end,
  292.  
  293.         DrawArea = function (x, y, w, h, character, textColour, bgColour)
  294.                 --width must be greater than 1, other wise we get a stack overflow
  295.                 if w < 0 then
  296.                         w = w * -1
  297.                 elseif w == 0 then
  298.                         w = 1
  299.                 end
  300.  
  301.                 for ix = 1, w do
  302.                         local currX = x + ix - 1
  303.                         for iy = 1, h do
  304.                                 local currY = y + iy - 1
  305.                                 Drawing.WriteToBuffer(currX, currY, character, textColour, bgColour)
  306.                         end
  307.                 end
  308.         end,
  309.  
  310.         DrawImage = function(_x,_y,tImage, w, h)
  311.                 if tImage then
  312.                         for y = 1, h do
  313.                                 if not tImage[y] then
  314.                                         break
  315.                                 end
  316.                                 for x = 1, w do
  317.                                         if not tImage[y][x] then
  318.                                                 break
  319.                                         end
  320.                                         local bgColour = tImage[y][x]
  321.                             local textColour = tImage.textcol[y][x] or colours.white
  322.                             local char = tImage.text[y][x]
  323.                             Drawing.WriteToBuffer(x+_x-1, y+_y-1, char, textColour, bgColour)
  324.                                 end
  325.                         end
  326.                 elseif w and h then
  327.                         Drawing.DrawBlankArea(x, y, w, h, colours.green)
  328.                 end
  329.         end,
  330.         --using .nft
  331.         LoadImage = function(path)
  332.                 local image = {
  333.                         text = {},
  334.                         textcol = {}
  335.                 }
  336.                 local fs = fs
  337.                 if OneOS then
  338.                         fs = OneOS.FS
  339.                 end
  340.                 if fs.exists(path) then
  341.                         local _open = io.open
  342.                         if OneOS then
  343.                                 _open = OneOS.IO.open
  344.                         end
  345.                 local file = _open(path, "r")
  346.                 local sLine = file:read()
  347.                 local num = 1
  348.                 while sLine do  
  349.                         table.insert(image, num, {})
  350.                         table.insert(image.text, num, {})
  351.                         table.insert(image.textcol, num, {})
  352.                                                    
  353.                         --As we're no longer 1-1, we keep track of what index to write to
  354.                         local writeIndex = 1
  355.                         --Tells us if we've hit a 30 or 31 (BG and FG respectively)- next char specifies the curr colour
  356.                         local bgNext, fgNext = false, false
  357.                         --The current background and foreground colours
  358.                         local currBG, currFG = nil,nil
  359.                         for i=1,#sLine do
  360.                                 local nextChar = string.sub(sLine, i, i)
  361.                                 if nextChar:byte() == 30 then
  362.                                 bgNext = true
  363.                                 elseif nextChar:byte() == 31 then
  364.                                 fgNext = true
  365.                                 elseif bgNext then
  366.                                 currBG = Drawing.GetColour(nextChar)
  367.                                 bgNext = false
  368.                                 elseif fgNext then
  369.                                 currFG = Drawing.GetColour(nextChar)
  370.                                 fgNext = false
  371.                                 else
  372.                                 if nextChar ~= " " and currFG == nil then
  373.                                        currFG = colours.white
  374.                                 end
  375.                                 image[num][writeIndex] = currBG
  376.                                 image.textcol[num][writeIndex] = currFG
  377.                                 image.text[num][writeIndex] = nextChar
  378.                                 writeIndex = writeIndex + 1
  379.                                 end
  380.                         end
  381.                         num = num+1
  382.                         sLine = file:read()
  383.                 end
  384.                 file:close()
  385.                 end
  386.                 return image
  387.         end,
  388.  
  389.         DrawCharactersCenter = function(x, y, w, h, characters, textColour,bgColour)
  390.                 w = w or Drawing.Screen.Width
  391.                 h = h or Drawing.Screen.Height
  392.                 x = x or 0
  393.                 y = y or 0
  394.                 x = math.ceil((w - #characters) / 2) + x
  395.                 y = math.floor(h / 2) + y
  396.  
  397.                 Drawing.DrawCharacters(x, y, characters, textColour, bgColour)
  398.         end,
  399.  
  400.         GetColour = function(hex)
  401.                 if hex == ' ' then
  402.                         return colours.transparent
  403.                 end
  404.             local value = tonumber(hex, 16)
  405.             if not value then return nil end
  406.             value = math.pow(2,value)
  407.             return value
  408.         end,
  409.  
  410.         Clear = function (_colour)
  411.                 _colour = _colour or colours.black
  412.                 Drawing.ClearBuffer()
  413.                 Drawing.DrawBlankArea(1, 1, Drawing.Screen.Width, Drawing.Screen.Height, _colour)
  414.         end,
  415.  
  416.         Buffer = {},
  417.         BackBuffer = {},
  418.  
  419.         DrawBuffer = function()
  420.                 for y,row in pairs(Drawing.Buffer) do
  421.                         for x,pixel in pairs(row) do
  422.                                 local shouldDraw = true
  423.                                 local hasBackBuffer = true
  424.                                 if Drawing.BackBuffer[y] == nil or Drawing.BackBuffer[y][x] == nil or #Drawing.BackBuffer[y][x] ~= 3 then
  425.                                         hasBackBuffer = false
  426.                                 end
  427.                                 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
  428.                                         shouldDraw = false
  429.                                 end
  430.                                 if shouldDraw then
  431.                                         term.setBackgroundColour(pixel[3])
  432.                                         term.setTextColour(pixel[2])
  433.                                         term.setCursorPos(x, y)
  434.                                         term.write(pixel[1])
  435.                                 end
  436.                         end
  437.                 end
  438.                 Drawing.BackBuffer = Drawing.Buffer
  439.                 Drawing.Buffer = {}
  440.                 term.setCursorPos(1,1)
  441.         end,
  442.  
  443.         ClearBuffer = function()
  444.                 Drawing.Buffer = {}
  445.         end,
  446.  
  447.         WriteStringToBuffer = function (x, y, characters, textColour,bgColour)
  448.                 for i = 1, #characters do
  449.                         local character = characters:sub(i,i)
  450.                         Drawing.WriteToBuffer(x + i - 1, y, character, textColour, bgColour)
  451.                 end
  452.         end,
  453.  
  454.         WriteToBuffer = function(x, y, character, textColour,bgColour)
  455.                 x = round(x)
  456.                 y = round(y)
  457.                 if bgColour == colours.transparent then
  458.                         Drawing.Buffer[y] = Drawing.Buffer[y] or {}
  459.                         Drawing.Buffer[y][x] = Drawing.Buffer[y][x] or {"", colours.white, colours.black}
  460.                         Drawing.Buffer[y][x][1] = character
  461.                         Drawing.Buffer[y][x][2] = textColour
  462.                 else
  463.                         Drawing.Buffer[y] = Drawing.Buffer[y] or {}
  464.                         Drawing.Buffer[y][x] = {character, textColour, bgColour}
  465.                 end
  466.         end,
  467. }
  468.  
  469. Current = {
  470.         Document = nil,
  471.         TextInput = nil,
  472.         CursorPos = {1,1},
  473.         CursorColour = colours.black,
  474.         Selection = {8, 36},
  475.         Window = nil,
  476.         Modified = false,
  477. }
  478.  
  479. local isQuitting = false
  480.  
  481. function OrderSelection()
  482.         if Current.Selection then
  483.                 if Current.Selection[1] <= Current.Selection[2] then
  484.                         return Current.Selection
  485.                 else
  486.                         return {Current.Selection[2], Current.Selection[1]}
  487.                 end
  488.         end
  489. end
  490.  
  491. function StripColours(str)
  492.         return str:gsub('['..string.char(14)..'-'..string.char(29)..']','')
  493. end
  494.  
  495. function FindColours(str)
  496.         local _, count = str:gsub('['..string.char(14)..'-'..string.char(29)..']','')
  497.         return count
  498. end
  499.  
  500. ColourFromCharacter = function(character)
  501.         local n = character:byte() - 14
  502.         if n > 16 then
  503.                 return nil
  504.         else
  505.                 return 2^n
  506.         end
  507. end
  508.  
  509. CharacterFromColour = function(colour)
  510.         return string.char(math.floor(math.log(colour)/math.log(2))+14)
  511. end
  512.  
  513. Events = {}
  514.  
  515. Button = {
  516.         X = 1,
  517.         Y = 1,
  518.         Width = 0,
  519.         Height = 0,
  520.         BackgroundColour = colours.lightGrey,
  521.         TextColour = colours.white,
  522.         ActiveBackgroundColour = colours.lightGrey,
  523.         Text = "",
  524.         Parent = nil,
  525.         _Click = nil,
  526.         Toggle = nil,
  527.  
  528.         AbsolutePosition = function(self)
  529.                 return self.Parent:AbsolutePosition()
  530.         end,
  531.  
  532.         Draw = function(self)
  533.                 local bg = self.BackgroundColour
  534.                 local tc = self.TextColour
  535.                 if type(bg) == 'function' then
  536.                         bg = bg()
  537.                 end
  538.  
  539.                 if self.Toggle then
  540.                         tc = UIColours.MenuBarActive
  541.                         bg = self.ActiveBackgroundColour
  542.                 end
  543.  
  544.                 local pos = GetAbsolutePosition(self)
  545.                 Drawing.DrawBlankArea(pos.X, pos.Y, self.Width, self.Height, bg)
  546.                 Drawing.DrawCharactersCenter(pos.X, pos.Y, self.Width, self.Height, self.Text, tc, bg)
  547.         end,
  548.  
  549.         Initialise = function(self, x, y, width, height, backgroundColour, parent, click, text, textColour, toggle, activeBackgroundColour)
  550.                 local new = {}    -- the new instance
  551.                 setmetatable( new, {__index = self} )
  552.                 height = height or 1
  553.                 new.Width = width or #text + 2
  554.                 new.Height = height
  555.                 new.Y = y
  556.                 new.X = x
  557.                 new.Text = text or ""
  558.                 new.BackgroundColour = backgroundColour or colours.lightGrey
  559.                 new.TextColour = textColour or colours.white
  560.                 new.ActiveBackgroundColour = activeBackgroundColour or colours.lightGrey
  561.                 new.Parent = parent
  562.                 new._Click = click
  563.                 new.Toggle = toggle
  564.                 return new
  565.         end,
  566.  
  567.         Click = function(self, side, x, y)
  568.                 if self._Click then
  569.                         if self:_Click(side, x, y, not self.Toggle) ~= false and self.Toggle ~= nil then
  570.                                 self.Toggle = not self.Toggle
  571.                                 Draw()
  572.                         end
  573.                         return true
  574.                 else
  575.                         return false
  576.                 end
  577.         end
  578. }
  579.  
  580. TextBox = {
  581.         X = 1,
  582.         Y = 1,
  583.         Width = 0,
  584.         Height = 0,
  585.         BackgroundColour = colours.lightGrey,
  586.         TextColour = colours.black,
  587.         Parent = nil,
  588.         TextInput = nil,
  589.         Placeholder = '',
  590.  
  591.         AbsolutePosition = function(self)
  592.                 return self.Parent:AbsolutePosition()
  593.         end,
  594.  
  595.         Draw = function(self)          
  596.                 local pos = GetAbsolutePosition(self)
  597.                 Drawing.DrawBlankArea(pos.X, pos.Y, self.Width, self.Height, self.BackgroundColour)
  598.                 local text = self.TextInput.Value
  599.                 if #tostring(text) > (self.Width - 2) then
  600.                         text = text:sub(#text-(self.Width - 3))
  601.                         if Current.TextInput == self.TextInput then
  602.                                 Current.CursorPos = {pos.X + 1 + self.Width-2, pos.Y}
  603.                         end
  604.                 else
  605.                         if Current.TextInput == self.TextInput then
  606.                                 Current.CursorPos = {pos.X + 1 + self.TextInput.CursorPos, pos.Y}
  607.                         end
  608.                 end
  609.                
  610.                 if #tostring(text) == 0 then
  611.                         Drawing.DrawCharacters(pos.X + 1, pos.Y, self.Placeholder, colours.lightGrey, self.BackgroundColour)
  612.                 else
  613.                         Drawing.DrawCharacters(pos.X + 1, pos.Y, text, self.TextColour, self.BackgroundColour)
  614.                 end
  615.  
  616.                 term.setCursorBlink(true)
  617.                
  618.                 Current.CursorColour = self.TextColour
  619.         end,
  620.  
  621.         Initialise = function(self, x, y, width, height, parent, text, backgroundColour, textColour, done, numerical)
  622.                 local new = {}    -- the new instance
  623.                 setmetatable( new, {__index = self} )
  624.                 height = height or 1
  625.                 new.Width = width or #text + 2
  626.                 new.Height = height
  627.                 new.Y = y
  628.                 new.X = x
  629.                 new.TextInput = TextInput:Initialise(text or '', function(key)
  630.                         if done then
  631.                                 done(key)
  632.                         end
  633.                         Draw()
  634.                 end, numerical)
  635.                 new.BackgroundColour = backgroundColour or colours.lightGrey
  636.                 new.TextColour = textColour or colours.black
  637.                 new.Parent = parent
  638.                 return new
  639.         end,
  640.  
  641.         Click = function(self, side, x, y)
  642.                 Current.Input = self.TextInput
  643.                 self:Draw()
  644.         end
  645. }
  646.  
  647. TextInput = {
  648.         Value = "",
  649.         Change = nil,
  650.         CursorPos = nil,
  651.         Numerical = false,
  652.         IsDocument = nil,
  653.  
  654.         Initialise = function(self, value, change, numerical, isDocument)
  655.                 local new = {}    -- the new instance
  656.                 setmetatable( new, {__index = self} )
  657.                 new.Value = tostring(value)
  658.                 new.Change = change
  659.                 new.CursorPos = #tostring(value)
  660.                 new.Numerical = numerical
  661.                 new.IsDocument = isDocument or false
  662.                 return new
  663.         end,
  664.  
  665.         Insert = function(self, str)
  666.                 if self.Numerical then
  667.                         str = tostring(tonumber(str))
  668.                 end
  669.  
  670.                 local selection = OrderSelection()
  671.  
  672.                 if self.IsDocument and selection then
  673.                         self.Value = string.sub(self.Value, 1, selection[1]-1) .. str .. string.sub( self.Value, selection[2]+2)
  674.                         self.CursorPos = selection[1]
  675.                         Current.Selection = nil
  676.                 else
  677.                         local _, newLineAdjust = string.gsub(self.Value:sub(1, self.CursorPos), '\n','')
  678.  
  679.                         self.Value = string.sub(self.Value, 1, self.CursorPos + newLineAdjust) .. str .. string.sub( self.Value, self.CursorPos + 1  + newLineAdjust)
  680.                         self.CursorPos = self.CursorPos + 1
  681.                 end
  682.                
  683.                 self.Change(key)
  684.         end,
  685.  
  686.         Extract = function(self, remove)
  687.                 local selection = OrderSelection()
  688.                 if self.IsDocument and selection then
  689.                         local _, newLineAdjust = string.gsub(self.Value:sub(selection[1], selection[2]), '\n','')
  690.                         local str = string.sub(self.Value, selection[1], selection[2]+1+newLineAdjust)
  691.                         if remove then
  692.                                 self.Value = string.sub(self.Value, 1, selection[1]-1) .. string.sub( self.Value, selection[2]+2+newLineAdjust)
  693.                                 self.CursorPos = selection[1] - 1
  694.                                 Current.Selection = nil
  695.                         end
  696.                         return str
  697.                 end
  698.         end,
  699.  
  700.         Char = function(self, char)
  701.                 if char == 'nil' then
  702.                         return
  703.                 end
  704.                 self:Insert(char)
  705.         end,
  706.  
  707.         Key = function(self, key)
  708.                 if key == keys.enter then
  709.                         if self.IsDocument then
  710.                                 self.Value = string.sub(self.Value, 1, self.CursorPos ) .. '\n' .. string.sub( self.Value, self.CursorPos + 1 )
  711.                                 self.CursorPos = self.CursorPos + 1
  712.                         end
  713.                         self.Change(key)               
  714.                 elseif key == keys.left then
  715.                         -- Left
  716.                         if self.CursorPos > 0 then
  717.                                 local colShift = FindColours(string.sub( self.Value, self.CursorPos, self.CursorPos))
  718.                                 self.CursorPos = self.CursorPos - 1 - colShift
  719.                                 self.Change(key)
  720.                         end
  721.                        
  722.                 elseif key == keys.right then
  723.                         -- Right                               
  724.                         if self.CursorPos < string.len(self.Value) then
  725.                                 local colShift = FindColours(string.sub( self.Value, self.CursorPos+1, self.CursorPos+1))
  726.                                 self.CursorPos = self.CursorPos + 1 + colShift
  727.                                 self.Change(key)
  728.                         end
  729.                
  730.                 elseif key == keys.backspace then
  731.                         -- Backspace
  732.                         if self.IsDocument and Current.Selection then
  733.                                 self:Extract(true)
  734.                                 self.Change(key)
  735.                         elseif self.CursorPos > 0 then
  736.                                 local colShift = FindColours(string.sub( self.Value, self.CursorPos, self.CursorPos))
  737.                                 local _, newLineAdjust = string.gsub(self.Value:sub(1, self.CursorPos), '\n','')
  738.  
  739.                                 self.Value = string.sub( self.Value, 1, self.CursorPos - 1 - colShift + newLineAdjust) .. string.sub( self.Value, self.CursorPos + 1 - colShift + newLineAdjust)
  740.                                 self.CursorPos = self.CursorPos - 1 - colShift
  741.                                 self.Change(key)
  742.                         end
  743.                 elseif key == keys.home then
  744.                         -- Home
  745.                         self.CursorPos = 0
  746.                         self.Change(key)
  747.                 elseif key == keys.delete then
  748.                         if self.IsDocument and Current.Selection then
  749.                                 self:Extract(true)
  750.                                 self.Change(key)
  751.                         elseif self.CursorPos < string.len(self.Value) then
  752.                                 self.Value = string.sub( self.Value, 1, self.CursorPos ) .. string.sub( self.Value, self.CursorPos + 2 )                               
  753.                                 self.Change(key)
  754.                         end
  755.                 elseif key == keys["end"] then
  756.                         -- End
  757.                         self.CursorPos = string.len(self.Value)
  758.                         self.Change(key)
  759.                 elseif key == keys.up and self.IsDocument then
  760.                         -- Up
  761.                         if Current.Document.CursorPos then
  762.                                 local page = Current.Document.Pages[Current.Document.CursorPos.Page]
  763.                                 self.CursorPos = page:GetCursorPosFromPoint(Current.Document.CursorPos.Collum + page.MarginX, Current.Document.CursorPos.Line - page.MarginY - 1 + Current.Document.ScrollBar.Scroll, true)
  764.                                 self.Change(key)
  765.                         end
  766.                 elseif key == keys.down and self.IsDocument then
  767.                         -- Down
  768.                         if Current.Document.CursorPos then
  769.                                 local page = Current.Document.Pages[Current.Document.CursorPos.Page]
  770.                                 self.CursorPos = page:GetCursorPosFromPoint(Current.Document.CursorPos.Collum + page.MarginX, Current.Document.CursorPos.Line - page.MarginY + 1 + Current.Document.ScrollBar.Scroll, true)
  771.                                 self.Change(key)
  772.                         end
  773.                 end
  774.         end
  775. }
  776.  
  777. Menu = {
  778.         X = 0,
  779.         Y = 0,
  780.         Width = 0,
  781.         Height = 0,
  782.         Owner = nil,
  783.         Items = {},
  784.         RemoveTop = false,
  785.  
  786.         Draw = function(self)
  787.                 Drawing.DrawBlankArea(self.X + 1, self.Y + 1, self.Width, self.Height, UIColours.Shadow)
  788.                 if not self.RemoveTop then
  789.                         Drawing.DrawBlankArea(self.X, self.Y, self.Width, self.Height, UIColours.MenuBackground)
  790.                         for i, item in ipairs(self.Items) do
  791.                                 if item.Separator then
  792.                                         Drawing.DrawArea(self.X, self.Y + i, self.Width, 1, '-', colours.grey, UIColours.MenuBackground)
  793.                                 else
  794.                                         local textColour = item.Colour or UIColours.MenuText
  795.                                         if (item.Enabled and type(item.Enabled) == 'function' and item.Enabled() == false) or item.Enabled == false then
  796.                                                 textColour = UIColours.MenuDisabledText
  797.                                         end
  798.                                         Drawing.DrawCharacters(self.X + 1, self.Y + i, item.Title, textColour, UIColours.MenuBackground)
  799.                                 end
  800.                         end
  801.                 else
  802.                         Drawing.DrawBlankArea(self.X, self.Y, self.Width, self.Height, UIColours.MenuBackground)
  803.                         for i, item in ipairs(self.Items) do
  804.                                 if item.Separator then
  805.                                         Drawing.DrawArea(self.X, self.Y + i - 1, self.Width, 1, '-', colours.grey, UIColours.MenuBackground)
  806.                                 else
  807.                                         local textColour = item.Colour or UIColours.MenuText
  808.                                         if (item.Enabled and type(item.Enabled) == 'function' and item.Enabled() == false) or item.Enabled == false then
  809.                                                 textColour = UIColours.MenuDisabledText
  810.                                         end
  811.                                         Drawing.DrawCharacters(self.X + 1, self.Y + i - 1, item.Title, textColour, UIColours.MenuBackground)
  812.  
  813.                                         Drawing.DrawCharacters(self.X - 1 + self.Width-#item.KeyName, self.Y + i - 1, item.KeyName, textColour, UIColours.MenuBackground)
  814.                                 end
  815.                         end
  816.                 end
  817.         end,
  818.  
  819.         NameForKey = function(self, key)
  820.                 if key == keys.leftCtrl then
  821.                         return '^'
  822.                 elseif key == keys.tab then
  823.                         return 'Tab'
  824.                 elseif key == keys.delete then
  825.                         return 'Delete'
  826.                 elseif key == keys.n then
  827.                         return 'N'
  828.                 elseif key == keys.a then
  829.                         return 'A'
  830.                 elseif key == keys.s then
  831.                         return 'S'
  832.                 elseif key == keys.o then
  833.                         return 'O'
  834.                 elseif key == keys.z then
  835.                         return 'Z'
  836.                 elseif key == keys.y then
  837.                         return 'Y'
  838.                 elseif key == keys.c then
  839.                         return 'C'
  840.                 elseif key == keys.x then
  841.                         return 'X'
  842.                 elseif key == keys.v then
  843.                         return 'V'
  844.                 elseif key == keys.r then
  845.                         return 'R'
  846.                 elseif key == keys.l then
  847.                         return 'L'
  848.                 elseif key == keys.t then
  849.                         return 'T'
  850.                 elseif key == keys.h then
  851.                         return 'H'
  852.                 elseif key == keys.e then
  853.                         return 'E'
  854.                 elseif key == keys.p then
  855.                         return 'P'
  856.                 elseif key == keys.f then
  857.                         return 'F'
  858.                 elseif key == keys.m then
  859.                         return 'M'
  860.                 elseif key == keys.q then
  861.                         return 'Q'
  862.                 else
  863.                         return '?'             
  864.                 end
  865.         end,
  866.  
  867.         Initialise = function(self, x, y, items, owner, removeTop)
  868.                 local new = {}    -- the new instance
  869.                 setmetatable( new, {__index = self} )
  870.                 if not owner then
  871.                         return
  872.                 end
  873.  
  874.                 local keyNames = {}
  875.  
  876.                 for i, v in ipairs(items) do
  877.                         items[i].KeyName = ''
  878.                         if v.Keys then
  879.                                 for _i, key in ipairs(v.Keys) do
  880.                                         items[i].KeyName = items[i].KeyName .. self:NameForKey(key)
  881.                                 end
  882.                         end
  883.                         if items[i].KeyName ~= '' then
  884.                                 table.insert(keyNames, items[i].KeyName)
  885.                         end
  886.                 end
  887.                 local keysLength = LongestString(keyNames)
  888.                 if keysLength > 0 then
  889.                         keysLength = keysLength + 2
  890.                 end
  891.  
  892.                 new.Width = LongestString(items, 'Title') + 2 + keysLength
  893.                 if new.Width < 10 then
  894.                         new.Width = 10
  895.                 end
  896.                 new.Height = #items + 2
  897.                 new.RemoveTop = removeTop or false
  898.                 if removeTop then
  899.                         new.Height = new.Height - 1
  900.                 end
  901.                
  902.                 if y < 1 then
  903.                         y = 1
  904.                 end
  905.                 if x < 1 then
  906.                         x = 1
  907.                 end
  908.  
  909.                 if y + new.Height > Drawing.Screen.Height + 1 then
  910.                         y = Drawing.Screen.Height - new.Height
  911.                 end
  912.                 if x + new.Width > Drawing.Screen.Width + 1 then
  913.                         x = Drawing.Screen.Width - new.Width
  914.                 end
  915.  
  916.  
  917.                 new.Y = y
  918.                 new.X = x
  919.                 new.Items = items
  920.                 new.Owner = owner
  921.                 return new
  922.         end,
  923.  
  924.         New = function(self, x, y, items, owner, removeTop)
  925.                 if Current.Menu and Current.Menu.Owner == owner then
  926.                         Current.Menu = nil
  927.                         return
  928.                 end
  929.  
  930.                 local new = self:Initialise(x, y, items, owner, removeTop)
  931.                 Current.Menu = new
  932.                 return new
  933.         end,
  934.  
  935.         Click = function(self, side, x, y)
  936.                 local i = y-1
  937.                 if self.RemoveTop then
  938.                         i = y
  939.                 end
  940.                 if i >= 1 and y < self.Height then
  941.                         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
  942.                                 self.Items[i]:Click()
  943.                                 if Current.Menu.Owner and Current.Menu.Owner.Toggle then
  944.                                         Current.Menu.Owner.Toggle = false
  945.                                 end
  946.                                 Current.Menu = nil
  947.                                 self = nil
  948.                         end
  949.                         return true
  950.                 end
  951.         end
  952. }
  953.  
  954. MenuBar = {
  955.         X = 1,
  956.         Y = 1,
  957.         Width = Drawing.Screen.Width,
  958.         Height = 1,
  959.         MenuBarItems = {},
  960.  
  961.         AbsolutePosition = function(self)
  962.                 return {X = self.X, Y = self.Y}
  963.         end,
  964.  
  965.         Draw = function(self)
  966.                 --Drawing.DrawArea(self.X - 1, self.Y, 1, self.Height, "|", UIColours.ToolbarText, UIColours.Background)
  967.  
  968.                 Drawing.DrawBlankArea(self.X, self.Y, self.Width, self.Height, colours.grey)
  969.                 for i, button in ipairs(self.MenuBarItems) do
  970.                         button:Draw()
  971.                 end
  972.         end,
  973.  
  974.         Initialise = function(self, items)
  975.                 local new = {}    -- the new instance
  976.                 setmetatable( new, {__index = self} )
  977.                 new.X = 1
  978.                 new.Y = 1
  979.                 new.MenuBarItems = items
  980.                 return new
  981.         end,
  982.  
  983.         AddToolbarItem = function(self, item)
  984.                 table.insert(self.ToolbarItems, item)
  985.                 self:CalculateToolbarItemPositions()
  986.         end,
  987.  
  988.         CalculateToolbarItemPositions = function(self)
  989.                 local currY = 1
  990.                 for i, toolbarItem in ipairs(self.ToolbarItems) do
  991.                         toolbarItem.Y = currY
  992.                         currY = currY + toolbarItem.Height
  993.                 end
  994.         end,
  995.  
  996.         Click = function(self, side, x, y)
  997.                 for i, item in ipairs(self.MenuBarItems) do
  998.                         if item.X <= x and item.X + item.Width > x then
  999.                                 if item:Click(item, side, x - item.X + 1, 1) then
  1000.                                         return true
  1001.                                 end
  1002.                         end
  1003.                 end
  1004.                 return false
  1005.         end
  1006. }
  1007.  
  1008. TextFormatPlainText = 1
  1009. TextFormatInkText = 2
  1010.  
  1011. Document = {
  1012.         X = 1,
  1013.         Y = 1,
  1014.         PageSize = {Width = 25, Height = 21},
  1015.         TextInput = nil,
  1016.         Pages = {},
  1017.         Format = TextFormatPlainText,
  1018.         Title = '',
  1019.         Path = nil,
  1020.         ScrollBar = nil,
  1021.         Lines = {},
  1022.         CursorPos = nil,
  1023.  
  1024.         CalculateLineWrapping = function(self)
  1025.                 local limit = self.PageSize.Width
  1026.                 local text = self.TextInput.Value
  1027.         local lines = {''}
  1028.         local words = {}
  1029.  
  1030.         for word, space in text:gmatch('(%S+)(%s*)') do
  1031.                 for i = 1, math.ceil(#word/limit) do
  1032.                         local _space = ''
  1033.                         if i == math.ceil(#word/limit) then
  1034.                                 _space = space
  1035.                         end
  1036.                         table.insert(words, {word:sub(1+limit*(i-1), limit*i), _space})
  1037.                 end
  1038.         end
  1039.  
  1040.         for i, ws in ipairs(words) do
  1041.                         local word = ws[1]
  1042.                         local space = ws[2]
  1043.                 local temp = lines[#lines] .. word .. space:gsub('\n','')
  1044.                 if #temp > limit then
  1045.                     table.insert(lines, '')
  1046.                 end
  1047.                 if space:find('\n') then
  1048.                     lines[#lines] = lines[#lines] .. word
  1049.                    
  1050.                     space = space:gsub('\n', function()
  1051.                             table.insert(lines, '')
  1052.                             return ''
  1053.                     end)
  1054.                 else
  1055.                     lines[#lines] = lines[#lines] .. word .. space
  1056.                 end
  1057.         end
  1058.         return lines
  1059.         end,
  1060.  
  1061.         CalculateCursorPos = function(self)
  1062.                 local passedCharacters = 0
  1063.                 Current.CursorPos = nil
  1064.                 for p, page in ipairs(self.Pages) do
  1065.                         page:Draw()
  1066.                         if not Current.CursorPos then
  1067.                                 for i, line in ipairs(page.Lines) do
  1068.                                         local relCursor = self.TextInput.CursorPos - FindColours(self.TextInput.Value:sub(1,self.TextInput.CursorPos))
  1069.                                         if passedCharacters + #StripColours(line.Text:gsub('\n','')) >= relCursor then
  1070.                                                 Current.CursorPos = {self.X + page.MarginX + (relCursor - passedCharacters), page.Y + 1 + i}
  1071.                                                 self.CursorPos = {Page = p, Line = i, Collum = relCursor - passedCharacters - FindColours(self.TextInput.Value:sub(1,self.TextInput.CursorPos-1))}
  1072.                                                 break
  1073.                                         end
  1074.                                         passedCharacters = passedCharacters + #StripColours(line.Text:gsub('\n',''))
  1075.                                 end
  1076.                         end
  1077.                 end
  1078.         end,
  1079.  
  1080.         Draw = function(self)
  1081.                 self:CalculatePages()
  1082.                 self:CalculateCursorPos()
  1083.                 self.ScrollBar:Draw()
  1084.         end,
  1085.  
  1086.         CalculatePages = function(self)
  1087.                 self.Pages = {}
  1088.                 local lines = self:CalculateLineWrapping()
  1089.                 self.Lines = lines
  1090.                 local pageLines = {}
  1091.                 local totalPageHeight = (3 + self.PageSize.Height + 2 * Page.MarginY)
  1092.                 for i, line in ipairs(lines) do
  1093.                         table.insert(pageLines, TextLine:Initialise(line))
  1094.                         if i % self.PageSize.Height == 0 then
  1095.                                 table.insert(self.Pages, Page:Initialise(self, pageLines, 3 - self.ScrollBar.Scroll + totalPageHeight*(#self.Pages)))
  1096.                                 pageLines = {}
  1097.                         end
  1098.                 end
  1099.                 if #pageLines ~= 0 then
  1100.                         table.insert(self.Pages, Page:Initialise(self, pageLines, 3 - self.ScrollBar.Scroll + totalPageHeight*(#self.Pages)))
  1101.                 end
  1102.  
  1103.                 self.ScrollBar.MaxScroll = totalPageHeight*(#self.Pages) - Drawing.Screen.Height + 1
  1104.         end,
  1105.  
  1106.         ScrollToCursor = function(self)
  1107.                 self:CalculateCursorPos()
  1108.                 if Current.CursorPos and
  1109.                         (Current.CursorPos[2] > Drawing.Screen.Height
  1110.                         or Current.CursorPos[2] < 2) then
  1111.                         self.ScrollBar:DoScroll(Current.CursorPos[2] - Drawing.Screen.Height)
  1112.                 end
  1113.         end,
  1114.  
  1115.         SetSelectionColour = function(self, colour)
  1116.                 local selection = OrderSelection()
  1117.                 local text = self.TextInput:Extract(true)
  1118.                 local colChar = CharacterFromColour(colour)
  1119.                 local precedingColour = ''
  1120.                 if FindColours(self.TextInput.Value:sub(self.TextInput.CursorPos+1, self.TextInput.CursorPos+1)) == 0 then
  1121.                         for i = 1, self.TextInput.CursorPos do
  1122.                                 local c = self.TextInput.Value:sub(self.TextInput.CursorPos - i,self.TextInput.CursorPos - i)
  1123.                                 if FindColours(c) == 1 then
  1124.                                         precedingColour = c
  1125.                                         break
  1126.                                 end
  1127.                         end
  1128.                         if precedingColour == '' then
  1129.                                 precedingColour = CharacterFromColour(colours.black)
  1130.                         end
  1131.                 end
  1132.  
  1133.                 self.TextInput:Insert(colChar..StripColours(text)..precedingColour)
  1134.                 --text = text:gsub('['..string.char(14)..'-'..string.char(29)..']','')
  1135.         end,
  1136.  
  1137.         Initialise = function(self, text, title, path)
  1138.                 local new = {}    -- the new instance
  1139.                 setmetatable( new, {__index = self} )
  1140.                 new.Title = title or 'New Document'
  1141.                 new.Path = path
  1142.                 new.X = (Drawing.Screen.Width - (new.PageSize.Width + 2*(Page.MarginX)))/2
  1143.                 new.Y = 2
  1144.                 new.TextInput = TextInput:Initialise(text, function()
  1145.                         new:ScrollToCursor()
  1146.                         Current.Modified = true
  1147.                         Draw()
  1148.                 end, false, true)
  1149.                 new.ScrollBar = ScrollBar:Initialise(Drawing.Screen.Width, new.Y, Drawing.Screen.Height-1, 0, nil, nil, nil, function()end)
  1150.                 Current.TextInput = new.TextInput
  1151.                 Current.ScrollBar = new.ScrollBar
  1152.                 return new
  1153.         end
  1154. }
  1155.  
  1156. ScrollBar = {
  1157.         X = 1,
  1158.         Y = 1,
  1159.         Width = 1,
  1160.         Height = 1,
  1161.         BackgroundColour = colours.grey,
  1162.         BarColour = colours.lightBlue,
  1163.         Parent = nil,
  1164.         Change = nil,
  1165.         Scroll = 0,
  1166.         MaxScroll = 0,
  1167.         ClickPoint = nil,
  1168.  
  1169.         AbsolutePosition = function(self)
  1170.                 return self.Parent:AbsolutePosition()
  1171.         end,
  1172.  
  1173.         Draw = function(self)
  1174.                 local pos = GetAbsolutePosition(self)
  1175.             local barHeight = self.Height - self.MaxScroll
  1176.             if barHeight < 3 then
  1177.               barHeight = 3
  1178.             end
  1179.             local percentage = (self.Scroll/self.MaxScroll)
  1180.  
  1181.             Drawing.DrawBlankArea(pos.X, pos.Y, self.Width, self.Height, self.BackgroundColour)
  1182.             Drawing.DrawBlankArea(pos.X, pos.Y + round(self.Height*percentage - barHeight*percentage), self.Width, barHeight, self.BarColour)
  1183.         end,
  1184.  
  1185.         Initialise = function(self, x, y, height, maxScroll, backgroundColour, barColour, parent, change)
  1186.                 local new = {}    -- the new instance
  1187.                 setmetatable( new, {__index = self} )
  1188.                 new.Width = 1
  1189.                 new.Height = height
  1190.                 new.Y = y
  1191.                 new.X = x
  1192.                 new.BackgroundColour = backgroundColour or colours.grey
  1193.                 new.BarColour = barColour or colours.lightBlue
  1194.                 new.Parent = parent
  1195.                 new.Change = change or function()end
  1196.                 new.MaxScroll = maxScroll
  1197.                 new.Scroll = 0
  1198.                 return new
  1199.         end,
  1200.  
  1201.         DoScroll = function(self, amount)
  1202.                 amount = round(amount)
  1203.                 if self.Scroll < 0 or self.Scroll > self.MaxScroll then
  1204.                         return false
  1205.                 end
  1206.                 self.Scroll = self.Scroll + amount
  1207.                 if self.Scroll < 0 then
  1208.                         self.Scroll = 0
  1209.                 elseif self.Scroll > self.MaxScroll then
  1210.                         self.Scroll = self.MaxScroll
  1211.                 end
  1212.                 self.Change()
  1213.                 return true
  1214.         end,
  1215.  
  1216.         Click = function(self, side, x, y, drag)
  1217.                 local percentage = (self.Scroll/self.MaxScroll)
  1218.                 local barHeight = (self.Height - self.MaxScroll)
  1219.                 if barHeight < 3 then
  1220.                         barHeight = 3
  1221.                 end
  1222.                 local relScroll = (self.MaxScroll*(y + barHeight*percentage)/self.Height)
  1223.                 if not drag then
  1224.                         self.ClickPoint = self.Scroll - relScroll + 1
  1225.                 end
  1226.  
  1227.                 if self.Scroll-1 ~= relScroll then
  1228.                         self:DoScroll(relScroll-self.Scroll-1 + self.ClickPoint)
  1229.                 end
  1230.                 return true
  1231.         end
  1232. }
  1233.  
  1234. AlignmentLeft = 1
  1235. AlignmentCentre = 2
  1236. AlignmentRight = 3
  1237.  
  1238. TextLine = {
  1239.         Text = "",
  1240.         Alignment = AlignmentLeft,
  1241.  
  1242.         Initialise = function(self, text, alignment)
  1243.                 local new = {}    -- the new instance
  1244.                 setmetatable( new, {__index = self} )
  1245.                 new.Text = text
  1246.                 new.Alignment = alignment or AlignmentLeft
  1247.                 return new
  1248.         end
  1249. }
  1250.  
  1251. local clickPos = 1
  1252. Page = {
  1253.         X = 1,
  1254.         Y = 1,
  1255.         Width = 1,
  1256.         Height = 1,
  1257.         MarginX = 3,
  1258.         MarginY = 2,
  1259.         BackgroundColour = colours.white,
  1260.         TextColour = colours.white,
  1261.         ActiveBackgroundColour = colours.lightGrey,
  1262.         Lines = {},
  1263.         Parent = nil,
  1264.  
  1265.         AbsolutePosition = function(self)
  1266.                 return self.Parent:AbsolutePosition()
  1267.         end,
  1268.  
  1269.         Draw = function(self)
  1270.                 local pos = GetAbsolutePosition(self)
  1271.  
  1272.                 if pos.Y > Drawing.Screen.Height or pos.Y + self.Height < 1 then
  1273.                         return
  1274.                 end
  1275.  
  1276.                 Drawing.DrawBlankArea(pos.X+self.Width,pos.Y -1 + 1, 1, self.Height, UIColours.Shadow)
  1277.                 Drawing.DrawBlankArea(pos.X+1, pos.Y -1 + self.Height, self.Width, 1, UIColours.Shadow)
  1278.                 Drawing.DrawBlankArea(pos.X, pos.Y -1, self.Width, self.Height, self.BackgroundColour)
  1279.  
  1280.                 local textColour = self.TextColour
  1281.                 if not Current.Selection then
  1282.                         for i, line in ipairs(self.Lines) do
  1283.                                 local _c = 1
  1284.                                 for c = 1, #line.Text do
  1285.                                         local col = ColourFromCharacter(line.Text:sub(c,c))
  1286.                                         if col then
  1287.                                                 textColour = col
  1288.                                         else
  1289.                                                 Drawing.WriteToBuffer(pos.X + self.MarginX - 1 + _c, pos.Y -2 + i + self.MarginY, line.Text:sub(c,c), textColour, self.BackgroundColour)
  1290.                                                 _c = _c + 1
  1291.                                         end
  1292.                                 end
  1293.                         end
  1294.                 else
  1295.                         local selection = OrderSelection()
  1296.                         local char = 1
  1297.                         local textColour = self.TextColour
  1298.                         for i, line in ipairs(self.Lines) do
  1299.                                 local _c = 1
  1300.                                 for c = 1, #line.Text do
  1301.                                         local col = ColourFromCharacter(line.Text:sub(c,c))
  1302.                                         if col then
  1303.                                                 textColour = col
  1304.                                         else
  1305.                                                 local tc = textColour
  1306.                                                 local colour = colours.white
  1307.                                                 if char >= selection[1] and char <= selection[2] then
  1308.                                                         colour = colours.lightBlue
  1309.                                                         tc = colours.white
  1310.                                                 end
  1311.  
  1312.                                                 Drawing.WriteToBuffer(pos.X + self.MarginX - 1 + _c, pos.Y -2 + i + self.MarginY, line.Text:sub(c,c), tc, colour)
  1313.                                                 _c = _c + 1
  1314.                                         end
  1315.                                         char = char + 1
  1316.                                 end
  1317.                         end
  1318.                 end
  1319.         end,
  1320.  
  1321.         Initialise = function(self, parent, lines, y)
  1322.                 local new = {}    -- the new instanc
  1323.                 setmetatable( new, {__index = self} )
  1324.                 new.Height = parent.PageSize.Height + 2 * self.MarginY
  1325.                 new.Width = parent.PageSize.Width + 2 * self.MarginX
  1326.                 new.X = 1
  1327.                 new.Y = y or 1
  1328.                 new.Lines = lines or {}
  1329.                 new.BackgroundColour = colours.white
  1330.                 new.TextColour = colours.black
  1331.                 new.Parent = parent
  1332.                 new.ClickPos = 1
  1333.                 return new
  1334.         end,
  1335.  
  1336.         GetCursorPosFromPoint = function(self, x, y, rel)
  1337.                 local pos = GetAbsolutePosition(self)
  1338.                 if rel then
  1339.                         pos = {Y = 0, X = 0}
  1340.                 end
  1341.                 local row = y - pos.Y + self.MarginY - self.Parent.ScrollBar.Scroll
  1342.                 local col = x - self.MarginX - pos.X + 1
  1343.                 local cursorPos = 0
  1344.                 if row <= 0 or col <= 0 then
  1345.                         return 0
  1346.                 end
  1347.  
  1348.                 if row > #self.Lines then
  1349.                         for i, v in ipairs(self.Lines) do
  1350.                                 cursorPos = cursorPos + #v.Text-- - FindColours(v.Text)
  1351.                         end
  1352.                         return cursorPos
  1353.                 end
  1354.  
  1355.                 --term.setCursorPos(1,3)
  1356.                 local prevLineCount = 0
  1357.                 for i, v in ipairs(self.Lines) do
  1358.                         if i == row then
  1359.                                 if col > #v.Text then
  1360.                                         col = #v.Text-- + FindColours(v.Text)
  1361.                                 else
  1362.                                         col = col + FindColours(v.Text:sub(1, col))
  1363.                                 end
  1364.                                 --term.setCursorPos(1,2)
  1365.                                 --print(prevLineCount)
  1366.                                 cursorPos = cursorPos + col + 2 - i - prevLineCount
  1367.                                 break
  1368.                         else
  1369.                                 prevLineCount = FindColours(v.Text)
  1370.                                 if prevLineCount ~= 0 then
  1371.                                         prevLineCount = prevLineCount
  1372.                                 end
  1373.                                 cursorPos = cursorPos + #v.Text + 2 - i + FindColours(v.Text)
  1374.                         end
  1375.                 end
  1376.  
  1377.                 return cursorPos - 2
  1378.         end,
  1379.  
  1380.         Click = function(self, side, x, y, drag)
  1381.                 local cursorPos = self:GetCursorPosFromPoint(x, y)
  1382.                 self.Parent.TextInput.CursorPos = cursorPos
  1383.                 if drag == nil then
  1384.                         Current.Selection = nil
  1385.                         clickPos = x
  1386.                 else
  1387.                         local relCursor = cursorPos-- - FindColours(self.Parent.TextInput.Value:sub(1,cursorPos)) + 1
  1388.                         if not Current.Selection then
  1389.                                 local adder = 1
  1390.                                 if clickPos and clickPos < x then
  1391.                                         adder = 0
  1392.                                 end
  1393.                                 Current.Selection = {relCursor + adder, relCursor + 1 + adder}
  1394.                         else
  1395.                                 Current.Selection[2] = relCursor + 1
  1396.                         end
  1397.                 end
  1398.                 Draw()
  1399.                 return true
  1400.         end
  1401. }
  1402.  
  1403. function GetAbsolutePosition(object)
  1404.         local obj = object
  1405.         local i = 0
  1406.         local x = 1
  1407.         local y = 1
  1408.         while true do
  1409.                 x = x + obj.X - 1
  1410.                 y = y + obj.Y - 1
  1411.  
  1412.                 if not obj.Parent then
  1413.                         return {X = x, Y = y}
  1414.                 end
  1415.  
  1416.                 obj = obj.Parent
  1417.  
  1418.                 if i > 32 then
  1419.                         return {X = 1, Y = 1}
  1420.                 end
  1421.  
  1422.                 i = i + 1
  1423.         end
  1424.  
  1425. end
  1426.  
  1427. function Draw()
  1428.         if not Current.Window then
  1429.                 Drawing.Clear(colours.lightGrey)
  1430.         else
  1431.                 Drawing.DrawArea(1, 2, Drawing.Screen.Width, Drawing.Screen.Height, '|', colours.black, colours.lightGrey)
  1432.         end
  1433.  
  1434.         if Current.Document then
  1435.                 Current.Document:Draw()
  1436.         end
  1437.  
  1438.         Current.MenuBar:Draw()
  1439.  
  1440.         if Current.Window then
  1441.                 Current.Window:Draw()
  1442.         end
  1443.  
  1444.         if Current.Menu then
  1445.                 Current.Menu:Draw()
  1446.         end
  1447.  
  1448.         Drawing.DrawBuffer()
  1449.  
  1450.         if Current.TextInput and Current.CursorPos and not Current.Menu and not(Current.Window and Current.Document and Current.TextInput == Current.Document.TextInput) and Current.CursorPos[2] > 1 then
  1451.                 term.setCursorPos(Current.CursorPos[1], Current.CursorPos[2])
  1452.                 term.setCursorBlink(true)
  1453.                 term.setTextColour(Current.CursorColour)
  1454.         else
  1455.                 term.setCursorBlink(false)
  1456.         end
  1457. end
  1458. MainDraw = Draw
  1459.  
  1460. LongestString = function(input, key)
  1461.         local length = 0
  1462.         for i = 1, #input do
  1463.                 local value = input[i]
  1464.                 if key then
  1465.                         if value[key] then
  1466.                                 value = value[key]
  1467.                         else
  1468.                                 value = ''
  1469.                         end
  1470.                 end
  1471.                 local titleLength = string.len(value)
  1472.                 if titleLength > length then
  1473.                         length = titleLength
  1474.                 end
  1475.         end
  1476.         return length
  1477. end
  1478.  
  1479. function LoadMenuBar()
  1480.         Current.MenuBar = MenuBar:Initialise({
  1481.                 Button:Initialise(1, 1, nil, nil, colours.grey, Current.MenuBar, function(self, side, x, y, toggle)
  1482.                         if toggle then
  1483.                                 Menu:New(1, 2, {
  1484.                                         {
  1485.                                                 Title = "New...",
  1486.                                                 Click = function()
  1487.                                                         Current.Document = Document:Initialise('')                                                     
  1488.                                                 end,
  1489.                                                 Keys = {
  1490.                                                         keys.leftCtrl,
  1491.                                                         keys.n
  1492.                                                 }
  1493.                                         },
  1494.                                         {
  1495.                                                 Title = 'Open...',
  1496.                                                 Click = function()
  1497.                                                         DisplayOpenDocumentWindow()
  1498.                                                 end,
  1499.                                                 Keys = {
  1500.                                                         keys.leftCtrl,
  1501.                                                         keys.o
  1502.                                                 }
  1503.                                         },
  1504.                                         {
  1505.                                                 Separator = true
  1506.                                         },
  1507.                                         {
  1508.                                                 Title = 'Save...',
  1509.                                                 Click = function()
  1510.                                                         SaveDocument()
  1511.                                                 end,
  1512.                                                 Keys = {
  1513.                                                         keys.leftCtrl,
  1514.                                                         keys.s
  1515.                                                 },
  1516.                                                 Enabled = function()
  1517.                                                         return true
  1518.                                                 end
  1519.                                         },
  1520.                                         {
  1521.                                                 Separator = true
  1522.                                         },
  1523.                                         {
  1524.                                                 Title = 'Print...',
  1525.                                                 Click = function()
  1526.                                                         PrintDocument()
  1527.                                                 end,
  1528.                                                 Keys = {
  1529.                                                         keys.leftCtrl,
  1530.                                                         keys.p
  1531.                                                 },
  1532.                                                 Enabled = function()
  1533.                                                         return true
  1534.                                                 end
  1535.                                         },
  1536.                                         {
  1537.                                                 Separator = true
  1538.                                         },
  1539.                                         {
  1540.                                                 Title = 'Quit',
  1541.                                                 Click = function()
  1542.                                                         Close()
  1543.                                                 end
  1544.                                         },
  1545.                         --[[
  1546.                                         {
  1547.                                                 Title = 'Save As...',
  1548.                                                 Click = function()
  1549.  
  1550.                                                 end
  1551.                                         }      
  1552.                         ]]--
  1553.                                 }, self, true)
  1554.                         else
  1555.                                 Current.Menu = nil
  1556.                         end
  1557.                         return true
  1558.                 end, 'File', colours.lightGrey, false),
  1559.                 Button:Initialise(7, 1, nil, nil, colours.grey, Current.MenuBar, function(self, side, x, y, toggle)
  1560.                         if not self.Toggle then
  1561.                                 Menu:New(7, 2, {
  1562.                         --[[
  1563.                                         {
  1564.                                                 Title = "Undo",
  1565.                                                 Click = function()
  1566.                                                 end,
  1567.                                                 Keys = {
  1568.                                                         keys.leftCtrl,
  1569.                                                         keys.z
  1570.                                                 },
  1571.                                                 Enabled = function()
  1572.                                                         return false
  1573.                                                 end
  1574.                                         },
  1575.                                         {
  1576.                                                 Title = 'Redo',
  1577.                                                 Click = function()
  1578.                                                        
  1579.                                                 end,
  1580.                                                 Keys = {
  1581.                                                         keys.leftCtrl,
  1582.                                                         keys.y
  1583.                                                 },
  1584.                                                 Enabled = function()
  1585.                                                         return false
  1586.                                                 end
  1587.                                         },
  1588.                                         {
  1589.                                                 Separator = true
  1590.                                         },
  1591.                         ]]--
  1592.                                         {
  1593.                                                 Title = 'Cut',
  1594.                                                 Click = function()
  1595.                                                         Clipboard.Cut(Current.Document.TextInput:Extract(true), 'text')
  1596.                                                 end,
  1597.                                                 Keys = {
  1598.                                                         keys.leftCtrl,
  1599.                                                         keys.x
  1600.                                                 },
  1601.                                                 Enabled = function()
  1602.                                                         return Current.Document ~= nil and Current.Selection and Current.Selection[1] and Current.Selection[2] ~= nil
  1603.                                                 end
  1604.                                         },
  1605.                                         {
  1606.                                                 Title = 'Copy',
  1607.                                                 Click = function()
  1608.                                                         Clipboard.Copy(Current.Document.TextInput:Extract(), 'text')
  1609.                                                 end,
  1610.                                                 Keys = {
  1611.                                                         keys.leftCtrl,
  1612.                                                         keys.c
  1613.                                                 },
  1614.                                                 Enabled = function()
  1615.                                                         return Current.Document ~= nil and Current.Selection and Current.Selection[1] and Current.Selection[2] ~= nil
  1616.                                                 end
  1617.                                         },
  1618.                                         {
  1619.                                                 Title = 'Paste',
  1620.                                                 Click = function()
  1621.                                                         local paste = Clipboard.Paste()
  1622.                                                         Current.Document.TextInput:Insert(paste)
  1623.                                                         Current.Document.TextInput.CursorPos = Current.Document.TextInput.CursorPos + #paste - 1
  1624.                                                 end,
  1625.                                                 Keys = {
  1626.                                                         keys.leftCtrl,
  1627.                                                         keys.v
  1628.                                                 },
  1629.                                                 Enabled = function()
  1630.                                                         return Current.Document ~= nil and (not Clipboard.isEmpty()) and Clipboard.Type == 'text'
  1631.                                                 end
  1632.                                         },
  1633.                                         {
  1634.                                                 Separator = true,      
  1635.                                         },
  1636.                                         {
  1637.                                                 Title = 'Select All',
  1638.                                                 Click = function()
  1639.                                                         Current.Selection = {1, #Current.Document.TextInput.Value:gsub('\n','')}
  1640.                                                 end,
  1641.                                                 Keys = {
  1642.                                                         keys.leftCtrl,
  1643.                                                         keys.a
  1644.                                                 },
  1645.                                                 Enabled = function()
  1646.                                                         return Current.Document ~= nil
  1647.                                                 end
  1648.                                         }
  1649.                                 }, self, true)
  1650.                         else
  1651.                                 Current.Menu = nil
  1652.                         end
  1653.                         return true
  1654.                 end, 'Edit', colours.lightGrey, false)
  1655.         })
  1656. end
  1657.  
  1658. function LoadMenuBar()
  1659.         Current.MenuBar = MenuBar:Initialise({
  1660.                 Button:Initialise(1, 1, nil, nil, colours.grey, Current.MenuBar, function(self, side, x, y, toggle)
  1661.                         if toggle then
  1662.                                 Menu:New(1, 2, {
  1663.                                         {
  1664.                                                 Title = "New...",
  1665.                                                 Click = function()
  1666.                                                         Current.Document = Document:Initialise('')                                                     
  1667.                                                 end,
  1668.                                                 Keys = {
  1669.                                                         keys.leftCtrl,
  1670.                                                         keys.n
  1671.                                                 }
  1672.                                         },
  1673.                                         {
  1674.                                                 Title = 'Open...',
  1675.                                                 Click = function()
  1676.                                                         DisplayOpenDocumentWindow()
  1677.                                                 end,
  1678.                                                 Keys = {
  1679.                                                         keys.leftCtrl,
  1680.                                                         keys.o
  1681.                                                 }
  1682.                                         },
  1683.                                         {
  1684.                                                 Separator = true
  1685.                                         },
  1686.                                         {
  1687.                                                 Title = 'Save...',
  1688.                                                 Click = function()
  1689.                                                         SaveDocument()
  1690.                                                 end,
  1691.                                                 Keys = {
  1692.                                                         keys.leftCtrl,
  1693.                                                         keys.s
  1694.                                                 },
  1695.                                                 Enabled = function()
  1696.                                                         return Current.Document ~= nil
  1697.                                                 end
  1698.                                         },
  1699.                                         {
  1700.                                                 Separator = true
  1701.                                         },
  1702.                                         {
  1703.                                                 Title = 'Print...',
  1704.                                                 Click = function()
  1705.                                                         PrintDocument()
  1706.                                                 end,
  1707.                                                 Keys = {
  1708.                                                         keys.leftCtrl,
  1709.                                                         keys.p
  1710.                                                 },
  1711.                                                 Enabled = function()
  1712.                                                         return true
  1713.                                                 end
  1714.                                         },
  1715.                                         {
  1716.                                                 Separator = true
  1717.                                         },
  1718.                                         {
  1719.                                                 Title = 'Quit',
  1720.                                                 Click = function()
  1721.                                                         if Close() and OneOS then
  1722.                                                                 OneOS.Close()
  1723.                                                         end
  1724.                                                 end,
  1725.                                                 Keys = {
  1726.                                                         keys.leftCtrl,
  1727.                                                         keys.q
  1728.                                                 }
  1729.                                         },
  1730.                         --[[
  1731.                                         {
  1732.                                                 Title = 'Save As...',
  1733.                                                 Click = function()
  1734.  
  1735.                                                 end
  1736.                                         }      
  1737.                         ]]--
  1738.                                 }, self, true)
  1739.                         else
  1740.                                 Current.Menu = nil
  1741.                         end
  1742.                         return true
  1743.                 end, 'File', colours.lightGrey, false),
  1744.                 Button:Initialise(7, 1, nil, nil, colours.grey, Current.MenuBar, function(self, side, x, y, toggle)
  1745.                         if not self.Toggle then
  1746.                                 Menu:New(7, 2, {
  1747.                         --[[
  1748.                                         {
  1749.                                                 Title = "Undo",
  1750.                                                 Click = function()
  1751.                                                 end,
  1752.                                                 Keys = {
  1753.                                                         keys.leftCtrl,
  1754.                                                         keys.z
  1755.                                                 },
  1756.                                                 Enabled = function()
  1757.                                                         return false
  1758.                                                 end
  1759.                                         },
  1760.                                         {
  1761.                                                 Title = 'Redo',
  1762.                                                 Click = function()
  1763.                                                        
  1764.                                                 end,
  1765.                                                 Keys = {
  1766.                                                         keys.leftCtrl,
  1767.                                                         keys.y
  1768.                                                 },
  1769.                                                 Enabled = function()
  1770.                                                         return false
  1771.                                                 end
  1772.                                         },
  1773.                                         {
  1774.                                                 Separator = true
  1775.                                         },
  1776.                         ]]--
  1777.                                         {
  1778.                                                 Title = 'Cut',
  1779.                                                 Click = function()
  1780.                                                         Clipboard.Cut(Current.Document.TextInput:Extract(true), 'text')
  1781.                                                 end,
  1782.                                                 Keys = {
  1783.                                                         keys.leftCtrl,
  1784.                                                         keys.x
  1785.                                                 },
  1786.                                                 Enabled = function()
  1787.                                                         return Current.Document ~= nil and Current.Selection and Current.Selection[1] and Current.Selection[2] ~= nil
  1788.                                                 end
  1789.                                         },
  1790.                                         {
  1791.                                                 Title = 'Copy',
  1792.                                                 Click = function()
  1793.                                                         Clipboard.Copy(Current.Document.TextInput:Extract(), 'text')
  1794.                                                 end,
  1795.                                                 Keys = {
  1796.                                                         keys.leftCtrl,
  1797.                                                         keys.c
  1798.                                                 },
  1799.                                                 Enabled = function()
  1800.                                                         return Current.Document ~= nil and Current.Selection and Current.Selection[1] and Current.Selection[2] ~= nil
  1801.                                                 end
  1802.                                         },
  1803.                                         {
  1804.                                                 Title = 'Paste',
  1805.                                                 Click = function()
  1806.                                                         local paste = Clipboard.Paste()
  1807.                                                         Current.Document.TextInput:Insert(paste)
  1808.                                                         Current.Document.TextInput.CursorPos = Current.Document.TextInput.CursorPos + #paste - 1
  1809.                                                 end,
  1810.                                                 Keys = {
  1811.                                                         keys.leftCtrl,
  1812.                                                         keys.v
  1813.                                                 },
  1814.                                                 Enabled = function()
  1815.                                                         return Current.Document ~= nil and (not Clipboard.isEmpty()) and Clipboard.Type == 'text'
  1816.                                                 end
  1817.                                         },
  1818.                                         {
  1819.                                                 Separator = true,      
  1820.                                         },
  1821.                                         {
  1822.                                                 Title = 'Select All',
  1823.                                                 Click = function()
  1824.                                                         Current.Selection = {1, #Current.Document.TextInput.Value:gsub('\n','')}
  1825.                                                 end,
  1826.                                                 Keys = {
  1827.                                                         keys.leftCtrl,
  1828.                                                         keys.a
  1829.                                                 },
  1830.                                                 Enabled = function()
  1831.                                                         return Current.Document ~= nil
  1832.                                                 end
  1833.                                         }
  1834.                                 }, self, true)
  1835.                         else
  1836.                                 Current.Menu = nil
  1837.                         end
  1838.                         return true
  1839.                 end, 'Edit', colours.lightGrey, false),
  1840.                 Button:Initialise(13, 1, nil, nil, colours.grey, Current.MenuBar, function(self, side, x, y, toggle)
  1841.                         if not self.Toggle then
  1842.                                 Menu:New(13, 2, {
  1843.                                         {
  1844.                                                 Title = 'Red',
  1845.                                                 Click = function(item)
  1846.                                                         Current.Document:SetSelectionColour(item.Colour)
  1847.                                                 end,
  1848.                                                 Colour = colours.red,
  1849.                                                 Enabled = function()
  1850.                                                         return (Current.Document ~= nil and Current.Selection ~= nil and Current.Selection[1] ~= nil and Current.Selection[2] ~= nil)
  1851.                                                 end
  1852.                                         },
  1853.                                         {
  1854.                                                 Title = 'Orange',
  1855.                                                 Click = function(item)
  1856.                                                         Current.Document:SetSelectionColour(item.Colour)
  1857.                                                 end,
  1858.                                                 Colour = colours.orange,
  1859.                                                 Enabled = function()
  1860.                                                         return (Current.Document ~= nil and Current.Selection ~= nil and Current.Selection[1] ~= nil and Current.Selection[2] ~= nil)
  1861.                                                 end
  1862.                                         },
  1863.                                         {
  1864.                                                 Title = 'Yellow',
  1865.                                                 Click = function(item)
  1866.                                                         Current.Document:SetSelectionColour(item.Colour)
  1867.                                                 end,
  1868.                                                 Colour = colours.yellow,
  1869.                                                 Enabled = function()
  1870.                                                         return (Current.Document ~= nil and Current.Selection ~= nil and Current.Selection[1] ~= nil and Current.Selection[2] ~= nil)
  1871.                                                 end
  1872.                                         },
  1873.                                         {
  1874.                                                 Title = 'Pink',
  1875.                                                 Click = function(item)
  1876.                                                         Current.Document:SetSelectionColour(item.Colour)
  1877.                                                 end,
  1878.                                                 Colour = colours.pink,
  1879.                                                 Enabled = function()
  1880.                                                         return (Current.Document ~= nil and Current.Selection ~= nil and Current.Selection[1] ~= nil and Current.Selection[2] ~= nil)
  1881.                                                 end
  1882.                                         },
  1883.                                         {
  1884.                                                 Title = 'Magenta',
  1885.                                                 Click = function(item)
  1886.                                                         Current.Document:SetSelectionColour(item.Colour)
  1887.                                                 end,
  1888.                                                 Colour = colours.magenta,
  1889.                                                 Enabled = function()
  1890.                                                         return (Current.Document ~= nil and Current.Selection ~= nil and Current.Selection[1] ~= nil and Current.Selection[2] ~= nil)
  1891.                                                 end
  1892.                                         },
  1893.                                         {
  1894.                                                 Title = 'Purple',
  1895.                                                 Click = function(item)
  1896.                                                         Current.Document:SetSelectionColour(item.Colour)
  1897.                                                 end,
  1898.                                                 Colour = colours.purple,
  1899.                                                 Enabled = function()
  1900.                                                         return (Current.Document ~= nil and Current.Selection ~= nil and Current.Selection[1] ~= nil and Current.Selection[2] ~= nil)
  1901.                                                 end
  1902.                                         },
  1903.                                         {
  1904.                                                 Title = 'Light Blue',
  1905.                                                 Click = function(item)
  1906.                                                         Current.Document:SetSelectionColour(item.Colour)
  1907.                                                 end,
  1908.                                                 Colour = colours.lightBlue,
  1909.                                                 Enabled = function()
  1910.                                                         return (Current.Document ~= nil and Current.Selection ~= nil and Current.Selection[1] ~= nil and Current.Selection[2] ~= nil)
  1911.                                                 end
  1912.                                         },
  1913.                                         {
  1914.                                                 Title = 'Cyan',
  1915.                                                 Click = function(item)
  1916.                                                         Current.Document:SetSelectionColour(item.Colour)
  1917.                                                 end,
  1918.                                                 Colour = colours.cyan,
  1919.                                                 Enabled = function()
  1920.                                                         return (Current.Document ~= nil and Current.Selection ~= nil and Current.Selection[1] ~= nil and Current.Selection[2] ~= nil)
  1921.                                                 end
  1922.                                         },
  1923.                                         {
  1924.                                                 Title = 'Blue',
  1925.                                                 Click = function(item)
  1926.                                                         Current.Document:SetSelectionColour(item.Colour)
  1927.                                                 end,
  1928.                                                 Colour = colours.blue,
  1929.                                                 Enabled = function()
  1930.                                                         return (Current.Document ~= nil and Current.Selection ~= nil and Current.Selection[1] ~= nil and Current.Selection[2] ~= nil)
  1931.                                                 end
  1932.                                         },
  1933.                                         {
  1934.                                                 Title = 'Green',
  1935.                                                 Click = function(item)
  1936.                                                         Current.Document:SetSelectionColour(item.Colour)
  1937.                                                 end,
  1938.                                                 Colour = colours.green,
  1939.                                                 Enabled = function()
  1940.                                                         return (Current.Document ~= nil and Current.Selection ~= nil and Current.Selection[1] ~= nil and Current.Selection[2] ~= nil)
  1941.                                                 end
  1942.                                         },
  1943.                                         {
  1944.                                                 Title = 'Light Grey',
  1945.                                                 Click = function(item)
  1946.                                                         Current.Document:SetSelectionColour(item.Colour)
  1947.                                                 end,
  1948.                                                 Colour = colours.lightGrey,
  1949.                                                 Enabled = function()
  1950.                                                         return (Current.Document ~= nil and Current.Selection ~= nil and Current.Selection[1] ~= nil and Current.Selection[2] ~= nil)
  1951.                                                 end
  1952.                                         },
  1953.                                         {
  1954.                                                 Title = 'Grey',
  1955.                                                 Click = function(item)
  1956.                                                         Current.Document:SetSelectionColour(item.Colour)
  1957.                                                 end,
  1958.                                                 Colour = colours.grey,
  1959.                                                 Enabled = function()
  1960.                                                         return (Current.Document ~= nil and Current.Selection ~= nil and Current.Selection[1] ~= nil and Current.Selection[2] ~= nil)
  1961.                                                 end
  1962.                                         },
  1963.                                         {
  1964.                                                 Title = 'Black',
  1965.                                                 Click = function(item)
  1966.                                                         Current.Document:SetSelectionColour(item.Colour)
  1967.                                                 end,
  1968.                                                 Colour = colours.black,
  1969.                                                 Enabled = function()
  1970.                                                         return (Current.Document ~= nil and Current.Selection ~= nil and Current.Selection[1] ~= nil and Current.Selection[2] ~= nil)
  1971.                                                 end
  1972.                                         },
  1973.                                         {
  1974.                                                 Title = 'Brown',
  1975.                                                 Click = function(item)
  1976.                                                         Current.Document:SetSelectionColour(item.Colour)
  1977.                                                 end,
  1978.                                                 Colour = colours.brown,
  1979.                                                 Enabled = function()
  1980.                                                         return (Current.Document ~= nil and Current.Selection ~= nil and Current.Selection[1] ~= nil and Current.Selection[2] ~= nil)
  1981.                                                 end
  1982.                                         }
  1983.                                 }, self, true)
  1984.                         else
  1985.                                 Current.Menu = nil
  1986.                         end
  1987.                         return true
  1988.                 end, 'Colour', colours.lightGrey, false)
  1989.         })
  1990. end
  1991.  
  1992. function SplashScreen()
  1993.         local w = colours.white
  1994.         local b = colours.black
  1995.         local u = colours.blue
  1996.         local lb = colours.lightBlue
  1997.         local splashIcon = {{w,w,w,b,w,w,w,b,w,w,w,},{w,w,w,b,w,w,w,b,w,w,w,},{w,w,w,b,u,u,u,b,w,w,w,},{w,b,b,u,u,u,u,u,b,b,w,},{b,u,u,lb,lb,u,u,u,u,u,b,},{b,u,lb,lb,u,u,u,u,u,u,b,},{b,u,lb,lb,u,u,u,u,u,u,b,},{b,u,u,u,u,u,u,u,u,u,b,},{w,b,b,b,b,b,b,b,b,b,w,},
  1998.         ["text"]={{" "," "," "," "," "," "," "," "," "," "," ",},{" "," "," "," "," "," "," "," "," "," "," ",},{" "," "," "," "," "," "," "," "," "," "," ",},{" "," "," "," "," "," "," "," "," "," "," ",},{" "," "," "," "," "," "," "," "," "," "," ",},{" "," "," "," ","I","n","k"," "," "," "," ",},{" "," "," "," "," "," "," "," "," "," "," ",},{" "," ","b","y"," ","o","e","e","d"," "," "},{" "," "," "," "," "," "," "," "," "," "," ",},},
  1999.         ["textcol"]={{w,w,w,w,w,w,w,w,w,w,w,},{w,w,w,w,w,w,w,w,w,w,w,},{w,w,w,w,w,w,w,w,w,w,w,},{w,w,w,w,w,w,w,w,w,w,w,},{w,w,w,w,w,w,w,w,w,w,w,},{w,w,w,w,w,w,w,w,w,w,w,},{w,w,w,w,w,w,w,w,w,w,w,},{lb,lb,lb,lb,lb,lb,lb,lb,lb,lb,lb,},{w,w,w,w,w,w,w,w,w,w,w,},},}
  2000.         Drawing.Clear(colours.white)
  2001.         Drawing.DrawImage((Drawing.Screen.Width - 11)/2, (Drawing.Screen.Height - 9)/2, splashIcon, 11, 9)
  2002.         Drawing.DrawBuffer()
  2003.         Drawing.Clear(colours.black)
  2004.         parallel.waitForAny(function()sleep(1)end, function()os.pullEvent('mouse_click')end)
  2005. end
  2006.  
  2007. function Initialise(arg)
  2008.         if OneOS then
  2009.                 fs = OneOS.FS
  2010.         end
  2011.  
  2012.         if not OneOS then
  2013.                 SplashScreen()
  2014.         end
  2015.         EventRegister('mouse_click', TryClick)
  2016.         EventRegister('mouse_drag', function(event, side, x, y)TryClick(event, side, x, y, true)end)
  2017.         EventRegister('mouse_scroll', Scroll)
  2018.         EventRegister('key', HandleKey)
  2019.         EventRegister('char', HandleKey)
  2020.         EventRegister('timer', Timer)
  2021.         EventRegister('terminate', function(event) if Close() then error( "Terminated", 0 ) end end)
  2022.        
  2023.         LoadMenuBar()
  2024.  
  2025.         --Current.Document = Document:Initialise('abcdefghijklmnopqrtuvwxy')--'Hello everybody!')
  2026.         if tArgs[1] then
  2027.                 if fs.exists(tArgs[1]) then
  2028.                         OpenDocument(tArgs[1])
  2029.                 else
  2030.                         --new
  2031.                 end
  2032.         else
  2033.                 Current.Document = Document:Initialise('')--'Hello everybody!')
  2034.         end
  2035.  
  2036.         --[[
  2037.         if arg and fs.exists(arg) then
  2038.                         OpenDocument(arg)
  2039.                 else
  2040.                         DisplayNewDocumentWindow()
  2041.                 end
  2042.         ]]--
  2043.         Draw()
  2044.  
  2045.         EventHandler()
  2046. end
  2047.  
  2048. local isControlPushed = false
  2049. controlPushedTimer = nil
  2050. closeWindowTimer = nil
  2051. function Timer(event, timer)
  2052.         if timer == closeWindowTimer then
  2053.                 if Current.Window then
  2054.                         Current.Window:Close()
  2055.                 end
  2056.                 Draw()
  2057.         elseif timer == controlPushedTimer then
  2058.                 isControlPushed = false
  2059.         end
  2060. end
  2061.  
  2062. local ignoreNextChar = false
  2063. function HandleKey(...)
  2064.         local args = {...}
  2065.         local event = args[1]
  2066.         local keychar = args[2]
  2067.                                                                                                                                                                                         --Mac left command character
  2068.         if event == 'key' and keychar == keys.leftCtrl or keychar == keys.rightCtrl or keychar == 219 then
  2069.                 isControlPushed = true
  2070.                 controlPushedTimer = os.startTimer(0.5)
  2071.         elseif isControlPushed then
  2072.                 if event == 'key' then
  2073.                         if CheckKeyboardShortcut(keychar) then
  2074.                                 isControlPushed = false
  2075.                                 ignoreNextChar = true
  2076.                         end
  2077.                 end
  2078.         elseif ignoreNextChar then
  2079.                 ignoreNextChar = false
  2080.         elseif Current.TextInput then
  2081.                 if event == 'char' then
  2082.                         Current.TextInput:Char(keychar)
  2083.                 elseif event == 'key' then
  2084.                         Current.TextInput:Key(keychar)
  2085.                 end
  2086.         end
  2087. end
  2088.  
  2089. function CheckKeyboardShortcut(key)
  2090.         local shortcuts = {}
  2091.         shortcuts[keys.n] = function() Current.Document = Document:Initialise('') end
  2092.         shortcuts[keys.o] = function() DisplayOpenDocumentWindow() end
  2093.         shortcuts[keys.s] = function() if Current.Document ~= nil then SaveDocument() end end
  2094.         shortcuts[keys.left] = function() if Current.TextInput then Current.TextInput:Key(keys.home) end end
  2095.         shortcuts[keys.right] = function() if Current.TextInput then Current.TextInput:Key(keys["end"]) end end
  2096. --      shortcuts[keys.q] = function() DisplayOpenDocumentWindow() end
  2097.         if Current.Document ~= nil then
  2098.                 shortcuts[keys.s] = function() SaveDocument() end
  2099.                 shortcuts[keys.p] = function() PrintDocument() end
  2100.                 if Current.Selection and Current.Selection[1] and Current.Selection[2] ~= nil then
  2101.                         shortcuts[keys.x] = function() Clipboard.Cut(Current.Document.TextInput:Extract(true), 'text') end
  2102.                         shortcuts[keys.c] = function() Clipboard.Copy(Current.Document.TextInput:Extract(), 'text') end
  2103.                 end
  2104.                 if (not Clipboard.isEmpty()) and Clipboard.Type == 'text' then
  2105.                         shortcuts[keys.v] = function() local paste = Clipboard.Paste()
  2106.                                                                         Current.Document.TextInput:Insert(paste)
  2107.                                                                         Current.Document.TextInput.CursorPos = Current.Document.TextInput.CursorPos + #paste - 1
  2108.                                                                 end
  2109.                 end
  2110.                 shortcuts[keys.a] = function() Current.Selection = {1, #Current.Document.TextInput.Value:gsub('\n','')} end
  2111.         end
  2112.                                                        
  2113.         if shortcuts[key] then
  2114.                 shortcuts[key]()
  2115.                 Draw()
  2116.                 return true
  2117.         else
  2118.                 return false
  2119.         end
  2120. end
  2121.  
  2122. --[[
  2123.         Check if the given object falls under the click coordinates
  2124. ]]--
  2125. function CheckClick(object, x, y)
  2126.         if object.X <= x and object.Y <= y and object.X + object.Width > x and object.Y + object.Height > y then
  2127.                 return true
  2128.         end
  2129. end
  2130.  
  2131. --[[
  2132.         Attempt to clicka given object
  2133. ]]--
  2134. function DoClick(object, side, x, y, drag)
  2135.         local obj = GetAbsolutePosition(object)
  2136.         obj.Width = object.Width
  2137.         obj.Height = object.Height
  2138.         if object and CheckClick(obj, x, y) then
  2139.                 return object:Click(side, x - object.X + 1, y - object.Y + 1, drag)
  2140.         end    
  2141. end
  2142.  
  2143. --[[
  2144.         Try to click at the given coordinates
  2145. ]]--
  2146. function TryClick(event, side, x, y, drag)
  2147.         if Current.Menu then
  2148.                 if DoClick(Current.Menu, side, x, y, drag) then
  2149.                         Draw()
  2150.                         return
  2151.                 else
  2152.                         if Current.Menu.Owner and Current.Menu.Owner.Toggle then
  2153.                                 Current.Menu.Owner.Toggle = false
  2154.                         end
  2155.                         Current.Menu = nil
  2156.                         Draw()
  2157.                         return
  2158.                 end
  2159.         elseif Current.Window then
  2160.                 if DoClick(Current.Window, side, x, y, drag) then
  2161.                         Draw()
  2162.                         return
  2163.                 else
  2164.                         Current.Window:Flash()
  2165.                         return
  2166.                 end
  2167.         end
  2168.         local interfaceElements = {}
  2169.  
  2170.         table.insert(interfaceElements, Current.MenuBar)
  2171.         table.insert(interfaceElements, Current.ScrollBar)
  2172.         for i, page in ipairs(Current.Document.Pages) do
  2173.                 table.insert(interfaceElements, page)
  2174.         end
  2175.  
  2176.         for i, object in ipairs(interfaceElements) do
  2177.                 if DoClick(object, side, x, y, drag) then
  2178.                         Draw()
  2179.                         return
  2180.                 end            
  2181.         end
  2182.         Draw()
  2183. end
  2184.  
  2185. function Scroll(event, direction, x, y)
  2186.         if Current.Window and Current.Window.OpenButton then
  2187.                 Current.Document.Scroll = Current.Document.Scroll + direction
  2188.                 if Current.Window.Scroll < 0 then
  2189.                         Current.Window.Scroll = 0
  2190.                 elseif Current.Window.Scroll > Current.Window.MaxScroll then
  2191.                         Current.Window.Scroll = Current.Window.MaxScroll
  2192.                 end
  2193.                 Draw()
  2194.         elseif Current.ScrollBar then
  2195.                 if Current.ScrollBar:DoScroll(direction*2) then
  2196.                         Draw()
  2197.                 end
  2198.         end
  2199. end
  2200.  
  2201.  
  2202. --[[
  2203.         Registers functions to run on certain events
  2204. ]]--
  2205. function EventRegister(event, func)
  2206.         if not Events[event] then
  2207.                 Events[event] = {}
  2208.         end
  2209.  
  2210.         table.insert(Events[event], func)
  2211. end
  2212.  
  2213. --[[
  2214.         The main loop event handler, runs registered event functinos
  2215. ]]--
  2216. function EventHandler()
  2217.         while true do
  2218.                 local event, arg1, arg2, arg3, arg4 = os.pullEventRaw()
  2219.                 if Events[event] then
  2220.                         for i, e in ipairs(Events[event]) do
  2221.                                 e(event, arg1, arg2, arg3, arg4)
  2222.                         end
  2223.                 end
  2224.         end
  2225. end
  2226.  
  2227.  
  2228. local function Extension(path, addDot)
  2229.         if not path then
  2230.                 return nil
  2231.         elseif not string.find(fs.getName(path), '%.') then
  2232.                 if not addDot then
  2233.                         return fs.getName(path)
  2234.                 else
  2235.                         return ''
  2236.                 end
  2237.         else
  2238.                 local _path = path
  2239.                 if path:sub(#path) == '/' then
  2240.                         _path = path:sub(1,#path-1)
  2241.                 end
  2242.                 local extension = _path:gmatch('%.[0-9a-z]+$')()
  2243.                 if extension then
  2244.                         extension = extension:sub(2)
  2245.                 else
  2246.                         --extension = nil
  2247.                         return ''
  2248.                 end
  2249.                 if addDot then
  2250.                         extension = '.'..extension
  2251.                 end
  2252.                 return extension:lower()
  2253.         end
  2254. end
  2255.  
  2256. local RemoveExtension = function(path)
  2257.         if path:sub(1,1) == '.' then
  2258.                 return path
  2259.         end
  2260.         local extension = Extension(path)
  2261.         if extension == path then
  2262.                 return fs.getName(path)
  2263.         end
  2264.         return string.gsub(path, extension, ''):sub(1, -2)
  2265. end
  2266.  
  2267. local acknowledgedColour = false
  2268. function PrintDocument()
  2269.         if OneOS then
  2270.                 OneOS.LoadAPI('/System/API/Helpers.lua')
  2271.                 OneOS.LoadAPI('/System/API/Peripheral.lua')
  2272.                 OneOS.LoadAPI('/System/API/Printer.lua')
  2273.         end
  2274.  
  2275.         local doPrint = function()
  2276.                 local window = PrintDocumentWindow:Initialise():Show()
  2277.         end
  2278.  
  2279.         if Peripheral.GetPeripheral('printer') == nil then
  2280.                 ButtonDialougeWindow:Initialise('No Printer Found', 'Please place a printer next to your computer. Ensure you also insert dye (left slot) and paper (top slots)', 'Ok', nil, function(window, ok)
  2281.                         window:Close()
  2282.                 end):Show()
  2283.         elseif not acknowledgedColour and FindColours(Current.Document.TextInput.Value) ~= 0 then
  2284.                 ButtonDialougeWindow:Initialise('Important', 'Due to the way printers work, you can\'t print in more than one colour. The dye you use will be the colour of the text.', 'Ok', nil, function(window, ok)
  2285.                         acknowledgedColour = true
  2286.                         window:Close()
  2287.                         doPrint()
  2288.                 end):Show()
  2289.         else
  2290.                 doPrint()
  2291.         end
  2292. end
  2293.  
  2294. function SaveDocument()
  2295.         local function save()
  2296.                 local h = fs.open(Current.Document.Path, 'w')
  2297.                 if h then
  2298.                         if Current.Document.Format == TextFormatPlainText then
  2299.                                 h.write(Current.Document.TextInput.Value)
  2300.                         else
  2301.                                 local lines = {}
  2302.                                 for p, page in ipairs(Current.Document.Pages) do
  2303.                                         for i, line in ipairs(page.Lines) do
  2304.                                                 table.insert(lines, line)
  2305.                                         end
  2306.                                 end
  2307.                                 h.write(textutils.serialize(lines))
  2308.                         end
  2309.                         Current.Modified = false
  2310.                 else
  2311.                         ButtonDialougeWindow:Initialise('Error', 'An error occured while saving the file, try again.', 'Ok', nil, function(window, ok)
  2312.                                 window:Close()
  2313.                         end):Show()
  2314.                 end
  2315.                 h.close()
  2316.         end
  2317.  
  2318.         if not Current.Document.Path then
  2319.                 SaveDocumentWindow:Initialise(function(self, success, path)
  2320.                         self:Close()
  2321.                         if success then
  2322.                                 local extension = ''
  2323.                                 if Current.Document.Format == TextFormatPlainText then
  2324.                                         extension = '.txt'
  2325.                                 elseif Current.Document.Format == TextFormatInkText then
  2326.                                         extension = '.ink'
  2327.                                 end
  2328.                                
  2329.                                 if path:sub(-4) ~= extension then
  2330.                                         path = path .. extension
  2331.                                 end
  2332.  
  2333.                                 Current.Document.Path = path
  2334.                                 Current.Document.Title = fs.getName(path)
  2335.                                 save()
  2336.                         end
  2337.                         if Current.Document then
  2338.                                 Current.TextInput = Current.Document.TextInput
  2339.                         end
  2340.                 end):Show()
  2341.         else
  2342.                 save()
  2343.         end
  2344. end
  2345.  
  2346. function DisplayOpenDocumentWindow()
  2347.         OpenDocumentWindow:Initialise(function(self, success, path)
  2348.                 self:Close()
  2349.                 if success then
  2350.                         OpenDocument(path)
  2351.                 end
  2352.         end):Show()
  2353. end
  2354.  
  2355. function OpenDocument(path)
  2356.         Current.Selection = nil
  2357.         local h = fs.open(path, 'r')
  2358.         if h then
  2359.                 Current.Document = Document:Initialise(h.readAll(), RemoveExtension(fs.getName(path)), path)
  2360.         else
  2361.                 ButtonDialougeWindow:Initialise('Error', 'An error occured while opening the file, try again.', 'Ok', nil, function(window, ok)
  2362.                         window:Close()
  2363.                         if Current.Document then
  2364.                                 Current.TextInput = Current.Document.TextInput
  2365.                         end
  2366.                 end):Show()
  2367.         end
  2368.         h.close()
  2369. end
  2370.  
  2371. local TidyPath = function(path)
  2372.         path = '/'..path
  2373.         local fs = fs
  2374.         if OneOS then
  2375.                 fs = OneOS.FS
  2376.         end
  2377.         if fs.isDir(path) then
  2378.                 path = path .. '/'
  2379.         end
  2380.  
  2381.         path, n = path:gsub("//", "/")
  2382.         while n > 0 do
  2383.                 path, n = path:gsub("//", "/")
  2384.         end
  2385.         return path
  2386. end
  2387.  
  2388. OpenDocumentWindow = {
  2389.         X = 1,
  2390.         Y = 1,
  2391.         Width = 0,
  2392.         Height = 0,
  2393.         CursorPos = 1,
  2394.         Visible = true,
  2395.         Return = nil,
  2396.         OpenButton = nil,
  2397.         PathTextBox = nil,
  2398.         CurrentDirectory = '/',
  2399.         Scroll = 0,
  2400.         MaxScroll = 0,
  2401.         GoUpButton = nil,
  2402.         SelectedFile = '',
  2403.         Files = {},
  2404.         Typed = false,
  2405.  
  2406.         AbsolutePosition = function(self)
  2407.                 return {X = self.X, Y = self.Y}
  2408.         end,
  2409.  
  2410.         Draw = function(self)
  2411.                 if not self.Visible then
  2412.                         return
  2413.                 end
  2414.                 Drawing.DrawBlankArea(self.X + 1, self.Y+1, self.Width, self.Height, colours.grey)
  2415.                 Drawing.DrawBlankArea(self.X, self.Y, self.Width, 3, colours.lightGrey)
  2416.                 Drawing.DrawBlankArea(self.X, self.Y+1, self.Width, self.Height-6, colours.white)
  2417.                 Drawing.DrawCharactersCenter(self.X, self.Y, self.Width, 1, self.Title, colours.black, colours.lightGrey)
  2418.                 Drawing.DrawBlankArea(self.X, self.Y + self.Height - 5, self.Width, 5, colours.lightGrey)
  2419.                 self:DrawFiles()
  2420.  
  2421.                 if (fs.exists(self.PathTextBox.TextInput.Value)) or (self.SelectedFile and #self.SelectedFile > 0 and fs.exists(self.CurrentDirectory .. self.SelectedFile)) then
  2422.                         self.OpenButton.TextColour = colours.black
  2423.                 else
  2424.                         self.OpenButton.TextColour = colours.lightGrey
  2425.                 end
  2426.  
  2427.                 self.PathTextBox:Draw()
  2428.                 self.OpenButton:Draw()
  2429.                 self.CancelButton:Draw()
  2430.                 self.GoUpButton:Draw()
  2431.         end,
  2432.  
  2433.         DrawFiles = function(self)
  2434.                 for i, file in ipairs(self.Files) do
  2435.                         if i > self.Scroll and i - self.Scroll <= 11 then
  2436.                                 if file == self.SelectedFile then
  2437.                                         Drawing.DrawCharacters(self.X + 1, self.Y + i - self.Scroll, file, colours.white, colours.lightBlue)
  2438.                                 elseif string.find(file, '%.txt') or string.find(file, '%.text') or string.find(file, '%.ink') or fs.isDir(self.CurrentDirectory .. file) then
  2439.                                         Drawing.DrawCharacters(self.X + 1, self.Y + i - self.Scroll, file, colours.black, colours.white)
  2440.                                 else
  2441.                                         Drawing.DrawCharacters(self.X + 1, self.Y + i - self.Scroll, file, colours.grey, colours.white)
  2442.                                 end
  2443.                         end
  2444.                 end
  2445.                 self.MaxScroll = #self.Files - 11
  2446.                 if self.MaxScroll < 0 then
  2447.                         self.MaxScroll = 0
  2448.                 end
  2449.         end,
  2450.  
  2451.         Initialise = function(self, returnFunc)
  2452.                 local new = {}    -- the new instance
  2453.                 setmetatable( new, {__index = self} )
  2454.                 new.Width = 32
  2455.                 new.Height = 17
  2456.                 new.Return = returnFunc
  2457.                 new.X = math.ceil((Drawing.Screen.Width - new.Width) / 2)
  2458.                 new.Y = math.ceil((Drawing.Screen.Height - new.Height) / 2)
  2459.                 new.Title = 'Open Document'
  2460.                 new.Visible = true
  2461.                 new.CurrentDirectory = '/'
  2462.                 new.SelectedFile = nil
  2463.                 if OneOS and fs.exists('/Desktop/Documents/') then
  2464.                         new.CurrentDirectory = '/Desktop/Documents/'
  2465.                 end
  2466.                 new.OpenButton = Button:Initialise(new.Width - 6, new.Height - 1, nil, nil, colours.white, new, function(self, side, x, y, toggle)
  2467.                         if fs.exists(new.PathTextBox.TextInput.Value) and self.TextColour == colours.black and not fs.isDir(new.PathTextBox.TextInput.Value) then
  2468.                                 returnFunc(new, true, TidyPath(new.PathTextBox.TextInput.Value))
  2469.                         elseif new.SelectedFile and self.TextColour == colours.black and fs.isDir(new.CurrentDirectory .. new.SelectedFile) then
  2470.                                 new:GoToDirectory(new.CurrentDirectory .. new.SelectedFile)
  2471.                         elseif new.SelectedFile and self.TextColour == colours.black then
  2472.                                 returnFunc(new, true, TidyPath(new.CurrentDirectory .. '/' .. new.SelectedFile))
  2473.                         end
  2474.                 end, 'Open', colours.black)
  2475.                 new.CancelButton = Button:Initialise(new.Width - 15, new.Height - 1, nil, nil, colours.white, new, function(self, side, x, y, toggle)
  2476.                         returnFunc(new, false)
  2477.                 end, 'Cancel', colours.black)
  2478.                 new.GoUpButton = Button:Initialise(2, new.Height - 1, nil, nil, colours.white, new, function(self, side, x, y, toggle)
  2479.                         local folderName = fs.getName(new.CurrentDirectory)
  2480.                         local parentDirectory = new.CurrentDirectory:sub(1, #new.CurrentDirectory-#folderName-1)
  2481.                         new:GoToDirectory(parentDirectory)
  2482.                 end, 'Go Up', colours.black)
  2483.                 new.PathTextBox = TextBox:Initialise(2, new.Height - 3, new.Width - 2, 1, new, new.CurrentDirectory, colours.white, colours.black)
  2484.                 new:GoToDirectory(new.CurrentDirectory)
  2485.                 return new
  2486.         end,
  2487.  
  2488.         Show = function(self)
  2489.                 Current.Window = self
  2490.                 return self
  2491.         end,
  2492.  
  2493.         Close = function(self)
  2494.                 Current.Input = nil
  2495.                 Current.Window = nil
  2496.                 self = nil
  2497.         end,
  2498.  
  2499.         GoToDirectory = function(self, path)
  2500.                 path = TidyPath(path)
  2501.                 self.CurrentDirectory = path
  2502.                 self.Scroll = 0
  2503.                 self.SelectedFile = nil
  2504.                 self.Typed = false
  2505.                 self.PathTextBox.TextInput.Value = path
  2506.                 local fs = fs
  2507.                 if OneOS then
  2508.                         fs = OneOS.FS
  2509.                 end
  2510.                 self.Files = fs.list(self.CurrentDirectory)
  2511.                 Draw()
  2512.         end,
  2513.  
  2514.         Flash = function(self)
  2515.                 self.Visible = false
  2516.                 Draw()
  2517.                 sleep(0.15)
  2518.                 self.Visible = true
  2519.                 Draw()
  2520.                 sleep(0.15)
  2521.                 self.Visible = false
  2522.                 Draw()
  2523.                 sleep(0.15)
  2524.                 self.Visible = true
  2525.                 Draw()
  2526.         end,
  2527.  
  2528.         Click = function(self, side, x, y)
  2529.                 local items = {self.OpenButton, self.CancelButton, self.PathTextBox, self.GoUpButton}
  2530.                 local found = false
  2531.                 for i, v in ipairs(items) do
  2532.                         if CheckClick(v, x, y) then
  2533.                                 v:Click(side, x, y)
  2534.                                 found = true
  2535.                         end
  2536.                 end
  2537.  
  2538.                 if not found then
  2539.                         if y <= 12 then
  2540.                                 local fs = fs
  2541.                                 if OneOS then
  2542.                                         fs = OneOS.FS
  2543.                                 end
  2544.                                 self.SelectedFile = fs.list(self.CurrentDirectory)[y-1]
  2545.                                 self.PathTextBox.TextInput.Value = TidyPath(self.CurrentDirectory .. '/' .. self.SelectedFile)
  2546.                                 Draw()
  2547.                         end
  2548.                 end
  2549.                 return true
  2550.         end
  2551. }
  2552.  
  2553. PrintDocumentWindow = {
  2554.         X = 1,
  2555.         Y = 1,
  2556.         Width = 0,
  2557.         Height = 0,
  2558.         CursorPos = 1,
  2559.         Visible = true,
  2560.         Return = nil,
  2561.         PrintButton = nil,
  2562.         CopiesTextBox = nil,
  2563.         Scroll = 0,
  2564.         MaxScroll = 0,
  2565.         PrinterSelectButton = nil,
  2566.         Title = '',
  2567.         Status = 0, --0 = neutral, 1 = good, -1 = error
  2568.         StatusText = '',
  2569.         SelectedPrinter = nil,
  2570.  
  2571.         AbsolutePosition = function(self)
  2572.                 return {X = self.X, Y = self.Y}
  2573.         end,
  2574.  
  2575.         Draw = function(self)
  2576.                 if not self.Visible then
  2577.                         return
  2578.                 end
  2579.                 Drawing.DrawBlankArea(self.X + 1, self.Y+1, self.Width, self.Height, colours.grey)
  2580.                 Drawing.DrawBlankArea(self.X, self.Y, self.Width, 1, colours.lightGrey)
  2581.                 Drawing.DrawBlankArea(self.X, self.Y+1, self.Width, self.Height-1, colours.white)
  2582.                 Drawing.DrawCharactersCenter(self.X, self.Y, self.Width, 1, self.Title, colours.black, colours.lightGrey)
  2583.                
  2584.                 self.PrinterSelectButton:Draw()
  2585.                 Drawing.DrawCharactersCenter(self.X,  self.Y + self.PrinterSelectButton.Y - 2, self.Width, 1, 'Printer', colours.black, colours.white)
  2586.                 Drawing.DrawCharacters(self.X + self.Width - 3, self.Y + self.PrinterSelectButton.Y - 1, '\\/', colours.black, colours.lightGrey)
  2587.                 Drawing.DrawCharacters(self.X + 1, self.Y + self.CopiesTextBox.Y - 1, 'Copies', colours.black, colours.white)
  2588.                 local statusColour = colours.grey
  2589.                 if self.Status == -1 then
  2590.                         statusColour = colours.red
  2591.                 elseif self.Status == 1 then
  2592.                         statusColour = colours.green
  2593.                 end
  2594.                 Drawing.DrawCharacters(self.X + 1, self.Y + self.CopiesTextBox.Y + 1, self.StatusText, statusColour, colours.white)
  2595.  
  2596.                 self.CopiesTextBox:Draw()
  2597.                 self.PrintButton:Draw()
  2598.                 self.CancelButton:Draw()
  2599.         end,
  2600.  
  2601.         Initialise = function(self)
  2602.                 local new = {}    -- the new instance
  2603.                 setmetatable( new, {__index = self} )
  2604.                 new.Width = 32
  2605.                 new.Height = 11
  2606.                 new.Return = returnFunc
  2607.                 new.X = math.ceil((Drawing.Screen.Width - new.Width) / 2)
  2608.                 new.Y = math.ceil((Drawing.Screen.Height - new.Height) / 2)
  2609.                 new.Title = 'Print Document'
  2610.                 new.Visible = true
  2611.                 new.PrintButton = Button:Initialise(new.Width - 7, new.Height - 1, nil, nil, colours.lightGrey, new, function(self, side, x, y, toggle)
  2612.                         local doPrint = true
  2613.                         if new.SelectedPrinter == nil then
  2614.                                 local p = Peripheral.GetPeripheral('printer')
  2615.                                 if p then
  2616.                                         new.SelectedPrinter = p.Side
  2617.                                         new.PrinterSelectButton.Text = p.Fullname
  2618.                                 else
  2619.                                         new.StatusText = 'No Connected Printer'
  2620.                                         new.Status = -1
  2621.                                         doPrint = false
  2622.                                 end
  2623.                         end
  2624.                         if doPrint then
  2625.                                 local printer = Printer:Initialise(new.SelectedPrinter)
  2626.                                 local err = printer:PrintLines(Current.Document.Lines, Current.Document.Title, tonumber(new.CopiesTextBox.TextInput.Value))
  2627.                                 if not err then
  2628.                                         new.StatusText = 'Document Printed!'
  2629.                                         new.Status = 1
  2630.                                         closeWindowTimer = os.startTimer(1)
  2631.                                 else
  2632.                                         new.StatusText = err
  2633.                                         new.Status = -1
  2634.                                 end
  2635.                         end
  2636.                 end, 'Print', colours.black)
  2637.                 new.CancelButton = Button:Initialise(new.Width - 15, new.Height - 1, nil, nil, colours.lightGrey, new, function(self, side, x, y, toggle)
  2638.                         new:Close()
  2639.                         Draw()
  2640.                 end, 'Close', colours.black)
  2641.                 new.PrinterSelectButton = Button:Initialise(2, 4, new.Width - 2, nil, colours.lightGrey, new, function(self, side, x, y, toggle)
  2642.                         local printers = {
  2643.                                         {
  2644.                                                 Title = "Automatic",
  2645.                                                 Click = function()
  2646.                                                         new.SelectedPrinter = nil
  2647.                                                         new.PrinterSelectButton.Text = 'Automatic'
  2648.                                                 end
  2649.                                         },
  2650.                                         {
  2651.                                                 Separator = true
  2652.                                         }
  2653.                                 }
  2654.                         for i, p in ipairs(Peripheral.GetPeripherals('printer')) do
  2655.                                 table.insert(printers, {
  2656.                                         Title = p.Fullname,
  2657.                                         Click = function(self)
  2658.                                                 new.SelectedPrinter = p.Side
  2659.                                                 new.PrinterSelectButton.Text = p.Fullname
  2660.                                         end
  2661.                                 })
  2662.                         end
  2663.                         Current.Menu = Menu:New(x, y+4, printers, self, true)
  2664.                 end, 'Automatic', colours.black)
  2665.                 new.CopiesTextBox = TextBox:Initialise(9, 6, 4, 1, new, 1, colours.lightGrey, colours.black, nil, true)
  2666.                 Current.TextInput = new.CopiesTextBox.TextInput
  2667.                 new.StatusText = 'Waiting...'
  2668.                 new.Status = 0
  2669.                 return new
  2670.         end,
  2671.  
  2672.         Show = function(self)
  2673.                 Current.Window = self
  2674.                 return self
  2675.         end,
  2676.  
  2677.         Close = function(self)
  2678.                 Current.Input = nil
  2679.                 Current.Window = nil
  2680.                 self = nil
  2681.         end,
  2682.  
  2683.         Flash = function(self)
  2684.                 self.Visible = false
  2685.                 Draw()
  2686.                 sleep(0.15)
  2687.                 self.Visible = true
  2688.                 Draw()
  2689.                 sleep(0.15)
  2690.                 self.Visible = false
  2691.                 Draw()
  2692.                 sleep(0.15)
  2693.                 self.Visible = true
  2694.                 Draw()
  2695.         end,
  2696.  
  2697.         Click = function(self, side, x, y)
  2698.                 local items = {self.PrintButton, self.CancelButton, self.CopiesTextBox, self.PrinterSelectButton}
  2699.                 for i, v in ipairs(items) do
  2700.                         if CheckClick(v, x, y) then
  2701.                                 v:Click(side, x, y)
  2702.                         end
  2703.                 end
  2704.                 return true
  2705.         end
  2706. }
  2707.  
  2708. SaveDocumentWindow = {
  2709.         X = 1,
  2710.         Y = 1,
  2711.         Width = 0,
  2712.         Height = 0,
  2713.         CursorPos = 1,
  2714.         Visible = true,
  2715.         Return = nil,
  2716.         SaveButton = nil,
  2717.         PathTextBox = nil,
  2718.         CurrentDirectory = '/',
  2719.         Scroll = 0,
  2720.         MaxScroll = 0,
  2721.         ScrollBar = nil,
  2722.         GoUpButton = nil,
  2723.         Files = {},
  2724.         Typed = false,
  2725.  
  2726.         AbsolutePosition = function(self)
  2727.                 return {X = self.X, Y = self.Y}
  2728.         end,
  2729.  
  2730.         Draw = function(self)
  2731.                 if not self.Visible then
  2732.                         return
  2733.                 end
  2734.                 Drawing.DrawBlankArea(self.X + 1, self.Y+1, self.Width, self.Height, colours.grey)
  2735.                 Drawing.DrawBlankArea(self.X, self.Y, self.Width, 3, colours.lightGrey)
  2736.                 Drawing.DrawBlankArea(self.X, self.Y+1, self.Width, self.Height-6, colours.white)
  2737.                 Drawing.DrawCharactersCenter(self.X, self.Y, self.Width, 1, self.Title, colours.black, colours.lightGrey)
  2738.                 Drawing.DrawBlankArea(self.X, self.Y + self.Height - 5, self.Width, 5, colours.lightGrey)
  2739.                 Drawing.DrawCharacters(self.X + 1, self.Y + self.Height - 5, self.CurrentDirectory, colours.grey, colours.lightGrey)
  2740.                 self:DrawFiles()
  2741.  
  2742.                 if (self.PathTextBox.TextInput.Value) then
  2743.                         self.SaveButton.TextColour = colours.black
  2744.                 else
  2745.                         self.SaveButton.TextColour = colours.lightGrey
  2746.                 end
  2747.  
  2748.                 self.PathTextBox:Draw()
  2749.                 self.SaveButton:Draw()
  2750.                 self.CancelButton:Draw()
  2751.                 self.GoUpButton:Draw()
  2752.         end,
  2753.  
  2754.         DrawFiles = function(self)
  2755.                 for i, file in ipairs(self.Files) do
  2756.                         if i > self.Scroll and i - self.Scroll <= 10 then
  2757.                                 if file == self.SelectedFile then
  2758.                                         Drawing.DrawCharacters(self.X + 1, self.Y + i - self.Scroll, file, colours.white, colours.lightBlue)
  2759.                                 elseif fs.isDir(self.CurrentDirectory .. file) then
  2760.                                         Drawing.DrawCharacters(self.X + 1, self.Y + i - self.Scroll, file, colours.black, colours.white)
  2761.                                 else
  2762.                                         Drawing.DrawCharacters(self.X + 1, self.Y + i - self.Scroll, file, colours.lightGrey, colours.white)
  2763.                                 end
  2764.                         end
  2765.                 end
  2766.                 self.MaxScroll = #self.Files - 11
  2767.                 if self.MaxScroll < 0 then
  2768.                         self.MaxScroll = 0
  2769.                 end
  2770.         end,
  2771.  
  2772.         Initialise = function(self, returnFunc)
  2773.                 local new = {}    -- the new instance
  2774.                 setmetatable( new, {__index = self} )
  2775.                 new.Width = 32
  2776.                 new.Height = 16
  2777.                 new.Return = returnFunc
  2778.                 new.X = math.ceil((Drawing.Screen.Width - new.Width) / 2)
  2779.                 new.Y = math.ceil((Drawing.Screen.Height - new.Height) / 2)
  2780.                 new.Title = 'Save Document'
  2781.                 new.Visible = true
  2782.                 new.CurrentDirectory = '/'
  2783.                 if OneOS and fs.exists('/Desktop/Documents/') then
  2784.                         new.CurrentDirectory = '/Desktop/Documents/'
  2785.                 end
  2786.                 new.SaveButton = Button:Initialise(new.Width - 6, new.Height - 1, nil, nil, colours.white, new, function(self, side, x, y, toggle)
  2787.                         if self.TextColour == colours.black and not fs.isDir(new.CurrentDirectory ..'/' .. new.PathTextBox.TextInput.Value) then
  2788.                                 returnFunc(new, true, TidyPath(new.CurrentDirectory ..'/' .. new.PathTextBox.TextInput.Value))
  2789.                         elseif new.SelectedFile and self.TextColour == colours.black and fs.isDir(new.CurrentDirectory .. new.SelectedFile) then
  2790.                                 new:GoToDirectory(new.CurrentDirectory .. new.SelectedFile)
  2791.                         end
  2792.                 end, 'Save', colours.black)
  2793.                 new.CancelButton = Button:Initialise(new.Width - 15, new.Height - 1, nil, nil, colours.white, new, function(self, side, x, y, toggle)
  2794.                         returnFunc(new, false)
  2795.                 end, 'Cancel', colours.black)
  2796.                 new.GoUpButton = Button:Initialise(2, new.Height - 1, nil, nil, colours.white, new, function(self, side, x, y, toggle)
  2797.                         local folderName = fs.getName(new.CurrentDirectory)
  2798.                         local parentDirectory = new.CurrentDirectory:sub(1, #new.CurrentDirectory-#folderName-1)
  2799.                         new:GoToDirectory(parentDirectory)
  2800.                 end, 'Go Up', colours.black)
  2801.                 new.PathTextBox = TextBox:Initialise(2, new.Height - 3, new.Width - 2, 1, new, '', colours.white, colours.black, function(key)
  2802.                         if key == keys.enter then
  2803.                                 new.SaveButton:Click()
  2804.                         end
  2805.                 end)
  2806.                 new.PathTextBox.Placeholder = 'Document Name'
  2807.                 Current.TextInput = new.PathTextBox.TextInput
  2808.                 new:GoToDirectory(new.CurrentDirectory)
  2809.                 return new
  2810.         end,
  2811.  
  2812.         Show = function(self)
  2813.                 Current.Window = self
  2814.                 return self
  2815.         end,
  2816.  
  2817.         Close = function(self)
  2818.                 Current.Input = nil
  2819.                 Current.Window = nil
  2820.                 self = nil
  2821.         end,
  2822.  
  2823.         GoToDirectory = function(self, path)
  2824.                 path = TidyPath(path)
  2825.                 self.CurrentDirectory = path
  2826.                 self.Scroll = 0
  2827.                 self.Typed = false
  2828.                 local fs = fs
  2829.                 if OneOS then
  2830.                         fs = OneOS.FS
  2831.                 end
  2832.                 self.Files = fs.list(self.CurrentDirectory)
  2833.                 Draw()
  2834.         end,
  2835.  
  2836.         Flash = function(self)
  2837.                 self.Visible = false
  2838.                 Draw()
  2839.                 sleep(0.15)
  2840.                 self.Visible = true
  2841.                 Draw()
  2842.                 sleep(0.15)
  2843.                 self.Visible = false
  2844.                 Draw()
  2845.                 sleep(0.15)
  2846.                 self.Visible = true
  2847.                 Draw()
  2848.         end,
  2849.  
  2850.         Click = function(self, side, x, y)
  2851.                 local items = {self.SaveButton, self.CancelButton, self.PathTextBox, self.GoUpButton}
  2852.                 local found = false
  2853.                 for i, v in ipairs(items) do
  2854.                         if CheckClick(v, x, y) then
  2855.                                 v:Click(side, x, y)
  2856.                                 found = true
  2857.                         end
  2858.                 end
  2859.  
  2860.                 if not found then
  2861.                         if y <= 11 then
  2862.                                 local files = fs.list(self.CurrentDirectory)
  2863.                                 if files[y-1] then
  2864.                                         self:GoToDirectory(self.CurrentDirectory..files[y-1])
  2865.                                         Draw()
  2866.                                 end
  2867.                         end
  2868.                 end
  2869.                 return true
  2870.         end
  2871. }
  2872.  
  2873. local WrapText = function(text, maxWidth)
  2874.         local lines = {''}
  2875.     for word, space in text:gmatch('(%S+)(%s*)') do
  2876.             local temp = lines[#lines] .. word .. space:gsub('\n','')
  2877.             if #temp > maxWidth then
  2878.                     table.insert(lines, '')
  2879.             end
  2880.             if space:find('\n') then
  2881.                     lines[#lines] = lines[#lines] .. word
  2882.                    
  2883.                     space = space:gsub('\n', function()
  2884.                             table.insert(lines, '')
  2885.                             return ''
  2886.                     end)
  2887.             else
  2888.                     lines[#lines] = lines[#lines] .. word .. space
  2889.             end
  2890.     end
  2891.         return lines
  2892. end
  2893.  
  2894. ButtonDialougeWindow = {
  2895.         X = 1,
  2896.         Y = 1,
  2897.         Width = 0,
  2898.         Height = 0,
  2899.         CursorPos = 1,
  2900.         Visible = true,
  2901.         CancelButton = nil,
  2902.         OkButton = nil,
  2903.         Lines = {},
  2904.  
  2905.         AbsolutePosition = function(self)
  2906.                 return {X = self.X, Y = self.Y}
  2907.         end,
  2908.  
  2909.         Draw = function(self)
  2910.                 if not self.Visible then
  2911.                         return
  2912.                 end
  2913.                 Drawing.DrawBlankArea(self.X + 1, self.Y+1, self.Width, self.Height, colours.grey)
  2914.                 Drawing.DrawBlankArea(self.X, self.Y, self.Width, 1, colours.lightGrey)
  2915.                 Drawing.DrawBlankArea(self.X, self.Y+1, self.Width, self.Height-1, colours.white)
  2916.                 Drawing.DrawCharactersCenter(self.X, self.Y, self.Width, 1, self.Title, colours.black, colours.lightGrey)
  2917.  
  2918.                 for i, text in ipairs(self.Lines) do
  2919.                         Drawing.DrawCharacters(self.X + 1, self.Y + 1 + i, text, colours.black, colours.white)
  2920.                 end
  2921.  
  2922.                 self.OkButton:Draw()
  2923.                 if self.CancelButton then
  2924.                         self.CancelButton:Draw()
  2925.                 end
  2926.         end,
  2927.  
  2928.         Initialise = function(self, title, message, okText, cancelText, returnFunc)
  2929.                 local new = {}    -- the new instance
  2930.                 setmetatable( new, {__index = self} )
  2931.                 new.Width = 28
  2932.                 new.Lines = WrapText(message, new.Width - 2)
  2933.                 new.Height = 5 + #new.Lines
  2934.                 new.Return = returnFunc
  2935.                 new.X = math.ceil((Drawing.Screen.Width - new.Width) / 2)
  2936.                 new.Y = math.ceil((Drawing.Screen.Height - new.Height) / 2)
  2937.                 new.Title = title
  2938.                 new.Visible = true
  2939.                 new.Visible = true
  2940.                 new.OkButton = Button:Initialise(new.Width - #okText - 2, new.Height - 1, nil, 1, nil, new, function()
  2941.                         returnFunc(new, true)
  2942.                 end, okText)
  2943.                 if cancelText then
  2944.                         new.CancelButton = Button:Initialise(new.Width - #okText - 2 - 1 - #cancelText - 2, new.Height - 1, nil, 1, nil, new, function()
  2945.                                 returnFunc(new, false)
  2946.                         end, cancelText)
  2947.                 end
  2948.  
  2949.                 return new
  2950.         end,
  2951.  
  2952.         Show = function(self)
  2953.                 Current.Window = self
  2954.                 return self
  2955.         end,
  2956.  
  2957.         Close = function(self)
  2958.                 Current.Window = nil
  2959.                 self = nil
  2960.         end,
  2961.  
  2962.         Flash = function(self)
  2963.                 self.Visible = false
  2964.                 Draw()
  2965.                 sleep(0.15)
  2966.                 self.Visible = true
  2967.                 Draw()
  2968.                 sleep(0.15)
  2969.                 self.Visible = false
  2970.                 Draw()
  2971.                 sleep(0.15)
  2972.                 self.Visible = true
  2973.                 Draw()
  2974.         end,
  2975.  
  2976.         Click = function(self, side, x, y)
  2977.                 local items = {self.OkButton, self.CancelButton}
  2978.                 local found = false
  2979.                 for i, v in ipairs(items) do
  2980.                         if CheckClick(v, x, y) then
  2981.                                 v:Click(side, x, y)
  2982.                                 found = true
  2983.                         end
  2984.                 end
  2985.                 return true
  2986.         end
  2987. }
  2988.  
  2989. TextDialougeWindow = {
  2990.         X = 1,
  2991.         Y = 1,
  2992.         Width = 0,
  2993.         Height = 0,
  2994.         CursorPos = 1,
  2995.         Visible = true,
  2996.         CancelButton = nil,
  2997.         OkButton = nil,
  2998.         Lines = {},
  2999.         TextInput = nil,
  3000.  
  3001.         AbsolutePosition = function(self)
  3002.                 return {X = self.X, Y = self.Y}
  3003.         end,
  3004.  
  3005.         Draw = function(self)
  3006.                 if not self.Visible then
  3007.                         return
  3008.                 end
  3009.                 Drawing.DrawBlankArea(self.X + 1, self.Y+1, self.Width, self.Height, colours.grey)
  3010.                 Drawing.DrawBlankArea(self.X, self.Y, self.Width, 1, colours.lightGrey)
  3011.                 Drawing.DrawBlankArea(self.X, self.Y+1, self.Width, self.Height-1, colours.white)
  3012.                 Drawing.DrawCharactersCenter(self.X, self.Y, self.Width, 1, self.Title, colours.black, colours.lightGrey)
  3013.  
  3014.                 for i, text in ipairs(self.Lines) do
  3015.                         Drawing.DrawCharacters(self.X + 1, self.Y + 1 + i, text, colours.black, colours.white)
  3016.                 end
  3017.  
  3018.  
  3019.                 Drawing.DrawBlankArea(self.X + 1, self.Y + self.Height - 4, self.Width - 2, 1, colours.lightGrey)
  3020.                 Drawing.DrawCharacters(self.X + 2, self.Y + self.Height - 4, self.TextInput.Value, colours.black, colours.lightGrey)
  3021.                 Current.CursorPos = {self.X + 2 + self.TextInput.CursorPos, self.Y + self.Height - 4}
  3022.                 Current.CursorColour = colours.black
  3023.  
  3024.                 self.OkButton:Draw()
  3025.                 if self.CancelButton then
  3026.                         self.CancelButton:Draw()
  3027.                 end
  3028.         end,
  3029.  
  3030.         Initialise = function(self, title, message, okText, cancelText, returnFunc, numerical)
  3031.                 local new = {}    -- the new instance
  3032.                 setmetatable( new, {__index = self} )
  3033.                 new.Width = 28
  3034.                 new.Lines = WrapText(message, new.Width - 2)
  3035.                 new.Height = 7 + #new.Lines
  3036.                 new.Return = returnFunc
  3037.                 new.X = math.ceil((Drawing.Screen.Width - new.Width) / 2)
  3038.                 new.Y = math.ceil((Drawing.Screen.Height - new.Height) / 2)
  3039.                 new.Title = title
  3040.                 new.Visible = true
  3041.                 new.Visible = true
  3042.                 new.OkButton = Button:Initialise(new.Width - #okText - 2, new.Height - 1, nil, 1, nil, new, function()
  3043.                         if #new.TextInput.Value > 0 then
  3044.                                 returnFunc(new, true, new.TextInput.Value)
  3045.                         end
  3046.                 end, okText)
  3047.                 if cancelText then
  3048.                         new.CancelButton = Button:Initialise(new.Width - #okText - 2 - 1 - #cancelText - 2, new.Height - 1, nil, 1, nil, new, function()
  3049.                                 returnFunc(new, false)
  3050.                         end, cancelText)
  3051.                 end
  3052.                 new.TextInput = TextInput:Initialise('', function(enter)
  3053.                         if enter then
  3054.                                 new.OkButton:Click()
  3055.                         end
  3056.                         Draw()
  3057.                 end, numerical)
  3058.  
  3059.                 Current.Input = new.TextInput
  3060.  
  3061.                 return new
  3062.         end,
  3063.  
  3064.         Show = function(self)
  3065.                 Current.Window = self
  3066.                 return self
  3067.         end,
  3068.  
  3069.         Close = function(self)
  3070.                 Current.Window = nil
  3071.                 Current.Input = nil
  3072.                 self = nil
  3073.         end,
  3074.  
  3075.         Flash = function(self)
  3076.                 self.Visible = false
  3077.                 Draw()
  3078.                 sleep(0.15)
  3079.                 self.Visible = true
  3080.                 Draw()
  3081.                 sleep(0.15)
  3082.                 self.Visible = false
  3083.                 Draw()
  3084.                 sleep(0.15)
  3085.                 self.Visible = true
  3086.                 Draw()
  3087.         end,
  3088.  
  3089.         Click = function(self, side, x, y)
  3090.                 local items = {self.OkButton, self.CancelButton}
  3091.                 local found = false
  3092.                 for i, v in ipairs(items) do
  3093.                         if CheckClick(v, x, y) then
  3094.                                 v:Click(side, x, y)
  3095.                                 found = true
  3096.                         end
  3097.                 end
  3098.                 return true
  3099.         end
  3100. }
  3101.  
  3102. function PrintCentered(text, y)
  3103.     local w, h = term.getSize()
  3104.     x = math.ceil(math.ceil((w / 2) - (#text / 2)), 0)+1
  3105.     term.setCursorPos(x, y)
  3106.     print(text)
  3107. end
  3108.  
  3109. function DoVanillaClose()
  3110.         term.setBackgroundColour(colours.black)
  3111.         term.setTextColour(colours.white)
  3112.         term.clear()
  3113.         term.setCursorPos(1, 1)
  3114.         PrintCentered("Thanks for using Ink!", (Drawing.Screen.Height/2)-1)
  3115.         term.setTextColour(colours.lightGrey)
  3116.         PrintCentered("Word Proccessor for ComputerCraft", (Drawing.Screen.Height/2))
  3117.         term.setTextColour(colours.white)
  3118.         PrintCentered("(c) oeed 2014", (Drawing.Screen.Height/2)+3)
  3119.         term.setCursorPos(1, Drawing.Screen.Height)
  3120.         error('', 0)
  3121. end
  3122.  
  3123. function Close()
  3124.         if isQuitting or not Current.Document or not Current.Modified then
  3125.                 if not OneOS then
  3126.                         DoVanillaClose()
  3127.                 end
  3128.                 return true
  3129.         else
  3130.                 local _w = ButtonDialougeWindow:Initialise('Quit Ink?', 'You have unsaved changes, do you want to quit anyway?', 'Quit', 'Cancel', function(window, success)
  3131.                         if success then
  3132.                                 if OneOS then
  3133.                                         OneOS.Close(true)
  3134.                                 else
  3135.                                         DoVanillaClose()
  3136.                                 end
  3137.                         end
  3138.                         window:Close()
  3139.                         Draw()
  3140.                 end):Show()
  3141.                 --it's hacky but it works
  3142.                 os.queueEvent('mouse_click', 1, _w.X, _w.Y)
  3143.                 return false
  3144.         end
  3145. end
  3146.  
  3147. if OneOS then
  3148.         OneOS.CanClose = function()
  3149.                 return Close()
  3150.         end
  3151. end
  3152.  
  3153. Initialise()
RAW Paste Data
We use cookies for various purposes including analytics. By continuing to use Pastebin, you agree to our use of cookies as described in the Cookies Policy. OK, I Understand
 
Top