ZNZNCOOP

fmaker

Sep 21st, 2015
480
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. ------------------------------------------------------------------------------------------
  2. --             Система визуального программирования FormsMaker от Zer0Galaxy            --
  3. -- http://computercraft.ru/topic/1044-sistema-vizualnogo-programmirovaniia-formsmaker/  --
  4. -- Последнюю версию программы можно скачать выполнив: pastebin get wA5KMKav fmaker.lua  --
  5. -- Для работы программы требуется библиотека forms: pastebin get iKzRve2g lib/forms.lua --
  6. ------------------------------------------------------------------------------------------
  7. forms=require("forms")
  8. fs = require("filesystem")
  9. local gpu=require("component").gpu
  10. local objTouch, objMove, objResize
  11. local xTouch, yTouch
  12. local WinW, WinH = gpu.getResolution()
  13. local activeForm
  14. local projName
  15. local projExt=".fmk"
  16. local noEvent={name=""}
  17. local eventToEdit
  18. local len=require("unicode").len
  19. Objects={}
  20. TForms={}
  21.  
  22. function mainForm()
  23.   forms.activeForm():hide()
  24.   activeForm:setActive()
  25. end
  26.  
  27. function showProp()
  28.   forms.activeForm():hide()
  29.   activeForm:setActive()
  30.   local properties={}
  31.   function addProp(obj)
  32.     for k,v in pairs(obj) do
  33.       if type(v)=="boolean" or type(v)=="number" or type(v)=="string" then
  34.       properties[k]=true end
  35.     end
  36.   end
  37.   addProp(objTouch)
  38.   local TComp=objTouch.__index
  39.   addProp(TComp)
  40.   TComp=getmetatable(TComp)
  41.   addProp(TComp)
  42.   PropList:clear()
  43.   for k in pairs(properties) do
  44.     if string.lower(k):find("color") then PropList:insert(string.format("%-10s│0x%06x",k,objTouch[k]),k)
  45.     else PropList:insert(string.format("%-10s│%s",k,objTouch[k]),k) end
  46.   end
  47.   PropList:sort()
  48.   for k,v in pairs(objTouch.events) do
  49.     v.name=k
  50.     PropList:insert(string.format("%-10s│%s",k,v.proc.name),v)
  51.   end
  52.   PropList.index=0
  53.   PropList.onChange=selProp
  54.   PropInsp:setActive()
  55. end
  56.  
  57. function mouseEv(self,ev,x,y,btn)
  58.   if self.elements then
  59.     for i=#self.elements,1,-1 do
  60.       local e=self.elements[i]
  61.       if x>=e.X and x<e.X+e.W and y>=e.Y and y<e.Y+e.H then
  62.         e.mouseEv(e,ev,x,y,btn)
  63.         return
  64.       end
  65.     end
  66.   end  
  67.   if self[ev] then self[ev](self, x-self.X+1,y-self.Y+1,btn) end
  68. end
  69.  
  70. function touch(obj,x,y,btn)
  71.   objTouch=obj
  72.   if btn==0 then     --Left click
  73.     xTouch=obj.X+x
  74.     yTouch=obj.Y+y
  75.     if x==obj.W and y==obj.H then  --Resize
  76.       objResize=obj
  77.     else                           --Move
  78.       objMove=obj
  79.     end
  80.   elseif btn==1 then --Right click
  81.     xTouch=x
  82.     yTouch=y
  83.     ObjList.index=0 ObjList.shift=0
  84.     ObjList.lines[1]="Свойства "..obj.name
  85.     ObjList.lines[2]="Удалить "..obj.name
  86.     ObjInsp.left=obj.X+x-1
  87.     if ObjInsp.left>WinW-ObjInsp.W+1 then ObjInsp.left=WinW-ObjInsp.W+1 end
  88.     if ObjInsp.left<1 then ObjInsp.left=1 end
  89.     ObjInsp.top=obj.Y+y-1
  90.     if ObjInsp.top>WinH-ObjInsp.H+1 then ObjInsp.top=WinH-ObjInsp.H+1 end
  91.     if ObjInsp.top<1 then ObjInsp.top=1 end
  92.     ObjInsp:setActive()
  93.   end
  94. end
  95.  
  96. function drag(obj,x,y,btn)
  97.   if btn==0 then
  98.     if not objTouch.parent then
  99.       gpu.setBackground(0)
  100.       gpu.fill(obj.X,obj.Y,obj.W,obj.H," ")
  101.     end
  102.     local dx,dy=obj.X+x-xTouch, obj.Y+y-yTouch
  103.     xTouch=obj.X+x
  104.     yTouch=obj.Y+y
  105.     if objMove then
  106.       objMove.left=objMove.left+dx
  107.       objMove.top=objMove.top+dy
  108.       if objMove.left<1 then objMove.left=1 objMove=nil
  109.       elseif objMove.top<1 then objMove.top=1 objMove=nil end
  110.     end
  111.     if objResize then
  112.       objResize.W=objResize.W+dx
  113.       objResize.H=objResize.H+dy
  114.       if objResize.W<2 then objResize.W=2 objResize=nil
  115.       elseif objResize.H<1 then objResize.H=1 objResize=nil end
  116.     end
  117.     if objTouch.parent then (objTouch.parent):draw()
  118.     else objTouch:draw()
  119.     end
  120.   end
  121. end
  122.  
  123. function drop(obj,x,y,btn)
  124.   objMove=nil
  125.   objResize=nil
  126. end
  127.  
  128. function checkName(name)
  129.   if not name:find("^[_%a][_%w]*$") then return false end
  130.   if Objects[name] then return false end
  131.   for i=1,#evEdtList.items do
  132.     if evEdtList.items[i].name==name then return false end
  133.   end
  134.   return true
  135. end
  136.  
  137. function reName(obj)
  138.   for k,v in pairs(Objects) do
  139.     if v==obj then Objects[k]=nil Objects[obj.name]=obj return end
  140.   end
  141. end
  142.  
  143. function getName(name)
  144.   local i=1
  145.   while true do
  146.     local n=name..i
  147.     if checkName(n) then return n end
  148.     i=i+1
  149.   end
  150. end
  151.  
  152. function getProcName(name)
  153.   local i,n=1,name
  154.   while true do
  155.     if checkName(n) then return n end
  156.     n=name..i
  157.     i=i+1
  158.   end
  159. end
  160.  
  161. function draw(self)
  162.   if self.parent then self.X=self.parent.X+self.left-1 self.Y=self.parent.Y+self.top-1
  163.   else self.X=self.left self.Y=self.top end
  164.   gpu.setBackground(self.color)
  165.   gpu.setForeground(self.fontColor)
  166.   local brd=nil
  167.   if self.border==1 then brd={"┌","─","┐","└","│","┘"}
  168.   elseif self.border==2 then brd={"╔","═","╗","╚","║","╝"}
  169.   end
  170.   if brd then
  171.     gpu.set(self.X,self.Y, brd[1]..string.rep(brd[2],self.W-2)..brd[3])
  172.     for i=self.Y+1,self.Y+self.H-2 do
  173.       gpu.set(self.X,i, brd[5]..string.rep(" ",self.W-2)..brd[5])
  174.     end
  175.     gpu.set(self.X,self.Y+self.H-1, brd[4]..string.rep(brd[2],self.W-2)..brd[6])
  176.   else gpu.fill(self.X,self.Y,self.W,self.H," ") end
  177.   self:paint()
  178.   if self.elements then
  179.     for i=1,#self.elements do
  180.       self.elements[i].draw(self.elements[i])
  181.     end
  182.   end
  183. end
  184.  
  185. function paint(self)
  186.   gpu.set(self.X+(self.W-len(self.name))/2,self.Y+(self.H-1)/2, self.name)
  187. end
  188.  
  189. function setProp(obj,name)
  190.  obj.name=name
  191.  obj.draw=draw
  192.  obj.mouseEv=mouseEv
  193.  obj.touch=touch
  194.  obj.drag=drag
  195.  obj.drop=drop
  196.  Objects[name]=obj
  197.  activeForm:setActive()
  198. end
  199.  
  200. local ignore1={"X","Y","name"}
  201. function compParams(self,...)
  202.   local ignore2={...}
  203.   local ignore={}
  204.   local str=''
  205.   for i=1,#ignore1 do ignore[ignore1[i]]=true end
  206.   for i=1,#ignore2 do
  207.     ignore[ignore2[i]]=true
  208. --  if i~=1 then str=str..',' end
  209.     local dat=self[ignore2[i]] or self.events[ignore2[i]]
  210.     if type(dat)=="boolean" or type(dat)=="number" then str=str..","..dat end
  211.     if type(dat)=="string" then str=str..',"'..dat..'"' end
  212.     if type(dat)=="table" then
  213.       if dat.proc.text then str=str..","..dat.proc.name end
  214.     end
  215.   end
  216.   str='('..str:sub(2)..')\n'
  217.   for k,v in pairs(self) do
  218.    if not ignore[k] then
  219.     if v~=self.__index[k] then
  220.       if type(v)=="boolean" or type(v)=="number" then str=str..self.name..'.'..k..'='..tostring(v)..'\n' end
  221.       if type(v)=="string" then str=str..self.name..'.'..k..'="'..v..'"\n' end
  222.     end
  223.    end
  224.   end
  225.   return str
  226. end
  227.  
  228. function compForm(self)
  229.   return self.name..'=forms.addForm'..compParams(self)
  230. end
  231. function makeForm()
  232.  local obj=forms.addForm()
  233.  activeForm=obj
  234.  setProp(obj, getName("Form"))
  235.  obj.border=1
  236.  obj.events={onCreate={params={},proc=noEvent}}
  237.  obj.compile=compForm
  238.  table.insert(TForms,obj)
  239.  obj:redraw()
  240.  return obj
  241. end
  242.  
  243. function delActiveForm()
  244.  if #TForms>1 then
  245.    for i=1,#TForms do
  246.      if TForms[i]==activeForm then table.remove(TForms,i) break end
  247.    end
  248.    activeForm=TForms[1]
  249.    mainForm()
  250.  else
  251.   Message("Удалить последнюю форму нельзя.\nДля удаления формы "..activeForm.name.."\nдобавьте еще одну форму в проект.")
  252.  end
  253. end
  254.  
  255. delFormDlg=forms.addForm()
  256. delFormDlg.W=40
  257. delFormDlg.H=8
  258. delFormDlg.left=math.floor((WinW-delFormDlg.W)/2)
  259. delFormDlg.top =math.floor((WinH-delFormDlg.H)/2)
  260. delFormDlg.border=2
  261. delFormDlg.color=0xff0000
  262. delFormLabel=delFormDlg:addLabel(2,3,"")
  263. delFormLabel.W=delFormDlg.W-2
  264. delFormLabel.H=3
  265. delFormLabel.centered=true
  266. delFormLabel.autoSize=false
  267. delFormLabel.color=delFormDlg.color
  268. delFormDlg:addButton(8,6,"Да",delActiveForm)
  269. delFormDlg:addButton(24,6,"Нет",mainForm)
  270.  
  271. function delForm()
  272.   delFormLabel.caption="Вы действительно хотите удалить форму "..activeForm.name.." со всем ее содержимым?"
  273.   delFormDlg:setActive()
  274. end
  275.  
  276. function compButton(self)
  277.   return self.name..'='..self.parent.name..':addButton'..compParams(self,"left","top","caption","onClick")
  278. end
  279. function makeButton(parent,x,y)
  280.  local name=getName("Button")
  281.  local obj=parent:addButton(x,y,name)
  282.  setProp(obj,name)
  283.  obj.events={onClick={params={"user"},proc=noEvent}}
  284.  obj.compile=compButton
  285.  return obj
  286. end
  287.  
  288. function compLabel(self)
  289.   return self.name..'='..self.parent.name..':addLabel'..compParams(self,"left","top","caption")
  290. end
  291. function makeLabel(parent,x,y)
  292.  local name=getName("Label")
  293.  local obj=parent:addLabel(x,y,name)
  294.  setProp(obj,name)
  295.  obj.events={}
  296.  obj.compile=compLabel
  297.  return obj
  298. end
  299.  
  300. function compEdit(self)
  301.   return self.name..'='..self.parent.name..':addEdit'..compParams(self,"left","top","onEnter")
  302. end
  303. function makeEdit(parent,x,y)
  304.  local obj=parent:addEdit(x,y)
  305.  setProp(obj, getName("Edit"))
  306.  obj.events={onEnter={params={"user"},proc=noEvent}}
  307.  obj.compile=compEdit
  308.  return obj
  309. end
  310.  
  311. function compFrame(self)
  312.   return self.name..'='..self.parent.name..':addFrame'..compParams(self,"left","top","border")
  313. end
  314. function makeFrame(parent,x,y)
  315.  local obj=parent:addFrame(x,y)
  316.  setProp(obj, getName("Frame"))
  317.  obj.events={}
  318.  obj.compile=compFrame
  319.  return obj
  320. end
  321.  
  322. function compList(self)
  323.   return self.name..'='..self.parent.name..':addList'..compParams(self,"left","top","onChange")
  324. end
  325. function makeList(parent,x,y)
  326.  local obj=parent:addList(x,y)
  327.  setProp(obj, getName("List"))
  328.  obj.events={onChange={params={"line","item","user"},proc=noEvent}}
  329.  obj.compile=compList
  330.  return obj
  331. end
  332.  
  333. function compEvent(self)
  334.   return self.name..'='..self.parent.name..':addEvent'..compParams(self,"eventName", "onEvent")
  335. end
  336. function makeEvent(parent,x,y)
  337.  local name=getName("Event")
  338.  local obj=parent:addEvent("")
  339.  setProp(obj,name)
  340.  obj.events={onEvent={params={"..."},proc=noEvent}}
  341.  obj.compile=compEvent
  342.  obj.paint=paint
  343.  return obj
  344. end
  345.  
  346. function compTimer(self)
  347.   return self.name..'='..self.parent.name..':addTimer'..compParams(self,"interval", "onTime")
  348. end
  349. function makeTimer(parent,x,y)
  350.  local name=getName("Timer")
  351.  local obj=parent:addTimer(5)
  352.  setProp(obj,name)
  353.  obj.events={onTime={params={},proc=noEvent}}
  354.  obj.compile=compTimer
  355.  obj.paint=paint
  356.  return obj
  357. end
  358.  
  359. function delObj(obj)
  360.  if obj.elements then
  361.   for i=1,#obj.elements do
  362.     delObj(obj.elements[i])
  363.   end
  364.  end
  365.  Objects[obj.name]=nil
  366. end
  367.  
  368. function delComp(comp)
  369.   if comp.parent then
  370.    delObj(comp)
  371.    comp:destruct()
  372.    activeForm:setActive()
  373.   else
  374.     delForm()
  375.   end
  376. end
  377.  
  378. function selObj(self,line,item)
  379.   ObjInsp:hide()
  380.   if type(item)=="function" then item(objTouch,xTouch,yTouch)
  381.   else Message("Опция пока не поддерживается") end
  382. end
  383.  
  384. ObjInsp=forms.addForm()
  385. ObjInsp.W=20
  386. ObjInsp.H=12
  387. ObjList=ObjInsp:addList(1,1,selObj)
  388. ObjList.W=ObjInsp.W
  389. ObjList.H=ObjInsp.H
  390. ObjList:addButton(ObjList.W-2,1,"X",mainForm).W=3
  391.  
  392. EdtForm=forms.addForm()
  393. EdtForm.W=33
  394. EdtForm.H=10
  395. EdtForm.left=math.floor((WinW-EdtForm.W)/2)
  396. EdtForm.top =math.floor((WinH-EdtForm.H)/2)
  397. EdtForm.border=2
  398. EdtLabel=EdtForm:addLabel(2,3)
  399. EdtLabel.W=EdtForm.W-2
  400. EdtLabel.centered=true
  401. EdtLabel.autoSize=false
  402. EdtEdit=EdtForm:addEdit(math.floor((EdtForm.W-20)/2)+1,4)
  403. EdtForm:addButton(5,8,"Ok",
  404. function()
  405.   local dat=objTouch[PropList.items[PropList.index]]
  406.   if type(dat)=="number" then dat=tonumber(EdtEdit.text)
  407.   else dat=EdtEdit.text end
  408.   if PropList.items[PropList.index]=="name" then
  409.     if not checkName(dat) then showProp() return end
  410.     if objTouch.caption==objTouch.name then objTouch.caption=dat end
  411.   end
  412.   if dat~=nil then objTouch[PropList.items[PropList.index]]=dat end
  413.   if PropList.items[PropList.index]=="name" then reName(objTouch) end
  414.   showProp()
  415. end)
  416. EdtForm:addButton(20,8,"Cancel",showProp)
  417.  
  418. function editProp(obj,prop)
  419.   if type(obj[prop])=="boolean" then
  420.     obj[prop]=not obj[prop]
  421.     showProp()
  422.     return
  423.   end
  424.   EdtLabel.caption=obj.name.."."..prop
  425.   if string.lower(prop):find("color") then EdtEdit.text=string.format("0x%06x",obj[prop])
  426.   else EdtEdit.text=tostring(obj[prop]) end
  427.   EdtForm:setActive()
  428. end
  429.  
  430. txtEditForm=forms.addForm()
  431. txtEditForm.W=WinW-24
  432. txtEdit=txtEditForm:addEdit(1,1)
  433. txtEdit.W=txtEditForm.W
  434. txtEdit.H=txtEditForm.H
  435.  
  436. function editEvent()
  437.   if eventToEdit.proc.text then
  438.     if PropInsp.left==1 then
  439.       txtEditForm.left=PropInsp.W+1
  440.     else
  441.       txtEditForm.left=1
  442.     end
  443.     txtEdit.text=eventToEdit.proc.text
  444.     txtEditForm:setActive()
  445.     txtEdit:touch(1,1,0)
  446.     showProp()
  447.   end
  448. end
  449. evEdtForm=forms.addForm()
  450. evEdtForm.W=28
  451. evEdtForm.H=14
  452. evEdtForm.left=math.floor((WinW-evEdtForm.W)/2)
  453. evEdtForm.top =math.floor((WinH-evEdtForm.H)/2)
  454. evEdtForm.border=2
  455. evEdtList=evEdtForm:addList(2,2,
  456. function(self,line,item) eventToEdit.proc=item showProp() end)
  457. evEdtList.W=evEdtForm.W-2
  458. evEdtList.border=0
  459. evEdtList.color=0x404040
  460. evEdtList:insert("Не назначено",noEvent)
  461. evEdtForm:addButton(2,13,"New",
  462. function()
  463.   local name=getProcName(objTouch.name..eventToEdit.name)
  464.   local begin="function "..name.."(self"
  465.   for i=1,#eventToEdit.params do
  466.     begin=begin..", "..eventToEdit.params[i]
  467.   end
  468.   eventToEdit.proc={name=name,text={begin..")","","end"}}
  469.   evEdtList:insert(name,eventToEdit.proc)
  470.   editEvent()
  471. end).W=8
  472. evEdtForm:addButton(11,13,"Edit",editEvent).W=8
  473. evEdtForm:addButton(20,13,"Cancel",showProp).W=8
  474.  
  475. function selProp(self,line,item)
  476.   if type(item)=="string" then editProp(objTouch,item)
  477.   elseif type(item)=="table" then
  478.     eventToEdit=item
  479.     evEdtList.index=0
  480.     for i=1,#evEdtList.items do
  481.       if eventToEdit.proc==evEdtList.items[i] then evEdtList.index=i break end
  482.     end
  483.     evEdtForm:setActive()
  484.   elseif type(item)=="function" then item(objTouch)
  485.   else Message("Опция пока не поддерживается") end
  486. end
  487.  
  488. PropInsp=forms.addForm()
  489. PropInsp.W=WinW-txtEditForm.W
  490. PropInsp.H=WinH
  491. PropList=PropInsp:addList(1,1,selProp)
  492. PropList.W=PropInsp.W
  493. PropList.H=PropInsp.H
  494. PropList:addButton(PropList.W-2,1,"X",mainForm).W=3
  495. PropList:addButton(PropList.W-7,1,"<>",
  496.   function()
  497.     if PropInsp.left==1 then PropInsp.left=WinW-PropInsp.W+1
  498.     else PropInsp.left=1 end
  499.     PropInsp:hide()
  500.     activeForm:draw()
  501.     PropInsp:draw()
  502.   end).W=4
  503.  
  504. MsgForm=forms.addForm()
  505. MsgForm.W=40
  506. MsgForm.H=8
  507. MsgForm.left=math.floor((WinW-MsgForm.W)/2)
  508. MsgForm.top =math.floor((WinH-MsgForm.H)/2)
  509. MsgForm.border=2
  510. MsgLabel=MsgForm:addLabel(2,3,"Система визуального программирования\nFormsMaker от Zer0Galaxy")
  511. MsgLabel.W=MsgForm.W-2
  512. MsgLabel.H=3
  513. MsgLabel.centered=true
  514. MsgLabel.autoSize=false
  515. MsgForm:addButton(15,6,"Ok",mainForm)
  516. function Message(mess)
  517.   MsgLabel.caption=mess
  518.   MsgForm:setActive()
  519. end
  520.  
  521. local file
  522. function compileComp(obj)
  523.   for k,v in pairs(obj.events) do
  524.     if v.proc.text and not v.proc.used then
  525.       file:write("\n")
  526.       for i=1,#v.proc.text do
  527.         file:write(v.proc.text[i].."\n")
  528.       end
  529.       v.proc.used=true
  530.     end
  531.   end
  532.   file:write("\n"..obj:compile())
  533.   if obj.elements then
  534.     for i=1,#obj.elements do compileComp(obj.elements[i]) end
  535.   end
  536. end
  537.  
  538. function compile()
  539.   for i=1, #evEdtList.items do
  540.     evEdtList.items[i].used=nil
  541.   end
  542.   file=io.open(projName..".lua",'w')
  543.   if not file then Message("Неверное имя файла\n"..projName..".lua") return end
  544.   file:write('-- Данный код сгенерирован программой FormsMaker\n')
  545.   file:write('-- http://computercraft.ru/topic/1044-sistema-vizualnogo-programmirovaniia-formsmaker/\n')
  546.   file:write('require("component").gpu.setResolution('..WinW..','..WinH..')\n')
  547.   file:write('forms=require("forms")\n')
  548.   file:write('forms.ignoreAll()\n')
  549.   for i=1,#TForms do compileComp(TForms[i]) end
  550.   file:write('\n')
  551.   for i=1,#TForms do
  552.     if TForms[i].events.onCreate.proc~=noEvent then  file:write(TForms[i].events.onCreate.proc.name..'('..TForms[i].name..')\n') end
  553.   end
  554.   file:write('forms.run('..activeForm.name..')')
  555.   file:close()
  556.   Message("Код сгенерирован в файл "..projName..".lua")
  557. end
  558.  
  559. function saveComp(obj)
  560.   if obj.parent then file:write("-- "..obj.type().." at "..obj.parent.name.."\n")
  561.   else file:write("-- "..obj.type().."\n") end
  562.   for k,v in pairs(obj) do
  563.     if v~=obj.__index[k] then
  564.       if type(v)=="boolean" or type(v)=="number" then file:write(k.."="..tostring(v).."\n") end
  565.       if type(v)=="string"  then file:write(k..'="'..v..'"\n') end
  566.     end
  567.   end
  568.   for name,ev in pairs(obj.events) do
  569.     if ev.proc~=noEvent then file:write(name.."="..ev.proc.name.."\n") end
  570.   end
  571.   if obj.elements then
  572.     for i=1,#obj.elements do saveComp(obj.elements[i]) end
  573.   end
  574. end
  575.  
  576. SavForm=forms.addForm()
  577. SavForm.W=33
  578. SavForm.H=10
  579. SavForm.left=math.floor((WinW-SavForm.W)/2)
  580. SavForm.top =math.floor((WinH-SavForm.H)/2)
  581. SavForm.border=2
  582. SavLabel=SavForm:addLabel(2,3)
  583. SavLabel.W=SavForm.W-2
  584. SavLabel.centered=true
  585. SavLabel.autoSize=false
  586. SavLabel.caption="Сохранить проект как:"
  587. SavEdit=SavForm:addEdit(math.floor((SavForm.W-20)/2)-1,4)
  588. SavForm:addLabel(25,5,projExt)
  589. SavForm:addButton(5,8,"Ok",
  590. function()
  591.   file=io.open(SavEdit.text..projExt,'w')
  592.   if not file then Message("Неверное имя файла\n"..SavEdit.text..projExt) return end
  593.   projName=SavEdit.text
  594.   for i=2,#evEdtList.items do
  595.     file:write("-- function "..evEdtList.items[i].name.." "..#evEdtList.items[i].text.." line(s)\n")
  596.     for j=1,#evEdtList.items[i].text do
  597.       file:write(evEdtList.items[i].text[j].."\n")
  598.     end
  599.   end
  600.   for i=1,#TForms do saveComp(TForms[i]) end
  601.   file:write("-- activeForm "..activeForm.name.."\n")
  602.   file:close()
  603.   Message("Проект сохранен в файл "..projName..projExt)
  604. end)
  605. SavForm:addButton(20,8,"Cancel",mainForm)
  606.  
  607. function saveProj()
  608.   SavEdit.text=projName
  609.   SavForm:setActive()
  610. end
  611.  
  612. function dubObj(obj)
  613.   if obj.parent then
  614.     local objnew
  615.     if obj:type()=="Button"    then objnew=makeButton(obj.parent)
  616.     elseif obj:type()=="Label" then objnew=makeLabel(obj.parent)
  617.     elseif obj:type()=="Edit"  then objnew=makeEdit(obj.parent)
  618.     elseif obj:type()=="Frame" then objnew=makeFrame(obj.parent)
  619.     elseif obj:type()=="List"  then objnew=makeList(obj.parent)
  620.     end
  621.     objnew.parent=obj.parent
  622.     for k,v in pairs(obj) do
  623.       if type(v)~="table" and k~="name" then objnew[k]=v end
  624.     end
  625.     for k,v in pairs(obj.events) do objnew.events[k].proc=v.proc end
  626.     objnew.left=obj.left+1
  627.     objnew.top=objnew.top+1
  628.     mainForm() activeForm:redraw()
  629.   else
  630.     Message("Форма не подлежит дублированию")
  631.   end
  632. end
  633.  
  634. function selForm(self,line,item)
  635.   activeForm=item
  636.   activeForm:setActive()
  637. end
  638.  
  639. function changeForm()
  640.   activeForm:setActive()
  641.   PropList:clear()
  642.   for i=1,#TForms do
  643.     PropList:insert(TForms[i].name,TForms[i])
  644.   end
  645.   PropList:sort()
  646.   PropList.index=0
  647.   PropList.onChange=selForm
  648.   PropInsp:setActive()
  649. end
  650.  
  651. function insertObj(obj)
  652.   PropList:insert(obj.name,obj)
  653.   if obj.elements then
  654.     for i=1,#obj.elements do
  655.       insertObj(obj.elements[i])
  656.     end
  657.   end
  658. end
  659.  
  660. function selObject(self,line,item)
  661.   objTouch=item
  662.   activeForm=item
  663.   while activeForm.parent do activeForm=activeForm.parent end
  664.   showProp()
  665. end
  666.  
  667. function foundObj()
  668.   activeForm:setActive()
  669.   PropList:clear()
  670.   for i=1,#TForms do
  671.     insertObj(TForms[i])
  672.   end
  673.   PropList:sort()
  674.   PropList.index=0
  675.   PropList.onChange=selObject
  676.   PropInsp:setActive()
  677. end
  678.  
  679. function run()
  680.   compile()
  681.   dofile(projName..".lua")
  682.   mainForm()
  683. end
  684.  
  685. ObjList:insert("Свойства ",showProp)
  686. ObjList:insert("Удалить ",delComp)
  687. ObjList:insert("Add button",makeButton)
  688. ObjList:insert("Add label",makeLabel)
  689. ObjList:insert("Add edit",makeEdit)
  690. ObjList:insert("Add frame",makeFrame)
  691. ObjList:insert("Add list",makeList)
  692. ObjList:insert("Add event",makeEvent)
  693. ObjList:insert("Add timer",makeTimer)
  694. ObjList:insert("Дублировать объект",dubObj)
  695. ObjList:insert("Найти объект",foundObj)
  696. ObjList:insert("На передний план")
  697. ObjList:insert("На задний план")
  698. ObjList:insert("Добавить форму",makeForm)
  699. ObjList:insert("Удалить форму",delForm)
  700. ObjList:insert("Сменить форму",changeForm)
  701. ObjList:insert("Выполнить",run)
  702. ObjList:insert("Сохранить проект",saveProj)
  703. ObjList:insert("Генерировать код",compile)
  704. ObjList:insert("Выход",forms.stop)
  705.  
  706. do
  707.   local arg=({...})[1]
  708.   if arg then
  709.     projName=arg:match("(.*)%"..projExt.."$") or arg
  710.     file=io.open(projName..projExt,'r')
  711.     if file then
  712.       local obj, typ, procname, n
  713.       for line in file:lines() do
  714.         typ,procname,n=line:match("^-- (%w+)%s*(%w*)%s*([_%w]*)")
  715.         if typ then
  716.           if typ=="function" then
  717.             local proc={name=procname,text={}}
  718.             for i=1,n do proc.text[i]=file:read() end
  719.             evEdtList:insert(procname,proc)
  720.           elseif typ=="Form" then
  721.             obj=makeForm()
  722.           elseif typ=="Button" then
  723.             obj=makeButton(Objects[n])
  724.           elseif typ=="Label" then
  725.             obj=makeLabel(Objects[n])
  726.           elseif typ=="Edit"  then
  727.             obj=makeEdit(Objects[n])
  728.           elseif typ=="Frame" then
  729.             obj=makeFrame(Objects[n])
  730.           elseif typ=="List"  then
  731.             obj=makeList(Objects[n])
  732.           elseif typ=="Event"  then
  733.             obj=makeEvent(Objects[n])
  734.           elseif typ=="Timer"  then
  735.             obj=makeTimer(Objects[n])
  736.           elseif typ=="activeForm" then
  737.             for i=1,#TForms do
  738.               if TForms[i].name==procname then activeForm=TForms[i] break end
  739.             end
  740.           else error("Неизвестный компонент "..typ.." в файле "..projName..projExt.."\n"..line)
  741.           end
  742.         else
  743.           if obj then
  744.             local field,value=line:match("(%w+)=(.+)")
  745.             if not field then error("Ошибка в файле "..projName..projExt.."\n"..line) end
  746.             if value=="true" or value=="false" then obj[field]=(value=="true")
  747.             elseif tonumber(value) then obj[field]=tonumber(value)
  748.             elseif value:find('^".*"$') then obj[field]=value:match('^"(.*)"$')
  749.             else
  750.               for i=2,#evEdtList.items do
  751.                 if evEdtList.items[i].name==value then obj.events[field].proc=evEdtList.items[i] break end
  752.               end
  753.             end
  754.             if field=="name" then reName(obj) end
  755.           else error("Ошибка в файле "..projName..projExt.."\n"..line) end
  756.         end
  757.       end
  758.       file:close()
  759.     else makeForm() end
  760.   else
  761.     projName="Project1"
  762.     makeForm()
  763.   end
  764. end
  765. forms.run(MsgForm)
RAW Paste Data