Advertisement
Guest User

Untitled

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