Advertisement
Rijen

GUI.lua

May 8th, 2023 (edited)
649
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 11.84 KB | Gaming | 0 0
  1.  
  2.  
  3. local event=require("event")
  4. -----------------------------------
  5. -- local gpu = component.gpu
  6. local WIDTH,HEIGHT = gpu.getResolution()
  7.  
  8. local Support = {
  9.     stringTruncate = function(string,maxWidth)
  10.         if unicode.len(string) <= maxWidth then
  11.             return string
  12.         else
  13.             return unicode.sub(string,1,maxWidth-3)..'...'
  14.         end
  15.     end
  16. }
  17.  
  18.  
  19. local GUI = {}
  20. function GUI:new()
  21.     local obj = {
  22.         background =0x262626,
  23.         foreground= 0xaaaaaa,
  24.     }
  25.     obj.eventMatrix = {}
  26.  
  27.     function obj:setBackground(color)
  28.         self.background = color
  29.         gpu.setBackground(color)
  30.         return self
  31.     end
  32.     function obj:setForeground(color)
  33.         self.foreground = color
  34.         gpu.setForeground(color)
  35.         return self
  36.     end
  37.  
  38.     function obj:clearEventMatrix()
  39.         for x=1,WIDTH do
  40.             self.eventMatrix[x] = {}
  41.             for y=1,HEIGHT do
  42.                 self.eventMatrix[x][y]={}
  43.             end
  44.         end
  45.     end
  46.  
  47.     function obj:clear()
  48.         gpu.setBackground(self.background)
  49.         gpu.fill(1,1,WIDTH,HEIGHT,' ')
  50.         self:clearEventMatrix()
  51.         return self
  52.     end
  53.  
  54.  
  55.     setmetatable(obj,self)
  56.     self.__index = self;
  57.     return obj
  58. end
  59.  
  60. local ComponentInterface = {}
  61.  
  62. function ComponentInterface:new()
  63.       -- TODO: Надо привафлять ID к каждому инстансу, чтобы понимать кто отправил кастомное событие
  64.     local obj ={ }
  65.  
  66.     obj.prevColors = {
  67.         back = gpu.getBackground(),
  68.         fore = gpu.getForeground(),
  69.     }
  70.  
  71.     -- protected
  72.     function obj:resetColor()
  73.         gpu.setBackground(self.prevColors.back)
  74.         gpu.setForeground(self.prevColors.fore)
  75.     end
  76.  
  77.     function obj:on(event_name,action)
  78.         for x = self.pos.startX, self.pos.endX do
  79.             for y = self.pos.startY, self.pos.endY do
  80.                 self.gui.eventMatrix[x][y][event_name]=action
  81.             end
  82.         end
  83.     end
  84.  
  85.     function ComponentInterface:draw()
  86.         print ('Need realize interface method ComponentInterface:draw')
  87.     end
  88.     setmetatable(obj,self)
  89.     self.__index = self; return obj
  90. end
  91.  
  92. local ButtonInterface = {}
  93.  
  94. setmetatable(ButtonInterface,{__index = ComponentInterface})
  95.  
  96. function ButtonInterface:new(text,marginLeft,marginTop,width)
  97.     local obj = ComponentInterface:new()
  98.     -- local obj = {
  99.     --     colors = {
  100.     --         container = 0x0,
  101.     --         text = 0xFF6d00
  102.     --     },
  103.     --     width = width or unicode.len(text)+4,
  104.     --     height = nil,
  105.     --     text = text,
  106.     --     prevColors = {
  107.     --         back = gpu.getBackground(),
  108.     --         fore = gpu.getForeground(),
  109.     --     },
  110.     -- }
  111.     obj.colors = {
  112.         container = 0x0,
  113.         text = 0xffa450
  114.     }
  115.     obj.width = width or unicode.len(text)+4
  116.     obj.height = nil
  117.     obj.text = text
  118.  
  119.  
  120.     if obj.width < unicode.len(text)+4 then
  121.         obj.width = unicode.len(text)+4
  122.     end
  123.     obj.pos = {
  124.         startX = marginLeft+1,
  125.         startY = marginTop+1,
  126.         endX = obj.width+marginLeft,
  127.         endY = nil -- Устанавливается наследниками
  128.     }
  129.  
  130.     function ButtonInterface:draw()
  131.         print ('Need realize interface method ButtonInterface:draw')
  132.     end
  133.  
  134.     setmetatable(obj,self)
  135.     self.__index = self; return obj
  136. end
  137.  
  138. local Button = {}
  139. setmetatable(Button,{__index = ButtonInterface})
  140.  
  141. function Button:draw()
  142.  
  143.     self.pos.endY = 3+ self.pos.startY-1
  144.     --Рисуем контейнер
  145.     gpu.setBackground(self.prevColors.back)
  146.     gpu.setForeground(self.colors.container)
  147.  
  148.     local symbols = {
  149.         '▄','█','▀'
  150.     }
  151.     for i, symbol in pairs(symbols) do
  152.         gpu.fill(self.pos.startX,self.pos.startY+i-1,self.width,1,symbol)
  153.     end
  154.  
  155.     --Меняем цвета для отрисовки текста
  156.     gpu.setBackground(self.colors.container)
  157.     gpu.setForeground(self.colors.text)
  158.  
  159.     local textOffset = 3
  160.     if width ~= unicode.len(self.text)+4 then
  161.         -- Если ширина не равна ширине текста с отступом по умолчанию
  162.         -- подровняем текст по центру
  163.         textOffset = self.width/2-(unicode.len(self.text)+4)/2 +2
  164.        
  165.     end
  166.  
  167.     gpu.set(self.pos.startX+textOffset,self.pos.startY+1, self.text)
  168.     self:resetColor()
  169.     return self
  170. end
  171.  
  172. local SmallButton = {}
  173. setmetatable(SmallButton,{__index = ButtonInterface})
  174.  
  175. function SmallButton:draw()
  176.  
  177.     self.pos.endY = self.pos.startY
  178.     gpu.setBackground(self.colors.container)
  179.     gpu.setForeground(self.colors.text)
  180.     gpu.fill(self.pos.startX,self.pos.startY,self.width,1,' ')
  181.  
  182.     local textOffset = 3
  183.    
  184.     if width ~= unicode.len(self.text)+4 then
  185.         -- Если ширина не равна ширине текста с отступом по умолчанию
  186.         -- подровняем текст по центру
  187.         textOffset = self.width/2-(unicode.len(self.text)+4)/2 +2
  188.        
  189.     end
  190.     gpu.set(self.pos.startX+textOffset,self.pos.startY, self.text)
  191.     self:resetColor()
  192.     return self
  193. end
  194.  
  195.  
  196. local Frame = {}
  197. setmetatable(Frame,{__index = ComponentInterface})
  198. function Frame:new(width,height,offsetX,offsetY)
  199.     local obj = ComponentInterface:new()
  200.  
  201.     obj.w = width or WIDTH
  202.     obj.h = height or HEIGHT
  203.     obj.offsetX = offsetX or 0
  204.     obj.offsetY = offsetY or 0
  205.     obj.frameColor = 0x555555
  206.     obj.textColor = 0xffa450
  207.    
  208.    
  209.  
  210.     obj.startX, obj.startY = 1+obj.offsetX, 1+obj.offsetY
  211.     obj.endX, obj.endY = obj.w+obj.offsetX,obj.h+obj.offsetY
  212.  
  213.     function obj:draw()
  214.         gpu.setForeground(self.frameColor)
  215.  
  216.         gpu.set(self.startX,self.startY,'╒')
  217.         gpu.set(self.endX,self.startY,'╕')
  218.         gpu.set(self.startX,self.endY,'╘')
  219.         gpu.set(self.endX,self.endY,'╛')
  220.         gpu.fill(self.startX+1,self.startY,self.w-2,1,'═')
  221.         gpu.fill(self.startX+1,self.endY,self.w-2,1,'═')
  222.    
  223.         gpu.fill(self.startX,self.startY+1,1,self.h-2,'│')
  224.         gpu.fill(self.endX,self.startY+1,1,self.h-2,'│')
  225.  
  226.         self:resetColor()
  227.         return self
  228.     end
  229.  
  230.     function obj:drawTitle(text,position)
  231.         local position = position or 'top'
  232.         if position == 'top' then
  233.             drawY = self.startY
  234.         else
  235.             drawY = self.endY
  236.         end
  237.  
  238.         local startpos = self.w/2-unicode.len(text)/2+self.offsetX+2
  239.  
  240.         gpu.setForeground(self.frameColor)
  241.         gpu.set(startpos-2,drawY,'╣')
  242.         gpu.set(startpos+unicode.len(text)+1,drawY,'╠')
  243.         gpu.setForeground(self.textColor)
  244.         gpu.set(startpos-1,drawY,' '..text..' ')
  245.         self:resetColor()
  246.         return self
  247.     end
  248.  
  249.     setmetatable(obj,self)
  250.     self.__index = self; return obj
  251. end
  252.  
  253.  
  254. local Table = {}
  255. setmetatable(Table,{__index = ComponentInterface})
  256. function Table:new(width,height,offsetX,offsetY)
  257.  
  258.     local obj = ComponentInterface:new()
  259.  
  260.     obj.w = width or WIDTH
  261.     obj.h = height or HEIGHT
  262.     obj.offsetX = offsetX or 0
  263.     obj.offsetY = offsetY or 0
  264.     obj.background = 0x212121
  265.     obj.textColor = 0xffa450
  266.     obj.scroll = 0
  267.     obj.rows={}
  268.    
  269.     obj.pos = {}
  270.     obj.pos.startX, obj.pos.startY = 1+obj.offsetX, 1+obj.offsetY
  271.     obj.pos.endX, obj.pos.endY = obj.w+obj.offsetX,obj.h+obj.offsetY
  272.  
  273.     function obj:drawScrollbar()
  274.         gpu.setBackground(0x0)
  275.         gpu.fill(self.pos.endX, self.pos.startY, 1,self.h,  ' ')
  276.         self:resetColor()
  277.     end
  278.  
  279.     function obj:draw()
  280.         gpu.setBackground(self.background)
  281.         gpu.fill(self.pos.startX,self.pos.startY,self.w-1,self.h,' ')
  282.    
  283.         self:resetColor()
  284.         return self
  285.     end
  286.  
  287.     function obj:setRows(rows)
  288.         self.rows = rows
  289.         return self
  290.     end
  291.  
  292.    
  293.     function obj:drawScrollThumb()
  294.         self:drawScrollbar()
  295.         if #self.rows<self.h then
  296.             return self
  297.         end
  298.         local visiblePercent = self.h/#self.rows
  299.         local thumbSize = math.floor(visiblePercent*self.h+0.5)
  300.         local thumbMargin = math.floor((self.scroll/#self.rows) * (self.h)+0.5)
  301.         gpu.setBackground(0xaaaaaa)
  302.         gpu.fill(self.pos.endX, self.pos.startY+thumbMargin, 1,thumbSize,  ' ')
  303.     end
  304.  
  305.     function obj:drawRows()
  306.         self:draw()
  307.         gpu.setBackground(self.background)
  308.         local j = 0
  309.         for i,row in pairs(self.rows) do
  310.            
  311.             if i>self.scroll and i<=self.h+self.scroll then
  312.                 if row.selected then
  313.                     gpu.setBackground(0x444444)
  314.                     gpu.fill(self.pos.startX,self.pos.startY+j,self.w-1,1,' ')
  315.                 end
  316.                 gpu.set(self.pos.startX+1,self.pos.startY+j,Support.stringTruncate(row.name,self.w-3))
  317.                 if row.selected then
  318.                     gpu.setBackground(self.background)
  319.                 end
  320.                 j=j+1
  321.             end
  322.            
  323.         end
  324.  
  325.         self:drawScrollThumb()
  326.         self:resetColor()
  327.         self:on('scroll',function(...)
  328.             local args = {...}
  329.             -- print(args[4])
  330.             self.scroll=self.scroll-args[4]
  331.             if self.scroll<0 then
  332.                 self.scroll = 0
  333.             end
  334.             if self.scroll > #self.rows-self.h then
  335.                 self.scroll = #self.rows-self.h
  336.             end
  337.            
  338.             self:drawRows()
  339.         end)
  340.         self:on('touch',function(...)
  341.             local args = {...}
  342.             local clickID = args[3]-self.pos.startY+self.scroll+1
  343.             if self.rows[clickID].selected==true then
  344.                 self.rows[clickID].selected=false
  345.                 event.push('gui.table.deselect',clickID)
  346.             else
  347.                 self.rows[clickID].selected=true
  348.                 event.push('gui.table.select',clickID)
  349.             end
  350.  
  351.             for i,row in pairs(self.rows) do
  352.                 if i ~=clickID then
  353.                     row.selected=false
  354.                 end
  355.             end
  356.  
  357.            
  358.             self:drawRows()
  359.         end)
  360.         return self
  361.     end
  362.  
  363.  
  364.     setmetatable(obj,self)
  365.     self.__index = self; return obj
  366. end
  367.  
  368. local ItemSelector = {}
  369. setmetatable(ItemSelector,{__index = ComponentInterface})
  370. function ItemSelector:new(width,height,offsetX,offsetY)
  371.     local obj = ComponentInterface:new()
  372.  
  373.     obj.w = width or WIDTH
  374.     obj.h = height or HEIGHT
  375.     obj.offsetX = offsetX or 0
  376.     obj.offsetY = offsetY or 0
  377.     obj.background = 0x212121
  378.     obj.textColor = 0xffa450
  379.  
  380.     obj.itemName = 'Выберите предмет из списка'
  381.    
  382.     obj.pos = {}
  383.     obj.pos.startX, obj.pos.startY = 1+obj.offsetX, 1+obj.offsetY
  384.     obj.pos.endX, obj.pos.endY = obj.w+obj.offsetX,obj.h+obj.offsetY
  385.  
  386.     function obj:draw()
  387.         gpu.setBackground(self.background)
  388.         gpu.setForeground(self.textColor)
  389.  
  390.         gpu.fill(self.pos.startX,self.pos.startY,self.w-1,self.h,' ')
  391.  
  392.         local startpos = self.w/2-(unicode.len(self.itemName)+2)/2+(self.offsetX+1)
  393.         gpu.set(startpos,obj.pos.startY+1,'['..self.itemName..']')
  394.  
  395.         Button:new('Сжечь!', 41, 9,15):draw()
  396.         Button:new('Не сжигать.', 58, 9,15):draw()
  397.  
  398.         self:resetColor()
  399.         return self
  400.     end
  401.  
  402.  
  403.     setmetatable(obj,self)
  404.     self.__index = self; return obj
  405. end
  406.  
  407. function GUI:printBySymbol(str,x,y,yield)
  408.     for i=1, #str do
  409.         local c = unicode.sub(str,i,i+1)
  410.         gpu.set(x+i-1,y,c)
  411.         os.sleep(0.05)
  412.     end    
  413. end
  414.  
  415.  
  416.  
  417. GUI.components = {
  418.     button = Button,
  419.     smallButton = SmallButton,
  420.     frame = Frame,
  421.     table = Table,
  422.     itemSelector = ItemSelector
  423. }
  424. function GUI:create(class)
  425.     -- local proto = elements[class]
  426.     class.gui = self
  427.     return class
  428. end
  429.  
  430.  
  431. return GUI
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement