Advertisement
austinv11

ggui

Dec 23rd, 2013
88
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 20.10 KB | None | 0 0
  1. --Created by GopherAtl
  2. --[[
  3. ggui library
  4. a wip, basic api for handling gui-based programs.
  5.  
  6. Currently features labels, edit boxes, buttons, and graphic elements, and has
  7. basic support for running guis on multiple monitors with one program.
  8.  
  9. designed, hopefully, to be easy-to-use, to give useful error messages for easier debugging, and
  10. to generally protect the user from their mistakes.
  11.  
  12. --]]
  13. local localVersion = "0.1"
  14. local author = "GopherAtl"
  15.  
  16. local nilSubstitute={"NIL"}
  17. local HANDLE={"HANDLE"}
  18.  
  19. local nextScreenID=1
  20.  
  21. local function newElement(screen,isDrawn)
  22.   local newElement={isDrawn=isDrawn}
  23.   screen.elements[#screen.elements+1]=newElement
  24.   return #screen.elements, newElement
  25. end
  26.  
  27.  
  28.  
  29. local defaultStyle={
  30.   ["label"]= {
  31.     fg=colors.white,
  32.     bg=colors.black,
  33.     textAlign="left",
  34.     anchorX="left",
  35.     anchorY="top",
  36.   },
  37.   ["button"]={
  38.     textAlign="center",
  39.     leftCh="",
  40.     rightCh="",
  41.     anchorX="left",
  42.     anchorY="top",
  43.     mono={
  44.       fg=colors.white,
  45.       bg=colors.black,
  46.       fgFocused=colors.black,
  47.       bgFocused=colors.white,
  48.       leftChFocused="[",
  49.       rightChFocused="]",
  50.     },
  51.     color={
  52.       fg=colors.white,
  53.       bg=colors.gray,
  54.       fgFocused=colors.yellow,
  55.       bgFocused=colors.blue,
  56.       leftChFocused="",
  57.       rightChFocused="",
  58.     },    
  59.   },
  60.  
  61.   ["textField"]={
  62.     textAlign="left",
  63.     leftCh="",
  64.     rightCh="",
  65.     anchorX="left",
  66.     anchorY="top",
  67.     mono={
  68.       fg=colors.black,
  69.       bg=colors.white,
  70.       fgFocused=colors.white,
  71.       bgFocused=colors.black,
  72.       leftChFocused="[",
  73.       rightChFocused="]",
  74.     },
  75.     color={
  76.       fg=colors.white,
  77.       bg=colors.black,
  78.       fgFocused=colors.yellow,
  79.       bgFocused=colors.blue,
  80.       leftChFocused="",
  81.       rightChFocused="",
  82.     },
  83.   },
  84.  
  85.   ["graphic"]={
  86.     anchorX="left",
  87.     anchorY="top",
  88.     bg=colors.black,
  89.     hAlign="center",
  90.     vAlign="center",
  91.   },
  92.  
  93.   ["screen"]={
  94.     anchorX="center",
  95.     anchorY="center",
  96.     bg=colors.black,
  97.   },
  98. }
  99.  
  100.  
  101.  
  102.  
  103. --[[
  104.   get the id of the tab group for a specified container object. By default gets the top-level
  105.   container.
  106.   NOTE: Containers not implemented yet, always returns the app container regardless of parameters.
  107. --]]
  108. local screenMembers={}
  109.  
  110. function screenMembers.getTabGroupID(screen)
  111.   return screen.tabGroupID
  112. end
  113.  
  114. --removes all items from the specified tab group.
  115. function screenMembers.clearTabGroup(screen, groupID)
  116.   for i=#screen.tabOrder,1,-1 do
  117.     screen.tabOrder[i]=nil
  118.   end
  119. end
  120.  
  121.  
  122. function screenMembers.setStyle(screen, objID, styleObj)
  123.   local e=screen.elements[objID]
  124.   if e==nil then
  125.     error("Invalid id in call to screen.setStyle",2)
  126.   end
  127.   e.style=styleObj
  128. end
  129.  
  130. function screenMembers.getStyleProperty(screen, objID, property, isColor)
  131.   local e=screen.elements[objID]
  132.   if e==nil then
  133.     error("Invalid id in call to screen.getStyleProperty",2)
  134.   end
  135.   if isColor==nil then
  136.     isColor=term.isColor and term.isColor() or nil
  137.   end
  138.   local style=e.style
  139.   local s=style and style[isColor and "color" or "mono"]
  140.   if s and s[property] then
  141.     style=s
  142.   end
  143.   if style==nil or style[property]==nil then    
  144.     style=defaultStyle[e.type]
  145.     local s=style and style[isColor and "color" or "mono"]
  146.     if s and s[property] then
  147.       style=s
  148.     end
  149.   end
  150.   return style and style[property]
  151. end
  152.  
  153.  
  154. function screenMembers.setFocus(screen, objID)
  155.   local e=screen.elements[objID]
  156.   if e==nil then
  157.     error("Invalid id in call to ggui.setStyle",2)
  158.   end
  159.   local prevFocus=screen.tabFocus
  160.   screen.tabFocus=objID
  161.   screen.tabIndex=0
  162.   for i=1,#screen.tabOrder do
  163.     if screen.tabOrder[i]==objID then
  164.       screen.tabIndex=i
  165.       break
  166.     end
  167.   end
  168.   if e.type=="textField" then
  169.     --text field got focus, give it key focus
  170.     screen.keyFocus=objID
  171.   else
  172.     screen.keyFocus=0
  173.   end  
  174.   screen.dirtySet[prevFocus]=true
  175.   screen.dirtySet[screen.tabFocus]=true
  176. end
  177.  
  178. function screenMembers.focusNext(screen)
  179.   screen.tabIndex=screen.tabIndex%#screen.tabOrder + 1
  180.   screenMembers.setFocus(screen,screen.tabOrder[screen.tabIndex])
  181. end
  182.  
  183. function screenMembers.focusPrev(screen)
  184.   screen.tabIndex=(screen.tabIndex+#screen.tabOrder-2)%#screen.tabOrder+1
  185.   screenMembers.setFocus(screen,screen.tabOrder[screen.tabIndex])
  186. end
  187.  
  188. --[[  
  189.   Equivalent to table.insert, inserts the gui element with id itemID to the tab group with groupID,
  190.   at specified index. If index not specified, adds to the end of the group.
  191. --]]
  192. function screenMembers.insertTabItem(screen, groupID, arg2, arg3)
  193.   local itemID=arg3 or arg2
  194.   local index=arg3 and arg2 or (#screen.elements[groupID]+1)
  195.   table.insert(screen.elements[groupID],index,itemID)
  196.   if #screen.elements[groupID]==1 then
  197.     screen.tabIndex=1
  198.     screen.tabFocus=itemID  
  199.   end
  200. end
  201.  
  202. --makes a label, returns id of the label
  203. function screenMembers.addLabel(screen, x,y, width, height, label)
  204.   local id, e=newElement(screen,true)  
  205.   e.x=x
  206.   e.y=y
  207.   e.width=width
  208.   e.height=height
  209.   e.label=label
  210.   e.type="label"
  211.   return id
  212. end
  213.  
  214.  
  215. --basically same as label, just creates a button that generates click events.
  216. function screenMembers.addButton(screen, x,y, width,height, label)
  217.   local id=screen.addLabel(x,y,width,height,label)
  218.   local e=screen.elements[id]
  219.   e.type="button"
  220.   screen.clickables[#screen.clickables+1]=id
  221.   screenMembers.insertTabItem(screen,screen.tabGroupID,id)
  222.   return id
  223. end
  224.  
  225. function screenMembers.addGraphic(screen, x,y, width,height, file, srcx, srcy, srcw, srch)
  226.   local id,e=newElement(screen,true)
  227.   e.x, e.y, e.width, e.height=x,y,width,height
  228.  
  229.   local rawImg=screen.imageCache[file] or paintutils.loadImage(file)
  230.   screen.imageCache[file]=rawImg
  231.  
  232.   if rawImg==nil then
  233.     error("graphic file '"..file.."' not found!",2)
  234.   end
  235.  
  236.   srcx=srcx or 1
  237.   srcy=srcy or 1
  238.   srch=srch or #rawImg
  239.   srcw=srcw or #rawImg[1]
  240.   --crop the image data to this size
  241.   if srcy<1 or srcx<1 or srcy+srch-1>#rawImg or srcx+srcw-1>#rawImg[1] then
  242.     error("image source ranges out of bounds!",2)
  243.   end
  244.   --clamp w/h
  245.   if srcw>width then
  246.     srcw=width
  247.   end
  248.   if srch>height then
  249.     srch=height
  250.   end
  251.   e.imgData={}
  252.   for y=1,srch do
  253.     e.imgData[y]={}
  254.     for x=1,srcw do
  255.       e.imgData[y][x]=rawImg[y+srcy-1][x+srcx-1]
  256.     end
  257.   end
  258.   e.type="graphic"
  259.   return id
  260. end
  261.  
  262. function screenMembers.addTextField(screen, x,y,width,height,initialValue,limit)
  263.   initialValue=initialValue or ""
  264.   limit=limit or width
  265.   local id=screen.addLabel(x,y,width,height,initialValue)
  266.   e=screen.elements[id]
  267.   e.type="textField"
  268.   e.cursorPos=#initialValue+1
  269.   e.limit=limit
  270.   if limit>width then
  271.     error("limit must be no larger than width!",2)
  272.   end
  273.   screen.clickables[#screen.clickables+1]=id
  274.   screenMembers.insertTabItem(screen,screen.tabGroupID,id)
  275.   return id
  276. end
  277.  
  278. --[[
  279.   adds a function to be called when an event occurs matching eventFilter.
  280.  
  281.   eventFilter can be just a string, in which case the handler will be called every time the named
  282.   event occurs. Can also be an array of filters; any non-nil values will be matched to the event
  283.   and it's parameters, and only when all match will handler be called.
  284.  
  285.   handler is a function that will be called when the filter is met. Handler will be always be passed
  286.   one argument, an array of the complete parameters of the event, including the event type, the same
  287.   as would be gotten by {os.pullEvent()}
  288.  
  289.   Any additional parameters will be additional arguments passed to handler when the event occurs.
  290. --]]
  291. function screenMembers.addEventHandler(screen, eventFilter, handler, ...)
  292.   if type(eventFilter)=="string" then
  293.     eventFilter={eventFilter}
  294.   end
  295.   local eh=screen.eventHandlers
  296.   for i=1,#eventFilter do
  297.     local filter=eventFilter[i]
  298.     if filter==nil then
  299.       filter=nilSubstitute
  300.     end
  301.     if eh[filter]==nil then
  302.       local new={[HANDLE]={}}
  303.       eh[filter]=new
  304.       eh=new
  305.     else
  306.       eh=eh[filter]
  307.     end
  308.   end
  309.   eh[HANDLE][#eh+1]={handler, {...}}
  310. end
  311.  
  312. --[[
  313.   change the label of a gui item. guiID is the value returned by the ggui.addXXX function that created
  314.   the element.
  315. --]]
  316. function screenMembers.setText(screen, guiID, newLabel)
  317.   local e=screen.elements[guiID]
  318.   if e==nil then
  319.     error("Invalid element ID in call to ggui.setText!",2)
  320.   end
  321.   e.label=newLabel
  322.   if e.cursorPos and e.cursorPos>#newLabel+1 then
  323.     e.cursorPos=#newLabel+1
  324.   end
  325.   screen.dirtySet[guiID]=true  
  326. end
  327.  
  328. function screenMembers.getText(screen, guiID)
  329.   local e=screen.elements[guiID]
  330.   if e then
  331.     return e.label
  332.   end
  333.   error("Invalid gui element in call to getText!",2)
  334. end
  335.  
  336.  
  337. function newScreen(display,width,height)
  338.   local screen={id=nextScreenID}
  339.   nextScreenID=nextScreenID+1
  340.  
  341.   screen.display=display or "term"
  342.   local scrW,scrH=term.getSize()  
  343.   if screen.display~="term" then
  344.     screen.redirect=peripheral.wrap(display)
  345.     if screen.redirect==nil or peripheral.getType(display)~="monitor" then
  346.       error("Invalid display '"..display.."'!",2)
  347.     end
  348.     scrW,scrH=screen.redirect.getSize()
  349.     if (width and width>scrW) or (height and height>scrH) then
  350.       error("screen larger than target display!",2)
  351.     end
  352.   else
  353.     screen.redirect=term.native
  354.   end
  355.   screen.width=width or scrW
  356.   screen.height=height or scrH
  357.  
  358.   screen.elements={}
  359.   screen.clickables={}
  360.   screen.tabGroupID, screen.tabOrder=newElement(screen,false)
  361.   screen.tabOrder.type="tabGroup"
  362.   screen.imageCache={}
  363.   screen.eventHandlers={}
  364.  
  365.   screen.tabIndex=0
  366.   screen.tabFocus=0
  367.   screen.dirtySet={}
  368.   screen.keyFocus=0
  369.  
  370.   local function wrap(screen,func)
  371.     return function(...)
  372.       --noob-friendly, supporting . or :. if they used : we'll get screen again.
  373.       --so, check for it, and drop it if they did.
  374.       local i=1
  375.       if ({...})[1]==screen then
  376.         i=2
  377.       end
  378.  
  379.       return func(screen,select(i,...))
  380.     end
  381.   end
  382.  
  383.   for k,v in pairs(screenMembers) do
  384.     screen[k]=wrap(screen,v)
  385.   end
  386.  
  387.   return screen
  388. end
  389.  
  390.  
  391. local function makeLabelString(text,width,align,left,right)
  392.   local left, right=left or "", right or ""
  393.   --constrain text length
  394.   local len=#text+#left+#right
  395.   if len>width then
  396.     text=text:sub(1+#left,width-#right)
  397.   elseif len<width then
  398.     if align=="right" then
  399.       text=string.rep(" ",width-len)..text
  400.     elseif align=="center" then
  401.       local half=(width-len)/2
  402.       text=string.rep(" ",math.floor(half))..text..string.rep(" ",math.ceil(half))
  403.     else
  404.       text=text..string.rep(" ",width-len)
  405.     end
  406.   end
  407.   text=left..text..right
  408.   return text
  409. end
  410.  
  411. local function positionElements(screen)
  412.   local scrOffX,scrOffY=0,0
  413.   local scrW,scrH=screen.redirect.getSize()
  414.   if scrW~=screen.width or scrH~=screen.height then
  415.     scrOffX=math.floor((scrW-screen.width)/2)
  416.     scrOffY=math.floor((scrH-screen.height)/2)
  417.   end
  418.   for i=1,#screen.elements do
  419.     local e=screen.elements[i]
  420.     if e.isDrawn then
  421.       local scrX,scrY=e.x,e.y
  422.       local anchorX,anchorY=screen.getStyleProperty(i,"anchorX"),screen.getStyleProperty(i,"anchorY")
  423.       if anchorX=="right" then
  424.         scrX=screen.width-e.x-e.width+1
  425.       elseif anchorX=="center" then
  426.         scrX=math.floor((screen.width-e.width+e.x)/2)
  427.       end
  428.       if anchorY=="bottom" then
  429.         scrY=screen.height-e.y-e.height+1
  430.       elseif anchorY=="center" then
  431.         scrY=math.floor((screen.height-e.height+e.y)/2)
  432.       end
  433.       e.scrX=scrX+scrOffX
  434.       e.scrY=scrY+scrOffY
  435.     end
  436.   end
  437.   dirtyAll(screen)
  438. end
  439.  
  440. local function drawElement(screen, id)
  441.   local e=screen.elements[id]
  442.   local scrX,scrY=e.scrX,e.scrY
  443.  
  444.   if e.type=="label" then
  445.     term.setCursorPos(scrX, scrY+math.floor((e.height-1)/2))
  446.     term.setTextColor(screen.getStyleProperty(id,"fg"))
  447.     term.setBackgroundColor(screen.getStyleProperty(id,"bg"))
  448.     term.write(makeLabelString(e.label,e.width,screen.getStyleProperty(id,"textAlign")))
  449.   elseif e.type=="button" or e.type=="textField" then
  450.     local focused=screen.tabFocus==id
  451.     term.setCursorPos(scrX,scrY+math.floor((e.height-1)/2))
  452.     term.setTextColor(screen.getStyleProperty(id,focused and "fgFocused" or "fg"))
  453.     term.setBackgroundColor(screen.getStyleProperty(id,focused and "bgFocused" or "bg"))
  454.     local pwChar=screen.getStyleProperty(id,"pwChar")
  455.     local text=e.label
  456.     if pwChar then
  457.       text=string.rep(pwChar,#e.label)  
  458.     end
  459.     term.write(makeLabelString(text,e.width,screen.getStyleProperty(id,"textAlign"),screen.getStyleProperty(id,focused and "leftChFocused" or "leftCh"),screen.getStyleProperty(id,focused and "rightChFocused" or "rightCh")))
  460.   elseif e.type=="graphic" then
  461.     --clear the area first
  462.     term.setBackgroundColor(screen.getStyleProperty(id,"bg"))
  463.     for y=1,e.height do
  464.       term.setCursorPos(scrX,scrY+y-1)
  465.       term.write(string.rep(" ",e.width))
  466.     end
  467.     --now blit the image
  468.     --calc and add offsets based on alignment
  469.     local hAlign, vAlign=screen.getStyleProperty(id,"hAlign"),screen.getStyleProperty(id,"vAlign")
  470.     if hAlign=="right" then
  471.       scrX=scrX+e.width-#e.imgData[1]
  472.     elseif hAlign=="center" then
  473.       scrX=scrX+math.floor((e.width-#e.imgData[1])/2)
  474.     end
  475.     if vAlign=="right" then
  476.       scrY=scrY+e.height-#e.imgData
  477.     elseif vAlign=="center" then
  478.       scrY=scrY+math.floor((e.height-#e.imgData)/2)
  479.     end
  480.    
  481.     paintutils.drawImage(e.imgData,scrX,scrY)
  482.      
  483.   end
  484. end
  485.  
  486. local function handleClick(screen, x,y,btn)
  487.   for i=1,#screen.clickables do
  488.     local id=screen.clickables[i]
  489.     local e=screen.elements[id]
  490.     if e then
  491.       if e.type=="button" and e.scrX<=x and e.scrY<=y and e.scrX+e.width>x and e.scrY+e.height>y then
  492.         screen.setFocus(id)
  493.         os.queueEvent("button_activate",screen.id,id)
  494.         return
  495.       end
  496.     end
  497.   end
  498. end
  499.  
  500.  
  501. local function activateElement(screen, id)
  502.   local e=screen.elements[id]
  503.   if e then
  504.     if e.type=="button" then
  505.       os.queueEvent("button_activate",screen.id, id)
  506.     end
  507.   end
  508. end
  509.  
  510.  
  511. local function handleEvent(event,h,handlers)
  512.   if h and type(h)=="table" then
  513.     --indexed items will be handlers with no more filters
  514.     for i=1,#h[HANDLE] do
  515.       if h==nil then
  516.         error("nil h in handleEvent",2)
  517.       elseif h[HANDLE][i]==nil then          
  518.         error("nil h["..i.."] in handleEvent",2)
  519.       elseif h[HANDLE][i][1]==nil then
  520.         error("nil h["..i.."][1] in handleEvent",2)          
  521.       end
  522.  
  523.       h[HANDLE][i][1](event,unpack(h[HANDLE][i][2]))
  524.     end
  525.     --even if had indexed handlers, may have more keyed handlers
  526.     handlers[#handlers+1]=h
  527.   end
  528. end
  529.  
  530. --called when keyboard focus is held by a text field
  531. local function handleKeyboardEvent(screen, event)
  532.  
  533.   local label=screen.getText(screen.keyFocus)
  534.   local e=screen.elements[screen.keyFocus]
  535.  
  536.   if event[1]=="key" then
  537.     if event[2]==keys.enter then
  538.       --shift focus forward
  539.       screen.focusNext()
  540.       --if the next guy is a button, allow the event to pass through
  541.       if screen.elements[screen.tabFocus].type~="button" then
  542.         return true
  543.       end
  544.     elseif event[2]==keys.left then
  545.       --cursor left
  546.       e.cursorPos=math.max(1,e.cursorPos-1)
  547.       return true
  548.     elseif event[2]==keys.right then
  549.       --cursor right
  550.       e.cursorPos=math.min(#label+1,e.cursorPos+1)
  551.       return true
  552.     elseif event[2]==keys.home then
  553.       --cursor to beginning
  554.       e.cursorPos=1
  555.       return true
  556.     elseif event[2]==keys["end"] then
  557.       --cursor to end
  558.       e.cursorPos=#label+1
  559.       return true
  560.     elseif event[2]==keys.backspace then
  561.       --backspace
  562.       label=label:sub(1,e.cursorPos-2)..label:sub(e.cursorPos)
  563.       e.cursorPos=math.max(1,e.cursorPos-1)
  564.       screen.setText(screen.keyFocus,label)
  565.       return true
  566.     elseif event[2]==keys.delete then
  567.       label=label:sub(1,e.cursorPos-1)..label:sub(e.cursorPos+1)
  568.       screen.setText(screen.keyFocus,label)
  569.       return true
  570.     end    
  571.   elseif event[1]=="char" then
  572.     --insert to text    
  573.     if #label<e.limit then
  574.       label=label:sub(1,e.cursorPos-1)..event[2]..label:sub(e.cursorPos)
  575.       e.cursorPos=e.cursorPos+1
  576.       screen.setText(screen.keyFocus,label)
  577.     end
  578.    
  579.     return true
  580.   end
  581.   --anything else, return true so it can be handled elsewhere
  582.   return false  
  583. end
  584.  
  585. function fixCursorPos(screen)
  586.   local e=screen.elements[screen.keyFocus]
  587.   if e==nil then
  588.     error("Invalid objID "..tostring(objID).."!",2)
  589.   end
  590.   local leftCh=screen.getStyleProperty(screen.keyFocus,"leftChFocused")  
  591.   term.setCursorPos(e.x+#leftCh+e.cursorPos-1, e.y)
  592.   term.setCursorBlink(true)
  593. end
  594.  
  595.  
  596. function dirtyAll(screen)
  597.   for i=1,#screen.elements do
  598.     screen.dirtySet[i]=true
  599.   end
  600. end
  601.  
  602. --run the gui. Once your gui controls are set up, you just call ggui.run with the array of screens
  603. --and you're set
  604. function run(...)
  605.   local screens={...}
  606.   local screenByDisplay={}
  607.   for i=1,#screens do
  608.     local screen=screens[i]
  609.     if screenByDisplay[screen.display] then
  610.       error("Multiple screens targeting display '"..screen.display.."'!",2)
  611.     end
  612.  
  613.     screenByDisplay[screen.display]=screen
  614.  
  615.     --position everything
  616.     positionElements(screen)
  617.     screen.redirect.setBackgroundColor(colors.black)
  618.     screen.redirect.clear()
  619.     if screen.display=="term" and screen.elements[screen.tabFocus] and screen.elements[screen.tabFocus].type=="textField" then
  620.       screen.keyFocus=screen.tabFocus
  621.     end
  622.   end
  623.  
  624.  
  625.    
  626.    
  627.   while true do
  628.     --draw dirty
  629.     for i=1,#screens do
  630.       local screen=screens[i]
  631.       if screen.display~="term" then
  632.         term.redirect(screen.redirect)
  633.       end
  634.       for element in pairs(screen.dirtySet) do
  635.         drawElement(screen,element)
  636.       end
  637.       if screen.display~="term" then
  638.         term.restore()
  639.       else
  640.         if screen.keyFocus~=0 then
  641.           fixCursorPos(screen)        
  642.         else
  643.           term.setCursorBlink(false)
  644.         end
  645.       end
  646.       --clear dirty set
  647.       screen.dirtySet={}
  648.     end
  649.     --fix cursor if necessary
  650.  
  651.     --wait for event
  652.     local event={os.pullEventRaw()}
  653.     --process system-level events
  654.     local eventType=event[1]
  655.    
  656.     local handled=false    
  657.    
  658.     if eventType=="terminate" then
  659.       break
  660.     elseif eventType=="mouse_click" then
  661.       local screen=screenByDisplay["term"]
  662.       if screen then
  663.         handleClick(screen, event[3],event[4],event[2])
  664.       end
  665.       handled=true
  666.     elseif eventType=="monitor_touch" then
  667.       local screen=screenByDisplay[event[2]]
  668.       if screen then
  669.         handleClick(screen, event[3],event[4],1)
  670.         handled=true
  671.       end
  672.     elseif eventType=="key" or eventType=="char" then
  673.       local screen=screenByDisplay["term"]
  674.       if screen then
  675.         if screen.keyFocus~=0 then
  676.           handled=handleKeyboardEvent(screen,event)
  677.         end
  678.         if not handled then
  679.           local key=event[2]
  680.           if key==keys.tab or key==keys.right or key==keys.down then
  681.               --tab to next control in tab group
  682.             screen.focusNext()          
  683.             handled=true
  684.           elseif key==keys.left or key==keys.up then
  685.             screen.focusPrev()
  686.             handled=true
  687.           elseif key==keys.enter then
  688.             activateElement(screen,screen.tabFocus)
  689.             handled=true
  690.           end
  691.         end
  692.       end
  693.     elseif eventType=="monitor_resize" then
  694.       local screen=screensByDisplay[event[2]]
  695.       if screen then
  696.         positionElements(screen)
  697.       end
  698.     end
  699.    
  700.     if not handled then
  701.       --now pass events off to any registered event handlers
  702.       local handlers={}
  703.       for i=1,#screens do
  704.         handlers[#handlers+1]=screens[i].eventHandlers
  705.       end
  706.       for i=1,#event do
  707.         local filter=event[i]      
  708.         local newHandlers={}        
  709.         for i=1,#handlers do      
  710.           handleEvent(event,handlers[i][filter],newHandlers)
  711.           handleEvent(event,handlers[i][nilSubstitute],newHandlers)
  712.         end
  713.         handlers=newHandlers
  714.         if #handlers==0 then
  715.           break
  716.         end
  717.       end
  718.     end
  719.   end    
  720. end
  721.  
  722.  
  723.  
  724. --]]
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement