Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- require "system"
- class "Control" {
- unique = 1,
- public = [[{
- init = function(parent)
- setPos(0, 0)
- setSize(0, 0)
- setVisible(true)
- setName("Control_"..Control.unique)
- Control.unique = Control.unique + 1
- __parent = parent
- end,
- setPos = function(x, y)
- this.x = x
- this.y = y
- return this
- end,
- getPos = function()
- return x, y
- end,
- getAbsPos = function()
- local x, y = 0, 0
- if __parent then
- x, y = __parent.getAbsPos()
- end
- x = x + this.x
- y = y + this.y
- return x, y
- end,
- setSize = function(w, h)
- width = w
- height = h
- return this
- end,
- getSize = function()
- return width, height
- end,
- getMinSize = function()
- return 1, 1
- end,
- setName = function(name)
- this.name = name
- return this
- end,
- setFGColor = function(color)
- fgc = color
- return this
- end,
- setBGColor = function(color)
- bgc = color
- return this
- end,
- click = function(x, y)
- end,
- onClick = function()
- end,
- setVisible = function(visible)
- this.visible = visible
- return this
- end,
- isVisible = function()
- return visible
- end,
- draw = function()
- if not isVisible() then return nil end
- local device = getDevice()
- if device then
- local l, t = getAbsPos()
- local w, h = getSize()
- local r, b = l + w - 1, t + h - 1
- local dx, dy = device.getSize()
- -- print("Drawing control at ("..l..","..t..")")
- if l < 1 then l = 1 end
- if t < 1 then t = 1 end
- if r > dx then r = dx end
- if b > dy then b = dy end
- if bgc then
- if device.setBackgroundColor then
- device.setBackgroundColor(bgc)
- end
- for row = t, b do
- device.setCursorPos(l, row)
- for col = l, r do
- device.write(" ")
- end
- end
- end
- end
- return device
- end,
- getDevice = function()
- if __parent then
- return __parent.getDevice()
- else return nil
- end
- end,
- contains = function(x, y)
- -- print(type(x))
- -- print(type(y))
- return x >= this.x and x < this.x + width and
- y >= this.y and y < this.y + height
- end
- }]]
- }
- class "Label" "Control" {
- public = [[{
- init = function()
- setAlign("center").setVAlign(center).setText("")
- end,
- getMinSize = function()
- return #text, 1
- end,
- setText = function(text)
- this.text = text
- return this
- end,
- setAlign = function(align)
- this.align = align
- return this
- end,
- setVAlign = function(align)
- this.valign = align
- return this
- end,
- draw = function()
- local device = super.draw()
- if not device then return end
- -- print("drawing label "..self.name)
- local x, y = getAbsPos()
- local text = text
- local slackx = width - #text
- local slacky = height - 1
- if align == "center" then
- x = x + slackx / 2
- elseif align == "right" then
- x = x + slackx
- end
- if valign == "center" then
- y = y + slacky / 2
- elseif valign == "bottom" then
- y = y + slacky
- end
- -- print("Displaying text '"..text.."' at ("..x..", "..y..")")
- device.setCursorPos(x, y)
- device.setTextColor(self.fgc)
- device.write(text)
- return device
- end
- }]]
- }
- class "Button" "Label" {
- public = [[{
- init = function()
- state = false
- end,
- setActive = function(state)
- if group then group.reset() end
- this.state = state
- update()
- return this
- end,
- setActiveColor = function(color)
- hlc = color
- update()
- return this
- end,
- setInactiveColor = function(color)
- iac = color
- update()
- return this
- end,
- setToggle = function(toggle)
- this.toggle = toggle
- return this
- end,
- update = function()
- bgc = state and hlc or iac
- end,
- draw = function()
- update()
- super.draw()
- end,
- click = function()
- if toggle then
- setActive(not state)
- else setActive(true)
- end
- draw()
- os.sleep(.15)
- onClick()
- if not toggle then setActive(false) end
- draw()
- os.sleep(.15)
- end
- }]]
- }
- class "ButtonGroup"
- public = [[{
- init = function()
- clear()
- end,
- add = function(button)
- if button.instanceof(Button) then
- table.insert(buttons, button)
- button.group = this
- else print("Not a button")
- end
- end,
- clear = function()
- buttons = {}
- end,
- reset = function()
- for i, b in ipairs(buttons) do
- b.state = false
- end
- end
- }]]
- }
- class "Container" "Control" {
- public = [[{
- clear = function()
- controls = {}
- controlsByName = {}
- end,
- init = function()
- clear()
- end,
- add = function(control)
- table.insert(controls, control)
- -- print(control.name)
- controlsByName[control.name] = control
- control.__parent = this
- control.__idx = #control
- end,
- find = function(name)
- return controlsByName[name]
- end,
- findIndex = function(control)
- if type(control) == "string" then
- control = find(control)
- end
- if control.__parent ~= this then return nil end
- if control.__idx and controls[control.__idx] == control then
- return control.__idx
- end
- for i = 1, #controls do
- if controls[i] == control then
- control.__idx = i
- return i
- end
- end
- return nil
- end,
- moveUp = function(control)
- idx = findIndex(control)
- if not idx or idx >= #controls then return nil end
- controls[idx] = controls[idx+1]
- controls[idx].__idx = idx
- controls[idx+1] = control
- control.__idx = idx+1
- end,
- moveDown = function(control)
- idx = findIndex(control)
- if not idx or idx <= 1 then return nil end
- controls[idx] = controls[idx-1]
- controls[idx]._idx = idx
- controls[idx-1] = control
- control.__idx = idx-1
- end,
- moveTop = function(control)
- while moveUp(control) do end
- end,
- moveBottom = function(control)
- while moveDown(control) do end
- end,
- addButton = function(name, text, func, param, x, y, w, h)
- b = new "Button"()
- b.name = name
- b.setText(text)
- b.setPos(x, y)
- b.setSize(w, h)
- b.setAction(func, param)
- b.setActive(false)
- add(b)
- end,
- addLabel = function(name, text, x, y, w, h)
- l = new "Label"()
- l.name = name
- l:setText(text)
- l:setPos(x, y)
- l:setSize(w, h)
- self:add(l)
- end,
- draw = function()
- local device = super.draw()
- if not device then return end
- for k, v in ipairs(controls) do
- v.draw()
- end
- return device
- end,
- click = function(x, y)
- print("Clicked ("..x..", "..y..")")
- for i = #controls, 1, -1 do
- local c = controls[i]
- if c.isVisible() and c.contains(x, y) then
- c.click(x - c.x, y - c.y)
- return
- end
- end
- onClick(x, y)
- end
- }]]
- }
- class "Screen" "Container"
- public = [[{
- init = function()
- setPos(1,1)
- end,
- setDevice = function(device)
- this.device = device
- if device then
- setSize(device.getSize())
- device.setScreen(this)
- end
- return this
- end,
- getDevice = function()
- return device
- end,
- draw = function()
- if device then
- device.clear()
- return super.draw()
- end
- end,
- click = function(x, y)
- sx, sy = getAbsPos()
- super.click(x - sx, y - sy)
- end
- }]]
- }
- class "Scrollbar" "Control"
- public = [[{
- init = function()
- thumb = new "Control"()
- thumb.__parent = this
- pos = 0
- max = 0
- end,
- setBounds = function(min, max)
- pos = 0
- this.min = min
- this.max = max
- return this
- end,
- setProgress = function(value)
- if value >= min and value <= max then
- pos = value
- end
- return this
- end,
- getProgress = function()
- return math.floor(pos + 0.5)
- end,
- setPercent = function(value)
- local range = max - min
- if range > 0 and value >= 0 and value <= 100 then
- pos = min + range * value
- end
- return this
- end,
- setType = function(value)
- type = value
- return this
- end,
- draw = function()
- -- print(self.__parent)
- device = super.draw()
- if not device then return end
- if width >= 1 and height >= 1 then
- -- print("Drawing scrollbar at ("..x..","..y..")")
- -- print("Min "..min.." Max "..max)
- if max > min then
- if type == "horizontal" then
- thumb.setSize(1, height)
- thumb.setPos((pos - min) / (max - min) * (width-1), 0)
- else
- thumb.setSize(self.width, 1)
- thumb.setPos(0, (pos - min) / (max - min) * (height-1))
- end
- -- print(self.thumb.name)
- -- print(self.thumb.isVisible())
- thumb.setBGColor(colors.blue)
- local tx, ty = thumb.getAbsPos()
- -- print("Drawing thumb at ("..tx..","..ty..")")
- thumb.draw()
- end
- end
- return device
- end,
- click = function(x, y)
- if type == horizontal then
- setPercent((x - this.x) / (width - 1))
- else
- setPercent((y - this.y) / (height - 1))
- end
- -- print("Set scrollbar to "..pos)
- end
- }]]
- }
- class "Grid" "Container"
- public = [[{
- init = function()
- hscroll = new "Scrollbar"(this)
- .setFGColor(colors.gray)
- .setBGColor(colors.lightGray)
- .setType("horizontal")
- vscroll = new "Scrollbar"(self)
- .setFGColor(colors.gray)
- .setBGColor(colors.lightGray)
- .setType("vertical")
- rows, cols = 0, 0
- end,
- setMargins = function(ml, mt, mr, mb)
- this.ml, this.mt, this.mr, this.mb = ml, mt, mr, mb
- return this
- end,
- setHGap = function(gap)
- hgap = gap
- return this
- end,
- setVGap = function(gap)
- vgap = gap
- return this
- end,
- setRows = function(rows)
- this.rows = rows
- return this
- end,
- setCols = function(cols)
- this.cols = cols
- return this
- end,
- --"horizontal": will lay out by columns
- --"vertical": will lay out by rows
- setDirection =function(dir)
- this.dir = dir
- return this
- end,
- doLayout = function()
- init()
- local minx, miny = 0, 0
- local ex, ey = 1, 1
- for k, v in ipairs(controls) do
- local w, h = v.getMinSize()
- if w > minx then minx = w end
- if h > miny then miny = h end
- end
- vcols = math.floor((width - ml - mr - ex + hgap) / (minx + hgap))
- vcols2 = math.floor((width - ml - mr + hgap) / (minx + hgap))
- vrows = math.floor((height - mt - mb - ey + vgap) / (miny + vgap))
- vrows2 = math.floor((height - mt - mb + vgap) / (miny + vgap))
- if rows < 1 and cols >= 1 then
- rows = math.ceil(#controls / cols)
- elseif cols < 1 and rows >=1 then
- cols = math.ceil(#controls / rows)
- else
- if dir == "vertical" then
- if cols < 1 then
- vrows = vrows2
- ey = 0
- if #controls <= vrows * vcols2 then
- vcols = vcols2
- ex = 0
- end
- cols = vcols
- end
- rows = math.ceil(#controls / cols)
- else
- if rows < 1 then
- vcols = vcols2
- ex = 0
- if #controls <= vcols * vrows2 then
- vrows = vrows2
- ey = 0
- end
- rows = vrows
- end
- cols = math.ceil(#controls / rows)
- end
- end
- if rows > vrows then
- vscroll.setBounds(0, rows - vrows)
- vscroll.setVisible(true)
- else
- vscroll.setBounds(0, 0)
- vscroll.setVisible(false)
- end
- if cols > vcols then
- hscroll.setBounds(0, cols - vcols)
- hscroll.setVisible(true)
- else
- hscroll.setBounds(0, 0)
- hscroll.setVisible(false)
- end
- vscroll.setPos(width - 1 - mr, mt)
- if hscroll.isVisible() then
- vscroll.setSize(1, height - mt - mb - 1)
- else vscroll.setSize(1, height - mt - mb)
- end
- hscroll.setPos(ml, height - 1 - mb)
- if vscroll.isVisible() then
- hscroll.setSize(width - ml - mr - 1, 1)
- else hscroll.setSize(width - ml - mr, 1)
- end
- cwidth = math.floor((width - ml - mr - ex + hgap) / vcols) - hgap
- cheight = math.floor((height - mt - mb - ey + vgap) / vrows) - vgap
- print(cwidth)
- print(cheight)
- for k, v in ipairs(controls) do
- v.setSize(cwidth, cheight)
- end
- end,
- draw = function()
- local voff = vscroll.getProgress()
- local hoff = hscroll.getProgress()
- if dir == "vertical" then
- local y = mt
- for row = 0, vrows - 1 do
- local x = ml
- for col = 0, vcols - 1 do
- local index = (row + voff) * cols + col + hoff + 1
- local control = controls[index]
- if control then
- control.setPos(x, y)
- control.draw()
- end
- x = x + cwidth + hgap
- end
- y = y + cheight + vgap
- end
- else
- local x = ml
- for col = 0, vcols - 1 do
- local y = mt
- for row = 0, vrows - 1 do
- local index = (col + hoff) * rows + row + voff + 1
- local control = controls[index]
- if control then
- control.setPos(x, y)
- control.draw()
- end
- y = y + cheight + vgap
- end
- x = x + cwidth + hgap
- end
- end
- vscroll.draw()
- hscroll.draw()
- end,
- click = function(x, y)
- if vscroll.isVisible() and vscroll.contains(x, y) then
- vscroll.click(x, y)
- elseif hscroll.isVisible() and hscroll.contains(x, y) then
- hscroll.click(x, y)
- else super.click(x, y)
- end
- end
- }]]
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement