Polyakov21

libAAF-stable

Nov 15th, 2015
258
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 32.80 KB | None | 0 0
  1. local AAF_SURFACE_PATH="/lib/surface" -- configure to path where your surfaceAPI is
  2.  
  3. local default_width,default_height=term.getSize()
  4.  
  5. if not surface then
  6.  
  7.     os.loadAPI(AAF_SURFACE_PATH)
  8.  
  9.     if not surface then
  10.         print("No Surface API found, has to be placed in "..AAF_SURFACE_PATH..".")
  11.         do return end
  12.     end
  13.  
  14. end
  15. if not term.isColor() then
  16.     print("AwesomeAppFramework can only be used on advanced computers.")
  17.     do return end
  18. end
  19.  
  20. -- COMPONENT CONFIGURATIONS
  21.  
  22. local BUTTON_COLOR_DOWN = colors.cyan
  23. local BUTTON_COLOR_NORMAL = colors.gray
  24.  
  25. local WINDOW_BACKGROUND = colors.lightGray
  26.  
  27. local ALERT_NORMAL = colors.white
  28. local ALERT_TEXT = colors.black
  29. local ALERT_ACCENT = colors.cyan
  30. local ALERT_ACCENT_TEXT = colors.black
  31.  
  32. local EDITTEXT_COLOR_NORMAL = colors.white
  33. local EDITTEXT_TEXT_NORMAL = colors.black
  34.  
  35. -- APPLICATION DEFINITIONS
  36.  
  37. Application = {
  38.     appWindow, alive
  39. }
  40. Application.__index=Application
  41.  
  42. -- COMPONENT DEFINITIONS
  43.  
  44. Screen = {
  45.     components = {}, holdComp=-1, focusedComp=-1, context=0, backColor=WINDOW_BACKGROUND,
  46.     altDown=false, appParent, graphics, appBar
  47. }
  48. Screen.__index = Screen
  49.  
  50. AppBar = {}
  51. AppBar.__index=AppBar
  52.  
  53. Component = {
  54. x,y,width,height,color,kind="component",
  55. draw = function(self) end,
  56. onMouseClick = function(self) end,
  57. onMouseDown = function(self) end,
  58. onMouseUp = function(self) end,
  59. onKeyDown = function(self) end,
  60. onKeyUp = function(self) end,
  61. screenOwner,
  62. }
  63. Component.__index=Component
  64.  
  65. Button = {
  66. x,y,width,height,color,kind="button",
  67. draw = function(self) end,
  68. onMouseClick = function(self) end,
  69. onMouseDown = function(self) end,
  70. onMouseUp = function(self) end
  71. }
  72. Button.__index=Button
  73.  
  74. EditText = {
  75. x,y,width,height,color=EDITTEXT_COLOR_NORMAL,colorText=EDITTEXT_TEXT_NORMAL,kind="edittext",
  76. draw = function(self) end,
  77. onKeyDown = function(self) end,
  78. onKeyUp = function(self) end
  79. }
  80. EditText.__index=EditText
  81.  
  82. Alert = {
  83. title,message,
  84. onMouseClick = function (self,x,y) end,
  85. onResult = function() end
  86. }
  87. Alert.__index=Alert
  88.  
  89. ConfirmDialog = {}
  90. ConfirmDialog.__index=ConfirmDialog
  91.  
  92. Label = {
  93. x,y,width,height,color,kind="label",
  94. draw = function(self) end,
  95. onMouseClick = function(self) end,
  96. onMouseDown = function(self) end,
  97. onMouseUp = function(self) end
  98. }
  99. Label.__index=Label
  100.  
  101. ProgressBar = {
  102. x,y,width,height,color,kind="progressbar",
  103. draw = function(self) end,
  104. onMouseClick = function(self) end,
  105. onMouseDown = function(self) end,
  106. onMouseUp = function(self) end
  107. }
  108. ProgressBar.__index=ProgressBar
  109.  
  110. ComboBox = {
  111. x,y,width,height,color,kind="combobox",
  112. draw = function(self) end,
  113. onMouseClick = function(self) end,
  114. onMouseDown = function(self) end,
  115. onMouseUp = function(self) end
  116. }
  117. ComboBox.__index=ComboBox
  118.  
  119. ImageView = {}
  120. ImageView.__index=ImageView
  121.  
  122. ListView={}
  123. ListView.__index=ListView
  124.  
  125. CheckBox = {}
  126. CheckBox.__index=CheckBox
  127.  
  128. ScrollView = {}
  129. ScrollView.__index=ScrollView
  130.  
  131. Container = {
  132. x,y,width,height,bgColor,kind="container",
  133. draw=function(self) end,
  134. onMouseClick = function(self) end,
  135. onMouseDown = function(self) end,
  136. onMouseUp = function(self) end
  137. }
  138. Container.__index=Container
  139.  
  140. -- MAIN CODE
  141.  
  142. function AppBar.onMouseDown(self,btn,x,y)
  143.     if self.hasCloseButton and x==self.w then
  144.         self.screenOwner:close()
  145.     end
  146. end
  147.  
  148. function AppBar.draw(self)
  149.     local surf=self:getSurface()
  150.    
  151.     surf:fillRect(1,1,self.w,1," ",colors.cyan)
  152.    
  153.     if self.hasCloseButton then
  154.        surf:fillRect(self.w,1,self.w,1,"X",colors.red)
  155.     end
  156.    
  157.     if self.title then
  158.         surf:drawText(self.w/2-#self.title/2, 1, self.title, colors.cyan, colors.black)
  159.     end
  160.    
  161.     surf:render(term,1,self.y)
  162. end
  163.  
  164. function AppBar.new(scr)
  165.     local self={
  166.         items={},
  167.         hasCloseButton=true,
  168.         showName=true,
  169.         draw=AppBar.draw,
  170.         getSurface=function(self) return self.graphics end,
  171.         onMouseDown=AppBar.onMouseDown,
  172.     }
  173.     local w,h=scr:getSize()
  174.     self.w=w
  175.     self.y=h+1
  176.     self.graphics=surface.create(w,1," ",colors.black, colors.white)
  177.     return self
  178. end
  179.  
  180. function Screen.showAlert(self, title, message, onres)
  181.     local c_alert=Alert.new(title,message)
  182.     if not (onres==nil) then
  183.         c_alert.onResult=onres
  184.     end
  185.     self.c_alert=c_alert
  186.     self.cont.context=1
  187.     self.context=1
  188. end
  189.  
  190. function Screen.showConfirm(self, title, message, onPos, onNeg, pos, neg)
  191.    
  192.     local c_alert=ConfirmDialog.new(title,message,pos,neg)
  193.     if onPos then
  194.         c_alert.onPositiveResult=onPos
  195.     end
  196.     if onNeg then
  197.         c_alert.onNegativeResult=onNeg
  198.     end
  199.    
  200.     self.c_alert=c_alert
  201.     self.cont.context=1
  202.     self.context=1
  203. end
  204.  
  205. function Screen.close(self)
  206.     self:onClose()
  207.     if (self.disposeOnClose) then
  208.     self.appParent:dispose()
  209.     end
  210. end
  211.  
  212. function Screen.onClose(self)
  213. end
  214.  
  215. function Screen.new(name,sw,sh,sx,sy,woAppBar)
  216.     local self = setmetatable({
  217.         cont=Container.new()
  218.     }, Screen)
  219.     self.cont.screenOwner=self
  220.     self.resetFocus=Screen.resetFocus
  221.     self.disposeOnClose=true
  222.    
  223.     if not woAppBar then
  224.     if (sw==nil)or(sh==nil) then
  225.     local tw,th=term.getSize()
  226.     self.cont:resize(tw,th-1)
  227.     else
  228.     self.cont:resize(sw,sh-1)
  229.     end
  230.     else
  231.  
  232.    
  233.     if (sw==nil)or(sh==nil) then
  234.     local tw,th=term.getSize()
  235.     self.cont:resize(tw,th)
  236.     else
  237.     self.cont:resize(sw,sh)
  238.     end
  239.    
  240.     end
  241.     self.cont.color=WINDOW_BACKGROUND
  242.     self.cont.top=true
  243.     self.c_alert=nil
  244.     local xw,yh=term.getSize()
  245.    
  246.     if not((sx==nil)or(sy==nil)) then
  247.         self:move(sx,sy)
  248.     else
  249.         self:move(1,1)
  250.     end
  251.    
  252.     if not woAppBar then
  253.      self.appBar=AppBar.new(self)
  254.      self.appBar.screenOwner=self
  255.      local w0,h0=self:getSize()
  256.      self.appBarHeight=h0+1
  257.     end
  258.        
  259.     if name then
  260.     self.name=name
  261.     if not woAppBar then
  262.     self.appBar.title=name
  263.     end
  264.     else
  265.     self.name="Application"
  266.     if not woAppBar then
  267.     self.appBar.title="Application"
  268.     end
  269.    
  270.     end
  271.     return self
  272. end
  273.  
  274. function Screen.getSize(self)
  275.     return self.cont.width, self.cont.height
  276. end
  277.  
  278. function Screen.dispose(self)
  279.     term.clear()
  280.     term.setCursorPos(1,1)
  281. end
  282.  
  283. function Screen.add(self, child)
  284.     self.cont:add(child)
  285. end
  286.  
  287. function isInRange(px,py,sx,sy,dx,dy)
  288.     return px>=sx and px<=dx and py>=sy and py<=dy
  289. end
  290.  
  291. function Screen.pollEvents(self)
  292.     if self.context==0 then
  293.  
  294.         -- Pull events from OS
  295.         local event = {os.pullEvent()}
  296.        
  297.         -- Skip this event if flag set
  298.         if self.ignoreNextEvent then
  299.         self.ignoreNextEvent=false
  300.         return
  301.         end
  302.        
  303.         -- Terminate application on Alt+X
  304.         if event[1]=="key" then
  305.         if keys.getName(event[2])=="leftAlt" or keys.getName(event[2])=="rightAlt" then
  306.         self.altDown=true
  307.         end
  308.         if keys.getName(event[2])=="x" and self.altDown then
  309.         self.appParent:dispose()
  310.         end
  311.         end
  312.        
  313.         -- If Alt is up, set flag to false
  314.         if event[1]=="key_up" then
  315.         if keys.getName(event[2])=="leftAlt" or keys.getName(event[2])=="rightAlt" then
  316.         self.altDown=false
  317.         end
  318.         end
  319.        
  320.         -- Send events to container
  321.  
  322.         if event[1]=="mouse_click" then
  323.         local btn=event[2]
  324.         local x=event[3]
  325.         local y=event[4]
  326.         if not(y==self.appBarHeight) then
  327.         self.cont:onMouseDown(btn,x,y,self)
  328.         else
  329.         self.appBar:onMouseDown(btn,x,y)
  330.         end
  331.         end
  332.        
  333.         if event[1]=="mouse_scroll" then
  334.          local btn=event[2]
  335.         local x=event[3]
  336.         local y=event[4]
  337.         if not(y==self.appBarHeight) then
  338.         self.cont:onMouseScroll(event[2],event[3],event[4],self)
  339.         end
  340.         end
  341.        
  342.         if event[1]=="mouse_up" then
  343.         self.cont:onMouseUp(event[2],event[3],event[4],self)
  344.         end
  345.        
  346.         if event[1]=="key" then
  347.         self.cont:onKeyDown(event[2])
  348.         end
  349.        
  350.         if event[1]=="key_up" then
  351.         self.cont:onKeyUp(event[2])
  352.         end
  353.     else
  354.         -- If context is not zero
  355.       local event = {os.pullEvent()}
  356.      
  357.       local comp=self.c_alert
  358.       if not (comp==nil) then
  359.      
  360.       if event[1]=="mouse_click" then
  361.       comp:onMouseClick(self,event[3],event[4])
  362.       end
  363.      
  364.       end
  365.  
  366.     end
  367.  
  368. end
  369.  
  370. function Screen.resize(self, w,h)
  371.     self.cont:resize(w,h)
  372. end
  373.  
  374. function Screen.move(self, x,y)
  375. self.cont.x=x
  376. self.cont.y=y
  377. end
  378.  
  379. function Screen.resetFocus(self)
  380.     self.cont:resetFocus()
  381. end
  382.  
  383. function Screen.draw(self)
  384.     self.cont:draw(true,self)
  385.    
  386.     if self.appBar then
  387.     self.appBar:draw()
  388.     end
  389. end
  390.  
  391. -- CONTAINER
  392.  
  393. function Container.getScreen(self)
  394.     return self.screenOwner
  395. end
  396.  
  397. function Container.resetFocus(self)
  398.     for _,comp in ipairs(self.subComponents) do
  399.         if comp.kind=="container" then
  400.             comp:resetFocus()
  401.         end
  402.     end
  403. end
  404.  
  405. function Container.onMouseDown(self,btn,x,y,owner)
  406.     for _,comp in ipairs(self.subComponents) do
  407.         if (isInRange(x,y,self.x+comp.x-1, self.y+comp.y-1, self.x+comp.x+comp.width-2, self.y+comp.y+comp.height-2)) then
  408.             self.screenOwner:resetFocus()
  409.             local globIndex=self.contId*100+_
  410.             self.holdComp=globIndex
  411.             self.screenOwner.focusedComp=globIndex
  412.             self.focusedComp=globIndex
  413.             comp:onMouseDown(btn,x,y,self)
  414.         end
  415.     end
  416. end
  417.  
  418. function Container.onMouseUp(self,btn,x,y,owner)
  419.     for _,comp in ipairs(self.subComponents) do
  420.         local globIndex=self.contId*100+_
  421.        
  422.         if (isInRange(x,y,self.x+comp.x-1, self.y+comp.y-1, self.x+comp.x+comp.width-2, self.x+comp.y+comp.height-2)) then
  423.             comp:onMouseClick(btn,x,y,self)
  424.             comp:onMouseUp(btn,x,y,self)
  425.         else
  426.             if globIndex==self.holdComp then
  427.                 comp:onMouseUp(btn,x,y,self)
  428.             end
  429.         end
  430.     end
  431. end
  432.  
  433. function Container.onKeyDown(self,key)
  434.     for _,comp in ipairs(self.subComponents) do
  435.         local globIndex=self.contId*100+_
  436.         if self.screenOwner.focusedComp==globIndex or self.focusedComp==globIndex then
  437.             comp:onKeyDown(key)
  438.         end
  439.     end
  440. end
  441.  
  442. function Container.onKeyUp(self,key)
  443.     for _,comp in ipairs(self.subComponents) do
  444.         local globIndex=self.contId*100+_
  445.         if self.screenOwner.focusedComp==globIndex or self.focusedComp==globIndex then
  446.             comp:onKeyUp(key)
  447.         end
  448.     end
  449. end
  450.  
  451. function Container.add(self,comp)
  452.     comp.screenOwner=self.screenOwner
  453.     comp.container=self
  454.     table.insert(self.subComponents,comp)
  455. end
  456.  
  457. function Container.draw(self,focused,window)
  458.  
  459.     if not self.top then
  460.  
  461.     local surf=self:getSurface()
  462.     if self.context==0 then
  463.         surf:fillRect(1,1,self.width,self.height,' ',self.color)
  464.         for _,comp in ipairs(self.subComponents) do
  465.         local globIndex=self.contId*100+_
  466.             if (comp.kind=="container") or (comp.kind=="scrollview") then
  467.                 comp:draw(globIndex==self.screenOwner.focusedComp, self)
  468.                 surf:drawSurfacePart(comp.x, comp.y, 1, 1, comp.width, comp.height, comp:getRSurface())
  469.             else
  470.                 comp:draw(globIndex==self.screenOwner.focusedComp, self)
  471.             end
  472.         end
  473.         if (self.top) then
  474.             --surf:render(term)
  475.  
  476.         end
  477.         elseif self.context==1 then
  478.             local comp = window.c_alert
  479.             comp:draw(self)
  480.             surf:render(term)
  481.     end
  482.    
  483.     else
  484.     local surf=self:getSurface()
  485.     if self.context==0 then
  486.         surf:fillRect(1,1,self.width,self.height,' ',self.color)
  487.         for _,comp in ipairs(self.subComponents) do
  488.         local globIndex=self.contId*100+_
  489.             if (comp.kind=="container") or (comp.kind=="scrollview") then
  490.                 comp:draw(globIndex==self.screenOwner.focusedComp, self)
  491.                 surf:drawSurfacePart(comp.x, comp.y, 1, 1, comp.width, comp.height, comp:getRSurface())
  492.             else
  493.                 comp:draw(globIndex==self.screenOwner.focusedComp, self)
  494.             end
  495.         end
  496.         if (self.top) then
  497.             --surf:render(term)
  498.             surf:render(term, self.x, self.y, 1, 1, self.width, self.height)
  499.            
  500.         end
  501.         elseif self.context==1 then
  502.             local comp = window.c_alert
  503.             comp:draw(self)
  504.             surf:render(term)
  505.     end
  506.    
  507.     end
  508. end
  509.  
  510. function Container.resize(self,w,h)
  511.     self.graphics=surface.create(w,h," ",self.color,colors.black)
  512.     self.width=w
  513.     self.height=h
  514. end
  515.  
  516. function Container.getSurface(self)
  517.     return self.graphics
  518. end
  519.  
  520. function Container.getRSurface(self)
  521.     return self.graphics
  522. end
  523.  
  524. function Container.onMouseScroll(self, dir, x, y, window)
  525.     for _,comp in ipairs(self.subComponents) do
  526.         if (isInRange(x,y,self.x+comp.x-1, self.y+comp.y-1, self.x+comp.x+comp.width-2, self.y+comp.y+comp.height-2)) then
  527.                 comp:onMouseScroll(dir,x,y,self)
  528.         end
  529.     end
  530. end
  531.  
  532. local globContId=0
  533.  
  534. function Container.new()
  535.     local self=setmetatable({
  536.     draw=Container.draw,
  537.     color=colors.red,
  538.     onMouseDown=Container.onMouseDown,
  539.     onMouseUp=Container.onMouseUp,
  540.     onKeyDown=Container.onKeyDown,
  541.     resetFocus=Container.resetFocus,
  542.     onKeyUp=Container.onKeyUp,
  543.     add=Container.add,
  544.     getScreen=Container.getScreen,
  545.     onMouseScroll=Container.onMouseScroll,
  546.     resize=Container.resize,
  547.     getSurface=Container.getSurface,
  548.     context=0,
  549.     contId=globContId+1,
  550.     x=1,
  551.     y=1,
  552.     kind="container",
  553.     subComponents = {}
  554.     }, Component)
  555.     globContId=globContId+1
  556.     self:resize(15,15)
  557.     return self
  558. end
  559.  
  560. -- SCROLLVIEW
  561.  
  562. function ScrollView.onMouseDown(self,btn,x,y,owner)
  563.    
  564.     if x==self.x+self.width-1 then
  565.     return
  566.     end
  567.    
  568.     for _,comp in ipairs(self.subComponents) do
  569.     if (isInRange(x,y,self.x+comp.x-1, self.y+comp.y-self.yOff-1, self.x+comp.x+comp.width-2, self.y+comp.y-self.yOff+comp.height-2)) then
  570.         self.screenOwner:resetFocus()
  571.        
  572.         local globIndex=self.contId*100+_
  573.        
  574.         self.holdComp=globIndex
  575.         self.screenOwner.focusedComp=globIndex
  576.        
  577.         self.focusedComp=globIndex
  578.         comp:onMouseDown(btn,x,y,self)
  579.        
  580.         end
  581.     end
  582. end
  583.  
  584. function ScrollView.onMouseUp(self,btn,x,y,owner)
  585.    for _,comp in ipairs(self.subComponents) do
  586.     local globIndex=self.contId*100+_
  587.     if (isInRange(x,y,self.x+comp.x-1, self.y+comp.y-self.yOff-1, self.x+comp.x+comp.width-2, self.y+comp.y-self.yOff+comp.height-2)) and globIndex==self.holdComp then
  588.     comp:onMouseClick(btn,x,y,self)
  589.     comp:onMouseUp(btn,x,y,self)
  590.     else
  591.    
  592.     if globIndex==self.holdComp then
  593.     comp:onMouseUp(btn,x,y,self)
  594.     end
  595.    
  596.     end
  597.     end
  598. end
  599.  
  600. function ScrollView.draw(self)
  601.     local surf=self:getRSurface()
  602.    
  603.    surf:fillRect(1,1,self.width-1,self.height,' ',self.color)
  604.     for _,comp in ipairs(self.subComponents) do
  605.     local globIndex=self.contId*100+_
  606.         if (comp.kind=="container") or (comp.kind=="scrollview") then
  607.             comp:draw(globIndex==self.screenOwner.focusedComp, self)
  608.             surf:drawSurfacePart(comp.x, comp.y, 1, 1, comp.width, comp.height, comp:getRSurface())
  609.         else
  610.             comp:draw(globIndex==self.screenOwner.focusedComp, self)
  611.         end
  612.     end
  613.    
  614.     surf:drawSurfacePart(1,1,1,self.yOff+1,self.width-1,self.height+self.yOff,self:getSurface())
  615.    
  616.     surf:fillRect(self.width,1,self.width,self.height,' ',colors.white)
  617.    
  618.     local max=self:findMaxY()
  619.     if max==0 then
  620.         surf:fillRect(self.width,1,self.width,self.height,' ',colors.gray)
  621.     else
  622.         local sbe=math.floor((self.yOff+self.height-1)/max*self.height+1)
  623.         local sbb=math.floor((self.yOff-1)/max*self.height+1)
  624.         surf:fillRect(self.width,sbe,self.width,sbb,' ',colors.gray)
  625.     end
  626.    
  627. end
  628.  
  629. function ScrollView.onMouseScroll(self,dir,x,y,parent)
  630. local yMax=self:findMaxY()
  631.  
  632. if dir==1 then
  633.  
  634. if self.yOff<yMax-self.height then
  635. self.yOff=self.yOff+1
  636. end
  637.  
  638. end
  639.  
  640. if dir==-1 then
  641. if self.yOff>0 then
  642. self.yOff=self.yOff-1
  643. end
  644. end
  645.  
  646. end
  647.  
  648. function ScrollView.findMaxY(self)
  649. local max=0
  650.  for _,comp in ipairs(self.subComponents) do
  651.  if comp.y+comp.height>max then max=comp.y+comp.height end
  652.  end
  653. return max
  654. end
  655.  
  656. function ScrollView.new(self)
  657.     local self=setmetatable({
  658.     yOff=0,
  659.     onMouseDown=ScrollView.onMouseDown,
  660.     add=Container.add,
  661.     onMouseUp=ScrollView.onMouseUp,
  662.     findMaxY=ScrollView.findMaxY,
  663.     onMouseScroll=ScrollView.onMouseScroll,
  664.     onKeyUp=Container.onKeyUp,
  665.     onKeyDown=Container.onKeyDown,
  666.     draw=ScrollView.draw,
  667.     getSurface=function(self) return self.internalSurf end,
  668.     getRSurface=function(self) return self.graphics end,
  669.     resetFocus=Container.resetFocus,
  670.     resize=Container.resize,
  671.     width=15,
  672.     context=0,
  673.     height=10,
  674.     x=1,
  675.     y=1,
  676.     color=colors.red,
  677.     internalSurf,
  678.     subComponents={},
  679.     kind="scrollview",
  680.     },Component)
  681.     self:resize(15,10)
  682.     self.contId=globContId+1
  683.     globContId=globContId+1
  684.     self.internalSurf=surface.create(self.width,100,' ',self.color,colors.black)
  685.     return self
  686. end
  687.  
  688. -- ALERT
  689.  
  690. function Alert.onMouseClick(self,window,x,y)
  691. local wid,hei=window:getSize()
  692. local ml=math.max(#self.title,#self.message)
  693. local sx=math.floor(wid/2-ml/2-1)
  694. local sy=math.floor(hei/2-2)
  695. local dx=math.floor(wid/2+ml/2+1)
  696. local dy=math.floor(hei/2+2)
  697.  
  698. if (x>=sx+1 and x<=sx+#" OK " and y==dy) then
  699. self:onResult()
  700. window.context=0
  701. window.cont.context=0
  702. window.c_alert=nil
  703. end
  704.  
  705. end
  706.  
  707. function Alert.draw(self,window)
  708. local wid,hei=term.getSize()
  709. local ml=math.max(#self.title,#self.message)
  710. local sx=math.floor(wid/2-ml/2-1)
  711. local sy=math.floor(hei/2-2)
  712. local dx=math.floor(wid/2+ml/2+1)
  713. local dy=math.floor(hei/2+2)
  714. local surf=window:getSurface()
  715. surf:fillRect(sx,sy,dx,dy,' ',ALERT_ACCENT)
  716. surf:fillRect(sx,sy+1,dx,dy,' ',ALERT_NORMAL)
  717. surf:drawText(sx+1,sy, self.title, ALERT_ACCENT, colors.black)
  718. surf:drawText(sx+1,sy+2,self.message,ALERT_NORMAL, colors.black)
  719. surf:drawText(sx+1,dy," OK ",ALERT_ACCENT,ALERT_ACCENT_TEXT)
  720. end
  721.  
  722. function Alert.new(title, text)
  723.   local self = setmetatable({
  724.   onMouseClick=Alert.onMouseClick,
  725.   draw=Alert.draw
  726.   }, Alert)
  727.   self.title=title
  728.   self.message=text
  729.   return self
  730. end
  731.  
  732. function ConfirmDialog.onMouseClick(self,window,x,y)
  733. local wid,hei=window:getSize()
  734. local ml=math.max(#self.title,#self.message,#(" "..self.posBtn.." ")+3+#(" "..self.negBtn.." "))
  735. local sx=math.floor(wid/2-ml/2-1)
  736. local sy=math.floor(hei/2-2)
  737. local dx=math.floor(wid/2+ml/2+1)
  738. local dy=math.floor(hei/2+2)
  739.  
  740. if (x>=sx+1 and x<=sx+#(" "..self.posBtn.." ") and y==dy) then
  741.     self:onPositiveResult()
  742.     window.context=0
  743.     window.cont.context=0
  744.     window.c_alert=nil
  745. end
  746.  
  747. if (x>=sx+#(" "..self.posBtn.." ")+2 and x<=sx+#(" "..self.posBtn.." ")+1+#(" "..self.negBtn.." ") and y==dy) then
  748.     self:onNegativeResult()
  749.     window.context=0
  750.     window.cont.context=0
  751.     window.c_alert=nil
  752. end
  753.  
  754. end
  755.  
  756. function ConfirmDialog.draw(self,window)
  757. local wid,hei=window.screenOwner:getSize()
  758. local ml=math.max(#self.title,#self.message,#(" "..self.posBtn.." ")+3+#(" "..self.negBtn.." "))
  759. local sx=math.floor(wid/2-ml/2-1)
  760. local sy=math.floor(hei/2-2)
  761. local dx=math.floor(wid/2+ml/2+1)
  762. local dy=math.floor(hei/2+2)
  763. local surf=window:getSurface()
  764. surf:fillRect(sx,sy,dx,dy,' ',ALERT_ACCENT)
  765. surf:fillRect(sx,sy+1,dx,dy,' ',ALERT_NORMAL)
  766. surf:drawText(sx+1,sy, self.title, ALERT_ACCENT, colors.black)
  767. surf:drawText(sx+1,sy+2,self.message,ALERT_NORMAL, colors.black)
  768.  
  769. surf:drawText(sx+1,dy,(" "..self.posBtn.." "),ALERT_ACCENT,ALERT_ACCENT_TEXT)
  770. surf:drawText(sx+2+#(" "..self.posBtn.." "),dy,(" "..self.negBtn.." "),ALERT_ACCENT,ALERT_ACCENT_TEXT)
  771. end
  772.  
  773. function ConfirmDialog.new(title, text, posBtn, negBtn)
  774.   local self = setmetatable({
  775.   onMouseClick=ConfirmDialog.onMouseClick,
  776.   draw=ConfirmDialog.draw,
  777.   posBtn="Yes",
  778.   negBtn="No",
  779.   onPositiveResult=function(self) end,
  780.   onNegativeResult=function(self) end,
  781.   }, ConfirmDialog)
  782.   self.title=title
  783.   self.message=text
  784.  
  785.   if posBtn then
  786.   self.posBtn=posBtn
  787.   end
  788.  
  789.   if negBtn then
  790.   self.negBtn=negBtn
  791.   end
  792.  
  793.   return self
  794. end
  795.  
  796. -- COMPONENT
  797.  
  798. function Component.new()
  799.   local self = setmetatable({}, Component)
  800.   self.x=0
  801.   self.y=0
  802.   self.width=0
  803.   self.height=0
  804.   return self
  805. end
  806.  
  807.  
  808. -- BUTTON
  809.  
  810. function Button.draw(self, focused)
  811.     if self.width==0 or self.height==0 then
  812.     return
  813.     end
  814.     local surf=self.container:getSurface()
  815.     surf:fillRect(self.x, self.y, self.x+self.width-1, self.y+self.height-1, ' ', self.color)
  816.     surf:drawText(self.x, self.y, string.sub(self.text,1,self.width), self.color, colors.white)
  817. end
  818.  
  819. function Button.onMouseDown(self)
  820.     self.color=self.colorPressed
  821. end
  822.  
  823. function Button.onMouseUp(self)
  824.     self.color=self.colorNormal
  825. end
  826.  
  827. function Button.new()
  828.   local self = setmetatable({
  829.   color=BUTTON_COLOR_NORMAL,
  830.   colorNormal=BUTTON_COLOR_NORMAL,
  831.   colorPressed=BUTTON_COLOR_DOWN,
  832.   draw=Button.draw,
  833.   onMouseDown=Button.onMouseDown,
  834.   onMouseUp=Button.onMouseUp,
  835.   onMouseClick=Button.onMouseClick,
  836.   width=8,
  837.   height=1,
  838.   x=1,
  839.   y=1,
  840.   kind="button",
  841.   text="button"
  842.   }, Component)
  843.   return self
  844. end
  845.  
  846. -- EditText
  847.  
  848. function EditText.draw(self,focused)
  849.     if self.width==0 or self.height==0 then
  850.     return
  851.     end
  852.     local surf=self.container:getSurface()
  853.     surf:fillRect(self.x, self.y, self.x+self.width-1, self.y+self.height-1, ' ', self.color)
  854.     local si=(#self.text-(self.width-1))>0 and #self.text-(self.width-1) or 1
  855.     local sd=(#self.text>self.width) and self.width or #self.text
  856.    
  857.     if not self.mask then
  858.     surf:drawText(self.x,self.y,string.sub(self.text,si,#self.text),self.color,self.colorText)
  859.     else
  860.    
  861.     if sd>0 then
  862.     surf:fillRect(self.x,self.y,self.x+sd-1,self.y,'*',self.color,self.colorText)
  863.     end
  864.    
  865.     end
  866.    
  867.    
  868.    
  869.     if (focused) then
  870.     surf:drawText(sd+self.x,self.y,'_',self.color,self.colorText)
  871.     end
  872. end
  873.  
  874. function EditText.onKeyUp(self, key)
  875.     if keys.getName(key)=="leftShift" or keys.getName(key)=="rightShift" then
  876.     self.shiftDown=false
  877.     return
  878.     end
  879. end
  880.  
  881. function isTypeable(key)
  882.     if key>=2 and key<=11 then return true end
  883.     if key>=16 and key<=27 then return true end
  884.     if key>=30 and key<=40 then return true end
  885.     if key>=44 and key<=53 then return true end
  886.     if keys.getName(key)=="space" then return true end
  887.     return false
  888. end
  889.  
  890. function toKey(key,shiftDown)
  891.     -- Handle special keys
  892.    
  893.     if keys.getName(key)=="leftBracket" then
  894.     return shiftDown and "{" or "["
  895.     end
  896.    
  897.     if keys.getName(key)=="rightBracket" then
  898.     return shiftDown and "}" or "]"
  899.     end
  900.    
  901.     if keys.getName(key)=="semiColon" then
  902.     return shiftDown and ":" or ";"
  903.     end
  904.    
  905.     if keys.getName(key)=="apostrophe" then
  906.     return shiftDown and "\"" or "'"
  907.     end
  908.    
  909.     if keys.getName(key)=="comma" then
  910.     return shiftDown and "<" or ","
  911.     end
  912.    
  913.     if keys.getName(key)=="period" then
  914.     return shiftDown and ">" or "."
  915.     end
  916.    
  917.     if keys.getName(key)=="slash" then
  918.     return shiftDown and "?" or "/"
  919.     end
  920.    
  921.     -- Numbers
  922.    
  923.     if key==2 then
  924.     return shiftDown and "!" or "1"
  925.     end
  926.    
  927.     if key==3 then
  928.     return shiftDown and "@" or "2"
  929.     end
  930.    
  931.     if key==4 then
  932.     return shiftDown and "#" or "3"
  933.     end
  934.    
  935.     if key==5 then
  936.     return shiftDown and "$" or "4"
  937.     end
  938.    
  939.     if key==6 then
  940.     return shiftDown and "%" or "5"
  941.     end
  942.    
  943.     if key==7 then
  944.     return shiftDown and "^" or "6"
  945.     end
  946.    
  947.     if key==8 then
  948.     return shiftDown and "&" or "7"
  949.     end
  950.    
  951.     if key==9 then
  952.     return shiftDown and "*" or "8"
  953.     end
  954.    
  955.     if key==10 then
  956.     return shiftDown and "(" or "9"
  957.     end
  958.    
  959.     if key==11 then
  960.     return shiftDown and ")" or "0"
  961.     end
  962.    
  963.     if shiftDown then
  964.     return string.upper(keys.getName(key))
  965.     end
  966.    
  967.     if keys.getName(key)=="space" then
  968.     return " "
  969.     end
  970.    
  971.     return keys.getName(key)
  972. end
  973.  
  974. function EditText.onKeyDown(self, key)
  975.  
  976.     if (#self.text>0) and (keys.getName(key)=="backspace") then
  977.     self.text=string.sub(self.text,1,#self.text-1)
  978.     return
  979.     end
  980.    
  981.     if keys.getName(key)=="leftShift" or keys.getName(key)=="rightShift" then
  982.     self.shiftDown=true
  983.     return
  984.     end
  985.    
  986.     if self.limit==0 then
  987.     if isTypeable(key) then
  988.     self.text=self.text..toKey(key,self.shiftDown)
  989.     self:onType(key)
  990.     end
  991.     else
  992.    
  993.     if isTypeable(key) and #self.text<self.limit then
  994.     self.text=self.text..toKey(key,self.shiftDown)
  995.     self:onType(key)
  996.     end
  997.    
  998.     end
  999.    
  1000. end
  1001.  
  1002. function EditText.new()
  1003.   local self = setmetatable({
  1004.   draw=EditText.draw,
  1005.   color=EDITTEXT_COLOR_NORMAL,
  1006.   colorText=EDITTEXT_TEXT_NORMAL,
  1007.   onKeyDown=EditText.onKeyDown,
  1008.   onKeyUp=EditText.onKeyUp,
  1009.   onType=function(self,key)end,
  1010.   x=1,
  1011.   y=1,
  1012.   width=17,
  1013.   height=1,
  1014.   limit=0,
  1015.   kind="edittext",
  1016.   text=""
  1017.   }, Component)
  1018.   return self
  1019. end
  1020.  
  1021. -- Label
  1022.  
  1023. function ellipsisize(str,n)
  1024. return string.sub(str,1,n-2)..".."
  1025. end
  1026.  
  1027. function Label.draw(self)
  1028.     local surf=self.container:getSurface()
  1029.     if self.width==0 then
  1030.     surf:drawText(self.x,self.y,self.text,self.container.color,self.color)
  1031.     else
  1032.     surf:drawText(self.x,self.y,ellipsisize(self.text,self.width),self.container.color,self.color)
  1033.     end
  1034. end
  1035.  
  1036. function Label.new()
  1037.     local self=setmetatable({
  1038.     draw=Label.draw,
  1039.     color=colors.black,
  1040.     width=0,
  1041.     height=0,
  1042.     x=1,
  1043.     y=1,
  1044.     text=""
  1045.     }, Component)
  1046.     return self
  1047. end
  1048.  
  1049. -- ListView
  1050.  
  1051. function ListView.draw(self)
  1052.     local surf=self.container:getSurface()
  1053.    
  1054.     for _,item in ipairs(self.items) do
  1055.     local col=_==self.itemSelected and colors.cyan or self.bgColor
  1056.     surf:fillRect(self.x,self.y+_-1,self.x+self.width-1,self.y+_-1,' ',col,self.color)
  1057.     surf:drawText(self.x,self.y+_-1,item,col,self.color)
  1058.     end
  1059. end
  1060.  
  1061. function ListView.add(self, item)
  1062.     table.insert(self.items, item)
  1063.     self.height=self.height+1
  1064. end
  1065.  
  1066. function ListView.onMouseDown(self,btn, x, y, sender)
  1067.     local indexClicked=sender.kind=="scrollview" and (sender.yOff==0 and y-sender.y-self.y+2 or y-sender.y-self.y+2+sender.yOff) or y-1
  1068.  
  1069.     if indexClicked<=#self.items then
  1070.     self.itemSelected=indexClicked
  1071.    
  1072.     if self.selectable then
  1073.     self:onSelectItem(indexClicked)
  1074.     end
  1075.    
  1076.     end
  1077. end
  1078.  
  1079. function ListView.onMouseUp(self,btn,x,y,sender)
  1080.     local indexClicked=sender.kind=="scrollview" and (sender.yOff==0 and y-sender.y-self.y+2 or y-sender.y-self.y+2+sender.yOff) or y-1
  1081.  
  1082.     if indexClicked==self.itemSelected and not self.selectable then
  1083.         self:onClickItem(self.itemSelected)
  1084.     end
  1085.    
  1086.     if not self.selectable then
  1087.     self.itemSelected=0
  1088.     end
  1089. end
  1090.  
  1091. function ListView.new()
  1092.     local self=setmetatable({
  1093.     draw=ListView.draw,
  1094.     add=ListView.add,
  1095.     color=colors.black,
  1096.     bgColor=colors.white,
  1097.     onMouseDown=ListView.onMouseDown,
  1098.     onMouseUp=ListView.onMouseUp,
  1099.     onSelectItem=function(self, index) end,
  1100.     onClickItem=function(self, index) end,
  1101.     selectable=false,
  1102.     itemSelected=0,
  1103.     width=15,
  1104.     height=0,
  1105.     x=1,
  1106.     y=1,
  1107.     items={},
  1108.     }, Component)
  1109.     return self
  1110. end
  1111.  
  1112. -- PROGRESSBAR
  1113.  
  1114. function ProgressBar.draw(self)
  1115. if self.width<=0 or self.height<=0 then
  1116. return
  1117. end
  1118. local surf=self.container:getSurface()
  1119. local pw=math.min(math.floor((self.value/self.valueMax)*(self.width-1)),self.width-1)
  1120. surf:fillRect(self.x,self.y,self.x+pw-1,self.height,' ',self.accent)
  1121. surf:fillRect(self.x+pw,self.y,self.width-1,self.height,' ',self.color)
  1122. end
  1123.  
  1124. function ProgressBar.new()
  1125.     local self=setmetatable({
  1126.     draw=ProgressBar.draw,
  1127.     accent=ALERT_ACCENT,
  1128.     color=colors.white,
  1129.     width=15,
  1130.     height=1,
  1131.     x=1,
  1132.     y=1,
  1133.     value=0,
  1134.     valueMax=100,
  1135.     text=""
  1136.     }, Component)
  1137.     return self
  1138. end
  1139.  
  1140. -- COMBOBOX
  1141.  
  1142. ComboBoxOverlay = {
  1143. draw=function() end,
  1144. onMouseClick=function() end,
  1145. x,y
  1146. }
  1147. ComboBoxOverlay.__index=ComboBoxOverlay
  1148.  
  1149. function ComboBoxOverlay.onMouseClick(self, window, x, y)
  1150.     if x>=self.x and x<=self.x+window.a_data.width-1 and y>=self.y and y<=self.y+#window.a_data.items-1 then
  1151.     window.cont.context=0
  1152.     window.context=0
  1153.     window.ignoreNextEvent=true
  1154.     local off=y-self.y+1
  1155.     window.a_data.selectedItem=off
  1156.     window.a_data:onSelectItem(off)
  1157.     else
  1158.     window.context=0
  1159.     window.ignoreNextEvent=true
  1160.     end
  1161. end
  1162.  
  1163. function ComboBoxOverlay.draw(self,window)
  1164.     local mw=window.screenOwner.a_data.width
  1165.     local mh=#window.screenOwner.a_data.items
  1166.     local surf=window:getSurface()
  1167.    
  1168.     surf:fillRect(self.x,self.y,self.x+mw-1,self.y+mh-1,' ',colors.white)
  1169.    
  1170.     for _,item in ipairs(window.screenOwner.a_data.items) do
  1171.      surf:drawText(self.x,self.y-1+_,item,colors.white,colors.black)
  1172.     end
  1173.  
  1174.     --window.cont:draw(self,nil, 1)
  1175. end
  1176.  
  1177. function ComboBoxOverlay.new()
  1178.     local self=setmetatable({
  1179.     onMouseClick=ComboBoxOverlay.onMouseClick,
  1180.     draw=ComboBoxOverlay.draw
  1181.     }, ComboBoxOverlay)
  1182.     return self
  1183. end
  1184.  
  1185. function ComboBox.onMouseClick(self,button,x,y,window)
  1186.     if #self.items>=2 then
  1187.    
  1188.     window:getScreen().cont.context=1
  1189.     window:getScreen().context=1
  1190.    window:getScreen().a_data=self
  1191.     local c_overlay=ComboBoxOverlay.new()
  1192.     c_overlay.x=self.x
  1193.     c_overlay.y=self.y
  1194.     window:getScreen().c_alert=c_overlay
  1195.     end
  1196. end
  1197.  
  1198. function ComboBox.draw(self)
  1199. local surf=self.container:getSurface()
  1200. surf:fillRect(self.x,self.y,self.x+self.width-2,self.y+self.height-1,' ',self.color)
  1201. if not (self.items[self.selectedItem]==nil) then
  1202.     surf:drawText(self.x,self.y,self.items[self.selectedItem],self.color,colors.black)
  1203. end
  1204. surf:fillRect(self.width-1,self.y,self.width-1,self.y+self.height-1,'V',self.accent,colors.black)
  1205. end
  1206.  
  1207. function ComboBox.new()
  1208.     local self=setmetatable({
  1209.     draw=ComboBox.draw,
  1210.     onMouseClick=ComboBox.onMouseClick,
  1211.     accent=ALERT_ACCENT,
  1212.     color=colors.white,
  1213.     width=15,
  1214.     height=1,
  1215.     x=1,
  1216.     y=1,
  1217.     selectedItem=1,
  1218.     onSelectItem=function(self, index) end,
  1219.     items={},
  1220.     kind="combobox",
  1221.     }, Component)
  1222.     return self
  1223. end
  1224.  
  1225. -- IMAGEVIEW
  1226.  
  1227. function ImageView.draw(self)
  1228.     local surf=self.container:getSurface()
  1229.     if self.fillBackground then
  1230.     surf:fillRect(self.x,self.y,self.width+self.x-1,self.y+self.height-1,' ',self.color)
  1231.     end
  1232.     if self.imgSurf then
  1233.     surf:drawSurfacePart(self.x, self.y, 1, 1, self.width, self.height, self.imgSurf)
  1234.     end
  1235. end
  1236.  
  1237. function ImageView.loadImage(self, file)
  1238.     self.file=file
  1239.     self.imgSurf=surface.load(file)
  1240. end
  1241.  
  1242. function ImageView.getSurface(self)
  1243.     return self.imgSurf
  1244. end
  1245.  
  1246. function ImageView.new(file)
  1247.   local self = setmetatable({}, Component)
  1248.  
  1249.   self.x=1
  1250.   self.y=1
  1251.   self.width=10
  1252.   self.height=10
  1253.   self.fillBackground=true
  1254.   self.color=colors.black
  1255.   if file then
  1256.   self.file=file
  1257.   self.imgSurf=surface.load(file)
  1258.   end
  1259.   self.kind="imageview"
  1260.   self.getSurface=ImageView.getSurface
  1261.   self.loadImage=ImageView.loadImage
  1262.   self.draw=ImageView.draw
  1263.   return self
  1264. end
  1265.  
  1266. -- CHECKBOX
  1267.  
  1268. function CheckBox.draw(self)
  1269.     local surf=self.container:getSurface()
  1270.     surf:drawText(self.x,self.y,string.sub(self.text,1,self.width-2), WINDOW_BACKGROUND, colors.black)
  1271.     local c=self.state and 'X' or ' '
  1272.     surf:drawPixel(self.x+self.width-1,self.y,c,colors.white,colors.black)
  1273. end
  1274.  
  1275. function CheckBox.onMouseClick(self)
  1276.     if self.state then
  1277.     self.state=false
  1278.     else
  1279.     self.state=true
  1280.     end
  1281. end
  1282.  
  1283. function CheckBox.new()
  1284.   local self = setmetatable({}, Component)
  1285.   self.x=1
  1286.   self.y=1
  1287.   self.width=15
  1288.   self.height=1
  1289.   self.text="Checkbox"
  1290.   self.kind="checkbox"
  1291.   self.state=state
  1292.   self.onMouseClick=CheckBox.onMouseClick
  1293.   self.draw=CheckBox.draw
  1294.   return self
  1295. end
  1296.  
  1297. -- APPLICATION
  1298.  
  1299. function Application.start(self, main_code)
  1300. self.alive=true
  1301. if (not (self.appWindow==nil)) then
  1302. self.appWindow.appParent=self
  1303. end
  1304. local win_proc=(function()
  1305. while self.alive do
  1306. if self.appWindow==nil then
  1307. sleep(1)
  1308. else
  1309. self.appWindow:draw()
  1310. self.appWindow:pollEvents()
  1311. end
  1312.  
  1313. end
  1314. end)
  1315.  
  1316. local function wake_notifier()
  1317.     local myTimer = os.startTimer(0.01)
  1318. end
  1319.  
  1320. if (not (self.appWindow==nil)) then
  1321. parallel.waitForAll(win_proc,main_code,wake_notifier)
  1322. elseif (not (main_code==nil)) then
  1323. main_code()
  1324. end
  1325. end
  1326.  
  1327. function Application.dispose(self)
  1328.     if not (self.appWindow==nil) then
  1329.         self.appWindow:dispose()
  1330.     end
  1331.     self.alive=false
  1332. end
  1333.  
  1334. function Application.new()
  1335.     local self=setmetatable({},Application)
  1336.     return self
  1337. end
Advertisement
Add Comment
Please, Sign In to add comment