Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- local event=require("event")
- -----------------------------------
- -- local gpu = component.gpu
- local WIDTH,HEIGHT = gpu.getResolution()
- local Support = {
- stringTruncate = function(string,maxWidth)
- if unicode.len(string) <= maxWidth then
- return string
- else
- return unicode.sub(string,1,maxWidth-3)..'...'
- end
- end
- }
- local GUI = {}
- function GUI:new()
- local obj = {
- background =0x262626,
- foreground= 0xaaaaaa,
- }
- obj.eventMatrix = {}
- function obj:setBackground(color)
- self.background = color
- gpu.setBackground(color)
- return self
- end
- function obj:setForeground(color)
- self.foreground = color
- gpu.setForeground(color)
- return self
- end
- function obj:clearEventMatrix()
- for x=1,WIDTH do
- self.eventMatrix[x] = {}
- for y=1,HEIGHT do
- self.eventMatrix[x][y]={}
- end
- end
- end
- function obj:clear()
- gpu.setBackground(self.background)
- gpu.fill(1,1,WIDTH,HEIGHT,' ')
- self:clearEventMatrix()
- return self
- end
- setmetatable(obj,self)
- self.__index = self;
- return obj
- end
- local ComponentInterface = {}
- function ComponentInterface:new()
- -- TODO: Надо привафлять ID к каждому инстансу, чтобы понимать кто отправил кастомное событие
- local obj ={ }
- obj.prevColors = {
- back = gpu.getBackground(),
- fore = gpu.getForeground(),
- }
- -- protected
- function obj:resetColor()
- gpu.setBackground(self.prevColors.back)
- gpu.setForeground(self.prevColors.fore)
- end
- function obj:on(event_name,action)
- for x = self.pos.startX, self.pos.endX do
- for y = self.pos.startY, self.pos.endY do
- self.gui.eventMatrix[x][y][event_name]=action
- end
- end
- end
- function ComponentInterface:draw()
- print ('Need realize interface method ComponentInterface:draw')
- end
- setmetatable(obj,self)
- self.__index = self; return obj
- end
- local ButtonInterface = {}
- setmetatable(ButtonInterface,{__index = ComponentInterface})
- function ButtonInterface:new(text,marginLeft,marginTop,width)
- local obj = ComponentInterface:new()
- -- local obj = {
- -- colors = {
- -- container = 0x0,
- -- text = 0xFF6d00
- -- },
- -- width = width or unicode.len(text)+4,
- -- height = nil,
- -- text = text,
- -- prevColors = {
- -- back = gpu.getBackground(),
- -- fore = gpu.getForeground(),
- -- },
- -- }
- obj.colors = {
- container = 0x0,
- text = 0xffa450
- }
- obj.width = width or unicode.len(text)+4
- obj.height = nil
- obj.text = text
- if obj.width < unicode.len(text)+4 then
- obj.width = unicode.len(text)+4
- end
- obj.pos = {
- startX = marginLeft+1,
- startY = marginTop+1,
- endX = obj.width+marginLeft,
- endY = nil -- Устанавливается наследниками
- }
- function ButtonInterface:draw()
- print ('Need realize interface method ButtonInterface:draw')
- end
- setmetatable(obj,self)
- self.__index = self; return obj
- end
- local Button = {}
- setmetatable(Button,{__index = ButtonInterface})
- function Button:draw()
- self.pos.endY = 3+ self.pos.startY-1
- --Рисуем контейнер
- gpu.setBackground(self.prevColors.back)
- gpu.setForeground(self.colors.container)
- local symbols = {
- '▄','█','▀'
- }
- for i, symbol in pairs(symbols) do
- gpu.fill(self.pos.startX,self.pos.startY+i-1,self.width,1,symbol)
- end
- --Меняем цвета для отрисовки текста
- gpu.setBackground(self.colors.container)
- gpu.setForeground(self.colors.text)
- local textOffset = 3
- if width ~= unicode.len(self.text)+4 then
- -- Если ширина не равна ширине текста с отступом по умолчанию
- -- подровняем текст по центру
- textOffset = self.width/2-(unicode.len(self.text)+4)/2 +2
- end
- gpu.set(self.pos.startX+textOffset,self.pos.startY+1, self.text)
- self:resetColor()
- return self
- end
- local SmallButton = {}
- setmetatable(SmallButton,{__index = ButtonInterface})
- function SmallButton:draw()
- self.pos.endY = self.pos.startY
- gpu.setBackground(self.colors.container)
- gpu.setForeground(self.colors.text)
- gpu.fill(self.pos.startX,self.pos.startY,self.width,1,' ')
- local textOffset = 3
- if width ~= unicode.len(self.text)+4 then
- -- Если ширина не равна ширине текста с отступом по умолчанию
- -- подровняем текст по центру
- textOffset = self.width/2-(unicode.len(self.text)+4)/2 +2
- end
- gpu.set(self.pos.startX+textOffset,self.pos.startY, self.text)
- self:resetColor()
- return self
- end
- local Frame = {}
- setmetatable(Frame,{__index = ComponentInterface})
- function Frame:new(width,height,offsetX,offsetY)
- local obj = ComponentInterface:new()
- obj.w = width or WIDTH
- obj.h = height or HEIGHT
- obj.offsetX = offsetX or 0
- obj.offsetY = offsetY or 0
- obj.frameColor = 0x555555
- obj.textColor = 0xffa450
- obj.startX, obj.startY = 1+obj.offsetX, 1+obj.offsetY
- obj.endX, obj.endY = obj.w+obj.offsetX,obj.h+obj.offsetY
- function obj:draw()
- gpu.setForeground(self.frameColor)
- gpu.set(self.startX,self.startY,'╒')
- gpu.set(self.endX,self.startY,'╕')
- gpu.set(self.startX,self.endY,'╘')
- gpu.set(self.endX,self.endY,'╛')
- gpu.fill(self.startX+1,self.startY,self.w-2,1,'═')
- gpu.fill(self.startX+1,self.endY,self.w-2,1,'═')
- gpu.fill(self.startX,self.startY+1,1,self.h-2,'│')
- gpu.fill(self.endX,self.startY+1,1,self.h-2,'│')
- self:resetColor()
- return self
- end
- function obj:drawTitle(text,position)
- local position = position or 'top'
- if position == 'top' then
- drawY = self.startY
- else
- drawY = self.endY
- end
- local startpos = self.w/2-unicode.len(text)/2+self.offsetX+2
- gpu.setForeground(self.frameColor)
- gpu.set(startpos-2,drawY,'╣')
- gpu.set(startpos+unicode.len(text)+1,drawY,'╠')
- gpu.setForeground(self.textColor)
- gpu.set(startpos-1,drawY,' '..text..' ')
- self:resetColor()
- return self
- end
- setmetatable(obj,self)
- self.__index = self; return obj
- end
- local Table = {}
- setmetatable(Table,{__index = ComponentInterface})
- function Table:new(width,height,offsetX,offsetY)
- local obj = ComponentInterface:new()
- obj.w = width or WIDTH
- obj.h = height or HEIGHT
- obj.offsetX = offsetX or 0
- obj.offsetY = offsetY or 0
- obj.background = 0x212121
- obj.textColor = 0xffa450
- obj.scroll = 0
- obj.rows={}
- obj.pos = {}
- obj.pos.startX, obj.pos.startY = 1+obj.offsetX, 1+obj.offsetY
- obj.pos.endX, obj.pos.endY = obj.w+obj.offsetX,obj.h+obj.offsetY
- function obj:drawScrollbar()
- gpu.setBackground(0x0)
- gpu.fill(self.pos.endX, self.pos.startY, 1,self.h, ' ')
- self:resetColor()
- end
- function obj:draw()
- gpu.setBackground(self.background)
- gpu.fill(self.pos.startX,self.pos.startY,self.w-1,self.h,' ')
- self:resetColor()
- return self
- end
- function obj:setRows(rows)
- self.rows = rows
- return self
- end
- function obj:drawScrollThumb()
- self:drawScrollbar()
- if #self.rows<self.h then
- return self
- end
- local visiblePercent = self.h/#self.rows
- local thumbSize = math.floor(visiblePercent*self.h+0.5)
- local thumbMargin = math.floor((self.scroll/#self.rows) * (self.h)+0.5)
- gpu.setBackground(0xaaaaaa)
- gpu.fill(self.pos.endX, self.pos.startY+thumbMargin, 1,thumbSize, ' ')
- end
- function obj:drawRows()
- self:draw()
- gpu.setBackground(self.background)
- local j = 0
- for i,row in pairs(self.rows) do
- if i>self.scroll and i<=self.h+self.scroll then
- if row.selected then
- gpu.setBackground(0x444444)
- gpu.fill(self.pos.startX,self.pos.startY+j,self.w-1,1,' ')
- end
- gpu.set(self.pos.startX+1,self.pos.startY+j,Support.stringTruncate(row.name,self.w-3))
- if row.selected then
- gpu.setBackground(self.background)
- end
- j=j+1
- end
- end
- self:drawScrollThumb()
- self:resetColor()
- self:on('scroll',function(...)
- local args = {...}
- -- print(args[4])
- self.scroll=self.scroll-args[4]
- if self.scroll<0 then
- self.scroll = 0
- end
- if self.scroll > #self.rows-self.h then
- self.scroll = #self.rows-self.h
- end
- self:drawRows()
- end)
- self:on('touch',function(...)
- local args = {...}
- local clickID = args[3]-self.pos.startY+self.scroll+1
- if self.rows[clickID].selected==true then
- self.rows[clickID].selected=false
- event.push('gui.table.deselect',clickID)
- else
- self.rows[clickID].selected=true
- event.push('gui.table.select',clickID)
- end
- for i,row in pairs(self.rows) do
- if i ~=clickID then
- row.selected=false
- end
- end
- self:drawRows()
- end)
- return self
- end
- setmetatable(obj,self)
- self.__index = self; return obj
- end
- local ItemSelector = {}
- setmetatable(ItemSelector,{__index = ComponentInterface})
- function ItemSelector:new(width,height,offsetX,offsetY)
- local obj = ComponentInterface:new()
- obj.w = width or WIDTH
- obj.h = height or HEIGHT
- obj.offsetX = offsetX or 0
- obj.offsetY = offsetY or 0
- obj.background = 0x212121
- obj.textColor = 0xffa450
- obj.itemName = 'Выберите предмет из списка'
- obj.pos = {}
- obj.pos.startX, obj.pos.startY = 1+obj.offsetX, 1+obj.offsetY
- obj.pos.endX, obj.pos.endY = obj.w+obj.offsetX,obj.h+obj.offsetY
- function obj:draw()
- gpu.setBackground(self.background)
- gpu.setForeground(self.textColor)
- gpu.fill(self.pos.startX,self.pos.startY,self.w-1,self.h,' ')
- local startpos = self.w/2-(unicode.len(self.itemName)+2)/2+(self.offsetX+1)
- gpu.set(startpos,obj.pos.startY+1,'['..self.itemName..']')
- Button:new('Сжечь!', 41, 9,15):draw()
- Button:new('Не сжигать.', 58, 9,15):draw()
- self:resetColor()
- return self
- end
- setmetatable(obj,self)
- self.__index = self; return obj
- end
- function GUI:printBySymbol(str,x,y,yield)
- for i=1, #str do
- local c = unicode.sub(str,i,i+1)
- gpu.set(x+i-1,y,c)
- os.sleep(0.05)
- end
- end
- GUI.components = {
- button = Button,
- smallButton = SmallButton,
- frame = Frame,
- table = Table,
- itemSelector = ItemSelector
- }
- function GUI:create(class)
- -- local proto = elements[class]
- class.gui = self
- return class
- end
- return GUI
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement