Advertisement
Guest User

SublimeText

a guest
Mar 8th, 2014
296
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 59.41 KB | None | 0 0
  1.    
  2.  
  3.     --WARNING: THIS PROGRAM IS MADE BY JENS KOLBINGER!!!
  4.     --         SEND ALL YOU WANT TO TELL ME ABOUT THIS PROGRAM TO jens.software@gmail.com
  5.      
  6.     platform.apilevel='1.0'
  7.      
  8.     __mG={}    --my globals! Dont overwrite them!
  9.     __mG.version="1.0.2"
  10.     __mG.on={}
  11.     __mG.WW=318    --WindowWidth
  12.     __mG.WH=212    --WindowHeight
  13.     __mG.maxChars=36
  14.     __mG.maxLines=12
  15.     __mG.chrS={25,2,8,15}    --1: posX of first character / 2: posY of first character / 3: width of each character / 4: height of each character
  16.     __mG.nl=string.char(10)
  17.     __mG.dialogue=false
  18.     __mG.dialogueVar={}
  19.     __mG.dialogueField=1
  20.     __mG.skriptName=""
  21.     __mG.code={""}
  22.     __mG.scroll={1,1}
  23.     __mG.coursor={1,1}
  24.     __mG.selection={}
  25.     __mG.mouseDown=false
  26.     __mG.updatedLines=nil
  27.     __mG.ERRline=nil
  28.     __mG.ERR=nil
  29.     __mG.font="serif"
  30.     __mG.moveOK=true
  31.     __mG.chrOffset={}
  32.     __mG.colDsp=platform.isColorDisplay()
  33.     __mG.calcLayout="touch"
  34.     __mG.markSyntax=true
  35.     __mG.message = class()
  36.     __mG.state={}    --state[__mG.stateNo].before/after = {lineStart,lineEnd,{"line at lineStart",...,"line at lineEnd},{cursor position x,y}}
  37.     __mG.stateNo=0    --current position in state history (min 0, max 10)
  38.      
  39.     function __mG.message:reset()
  40.         function __mG.message:action() end
  41.         __mG.message.show=false
  42.         __mG.message.selButton=1
  43.         __mG.text={}
  44.     end
  45.     __mG.message:reset()
  46.      
  47.     function __mG.copy_table(t)
  48.             local t2 = {}
  49.             for k,v in pairs(t) do
  50.                 if type(v)=="table" then v=__mG.copy_table(v) end
  51.                     t2[k] = v
  52.             end
  53.             return t2
  54.     end
  55.      
  56.     __mG.fileList={}    --Table that indicates if a file with name n already exists: __mG.fileList["test"]=true if the file "test" exists
  57.     __mG.repChr={}    --replace character(s)
  58.      
  59.     __mG.repChr["touch"]={}
  60.      
  61.     --basic universial functions
  62.     __mG.repChr["touch"]["−"]=":"    --key [(-)]
  63.     __mG.repChr["touch"]["≥"]=">="
  64.     __mG.repChr["touch"]["≤"]="<="
  65.     __mG.repChr["touch"]["≠"]="~="
  66.     __mG.repChr["touch"]["√"]="math.sqrt("
  67.     for i, name in pairs({"sin(","cos(","tan("}) do __mG.repChr["touch"][name]="math."..name end
  68.     __mG.repChr["touch"]["sin("]="math.asin("
  69.     __mG.repChr["touch"]["cos("]="math.acos("
  70.     __mG.repChr["touch"]["tan("]="math.atan("
  71.     __mG.repChr["touch"]["π"]="math.pi"
  72.      
  73.     --special functions for clickpad
  74.     __mG.repChr["click"]=__mG.copy_table(__mG.repChr["touch"])
  75.     __mG.repChr["click"]["cos("]="["
  76.     __mG.repChr["click"]["tan("]="]"
  77.     __mG.repChr["click"]["cos("]="{"
  78.     __mG.repChr["click"]["tan("]="}"
  79.     __mG.repChr["click"]["exp("]="math.exp("
  80.     __mG.repChr["click"]["ln("]="math.log10("
  81.     __mG.repChr["click"]["log("]="math.log("
  82.     __mG.repChr["click"][""]="~"    --that i button below the > button
  83.      
  84.     --special functions for touchpad
  85.     __mG.repChr["touch"]["exp("]="["
  86.     __mG.repChr["touch"]["10^("]="]"
  87.     __mG.repChr["touch"]["ln("]="{"
  88.     __mG.repChr["touch"]["log("]="}"
  89.      
  90.     __mG.wordRGB={}
  91.     __mG.wordRGB["--"]={128,128,128}
  92.     for i, word in pairs({"'",'"',"[[","]]"}) do
  93.         if __mG.colDsp then
  94.             __mG.wordRGB[word]={230,219,116}
  95.         else
  96.             __mG.wordRGB[word]={110,110,110}
  97.         end
  98.     end
  99.     for i, word in pairs({"nil","true","false"}) do
  100.         if __mG.colDsp then
  101.             __mG.wordRGB[word]={140,0,220}
  102.         else
  103.             __mG.wordRGB[word]={110,110,110}
  104.         end
  105.     end
  106.     for i, word in pairs({"function","return","end","for","in","do","if","then","else","elseif","while","and","or","not","local","repeat","break"}) do
  107.         if __mG.colDsp then
  108.             __mG.wordRGB[word]={249,38,114}
  109.         else
  110.             __mG.wordRGB[word]={80,80,80}
  111.         end
  112.     end
  113.     for i, word in pairs({"/","*","-","+","="}) do
  114.         if __mG.colDsp then
  115.             __mG.wordRGB[word]={249,38,114}
  116.         else
  117.             __mG.wordRGB[word]={80,80,80}
  118.         end
  119.     end
  120.     for i, word in pairs({"assert","collectgarbage","error","_G","getfenv","getmetatable","ipairs","load","loadstring","next","pairs","pcall","print","rawequal","rawget","rawset","select","setfenv","setmetatable","tonumber","tostring","type","unpack","_VERSION","xpcall","require","class"}) do
  121.         if __mG.colDsp then
  122.             __mG.wordRGB[word]={96,217,228}
  123.         else
  124.             __mG.wordRGB[word]={170,170,170}
  125.         end
  126.     end
  127.      
  128.     function __mG.createMenu()
  129.         __mG.fileList={}    
  130.         local loadMenu={"Load"}
  131.         local files=var.recall("JSEFiles")    --List of all saved files as string
  132.         if not files or files=="" then    
  133.             __mG.fileList={}
  134.         else
  135.             files=files:split("§")    --list as string to table
  136.             for i, fileName in pairs(files) do
  137.                 if fileName and fileName~="" then
  138.                     __mG.fileList[fileName]=true
  139.                     table.insert(loadMenu,{fileName,__mG_translateMenu})
  140.                 end
  141.             end
  142.         end
  143.         __mG.menu = {
  144.             {"Code",
  145.                 {"Run", __mG_translateMenu},
  146.                 {"Undo   (ctrl+del)", __mG_translateMenu},
  147.                 {"Redo   (ctrl+menu)", __mG_translateMenu},
  148.                 {"Copy   (ctrl+C)",__mG.on.copy},
  149.                 {"Paste  (ctrl+V)",__mG.on.paste},
  150.                 {"Select all", __mG_translateMenu},
  151.                 {"Import from library...", __mG_translateMenu}
  152.             },
  153.             {"Insert",
  154.                 {"platform.window:invalidate()", __mG_translateMenu},
  155.                 {"if...then", __mG_translateMenu},
  156.                 {"for...do", __mG_translateMenu},
  157.                 {"function", __mG_translateMenu},
  158.                 {"gc:setColorRGB(", __mG_translateMenu},
  159.                 {"gc:drawString(", __mG_translateMenu},
  160.                 {"gc:drawLine(", __mG_translateMenu},
  161.                 {"gc:fillRect(", __mG_translateMenu},
  162.                 {"gc:drawRect(", __mG_translateMenu},
  163.             },  
  164.             {"File",
  165.                 {"New", __mG_translateMenu},
  166.                 {"Save", __mG_translateMenu},
  167.                 {"Save as...", __mG_translateMenu},
  168.                 {"Delete", __mG_translateMenu}
  169.             },
  170.             __mG.copy_table(loadMenu),
  171.             {"View",
  172.                 {"Go to top", __mG_translateMenu},
  173.                 {"Go to end", __mG_translateMenu},
  174.                 {"Go to line...", __mG_translateMenu},
  175.                 {"Change font", __mG_translateMenu},
  176.                 {"Toggle syntax marking", __mG_translateMenu},
  177.             },
  178.             {"Controls",
  179.                 {"nspire with touchpad", __mG_translateMenu},
  180.                 {"nspire with clickpad", __mG_translateMenu},
  181.                 {"no button rebingings", __mG_translateMenu},
  182.             },
  183.             {"Help",
  184.                 {"Help", __mG_translateMenu},
  185.                 {"About", __mG_translateMenu}
  186.             }
  187.         }
  188.         toolpalette.register(__mG.menu)
  189.     end
  190.      
  191.     function __mG.resetEditor()
  192.         __mG.message:reset()
  193.         __mG.dialogue=false
  194.         __mG.skriptName=""
  195.         __mG.code={""}
  196.         __mG.coursor={1,1}
  197.         __mG.scroll={1,1}
  198.     end
  199.      
  200.     function __mG_translateMenu(box,item)
  201.         if box=="Load" then
  202.             local code=var.recall("JSEF"..item)
  203.             if code then
  204.                 __mG.message.show=true
  205.                 __mG.message.text={"Warning!","When you load a file, the current","code will be lost (if not saved).","","Do you want to continue anyways?","","","Continue with [enter]        Cancel with [esc]"}
  206.                 function __mG.message:action()
  207.                     __mG.resetEditor()
  208.                     __mG.skriptName=item
  209.                     __mG.code=code:split(__mG.nl)
  210.                 end
  211.             end
  212.         elseif box=="Insert" then
  213.             local function addEnd(firstLine)
  214.                 local space=""
  215.                 for i=1, __mG.coursor[1]-1 do
  216.                     space=space.." "
  217.                 end
  218.                 return firstLine..__mG.nl..space..__mG.nl..space.."end"
  219.             end
  220.             local coursorPos={unpack(__mG.coursor)}
  221.             if item=="if...then" then
  222.                 item=addEnd("if  then")
  223.                 __mG.insertText(item)
  224.                 __mG.coursor={coursorPos[1]+3,coursorPos[2]}
  225.             elseif item=="for...do" then
  226.                 item=addEnd("for  do")
  227.                 __mG.insertText(item)
  228.                 __mG.coursor={coursorPos[1]+4,coursorPos[2]}
  229.             elseif item=="function" then
  230.                 item=addEnd("function ()")
  231.                 __mG.insertText(item)
  232.                 __mG.coursor={coursorPos[1]+9,coursorPos[2]}
  233.             end
  234.             __mG.adjustScroll()
  235.         elseif item=="New" then
  236.             __mG.message.show=true
  237.             __mG.message.text={"Warning!","When you create a new file, the current","code will be lost (if not saved).","","Do you want to continue anyways?","","","Continue with [enter]        Cancel with [esc]"}
  238.             function __mG.message:action()
  239.                 __mG.resetEditor()
  240.             end
  241.         elseif item=="Save" then
  242.             if not __mG.skriptName or __mG.skriptName=="" then
  243.                 __mG.dialogue="inputName"
  244.                 __mG.dialogueVar={__mG.skriptName}
  245.             else
  246.                 __mG.saveAs(__mG.skriptName)
  247.             end
  248.         elseif item=="Save as..." then
  249.             __mG.dialogue="inputName"
  250.             __mG.dialogueVar={__mG.skriptName}
  251.         elseif box=="Controls" then
  252.             if item=="nspire with touchpad" then
  253.                 __mG.calcLayout="touch"
  254.             elseif item=="nspire with clickpad" then
  255.                 __mG.calcLayout="click"
  256.             elseif item=="no button rebingings" then
  257.                 __mG.calcLayout="none"
  258.             end
  259.             math.eval("DelVar JSElayout")
  260.             var.store("JSElayout", __mG.calcLayout)
  261.             document.markChanged()
  262.         elseif item=="Delete" then
  263.             __mG.message.show=true
  264.             __mG.message.text={"Delete?","Do you really want to delete the current file:","'"..__mG.skriptName.."' ?","","","","","Continue with [enter]        Cancel with [esc]"}
  265.             function __mG.message:action()
  266.                 math.eval("DelVar JSEF"..__mG.skriptName)
  267.                 __mG.fileList[__mG.skriptName]=false
  268.                 __mG.saveFileList()
  269.                 __mG.createMenu()
  270.             end
  271.         elseif item=="Run" then
  272.             if var.recall("JSEshowInfo")~="NO" then
  273.                 __mG.message.show=true
  274.                 __mG.message.text={"Info!","Stop the running code with the [EE] key on","the left!","Better save your code before running it!","","Press [tab] to continue and never show","this info again!","Continue with [enter]        Cancel with [esc]"}
  275.                 function __mG.message:action()
  276.                     __mG.runCode()
  277.                 end
  278.                 platform.window:invalidate()
  279.             else
  280.                 __mG.runCode()
  281.             end
  282.         elseif item=="Undo   (ctrl+del)" then
  283.             __mG.undo()
  284.         elseif item=="Redo   (ctrl+menu)" then
  285.             __mG.redo()
  286.         elseif item=="Go to top" then
  287.             __mG.coursor={1,1}
  288.             __mG.adjustScroll()
  289.         elseif item=="Go to end" then
  290.             __mG.coursor[2]=#__mG.code
  291.             __mG.coursor[1]=__mG.code[__mG.coursor[2]]:len()
  292.             __mG.adjustScroll()
  293.         elseif item=="Go to line..." then
  294.             __mG.dialogue="gotoLine"
  295.             __mG.dialogueVar={""}
  296.         elseif item=="Change font" then
  297.             if __mG.font=="sansserif" then __mG.font="serif"
  298.             else __mG.font="sansserif" end
  299.             math.eval("DelVar JSEfont")
  300.             var.store("JSEfont",__mG.font)
  301.             document.markChanged()
  302.             __mG.initialChrOff()
  303.         elseif item=="Toggle syntax marking" then
  304.             __mG.markSyntax=not __mG.markSyntax
  305.             math.eval("DelVar JSEmarkSyntax")
  306.             var.store("JSEmarkSyntax", tostring(__mG.markSyntax))
  307.             document.markChanged()
  308.         elseif item=="Select all" then
  309.             __mG.selection[1]={1,1}
  310.             __mG.selection[2]={__mG.code[#__mG.code]:len()+1,#__mG.code}
  311.             __mG.coursor=__mG.copy_table(__mG.selection[2])
  312.             __mG.adjustScroll()
  313.             platform.window:invalidate()
  314.         elseif item=="Import from library..." then
  315.             __mG.dialogue="importFromLibrary"
  316.             __mG.dialogueVar={"",""}
  317.             __mG.dialogueField=1
  318.         elseif item=="Help" then
  319.             __mG.message.show=true
  320.             if __mG.calcLayout=="touch" then
  321.                 __mG.message.text={"Help","Run your program with 'Code'==>'Run'. Stop","running program with the [EE] key on the","left! Ctrl+click and move around to select","code. There are several rebound buttons:","e^x==>[    10^x==>]    ln==>{    log==>}","(-)==>:      Switch calc-layout in 'Controls'!","Close with [esc]"}
  322.             else
  323.                 __mG.message.text={"Help","Run your program with 'Code'==>'Run'. Stop","running program with the [EE] key on the","left! Ctrl+click and move around to select","code. There are several rebound buttons:","cos==>[    tan==>]    cos==>{    tan==>}","==>~ Switch calculator layout in 'Controls'!","Close with [esc]"}
  324.             end
  325.         elseif item=="About" then
  326.             __mG.message.show=true
  327.             __mG.message.text={"About","This is Jens' Script Editor "..__mG.version.." by","Jens Kolbinger","Inspired by 'oclua' by Olivier Armand.","Special thanks to the omnimaga user","adriweb who helped me with iPad","compatibility.","Any feedback to jens.software@gmail.com"}
  328.         end
  329.         platform.window:invalidate()
  330.     end
  331.      
  332.     function __mG.on.create()
  333.         __mG.createMenu()
  334.         local font=var.recall("JSEfont")
  335.         if font=="serif" then
  336.             __mG.font="serif"
  337.         elseif font=="sansserif" then
  338.             __mG.font="sansserif"
  339.         end
  340.         __mG.initialChrOff()
  341.         local layout=var.recall("JSElayout")
  342.         if layout=="touch" then
  343.             __mG.calcLayout="touch"
  344.         elseif layout=="click" then
  345.             __mG.calcLayout="click"
  346.         elseif layout=="none" then
  347.             __mG.calcLayout="none"
  348.         end
  349.         local markSyntax=var.recall("JSEmarkSyntax")
  350.         if markSyntax=="true" then
  351.             __mG.markSyntax=true
  352.         elseif markSyntax=="false" then
  353.             __mG.markSyntax=false
  354.         end
  355.     end
  356.      
  357.     function __mG.initialChrOff()
  358.         --rendering is much faster if you calculate every characters position before rendering them!
  359.         __mG.chrOffset={}
  360.         local function init(gc)
  361.             gc:setFont(__mG.font,"r",10)
  362.             for i=33,126 do    --all displayable characters
  363.                 __mG.chrOffset[string.uchar(i)]=math.floor(4-gc:getStringWidth(string.uchar(i))/2+0.5)
  364.             end
  365.         end
  366.         if platform.withGC then
  367.             platform.withGC(init)
  368.         else
  369.             local gc
  370.             gc=platform.gc()
  371.             gc:begin()
  372.             init(gc)
  373.             gc:finish()
  374.         end
  375.         if __mG.font=="serif" then
  376.             for i, chr in pairs({"i","j","l","m","W","E","T","Z","I","L","M","(",")","{","}","-","?","&","+","^"}) do
  377.                 __mG.chrOffset[chr]=__mG.chrOffset[chr]+1
  378.             end
  379.         else
  380.             for i, chr in pairs({"T","W","^","<","=",">","}","+",",",";"}) do
  381.                 __mG.chrOffset[chr]=__mG.chrOffset[chr]+1
  382.             end
  383.         end
  384.     end
  385.      
  386.     function __mG.saveFileList()
  387.         local fileListStr=""
  388.         for name, bool in pairs(__mG.fileList) do
  389.             if bool then
  390.                 fileListStr=fileListStr..name.."§"
  391.             end
  392.         end
  393.         math.eval("DelVar JSEFiles")
  394.         var.store("JSEFiles", fileListStr)
  395.         document.markChanged()
  396.     end
  397.      
  398.     function __mG.saveAs(skriptName)
  399.         __mG.fileList[skriptName]=true
  400.         __mG.saveFileList()
  401.         math.eval("DelVar "..skriptName)
  402.         var.store("JSEF"..skriptName, __mG.arrToStr(__mG.code))
  403.         __mG.createMenu()
  404.         document.markChanged()
  405.     end
  406.      
  407.     function __mG.on.help()
  408.         __mG_translateMenu("Help","Help")
  409.     end
  410.      
  411.     function __mG.arrToStr(arr)
  412.         local str=""
  413.         for i=1, #arr do
  414.             if i<#arr then
  415.                 str=str..arr[i]..__mG.nl
  416.             else
  417.                 str=str..arr[i]
  418.             end
  419.         end
  420.         return str
  421.     end
  422.      
  423.     function __mG.insert(str,i,insertion)
  424.         return str:sub(0,i-1)..insertion..str:sub(i,str:len())
  425.     end
  426.      
  427.     function __mG.onError()
  428.         print(__mG.ERR)
  429.         local errArr=__mG.ERR:split(":")
  430.         __mG.ERRline=tonumber(errArr[#errArr-1])
  431.         __mG.ERR=errArr[#errArr]
  432.         __mG.reloadSEHandlers()
  433.     end
  434.      
  435.     __mG.oldTPregister=toolpalette.register
  436.     function __mG.touchTPregister(menu)
  437.         local scriptMenu={"Script Editor",{"Return",__mG.reloadSEHandlers}}
  438.         if touch and touch.isKeyboardAvailable() then
  439.             table.insert(scriptMenu,{"Keyboard Up",__mG.translateScriptMenu})
  440.             table.insert(scriptMenu,{"Keyboard Down",__mG.translateScriptMenu})
  441.         end
  442.         table.insert(menu,scriptMenu)
  443.         __mG.oldTPregister(menu)
  444.     end
  445.      
  446.     function __mG.translateScriptMenu(box,item)
  447.         if item=="Keyboard Up" then
  448.             touch.showKeyboard(true)
  449.         elseif item=="Keyboard Down" then
  450.             touch.showKeyboard(false)
  451.         end
  452.     end
  453.      
  454.     function __mG.runCode()
  455.         timer.stop()
  456.         __mG.ERR = nil
  457.         __mG.ERRline=nil
  458.         local codeStr=__mG.arrToStr(__mG.code)
  459.         local chunk, errload = loadstring(codeStr)
  460.         if not chunk then
  461.             __mG.ERR = errload
  462.             __mG.onError()
  463.         else
  464.             on = {}
  465.             if platform.isTabletModeRendering and platform.isTabletModeRendering() then
  466.                 toolpalette.register = __mG.touchTPregister
  467.             end
  468.             toolpalette.register({})
  469.             cursor.set("default")
  470.             local status, errcall = pcall(chunk)
  471.             if not status then
  472.                 __mG.ERR = errcall
  473.                 __mG.onError()
  474.                 return
  475.             end
  476.             for name, funct in pairs(on) do    --make every function save!
  477.                 if funct then
  478.                     on[name]=function(v1,v2,v3,v4,v5)
  479.                         local status, errcall = pcall(function() funct(v1,v2,v3,v4,v5) end)
  480.                         if not status then
  481.                             __mG.ERR = errcall
  482.                             __mG.onError()
  483.                             return
  484.                         end
  485.                     end
  486.                 end
  487.             end
  488.             if not __mG.ERR then
  489.                 local userCharIn=on.charIn
  490.                 function on.charIn(chr,v2,v3,v4,v5)
  491.                     if chr=="" then    --that EE button thing
  492.                         __mG.reloadSEHandlers()
  493.                     else
  494.                         if userCharIn then
  495.                             userCharIn(chr,v2,v3,v4,v5)
  496.                         end
  497.                     end
  498.                 end
  499.                 if on.construction then on.construction() end
  500.                 if on.resize then on.resize(platform.window:width(),platform.window:height()) end
  501.                 if on.activate then on.activate() end
  502.                 if on.getFocus then on.getFocus() end
  503.                 if on.create then on.create() end
  504.             end
  505.             platform.window:invalidate()
  506.         end
  507.     end
  508.      
  509.     function __mG.validSel(oldSel)  
  510.         if not oldSel then return false end
  511.         if not (oldSel[1] and oldSel[2]) then
  512.             return false
  513.         end
  514.         local newSel=__mG.copy_table(oldSel)
  515.         if oldSel[1][2]==oldSel[2][2] then
  516.             if oldSel[1][1]==oldSel[2][1] then
  517.                 return false
  518.             elseif oldSel[1][1]>oldSel[2][1] then
  519.                 newSel[1][1]=oldSel[2][1]
  520.                 newSel[2][1]=oldSel[1][1]
  521.             end
  522.         elseif oldSel[1][2]>oldSel[2][2] then
  523.             newSel[1]=__mG.copy_table(oldSel[2])
  524.             newSel[2]=__mG.copy_table(oldSel[1])
  525.         end
  526.         return newSel
  527.     end
  528.      
  529.     function __mG.on.grabDown()
  530.         if __mG.selection[1] then
  531.             if __mG.selection[2] then
  532.                 __mG.selection={}
  533.             else
  534.                 __mG.selection[2]=__mG.copy_table(__mG.coursor)
  535.             end
  536.         else
  537.             __mG.selection[1]=__mG.copy_table(__mG.coursor)
  538.         end
  539.         platform.window:invalidate()
  540.     end
  541.      
  542.     function __mG.getSelAsStr()
  543.         local newSel=__mG.validSel(__mG.selection)
  544.         if newSel then
  545.             local text=""
  546.             if newSel[1][2]==newSel[2][2] then
  547.                 text = __mG.code[newSel[1][2]]:sub(newSel[1][1],newSel[2][1]-1)
  548.             else
  549.                 local firstLine = __mG.code[newSel[1][2]]
  550.                 text = firstLine:sub(newSel[1][1],firstLine:len())
  551.                 if newSel[2][2]-newSel[1][2]>1 then
  552.                     for l=newSel[1][2]+1, newSel[2][2]-1 do
  553.                         text=text..__mG.nl..__mG.code[l]
  554.                     end
  555.                 end
  556.                 local lastLine=__mG.code[newSel[2][2]]
  557.                 text=text..__mG.nl..lastLine:sub(1,newSel[2][1]-1)
  558.             end
  559.             return text
  560.         else
  561.             return ""
  562.         end
  563.     end
  564.      
  565.     function __mG.on.copy()
  566.         local markLine=false
  567.         if __mG.selection[1] then
  568.             if __mG.selection[2] then
  569.                 if __mG.selection[2][2]==__mG.selection[1][2] and __mG.selection[2][1]==__mG.selection[1][1] then
  570.                     markLine=true
  571.                 end
  572.             else    
  573.                 markLine=true
  574.             end
  575.         else
  576.             markLine=true
  577.         end
  578.         if markLine then
  579.             local line=__mG.code[__mG.coursor[2]]
  580.             __mG.selection={{1,__mG.coursor[2]},{line:len()+1,__mG.coursor[2]}}
  581.             platform.window:invalidate()
  582.         end
  583.         local copyStr=__mG.getSelAsStr()
  584.         if copyStr and copyStr:len()>0 then
  585.             clipboard.addText(copyStr)
  586.         end
  587.     end
  588.      
  589.     function __mG.on.cut()
  590.         __mG.on.copy()
  591.         __mG.on.backspaceKey()
  592.     end
  593.      
  594.     function __mG.insertText(text)
  595.         if text and text~=""then
  596.             local state={}
  597.             state.before=__mG.createState("coursor")
  598.             text=text:split(__mG.nl)
  599.             if #text==1 then
  600.                 __mG.code[__mG.coursor[2]]=__mG.insert(__mG.code[__mG.coursor[2]],__mG.coursor[1],text[1])
  601.                 __mG.coursor[1]=__mG.coursor[1]+text[1]:len()
  602.                 state.after = __mG.createState("coursor")
  603.             else
  604.                 state.after = {__mG.coursor[2],__mG.coursor[2],{}}
  605.                 local oldLine = __mG.code[__mG.coursor[2]]
  606.                 local leftOfC = oldLine:sub(1,__mG.coursor[1]-1)
  607.                 local rightOfC = oldLine:sub(__mG.coursor[1],oldLine:len())
  608.                 __mG.code[__mG.coursor[2]]=leftOfC..text[1]
  609.                 table.insert(state.after[3], __mG.code[__mG.coursor[2]])
  610.                 table.remove(text,1)
  611.                 for i, line in pairs(text) do
  612.                     __mG.coursor={1,__mG.coursor[2]+1}
  613.                     table.insert(__mG.code, __mG.coursor[2], line)
  614.                     table.insert(state.after[3], line)
  615.                     state.after[2]=state.after[2]+1
  616.                 end
  617.                 __mG.coursor[1]=__mG.code[__mG.coursor[2]]:len()+1
  618.                 __mG.code[__mG.coursor[2]]=__mG.code[__mG.coursor[2]]..rightOfC
  619.                 state.after[3][#state.after[3]]=__mG.code[__mG.coursor[2]]
  620.                 state.after[4]=__mG.copy_table(__mG.coursor)
  621.             end
  622.             __mG.adjustScroll()
  623.             platform.window:invalidate()
  624.             __mG.registerState(state)
  625.         end
  626.     end
  627.      
  628.     function __mG.on.paste()
  629.         local text=clipboard.getText()
  630.         if __mG.selection[1] and __mG.selection[2] then
  631.             __mG.on.backspaceKey()
  632.         end
  633.         __mG.insertText(text)
  634.     end
  635.        
  636.     function __mG.on.escapeKey()
  637.         if __mG.message.show then
  638.             __mG.message:reset()
  639.         elseif __mG.dialogue then
  640.             __mG.dialogue=false
  641.             __mG.dialogueVar={}
  642.         elseif __mG.selection[1] then
  643.             __mG.selection={}
  644.         end
  645.         platform.window:invalidate()
  646.     end
  647.      
  648.     function __mG.on.enterKey()
  649.         if __mG.message.show then
  650.             __mG.message:action()
  651.             __mG.message:reset()
  652.             platform.window:invalidate()
  653.             return
  654.         elseif __mG.dialogue=="inputName" then
  655.             if __mG.dialogueVar[1]:len()>0 then
  656.                 if __mG.fileList[__mG.dialogueVar[1]] then
  657.                     __mG.message.show=true
  658.                     __mG.message.text={"File already exists!","There is already a file with the name:","'"..__mG.dialogueVar[1].."'","","Do you want to overwrite it?","","","Continue with [enter]        Cancel with [esc]"}
  659.                     function __mG.message:action()
  660.                         __mG.skriptName=__mG.dialogueVar[1]
  661.                         __mG.saveAs(__mG.skriptName)
  662.                         __mG.dialogue=false
  663.                         platform.window:invalidate()
  664.                     end
  665.                 else
  666.                     __mG.skriptName=__mG.dialogueVar[1]
  667.                     __mG.saveAs(__mG.skriptName)
  668.                     __mG.dialogue=false
  669.                 end
  670.                 platform.window:invalidate()
  671.             end
  672.             return
  673.         elseif __mG.dialogue=="gotoLine" then
  674.             if __mG.dialogueVar[1]:len()>0 then
  675.                 local line=math.max(math.min(tonumber(__mG.dialogueVar[1]),#__mG.code),1)
  676.                 __mG.coursor={1,line}
  677.                 __mG.adjustScroll()
  678.                 __mG.dialogue=false
  679.                 __mG.dialogueVar={}
  680.                 platform.window:invalidate()
  681.             end
  682.             return
  683.         elseif __mG.dialogue=="importFromLibrary" then
  684.             if __mG.dialogueVar[2]:len()<1 then
  685.                 __mG.dialogueField=2
  686.             elseif __mG.dialogueVar[1]:len()>0 then
  687.                 local text, err = var.recall(__mG.dialogueVar[1].."\\"..__mG.dialogueVar[2])
  688.                 if err then
  689.                     print(text, err)
  690.                     __mG.message.show=true
  691.                     __mG.message.text={"Error importing from library!","There was an error while loading the","requested variable!",'Check if the file "'..__mG.dialogueVar[1]..'.tns"','is in the folder "MyLib" and contains the','variable "'..__mG.dialogueVar[2]..'"!',"","Close with [esc]"}
  692.                 elseif text and text~="" then
  693.                     __mG.insertText(text)
  694.                     __mG.dialogue=false
  695.                     __mG.dialogueVar={}
  696.                 end
  697.             end
  698.             platform.window:invalidate()
  699.             return
  700.         end
  701.        
  702.         if __mG.selection[1] then
  703.             __mG.on.backspaceKey()
  704.         end
  705.        
  706.         local state={}
  707.         state.before = __mG.createState("coursor")
  708.         local oldLine = __mG.code[__mG.coursor[2]]
  709.         local leftOfC = oldLine:sub(1,__mG.coursor[1]-1)
  710.         local rightOfC = oldLine:sub(__mG.coursor[1],oldLine:len())
  711.         table.insert(__mG.code, __mG.coursor[2], "")
  712.         __mG.code[__mG.coursor[2]]=leftOfC
  713.         __mG.code[__mG.coursor[2]+1]=rightOfC
  714.         __mG.coursor={1,__mG.coursor[2]+1}
  715.         local c=1
  716.         while c<=__mG.code[__mG.coursor[2]-1]:len() and __mG.code[__mG.coursor[2]-1]:sub(c,c)==" " do
  717.             __mG.code[__mG.coursor[2]]=" "..__mG.code[__mG.coursor[2]]
  718.             __mG.coursor[1]=__mG.coursor[1]+1
  719.             c=c+1
  720.         end
  721.         state.after={__mG.coursor[2]-1,__mG.coursor[2],{__mG.code[__mG.coursor[2]-1],__mG.code[__mG.coursor[2]]},__mG.copy_table(__mG.coursor)}
  722.         __mG.registerState(state)
  723.         __mG.adjustScroll()
  724.         platform.window:invalidate()
  725.     end
  726.      
  727.     function __mG.on.returnKey()
  728.         __mG.on.enterKey()
  729.     end
  730.      
  731.     function __mG.on.tabKey()
  732.         if __mG.message.show then
  733.             if __mG.message.text[1]=="Info!" then
  734.                 var.store("JSEshowInfo","NO")
  735.                 __mG.message:reset()
  736.                 platform.window:invalidate()
  737.                 __mG.runCode()
  738.             end
  739.             return
  740.         elseif __mG.dialogue then
  741.             if __mG.dialogue=="importFromLibrary" then
  742.                 if __mG.dialogueField==1 then
  743.                     __mG.dialogueField=2
  744.                 else
  745.                     __mG.dialogueField=1
  746.                 end
  747.                 platform.window:invalidate()
  748.             end
  749.             return
  750.         end
  751.         local state={}
  752.         local newSel=__mG.validSel(__mG.selection)
  753.         if newSel then
  754.             state.before={newSel[1][2],newSel[2][2],{},__mG.copy_table(newSel[2])}
  755.             state.after={newSel[1][2],newSel[2][2],{}}
  756.             for l=newSel[1][2], newSel[2][2] do
  757.                 table.insert(state.before[3],__mG.code[l])
  758.                 __mG.code[l]="    "..__mG.code[l]
  759.                 table.insert(state.after[3],__mG.code[l])
  760.             end
  761.             if newSel[1][1]==1 then
  762.                 __mG.selection[1][1]=1
  763.             else
  764.                 __mG.selection[1][1]=newSel[1][1]+4
  765.             end
  766.             __mG.selection[2][1]=newSel[2][1]+4
  767.             __mG.coursor=__mG.copy_table(__mG.selection[2])
  768.             state.after[4]=__mG.copy_table(__mG.selection[2])
  769.         else
  770.             state.before=__mG.createState("coursor")
  771.             __mG.code[__mG.coursor[2]]=__mG.insert(__mG.code[__mG.coursor[2]],__mG.coursor[1],"    ")
  772.             __mG.coursor[1]=__mG.coursor[1]+4
  773.             state.after=__mG.createState("coursor")
  774.         end
  775.         __mG.adjustScroll()
  776.         platform.window:invalidate()
  777.         __mG.registerState(state)
  778.     end
  779.      
  780.     function __mG.on.backtabKey()
  781.         if __mG.dialogue or __mG.message.show then return end
  782.         local function backTabInLine(lineNo)
  783.             __mG.coursor[2]=lineNo
  784.             local found=false
  785.             local i=1
  786.             local line=__mG.code[lineNo]
  787.             while i<=line:len()+1 and not found do    --search for first character
  788.                 if line:sub(i,i)~=" " then found=true end    
  789.                 i=i+1
  790.             end
  791.             i=i-1
  792.             if i>1 then    --if first character is not at left border
  793.                 __mG.coursor[1]=i    --go to the left of first character
  794.                 __mG.code[lineNo]=line:sub(math.min(i-1,4)+1,line:len()+1)
  795.                 __mG.coursor[1]=__mG.coursor[1]-math.min(i-1,4)
  796.             end
  797.         end
  798.         local state={}
  799.         local newSel=__mG.validSel(__mG.selection)
  800.         if newSel then
  801.             state.before={newSel[1][2],newSel[2][2],{},__mG.copy_table(newSel[2])}
  802.             state.after={newSel[1][2],newSel[2][2],{}}
  803.             for l=newSel[1][2], newSel[2][2] do
  804.                 table.insert(state.before[3],__mG.code[l])
  805.                 backTabInLine(l)
  806.                 table.insert(state.after[3],__mG.code[l])
  807.             end
  808.             __mG.selection[1]={1,newSel[1][2]}
  809.             __mG.selection[2]=__mG.copy_table(__mG.coursor)
  810.             state.after[4]=__mG.copy_table(__mG.coursor)
  811.         else
  812.             state.before=__mG.createState("coursor")
  813.             backTabInLine(__mG.coursor[2])
  814.             state.after=__mG.createState("coursor")
  815.         end
  816.         __mG.adjustScroll()
  817.         __mG.registerState(state)
  818.         platform.window:invalidate()
  819.     end
  820.      
  821.     function __mG.adjustScroll()
  822.         local x,y=unpack(__mG.scroll)
  823.         if __mG.coursor[2]-__mG.scroll[2]<1 then    --cursor too far up
  824.            __mG.scroll[2]=math.max(__mG.coursor[2]-1,1)
  825.         end
  826.         if __mG.coursor[2]-__mG.scroll[2]>__mG.maxLines-2 then    --cursor too far down
  827.             __mG.scroll[2]=math.min(__mG.coursor[2]-__mG.maxLines+2,#__mG.code)
  828.         end
  829.         if __mG.scroll[2]+__mG.maxLines>#__mG.code then    --at the end of the code
  830.             __mG.scroll[2]=math.max(#__mG.code-__mG.maxLines+1,1)
  831.         end
  832.         if __mG.coursor[1]-__mG.scroll[1]<1 then    --cursor too far left
  833.            __mG.scroll[1]=math.max(__mG.coursor[1]-3,1)
  834.         end
  835.         if __mG.coursor[1]-__mG.scroll[1]>__mG.maxChars-1 then    --cursor too far right
  836.             __mG.scroll[1]=math.max(__mG.coursor[1]-__mG.maxChars+3,1)
  837.         end
  838.         if x~=__mG.scroll[1] or y~=__mG.scroll[2] then
  839.             platform.window:invalidate()
  840.             __mG.updatedLines=nil
  841.         end
  842.     end
  843.      
  844.     function __mG.on.arrowKey(dir)
  845.         cursor.hide()
  846.         if  __mG.message.show then return
  847.         elseif __mG.dialogue then
  848.             if __mG.dialogue=="importFromLibrary" then
  849.                 if __mG.dialogueField==1 then
  850.                     __mG.dialogueField=2
  851.                 else
  852.                     __mG.dialogueField=1
  853.                 end
  854.                 platform.window:invalidate()
  855.             end
  856.             return
  857.         end
  858.         if dir=="up" then
  859.             if __mG.code[__mG.coursor[2]-1] then
  860.                 __mG.coursor[2]=__mG.coursor[2]-1
  861.                 __mG.updateLines(__mG.coursor[2],__mG.coursor[2]+1)
  862.             end
  863.         elseif dir=="down" then
  864.             if __mG.code[__mG.coursor[2]+1] then
  865.                 __mG.coursor[2]=__mG.coursor[2]+1
  866.                 __mG.updateLines(__mG.coursor[2]-1,__mG.coursor[2])
  867.             end
  868.         elseif dir=="right" then
  869.             __mG.coursor[1]=__mG.coursor[1]+1
  870.             if __mG.coursor[1]>__mG.code[__mG.coursor[2]]:len()+1 then
  871.                 if __mG.code[__mG.coursor[2]+1] then
  872.                     __mG.coursor[2]=__mG.coursor[2]+1
  873.                     __mG.coursor[1]=1
  874.                 end
  875.                 __mG.updateLines(__mG.coursor[2]-1,__mG.coursor[2])
  876.             else
  877.                 __mG.updateLines(__mG.coursor[2])
  878.             end
  879.         elseif dir=="left" then
  880.             __mG.coursor[1]=__mG.coursor[1]-1
  881.             if __mG.coursor[1]<1 then
  882.                 if __mG.code[__mG.coursor[2]-1] then
  883.                     __mG.coursor[2]=__mG.coursor[2]-1
  884.                     __mG.coursor[1]=__mG.code[__mG.coursor[2]]:len()+1
  885.                 end
  886.                 __mG.updateLines(__mG.coursor[2],__mG.coursor[2]+1)
  887.             else
  888.                 __mG.updateLines(__mG.coursor[2])
  889.             end
  890.         end
  891.         __mG.moveOK=false
  892.         __mG.coursor[1]=math.max(math.min(__mG.coursor[1],__mG.code[__mG.coursor[2]]:len()+1),1)
  893.         if __mG.selection[1] then
  894.             __mG.selection[2]=__mG.copy_table(__mG.coursor)
  895.         end
  896.         __mG.adjustScroll()
  897.         --platform.window:invalidate()
  898.     end
  899.      
  900.     function __mG.on.backspaceKey()
  901.         if __mG.message.show then return end
  902.         if __mG.dialogue then
  903.             local i = 1
  904.             if __mG.dialogue=="importFromLibrary" then
  905.                 i=__mG.dialogueField
  906.             end
  907.             if __mG.dialogueVar[i]:len()>0 then
  908.                 __mG.dialogueVar[i]=__mG.dialogueVar[i]:sub(1,__mG.dialogueVar[i]:len()-1)
  909.                 platform.window:invalidate()
  910.             end
  911.             return
  912.         end
  913.        
  914.         local state={}
  915.         local line=__mG.code[__mG.coursor[2]]
  916.         if __mG.selection[1] then
  917.             local newSel=__mG.validSel(__mG.selection)
  918.             if newSel then
  919.                 state.before=__mG.createState("selection",newSel)
  920.                 if newSel[1][2]==newSel[2][2] then
  921.                     __mG.code[newSel[1][2]]=line:sub(1,newSel[1][1]-1)..line:sub(newSel[2][1],line:len())
  922.                     __mG.coursor[1]=newSel[1][1]
  923.                 else
  924.                     local firstLine=__mG.code[newSel[1][2]]
  925.                     local lastLine=__mG.code[newSel[2][2]]
  926.                     __mG.code[newSel[1][2]]=firstLine:sub(1,newSel[1][1]-1)..lastLine:sub(newSel[2][1],lastLine:len())
  927.                     for i=newSel[1][2]+1, newSel[2][2] do
  928.                         table.remove(__mG.code,newSel[1][2]+1)
  929.                     end
  930.                     __mG.coursor=__mG.copy_table(newSel[1])
  931.                 end
  932.                 __mG.selection={}
  933.                 platform.window:invalidate()
  934.             end
  935.         elseif __mG.coursor[1]==1 then    --if coursor is at left border
  936.             if __mG.coursor[2]>1 then    --not at first line
  937.                 state.before={__mG.coursor[2]-1,__mG.coursor[2],{__mG.code[__mG.coursor[2]-1],__mG.code[__mG.coursor[2]]},__mG.copy_table(__mG.coursor)}
  938.                 local oldLen=__mG.code[__mG.coursor[2]-1]:len()+1    
  939.                 __mG.code[__mG.coursor[2]-1]=__mG.code[__mG.coursor[2]-1]..__mG.code[__mG.coursor[2]]    --add old line to line above
  940.                 table.remove(__mG.code,__mG.coursor[2])
  941.                 __mG.coursor={oldLen,__mG.coursor[2]-1}
  942.             end
  943.             platform.window:invalidate()
  944.         else    --remove character
  945.             state.before=__mG.createState("coursor")
  946.             __mG.code[__mG.coursor[2]]=line:sub(1,__mG.coursor[1]-2)..line:sub(__mG.coursor[1],line:len())
  947.             __mG.updateLines(__mG.coursor[2])
  948.             __mG.coursor[1]=__mG.coursor[1]-1
  949.         end
  950.        
  951.         state.after=__mG.createState("coursor")
  952.         __mG.registerState(state)
  953.         __mG.adjustScroll()
  954.     end
  955.        
  956.     function __mG.on.mouseMove(mx,my)
  957.         if __mG.mouseDown then
  958.             __mG.selection[1]=__mG.copy_table(__mG.mouseDown)
  959.             __mG.selection[2]=__mG.getChrPos(mx,my)
  960.             __mG.coursor=__mG.copy_table(__mG.selection[2])
  961.             __mG.adjustScroll()
  962.             platform.window:invalidate()
  963.         end
  964.         if mx>=(__mG.WW-3) then
  965.             cursor.set("hand pointer")
  966.         else
  967.             cursor.set("text")
  968.         end
  969.     end
  970.      
  971.     function __mG.on.mouseUp()
  972.         __mG.mouseDown=nil
  973.         if platform.isTabletModeRendering and platform.isTabletModeRendering() then -- 3.4 detection
  974.             -- toolpalette bug workaround
  975.             platform.window:setFocus(false)
  976.             platform.window:setFocus(true)
  977.             if touch then
  978.                  if not touch.isKeyboardVisible() then
  979.                       touch.showKeyboard()
  980.                  end
  981.             end
  982.         end
  983.     end
  984.      
  985.     function __mG.getChrPos(x,y)
  986.         y=y+5    --middle of the "text" cursor
  987.         local newY = math.max(math.min(math.floor((y-__mG.chrS[2])/__mG.chrS[4])+__mG.scroll[2],#__mG.code),1)
  988.         local newX = math.max(math.min(math.floor((x-__mG.chrS[1])/__mG.chrS[3])+__mG.scroll[1],__mG.code[newY]:len()+1),1)
  989.         return {newX,newY}
  990.     end
  991.      
  992.     function __mG.on.mouseDown(mx,my)
  993.         if __mG.message.show or __mG.dialogue then
  994.             local x1,x2,y1,y2
  995.             if __mG.message.show then
  996.                 x1,x2,y1,y2 = 24,293,24,187
  997.             elseif __mG.dialogue=="importFromLibrary" then
  998.                 x1,x2,y1,y2 = 30,288,50,162
  999.             else
  1000.                 x1,x2,y1,y2 = 30,288,70,142
  1001.             end
  1002.             if mx>=x1 and mx<=x2 and my>=y1 and my<=y2 then
  1003.                 __mG.on.enterKey()
  1004.             else
  1005.                 __mG.on.escapeKey()
  1006.             end
  1007.             return
  1008.         end
  1009.         if mx>=(__mG.WW-3) then
  1010.             my=my-5
  1011.             __mG.scroll={1,math.max(math.min(math.floor((my/(__mG.WH-20))*(#__mG.code-math.floor(__mG.maxLines/2-0.5)-1)),#__mG.code-(__mG.maxLines-1)),1)}
  1012.             __mG.coursor={1,__mG.scroll[2]}
  1013.         elseif mx==0 and my==0 then    --cursor is hidden
  1014.             cursor.show()
  1015.         else
  1016.             __mG.coursor=__mG.getChrPos(mx,my)
  1017.             __mG.mouseDown=__mG.copy_table(__mG.coursor)
  1018.             if __mG.selection[1] then
  1019.                 __mG.on.grabDown()
  1020.             end
  1021.             __mG.adjustScroll()
  1022.         end
  1023.         platform.window:invalidate()
  1024.     end
  1025.      
  1026.     function __mG.on.charIn(chr)
  1027.         if __mG.message.show then return end
  1028.         if __mG.dialogue=="inputName" then
  1029.             if chr~=" " and not var.store("tEsT"..__mG.dialogueVar[1]..chr,"") then
  1030.                 __mG.dialogueVar[1]=__mG.dialogueVar[1]..chr
  1031.                 math.eval("DelVar ".."tEsT"..__mG.dialogueVar[1])
  1032.             end
  1033.             platform.window:invalidate()
  1034.         elseif __mG.dialogue=="gotoLine" then
  1035.             if tostring(tonumber(chr))==chr and __mG.dialogueVar[1]:len()<5 then    --chr is a number
  1036.                 __mG.dialogueVar[1]=__mG.dialogueVar[1]..chr
  1037.             end
  1038.             platform.window:invalidate()
  1039.         elseif __mG.dialogue=="importFromLibrary" then
  1040.             if __mG.dialogueVar[__mG.dialogueField]:len()<15 then
  1041.                 __mG.dialogueVar[__mG.dialogueField]=__mG.dialogueVar[__mG.dialogueField]..chr
  1042.             end
  1043.             platform.window:invalidate()
  1044.         else
  1045.             if not __mG.code[__mG.coursor[2]] then __mG.code[__mG.coursor[2]]="" end
  1046.        
  1047.             local state={}
  1048.             state.before=__mG.createState("coursor")
  1049.            
  1050.             if __mG.selection[1] then
  1051.                 if __mG.selection[2] then
  1052.                     __mG.on.backspaceKey()
  1053.                 else
  1054.                     __mG.selection={}
  1055.                 end
  1056.             end      
  1057.             if __mG.repChr[__mG.calcLayout] and __mG.repChr[__mG.calcLayout][chr] then
  1058.                 chr=__mG.repChr[__mG.calcLayout][chr]
  1059.             end
  1060.            
  1061.             __mG.code[__mG.coursor[2]]=__mG.insert(__mG.code[__mG.coursor[2]],__mG.coursor[1],chr)
  1062.             __mG.coursor[1]=__mG.coursor[1]+chr:len()
  1063.             __mG.updateLines(__mG.coursor[2])
  1064.             __mG.adjustScroll()
  1065.            
  1066.             state.after=__mG.createState("coursor")
  1067.             __mG.registerState(state)
  1068.         end
  1069.     end
  1070.      
  1071.     function __mG.updateLines(lineStart, lineEnd)
  1072.         if not lineEnd then lineEnd=lineStart end
  1073.         platform.window:invalidate(__mG.chrS[1],2+__mG.chrS[2]+(lineStart-__mG.scroll[2])*__mG.chrS[4],__mG.WW-__mG.chrS[1],(lineEnd-lineStart+1)*__mG.chrS[4])
  1074.         __mG.updatedLines={}
  1075.         for l=lineStart, lineEnd do
  1076.             table.insert(__mG.updatedLines,l)
  1077.         end
  1078.     end
  1079.      
  1080.     function __mG.on.clearKey()
  1081.         __mG.undo()
  1082.     end
  1083.      
  1084.     function __mG.on.contextMenu()
  1085.         __mG.redo()
  1086.     end
  1087.      
  1088.     function __mG.createState(param,sel)
  1089.         local state={}
  1090.         if param=="coursor" then
  1091.             state={__mG.coursor[2],__mG.coursor[2],{__mG.code[__mG.coursor[2]]},__mG.copy_table(__mG.coursor)}
  1092.         elseif param=="selection" then
  1093.             state={sel[1][2],sel[2][2],{},__mG.copy_table(sel[2])}
  1094.             for l=sel[1][2],sel[2][2] do
  1095.                 table.insert(state[3], __mG.code[l])
  1096.             end
  1097.         end
  1098.         return state
  1099.     end
  1100.      
  1101.     function __mG.registerState(state)
  1102.         if __mG.stateNo>=10 then
  1103.             table.remove(__mG.state,1)
  1104.         else
  1105.             __mG.stateNo=__mG.stateNo+1
  1106.             for i=__mG.stateNo, 10 do
  1107.                 __mG.state[i]=nil
  1108.             end
  1109.         end
  1110.         __mG.state[__mG.stateNo]=state
  1111.     end
  1112.      
  1113.     function __mG.undo()
  1114.         if __mG.stateNo>=1 then
  1115.             __mG.selection={}
  1116.             local state=__mG.state[__mG.stateNo]
  1117.             for l=state.after[1], state.after[2] do    --delete new lines
  1118.                 table.remove(__mG.code,state.after[1])
  1119.             end
  1120.             l2=1
  1121.             for l=state.before[1], state.before[2] do    --insert old lines
  1122.                 table.insert(__mG.code,l,state.before[3][l2])
  1123.                 l2=l2+1
  1124.             end
  1125.             __mG.coursor=state.before[4]
  1126.             __mG.adjustScroll()
  1127.             __mG.stateNo=__mG.stateNo-1
  1128.             platform.window:invalidate()
  1129.         end
  1130.     end
  1131.     function __mG.redo()
  1132.         if __mG.stateNo<10 and __mG.state[__mG.stateNo+1] then
  1133.             __mG.selection={}
  1134.             __mG.stateNo=__mG.stateNo+1
  1135.             local state=__mG.state[__mG.stateNo]
  1136.             for l=state.before[1], state.before[2] do    --delete old lines
  1137.                 table.remove(__mG.code,state.before[1])
  1138.             end
  1139.             l2=1
  1140.             for l=state.after[1], state.after[2] do    --insert new lines
  1141.                 table.insert(__mG.code,l,state.after[3][l2])
  1142.                 l2=l2+1
  1143.             end
  1144.             __mG.coursor=state.after[4]
  1145.             __mG.adjustScroll()
  1146.             platform.window:invalidate()
  1147.         end
  1148.     end
  1149.      
  1150.     function __mG.on.timer()
  1151.         timer.stop()
  1152.         __mG.createMenu()
  1153.         platform.window:invalidate()
  1154.     end
  1155.      
  1156.     function __mG.on.resize(w,h)
  1157.         __mG.WW=w
  1158.         __mG.WH=h
  1159.         if platform.isDeviceModeRendering() then
  1160.             __mG.chrS[3]=8
  1161.             __mG.chrS[4]=15
  1162.         else
  1163.             __mG.chrS[3]=10
  1164.             __mG.chrS[4]=18
  1165.         end
  1166.         __mG.maxLines=math.floor((h-__mG.chrS[2]-25)/__mG.chrS[4])
  1167.         __mG.maxChars=math.floor((w-__mG.chrS[1]-5)/__mG.chrS[3])
  1168.         __mG.adjustScroll()
  1169.         platform.window:invalidate()
  1170.     end
  1171.      
  1172.     function __mG.on.paint(gc)
  1173.         local function getPosX(pos)    --pixel koordinate of a character on position pos
  1174.             return __mG.chrS[1]+(pos-__mG.scroll[1])*__mG.chrS[3]
  1175.         end
  1176.         --draw Work Space
  1177.         gc: setColorRGB(39,40,34)
  1178.         gc: fillRect(0,0,platform.window:width(),platform.window:height()-20)
  1179.         --draw Rim
  1180.         if __mG.colDsp then
  1181.             gc:setColorRGB(43,44,38)
  1182.         else
  1183.             gc:setColorRGB(220,220,220)
  1184.         end
  1185.         gc:fillRect(0,0,__mG.chrS[1],__mG.WH-20)
  1186.         gc:setColorRGB(255,255,255)
  1187.         gc:fillRect(__mG.chrS[1]-2,0,1,__mG.WH-20)
  1188.        
  1189.         local function drawLine(l)
  1190.             local lineNo=__mG.scroll[2]+l
  1191.             local line=__mG.code[lineNo]
  1192.             local posY=__mG.chrS[2]+(l)*__mG.chrS[4]  
  1193.             local newSel=__mG.validSel(__mG.selection)
  1194.            
  1195.             --mark active line
  1196.             if lineNo==__mG.coursor[2] then    
  1197.                 if __mG.colDsp then
  1198.                     gc:setColorRGB(43,44,38)
  1199.                 else
  1200.                     gc:setColorRGB(240,240,240)
  1201.                 end
  1202.                 gc:fillRect(__mG.chrS[1],posY+2,__mG.WW-__mG.chrS[1],__mG.chrS[4])
  1203.                 gc:setColorRGB(0,0,0)
  1204.             end
  1205.            
  1206.              --mark error line
  1207.             if lineNo==__mG.ERRline then  
  1208.                 if __mG.colDsp then
  1209.                     gc:setColorRGB(230,150,150)
  1210.                 else
  1211.                     gc:setColorRGB(150,150,150)
  1212.                 end
  1213.                 gc:fillRect(0,posY+2,__mG.chrS[1],__mG.chrS[4])
  1214.             end
  1215.            
  1216.             if line then
  1217.                  --draw line number
  1218.                 if newSel and lineNo>=newSel[1][2] and lineNo<=newSel[2][2] then
  1219.                     if __mG.colDsp then    
  1220.                         gc:setColorRGB(0,0,255)
  1221.                     else
  1222.                         gc:setColorRGB(255,255,255)
  1223.                     end
  1224.                 else
  1225.                     if __mG.colDsp then    
  1226.                         gc:setColorRGB(255,255,255)
  1227.                     else
  1228.                         gc:setColorRGB(20,20,20)
  1229.                     end
  1230.                 end
  1231.                 if lineNo>9999 then    --who would write that much on a calulator?!                                                                                                                                                                                             I
  1232.                     gc:setFont("serif","r",7)
  1233.                     gc:drawString(tostring(lineNo),1,posY+3,"top")
  1234.                 elseif lineNo>999 then
  1235.                     if platform.isDeviceModeRendering() then
  1236.                         gc:setFont("serif","r",9)
  1237.                         gc:drawString(tostring(lineNo),1,posY+1,"top")
  1238.                     else
  1239.                         gc:setFont("serif","r",6)
  1240.                         gc:drawString(tostring(lineNo),1,posY+3,"top")
  1241.                     end
  1242.                    
  1243.                 else
  1244.                     gc:setFont("serif","r",10)
  1245.                     gc:drawString(tostring(lineNo),1,posY,"top")
  1246.                 end
  1247.             end
  1248.            
  1249.             --mark selection
  1250.             if __mG.selection[1] then
  1251.                 if __mG.colDsp then
  1252.                     gc:setColorRGB(200,200,255)
  1253.                 else
  1254.                     gc:setColorRGB(200,200,200)
  1255.                 end
  1256.                 if newSel then
  1257.                     if newSel[1][2]==newSel[2][2] and lineNo==newSel[1][2] then
  1258.                         local startX=math.max(getPosX(newSel[1][1]),__mG.chrS[1])
  1259.                         local endX=math.min(getPosX(newSel[2][1]),__mG.WW)
  1260.                         if startX<__mG.WW and endX>__mG.chrS[1] then
  1261.                             gc:fillRect(startX,posY+2,endX-startX,__mG.chrS[4])
  1262.                         end
  1263.                     else
  1264.                         if lineNo==newSel[1][2] then
  1265.                             local posX1=math.max(getPosX(newSel[1][1]),__mG.chrS[1])
  1266.                             if posX1<__mG.WW then
  1267.                                 gc:fillRect(posX1,posY+2,__mG.WW-posX1,__mG.chrS[4])
  1268.                             end
  1269.                         end
  1270.                         if lineNo>newSel[1][2] and lineNo<newSel[2][2] then
  1271.                             gc:fillRect(__mG.chrS[1],posY+2,__mG.WW-__mG.chrS[1],__mG.chrS[4])
  1272.                         end
  1273.                         if lineNo==newSel[2][2] then
  1274.                             local posX2=math.min(getPosX(newSel[2][1]),__mG.WW)
  1275.                             if posX2>__mG.chrS[1] then
  1276.                                 gc:fillRect(__mG.chrS[1],posY+2,posX2-__mG.chrS[1],__mG.chrS[4])
  1277.                             end
  1278.                         end
  1279.                     end
  1280.                 end
  1281.             end
  1282.                    
  1283.             --draw line
  1284.             if line and line~="" then
  1285.      
  1286.                 gc:setFont(__mG.font,"r",10)
  1287.                
  1288.                 local lineRGB={}
  1289.                 local comment=false
  1290.                 if __mG.markSyntax then
  1291.                     --compute syntax marking
  1292.                     local function markSyntax()
  1293.                         local line=__mG.code[lineNo].." "
  1294.                         local isString=false
  1295.                         local word=""
  1296.                         for c=1, math.min(line:len(),250) do
  1297.                             local chr = line:usub(c,c)
  1298.                             local no=string.byte(chr)
  1299.                             if not no then no=0 end
  1300.                             if comment then
  1301.                                 lineRGB[c]=__mG.wordRGB["--"]
  1302.                             elseif isString then
  1303.                                 lineRGB[c]=__mG.wordRGB['"']
  1304.                                 if chr==isString then
  1305.                                     isString=false
  1306.                                 elseif isString=="[[" and chr=="]" and line:sub(c-1,c-1)=="]" then
  1307.                                     isString=false
  1308.                                 end
  1309.                             else
  1310.                                 if not((no>=65 and no<=90) or (no>=97 and no<=122) or no==95) then --other character than letter or _
  1311.                                     if __mG.wordRGB[word] then
  1312.                                         for lc=c-word:len(), c-1 do
  1313.                                             lineRGB[lc]=__mG.wordRGB[word]
  1314.                                         end
  1315.                                     end
  1316.                                     word=""
  1317.                                     if c>__mG.scroll[1]+__mG.maxChars then
  1318.                                         return
  1319.                                     end
  1320.                                 elseif string.byte(chr)>=33 then
  1321.                                     word=word..chr
  1322.                                 end
  1323.                                 if chr=='"' or chr=="'" then
  1324.                                     isString=chr
  1325.                                     lineRGB[c]=__mG.wordRGB['"']
  1326.                                 elseif chr=="-" then
  1327.                                     if line:sub(c+1,c+1)=="-" then
  1328.                                         comment=c
  1329.                                         lineRGB[c]=__mG.wordRGB["--"]
  1330.                                     end
  1331.                                 elseif chr=="[" then
  1332.                                     if line:sub(c+1,c+1)=="[" then
  1333.                                         isString="[["
  1334.                                         lineRGB[c]=__mG.wordRGB['"']
  1335.                                     end
  1336.                                 end
  1337.                             end
  1338.                         end
  1339.                     end
  1340.                     markSyntax()
  1341.                 end
  1342.                
  1343.                 --draw characters
  1344.                 for c=0, __mG.maxChars-1 do    --for all visible characters
  1345.                     i=__mG.scroll[1]+c
  1346.                    
  1347.                     if i<=line:len() then
  1348.                         char=line:usub(i,i)
  1349.                         if not char then print("FAIL!") end
  1350.                         local no=string.byte(char)
  1351.                         if not no then
  1352.                             no=0
  1353.                         end
  1354.                        
  1355.                         local posX=__mG.chrS[1]+c*__mG.chrS[3]
  1356.      
  1357.                         gc:setColorRGB(255,255,255)
  1358.                         gc:setFont(__mG.font,"r",10)
  1359.                         if __mG.markSyntax then
  1360.                             if lineRGB[i] then
  1361.                                 gc:setColorRGB(unpack(lineRGB[i]))
  1362.                             end
  1363.                             if comment then
  1364.                                 if i>=comment then
  1365.                                     gc:setFont(__mG.font,"i",10)
  1366.                                 end
  1367.                             end
  1368.                         end
  1369.                        
  1370.                         if not __mG.chrOffset[char] then
  1371.                             __mG.chrOffset[char]=5-gc:getStringWidth(char)/2
  1372.                         end
  1373.                        
  1374.                         if no>=33 then
  1375.                             gc:drawString(char,posX+__mG.chrOffset[char],posY,"top")
  1376.                         end
  1377.                     end
  1378.                 end --for c=0, 35 do
  1379.             end --if not(line=="" or line==nil) then
  1380.         end    --function drawLine(l)
  1381.        
  1382.         if __mG.updatedLines and platform.isDeviceModeRendering() and not(platform.hw and platform.hw()>4) then    --only if definitely not rendering on PC
  1383.             for i, ul in pairs(__mG.updatedLines) do
  1384.                 drawLine(ul-__mG.scroll[2])
  1385.                 print(ul)
  1386.             end
  1387.         else
  1388.             for ul=0,__mG.maxLines-1 do
  1389.                 drawLine(ul)
  1390.             end
  1391.         end
  1392.         __mG.updatedLines=nil
  1393.        
  1394.         --draw cursor
  1395.         if __mG.selection[1] then
  1396.             gc:setColorRGB(0,0,255)
  1397.         else
  1398.             gc:setColorRGB(0,0,0)
  1399.         end
  1400.         local posX=getPosX(__mG.coursor[1])    local posY=__mG.chrS[2]+(__mG.coursor[2]-__mG.scroll[2])*__mG.chrS[4]+2
  1401.         gc:drawLine(posX,posY,posX,posY+__mG.chrS[4]-1)
  1402.        
  1403.         --draw error "console"
  1404.         gc:setColorRGB(0,0,0)
  1405.         gc:drawLine(0,__mG.WH-20,__mG.WW,__mG.WH-20)
  1406.         if __mG.ERR then
  1407.             if __mG.colDsp then
  1408.                 gc:setColorRGB(100,0,50)
  1409.             else
  1410.                 gc:setColorRGB(20,20,20)
  1411.             end
  1412.             gc:setFont("serif","r",7)
  1413.             gc:drawString(__mG.ERRline..": "..__mG.ERR,5,__mG.WH-15,"top")
  1414.         end
  1415.        
  1416.         --draw scroll bar
  1417.         gc:setColorRGB(130,130,130)
  1418.         local posY1=math.floor((__mG.scroll[2]-1)/#__mG.code*(__mG.WH-20))
  1419.         local posY2=math.min(math.floor(((__mG.scroll[2]+(__mG.maxLines-1))/#__mG.code)*(__mG.WH-20)),(__mG.WH-20))
  1420.         local height=posY2-posY1
  1421.         gc:fillRect(__mG.WW-3,posY1,3,height)
  1422.        
  1423.         __mG.moveOK=true
  1424.         if __mG.dialogue=="inputName" or __mG.dialogue=="gotoLine" then
  1425.             gc:setColorRGB(0,0,0)
  1426.             gc:drawRect(30,70,258,72)
  1427.             gc:setColorRGB(200,200,200)
  1428.             gc:fillRect(31,71,257,71)
  1429.             gc:setColorRGB(230,230,230)
  1430.             gc:fillRect(40,100,238,20)
  1431.             gc:setFont("sansserif","b",12)
  1432.             gc:setColorRGB(20,20,20)
  1433.             if __mG.dialogue=="inputName" then
  1434.                 gc:drawString("Save as...",40,75,"top")
  1435.                 gc:setFont("sansserif","r",10)
  1436.                 gc:drawString("Press enter to save  (esc to cancel)",41,140,"bottom")
  1437.             elseif __mG.dialogue=="gotoLine" then
  1438.                 gc:drawString("Go to line...",40,75,"top")
  1439.                 gc:setFont("sansserif","r",10)
  1440.                 gc:drawString("Press enter to go  (esc to cancel)",41,140,"bottom")
  1441.             end
  1442.             gc:drawString(__mG.dialogueVar[1],45,100,"top")
  1443.         elseif __mG.dialogue=="importFromLibrary" then
  1444.             gc:setColorRGB(0,0,0)
  1445.             gc:drawRect(30,50,258,112)
  1446.             gc:setColorRGB(200,200,200)
  1447.             gc:fillRect(31,51,257,111)
  1448.             gc:setColorRGB(230,230,230)
  1449.             gc:fillRect(40,80,238,20)
  1450.             gc:fillRect(40,120,238,20)
  1451.             gc:setColorRGB(20,20,20)
  1452.             gc:setPen("medium")
  1453.             gc:drawRect(40,80+(__mG.dialogueField-1)*40,238,20)
  1454.             gc:setPen("thin")
  1455.             gc:setFont("sansserif","b",12)
  1456.             gc:drawString("Import from file...",40,55,"top")
  1457.             gc:setFont("sansserif","b",10)
  1458.             gc:drawString("Variable name...",40,100,"top")
  1459.             gc:setFont("sansserif","r",10)
  1460.             gc:drawString("Press enter to save  (esc to cancel)",41,160,"bottom")
  1461.             gc:drawString(__mG.dialogueVar[1],45,80,"top")
  1462.             gc:drawString(__mG.dialogueVar[2],45,120,"top")
  1463.         end
  1464.         if __mG.message.show then
  1465.             gc:setColorRGB(0,0,0)
  1466.             gc:drawRect(24,24,318-49,212-49)
  1467.             gc:setColorRGB(255,255,200)
  1468.             gc:fillRect(25,25,318-50,212-50)
  1469.             gc:setColorRGB(0,0,0)
  1470.             gc:drawLine(25,60,318-25,60)
  1471.             gc:setFont("sansserif","b",11)
  1472.             gc:drawString(__mG.message.text[1],40,32,"top")
  1473.             if platform.isDeviceModeRendering() then
  1474.                 gc:setFont("sansserif","r",10)
  1475.             else
  1476.                 gc:setFont("sansserif","r",7)
  1477.             end
  1478.             for l=0,6 do
  1479.                 if not __mG.message.text[l+2] then __mG.message.text[l+2]="" end
  1480.                 gc:drawString(__mG.message.text[l+2], 33, 63+l*17, "top")
  1481.             end
  1482.         end
  1483.     end
  1484.      
  1485.     function __mG.reloadSEHandlers()
  1486.         on={}
  1487.         on=__mG.copy_table(__mG.on)
  1488.         timer.stop()
  1489.         toolpalette.register=__mG.oldTPregister
  1490.         __mG.on.create()
  1491.         cursor.set("text")
  1492.         toolpalette.enableCut(true)    toolpalette.enableCopy(true)    toolpalette.enablePaste(true)
  1493.         platform.window:invalidate()
  1494.         timer.start(0.1)    --after a crash in the on.paint funcion it won't update directly
  1495.     end
  1496.     __mG.reloadSEHandlers()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement