Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- local Os = {}
- Os.Work = true
- Os.Renderers = {}
- local Vec2 = {} do
- Vec2.__index = Vec2
- function Vec2.New(x,y)
- return setmetatable({X=x,Y=y},Vec2)
- end
- function Vec2:XY()
- return self.X,self.Y
- end
- function Vec2:__add(other)
- return Vec2.New(self.X+other.X,self.Y+other.Y)
- end
- end
- local BaseRenderer = {} do
- BaseRenderer.__index = BaseRenderer
- function BaseRenderer.New(pos,size,text,txtCol,bgCol,scroll)
- return setmetatable({
- Pos = pos,
- Size = size,
- Text = text,
- TextColor = txtCol,
- BackgroundColor = bgCol,
- Scroll = scroll,
- TextOffset = 0
- }, BaseRenderer)
- end
- function BaseRenderer:ColorizeTerm()
- local txtColor = self.TextColor or Screen.DefaultTextColor
- term.setTextColor(txtColor)
- local bgColor = self.BackgroundColor or Screen.DefaultBackgroundColor
- term.setBackgroundColor(bgColor)
- end
- function BaseRenderer:RenderLine(line)
- local text = self.Text
- local width, height = self.Size:XY()
- local yoff = line+(self.Scroll or 0)-1
- local start = math.min(#text+1,yoff*width+1)
- local finish = math.min(#text+1,start+width-1)
- local tx = start < 1 and "" or text:sub(start,finish)
- return tx..(" "):rep(width-#tx)
- end
- function BaseRenderer:Render()
- self:ColorizeTerm()
- local pX, pY = self.Pos:XY()
- for y=1, self.Size.Y do
- term.setCursorPos(pX,pY+y-1)
- term.write(self:RenderLine(y))
- end
- self.TextOffset = 0
- end
- end
- local InputService = {} do
- local Connected = {}
- function InputService.Connect(obj,name)
- Connected[obj] = function(e,k)
- obj[name](obj,e,k)
- end
- end
- function InputService.Disconnect(obj)
- Connected[obj] = nil
- end
- function InputService.Run()
- while Os.Work do
- local event, key = os.pullEvent( "key" )
- for _,v in pairs(Connected) do
- v(event, key)
- end
- end
- end
- end
- local RendererMaker = {} do
- local Addons = {} do
- function Addons.Frame(renderer)
- local renderFn = renderer.RenderLine
- function renderer.RenderLine (self,line)
- local px,py = self.Pos:XY()
- local width,height = self.Size:XY()
- if line == 1 or line == height then
- local text = line == 1 and "press Q to close" or ""
- return '+'..text..("-"):rep(width-#text)..'+'
- end
- local actualLine = line-1
- local rightch = (self.Scroll == actualLine-1 and '<') or '|'
- return '|'..renderFn(self,actualLine)..rightch
- end
- end
- function Addons.AdvancedText(renderer)
- function renderer.RenderLine(self,line)
- local width, height = self.Size:XY()
- local text = self.Text
- local textoffset = self.TextOffset
- local yoff = line+(self.Scroll or 0)-1
- local soffset = yoff*width
- local start, ends = 1+soffset+textoffset,width+soffset+textoffset
- if start<1 then
- return (" "):rep(width)
- end
- local s = text:sub(start, ends)
- local nline = s:find('\n')
- local cnext = text:sub(ends+1,ends+1)
- if nline then
- s = s:sub(1,nline-1)..(' '):rep(width-nline+1)
- self.TextOffset = textoffset - width + nline
- elseif cnext == '\n' then
- self.TextOffset = textoffset + 1
- else
- local i = s:reverse():find(' ')
- if i and (cnext~='' and cnext~=' ' and cnext~='\n') then
- self.TextOffset = textoffset - i + 1
- s = s:sub(1,-i)
- end
- if #s<width then s = s..(' '):rep(width-#s) end
- end
- return s
- end
- end
- function Addons.InputEvent(renderer, handler)
- renderer.InputHandle = handler
- end
- end
- local Creator = {} do
- Creator.__index = Creator
- function Creator.New()
- return setmetatable({Addons = {}, Methods = {}},Creator)
- end
- function Creator:DEVAdd(name)
- self.Addons[name] = true
- return self
- end
- function Creator:AddMethod(name,method)
- self.Methods[name] = method
- return self
- end
- function Creator:AddAdvancedText()
- self.Addons.AdvancedText = {}
- return self
- end
- function Creator:AddInputEvent(handler)
- self.Addons.InputEvent = {handler}
- return self
- end
- function Creator:AddFrame()
- self.Addons.Frame = {}
- return self
- end
- function Creator:Remove(name)
- self.Addons[name] = nil
- return self
- end
- function Creator:End(newMaker,Base)
- Base = Base or BaseRenderer
- local Renderer = setmetatable({},Base)
- Renderer.__index = Renderer
- Renderer.Creator = self
- self.NewMaker = newMaker or function(self)
- return function(...)
- local base = Base.New(...)
- return setmetatable(base,Renderer)
- end
- end
- Renderer.New = self.NewMaker(Renderer)
- for i,v in pairs(self.Methods) do
- Renderer[i] = v
- end
- for i,v in pairs(self.Addons) do
- print(Addons[i],i)
- Addons[i](Renderer,table.unpack(v))
- end
- return Renderer
- end
- end
- function RendererMaker.Begin()
- return Creator.New()
- end
- end
- local MyRenderer = RendererMaker.Begin()
- :AddAdvancedText()
- :AddFrame()
- :AddFrame()
- :AddInputEvent(function(self,event,key)
- if key == keys.down then
- self.Scroll = self.Scroll + 1
- elseif key == keys.up then
- self.Scroll = self.Scroll - 1
- elseif key == keys.q then
- self:Close()
- elseif key == keys.right then
- self.Size.X = self.Size.X+1
- elseif key == keys.left then
- self.Size.X = self.Size.X-1
- end
- end)
- :AddMethod("Close",function(self)
- Os.Renderers[self] = nil
- InputService.Disconnect(self)
- end)
- :End(function(self)
- return function(...)
- local Base = BaseRenderer
- local base = Base.New(...)
- local obj = setmetatable(base,self)
- InputService.Connect(obj,"InputHandle")
- Os.Renderers[obj] = obj
- return obj
- end
- end)
- local Screen = {} do
- Screen.DefaultBackgroundColor = colors.black
- Screen.DefaultTextColor = colors.white
- function Screen.Clear()
- term.setBackgroundColor(Screen.DefaultBackgroundColor)
- term.setTextColor(Screen.DefaultTextColor)
- local sX,sY = term.getSize()
- for y=1, sY do
- term.setCursorPos(1,y)
- term.write((" "):rep(sX))
- end
- end
- end
- Screen.BaseRenderer = BaseRenderer
- Os.Screen = Screen
- function Main()
- local rect1 = MyRenderer.New(
- Vec2.New(1,1),
- Vec2.New(30,10),
- [[Hello, World!]],
- colors.red,
- colors.yellow,
- 0
- )
- while Os.Work do
- Screen.Clear()
- for _,v in pairs(Os.Renderers) do
- v:Render()
- end
- sleep(1/24)
- end
- end
- parallel.waitForAll(Main,InputService.Run)
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement