Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- -- util functions
- function ags.DrawingSurface:Frame(x,y,w,h)
- x = x or 0
- y = y or 0
- w = w or self.Width - 1
- h = h or self.Height - 1
- local fillColor = 12678
- local lineColor = 27501
- local cornerColor = 21130
- --fill first
- --self.DrawingColor = fillColor
- --self:DrawRectangle(x,y,x + w, y + h)
- --lines
- self.DrawingColor = lineColor
- self:DrawUnfilledRect(x,y,w,h)
- --corners
- self.DrawingColor = cornerColor
- self:DrawRectangle(x,y,x + 2, y + 2) -- top left
- self:DrawRectangle(x + w - 2, y,x + w, y + 2) -- top right
- self:DrawRectangle(x + w - 2, y + h - 2,x + w, y + h) -- bottom right
- self:DrawRectangle(x,y + h - 2,x, y + h) -- bottom left
- end
- function ags.DrawingSurface:DrawUnfilledRect(x,y,w,h)
- self:DrawLine(x, y, x + w, y)
- self:DrawLine(x, y + h, x + w, y + h)
- self:DrawLine(x, y, x, y + h)
- self:DrawLine(x + w, y, x + w, y + h)
- end
- --color stuff
- Color = {}
- Color.mt = {}
- Color.mt.__index = function(t,v)
- if v == "r" or v == "g" or v == "b" or v == "a" then
- return t.rawColor[v]
- else
- return Color[v]
- end
- end
- Color.mt__newindex = function(t,k,v)
- if k == "r" or k == "g" or k == "b" or k == "a" then
- t.rawColor[k] = clamp(v,0,255)
- else
- t[k] = v
- end
- end
- function Color.FromRGBA(r,g,b,a)
- local o = {}
- setmetatable(o, Color.mt)
- o.rawColor = {}
- o.rawColor.r = r
- o.rawColor.g = g
- o.rawColor.b = b
- o.rawColor.a = a or 255
- return o
- end
- function Color:Copy()
- return Color.FromRGBA(self:unpack())
- end
- function Color:AsAGS()
- return ags.Game.GetColorFromRGB(self.r,self.g,self.b)
- end
- function Color:unpack()
- return self.r, self.g, self.b, self.a
- end
- Color.DarkRed = Color.FromRGBA(128,0,0)
- Color.DarkGreen = Color.FromRGBA(0,128,0)
- Color.DarkBlue = Color.FromRGBA(0,0,128)
- Color.LightGrey = Color.FromRGBA(200,200,200)
- Color.DarkGrey = Color.FromRGBA(50,50,50)
- Color.Blue = Color.FromRGBA(0,8,200)
- Color.White = Color.FromRGBA(255,255,255)
- Color.Black = Color.FromRGBA(0,0,0)
- --GUI
- manager = require('guimanager')
- gui =
- {
- x = 0,
- y = 0,
- width = 100,
- height = 100,
- bgColor = Color.FromRGBA(10,10,10,255),
- fgColor = Color.White,
- borderColor = Color.LightGrey,
- titleBarHeight = 11,
- font = 1,
- zOrder = 1,
- draggable = true
- }
- function gui:new(o)
- o = o or {}
- setmetatable(o, self)
- self.__index = self
- o.visible = o.visible == null and true or o.visible
- o.controls = {}
- o.sprite = ags.DynamicSprite.Create(o.width, o.height)
- manager:add(o)
- return o
- end
- function gui:mouseLeave()
- end
- function gui:mouseEnter()
- -- body
- end
- function gui:mouseUp()
- end
- function gui:keyDown(key)
- return false
- end
- function gui:keyUp(key)
- end
- function gui:mouseDown(x,y,mb)
- if y < self.titleBarHeight and self.draggable then
- self.dragging = true
- manager.dragging = self
- self.offset = {x,y}
- elseif x > self.width - 3 and y > self.height - 3 then
- self.resizing = true
- manager.resizing = self
- self.offset = {x,y}
- self.lastSize = {self.width, self.height}
- end
- end
- function gui:clampToScreen()
- local w = ags.System.ViewportWidth
- local h = ags.System.ViewportHeight
- self.x = clamp(self.x,0,w - self.width)
- self.y = clamp(self.y,0,h - self.height)
- end
- function gui:getControl(x,y)
- for i,v in ipairs(self.controls) do
- if v.x < x and x < v.x + v.width and v.y < y and y < v.y + v.height then
- if v.getControl then
- return v:getControl(x - v.x, y - v.y) or v
- else
- return v
- end
- end
- end
- end
- function gui:update( dt )
- if self.dragging then
- local x,y = ags.Mouse.x, ags.Mouse.y
- self.x = x - self.offset[1]
- self.y = y - self.offset[2]
- elseif self.resizing then
- local x,y = ags.Mouse.x, ags.Mouse.y
- self.width = math.max(self.lastSize[1] + (x - (self.lastSize[1] + self.x)), 1)
- self.height = math.max(self.lastSize[2] + (y - (self.lastSize[2] + self.y)), 1)
- end
- self:clampToScreen()
- for i,v in ipairs(self.controls or {}) do
- v:update(dt)
- end
- end
- function gui:show()
- self.visible = true
- end
- function gui:hide()
- self.visible = false
- end
- function gui:addControl(c)
- table.insert(self.controls, c)
- end
- function gui:absolutePos()
- return self.x, self.y
- end
- function gui.__tostring()
- return "GUI"
- end
- function gui:draw(surface)
- if not self.visible then return end
- if self.width ~= self.sprite.Width or self.height ~= self.sprite.height then
- self.sprite:Delete()
- self.sprite = ags.DynamicSprite.Create(self.width, self.height)
- end
- local s = self.sprite:GetDrawingSurface()
- s:Clear()
- if self.background then
- s:DrawImage(0,0,self.background)
- else
- s.DrawingColor = ags.Game.GetColorFromRGB(self.bgColor:unpack())
- s:DrawRectangle(0, 0,self.width, self.height)
- s.DrawingColor = ags.Game.GetColorFromRGB(self.borderColor:unpack())
- s:DrawRectangle(0,0, self.width, self.titleBarHeight)
- s:Frame()
- if self.text then
- s.DrawingColor = ags.Game.GetColorFromRGB(self.fgColor:unpack())
- s:DrawString(5, 2 ,self.font, self.text)
- end
- end
- for i,v in ipairs(self.controls or {}) do
- v:draw(0,0,s)
- end
- surface:DrawImage(self.x,self.y,self.sprite.Graphic)
- end
- -- gui control
- gui.control =
- {
- x = 0,
- y = 0,
- width = 30,
- height = 10,
- bgColor = Color.DarkGrey,
- fgColor = Color.White,
- hlColor = Color.Blue,
- font = 1,
- text = ""
- }
- function gui.control:new(o)
- local nullFunc = function() end
- o = o or {}
- o.update = nullFunc
- o.draw = nullFunc
- o.mouseOver = nullFunc
- o.mouseEnter = nullFunc
- o.mouseLeave = nullFunc
- o.mouseDown = nullFunc
- o.mouseUp = nullFunc
- o.keyDown = nullFunc
- o.type = "control"
- o.visible = true
- setmetatable(o, { __index = self})
- return o
- end
- function gui.control.__tostring()
- return self.type .. " - " .. (self.name or "")
- end
- function gui.control:parentTo(parent)
- parent:addControl(self)
- self.parent = parent
- end
- function gui.control:focus()
- manager:setFocus(self)
- end
- function gui.control:isFocussed()
- return manager.focussedControl == self
- end
- function gui.control:absolutePos()
- local x,y = self.x, self.y
- local p = self.parent
- local xx,yy = p:absolutePos()
- x,y = xx + x, yy +y
- return x,y
- end
- -- gui button
- gui.button = gui.control:new()
- gui.button.type = "button"
- --setmetatable(gui.button, { __index = gui.control} )
- function gui.button:new(o, parent)
- o = o or {}
- setmetatable(o, { __index = self })
- o:parentTo(parent)
- return o
- end
- function gui.button:mouseEnter()
- self.isMouseOver = true
- end
- function gui.button:mouseLeave()
- self.isMouseOver = false
- self.isPressed = false
- end
- function gui.button:mouseDown(x,y,mb)
- if mb == 1 then
- self.isPressed = true
- end
- end
- function gui.button:mouseUp(x,y,mb)
- if mb == 1 and self.isPressed then
- self:onClick()
- self.isPressed = false
- end
- end
- function gui.button:onClick( ... )
- -- body
- end
- function gui.button:draw(x,y,surface)
- if self.parent.isLayout then
- x,y = self.x + x, self.y + y
- else
- x,y = self.x, self.y
- end
- if self.clip then
- self.width = ags.GetTextWidth(self.text,self.font) + 6
- end
- surface.DrawingColor = ags.Game.GetColorFromRGB(self.bgColor:unpack())
- surface:DrawRectangle(x,y,x + self.width, y + self.height)
- local low = {self.bgColor.r * 0.7, self.bgColor.g * 0.7, self.bgColor.b * 0.7,255}
- local high =
- {
- clamp(self.bgColor.r * 1.5,0,255),
- clamp(self.bgColor.g * 1.5,0,255),
- clamp(self.bgColor.b * 1.5,0,255),
- 255
- }
- if self.isPressed or self.toggled then
- low,high = high,low
- end
- surface.DrawingColor = ags.Game.GetColorFromRGB(unpack(high))
- surface:DrawPath(x,y + self.height,x, y, x + self.width, y)
- surface.DrawingColor = ags.Game.GetColorFromRGB(unpack(low))
- surface:DrawPath(x,y + self.height,x + self.width, y + self.height, x + self.width, y)
- surface.DrawingColor = ags.Game.GetColorFromRGB(self.fgColor:unpack())
- surface:DrawString(x + 3, y + 2, self.font, self.text)
- end
- gui.label = gui.control:new()
- gui.label.type = "label"
- function gui.label:new( o,parent )
- o = o or {}
- setmetatable(o, { __index = self })
- o:parentTo(parent)
- o.alignment = o.alignment or "left"
- o.clip = o.clip or false
- return o
- end
- function gui.label:draw(x,y, surface)
- if self.parent.isLayout then
- x,y = self.x + x, self.y + y
- end
- surface.DrawingColor= self.fgColor:AsAGS()
- surface:DrawString(x,y,self.font,self.text)
- -- local lines = self.text:split("\n")
- -- local w = 0
- -- for _,v in ipairs(lines) do
- -- local lw = self.font:getWidth(v)
- -- w = w > lw and w or lw
- -- end
- -- self.width = w
- -- local _, linecount = string.gsub(self.text, "\n", "")
- -- linecount = linecount + 1
- -- self.height = self.font:getHeight() * linecount
- -- love.graphics.printf(self.text, x, y, self.width + 1, self.alignment)
- end
- -- gui textbox
- gui.textbox = gui.control:new()
- gui.textbox.type = "textbox"
- function gui.textbox:new(o, parent)
- o = o or {}
- o.caret = 0
- o.caretOn = false
- o.caretSpeed = 1
- o.activate = o.activate or function() end
- setmetatable(o, { __index = self })
- o:parentTo(parent)
- return o
- end
- function gui.textbox:keyDown(key)
- if key == 13 then self:activate() return end -- pressed enter
- if key == 8 and self.text:len() > 0 then -- pressed backspace
- self.text = self.text:sub(1, self.text:len() - 1)
- return
- end
- if key < 32 or key > 90 then return end --non ascii keys
- key = string.char(key) -- else
- key = key:lower()
- if ags.IsKeyPressed(403) or ags.System.CapsLock then
- key = key:upper()
- end
- self.text = self.text .. key
- end
- function gui.textbox:update(dt)
- self.caret = self.caret + dt
- if self.caret > self.caretSpeed then
- self.caretOn = not self.caretOn
- self.caret = self.caret - self.caretSpeed
- end
- end
- function gui.textbox:draw(x,y,surface)
- if self.parent.isLayout then
- x,y = self.x + x, self.y + y
- else
- x,y = self.x, self.y
- end
- local w,h = self.width, self.height
- if self.label then
- surface.DrawingColor = self.fgColor:AsAGS()
- local txHeight = ags.GetTextHeight(self.label, self.font, 300)
- surface:DrawString(x, y + h / 2 - txHeight / 2, self.font, self.label)
- local ext = ags.GetTextWidth(self.label, self.font) + 2
- x = x + ext
- w = w - ext
- end
- local tempSpr = ags.DynamicSprite.Create(w,h)
- local tempSur = tempSpr:GetDrawingSurface()
- tempSur.DrawingColor = self.bgColor:AsAGS()
- tempSur:Clear(tempSur.DrawingColor)
- tempSur.DrawingColor = self.fgColor:AsAGS()
- tempSur:DrawString(2, 2, self.font, self.text)
- if self:isFocussed() then
- if self.caretOn then
- local textWidth = ags.GetTextWidth(self.text, self.font)
- local textHeight = ags.GetTextHeight("aYJGilymn", self.font, 500)
- tempSur:DrawLine(textWidth + 2, 2, textWidth + 2, textHeight)
- end
- end
- if self:isFocussed() then
- tempSur.DrawingColor = self.hlColor:AsAGS()
- else
- tempSur.DrawingColor = self.fgColor:AsAGS()
- end
- tempSur:DrawUnfilledRect(0,0,w - 1,h - 1)
- tempSur:Release()
- surface:DrawImage(x,y,tempSpr.Graphic)
- tempSpr:Delete()
- end
- -- gui imagebox
- gui.imagebox = gui.control:new()
- gui.imagebox.type = "imagebox"
- function gui.imagebox:new(o, parent)
- o = o or {}
- setmetatable(o, { __index = self })
- o:parentTo(parent)
- return o
- end
- function gui.imagebox:draw()
- if not self.image then return end
- ags.AbortGame("Image box hasnt been converted to AGS yet")
- local x,y = self:absolutePos()
- if self.clipped then
- lg.setScissor(x,y,self.width, self.height)
- end
- lg.draw(self.image,x,y)
- lg.setScissor()
- end
- -- gui layout
- gui.layout = gui.control:new()
- gui.layout.type = "layout"
- function gui.layout:new(o, parent)
- o = o or {}
- setmetatable(o, { __index = self })
- o:parentTo(parent)
- o.direction = o.direction or "vertical"
- o.drawX = o.x
- o.drawY = o.y
- o.margin = o.margin or 4
- o.spacing = o.spacing or 2
- o.border = o.border == null and true or o.border
- o.controls = {}
- o.isLayout = true
- return o
- end
- function gui.layout.__tostring()
- return "layout"
- end
- function gui.layout:addControl(con)
- table.insert(self.controls, con)
- end
- --function gui.layout:absolutePos()
- --local xx,yy = self.parent:absolutePos()
- --return xx + self.drawX, yy + self.drawY
- --end
- function gui.layout:getControl(x,y)
- for g,v in pairs(self.positions or {}) do
- if v[1] < x and x < v[1] + v[3] and v[2] < y and y < v[2] + v[4] then
- if g.getControl then
- return g:getControl(x - v[1], y - v[2]) or g
- else
- return g
- end
- end
- end
- end
- function gui.layout:update(dt)
- for i,v in ipairs(self.controls or {}) do
- v:update(dt)
- end
- end
- function gui.layout:draw(x,y,surface)
- if not self.visible then return end
- self.drawX = x + self.x + self.margin
- self.drawY = y + self.y + self.margin
- if self.text and self.text ~= "" and self.direction == "vertical" then
- -- not supported in AGS yet
- end
- self.positions = {}
- self.maxHeight = 0
- self.maxWidth = 0
- local drawnOne = false
- for i,v in ipairs(self.controls or {}) do
- if drawnOne and v.visible then
- if self.direction == "vertical" then
- self.drawY = self.drawY + self.spacing
- else
- self.drawX = self.drawX + self.spacing
- end
- end
- v:draw(self.drawX, self.drawY, surface)
- drawnOne = true
- if v.visible then
- self.positions[v] = {self.drawX - x - self.x, self.drawY - y - self.y, v.width, v.height}
- if self.direction == "vertical" then
- self.drawY = self.drawY + v.height
- self.maxWidth = math.max(self.maxWidth, v.width)
- else
- self.drawX = self.drawX + v.width
- self.maxHeight = math.max(self.maxHeight, v.height)
- end
- end
- end
- if self.direction == "vertical" then
- self.height = self.drawY + self.margin - y - self.y
- self.width = self.maxWidth + self.margin * 2
- else
- self.width = self.drawX + self.margin - x - self.x
- self.height = self.maxHeight + self.margin * 2
- end
- if self.border then
- --love.graphics.setColor(self.fgColor:unpack())
- --love.graphics.rectangle("line",self.x + x, self.y + y, self.width, self.height)
- end
- end
- gui.hline = gui.control:new()
- gui.hline.type = "hline"
- function gui.hline:new(o, parent)
- o = o or {}
- o.x = o.x or 0
- o.y = o.y or 0
- o.height = 0
- setmetatable(o, { __index = self })
- o:parentTo(parent)
- end
- function gui.hline:draw(x,y, surface)
- love.graphics.setColor(self.fgColor:unpack())
- love.graphics.line(x,y,x + self.parent.width - 10, y)
- end
- gui.selector = {}
- function gui.selector:new(o,parent)
- o.choices = o.choices or {}
- local lo = gui.layout:new({direction = "horizontal"}, parent)
- lo.label = gui.label:new({text = o.text, y = 2, x =0}, lo)
- lo.left = gui.button:new({text = "<", x=0,y=0, width = 15, height = 15}, lo)
- lo.choice = gui.label:new({alignment = "center", text = o.choices[1], clip = true,width = 65, x=0,y=2,height = 15}, lo)
- lo.right = gui.button:new({text = ">", x=0,y=0, width = 15, height = 15}, lo)
- lo.selectedIndex = 1
- lo.left.onClick = function()
- lo.selectedIndex = loop(lo.selectedIndex - 1,1,#lo.choices)
- lo.choice.text = lo.choices[lo.selectedIndex]
- if lo.onChange and type(lo.onChange == "function") then
- lo.onChange(lo)
- end
- end
- lo.right.onClick = function()
- lo.selectedIndex = loop(lo.selectedIndex + 1,1,#lo.choices)
- lo.choice.text = lo.choices[lo.selectedIndex]
- if lo.onChange and type(lo.onChange == "function") then
- lo.onChange(lo)
- end
- end
- lo.update = function(dt)
- gui.layout.update(self,dt)
- lo.choice.text = lo.choices[lo.selectedIndex]
- end
- lo.choices = o.choices
- return lo
- end
- gui.toolbar = {}
- function gui.toolbar:new(o,parent)
- o.choices = o.choices or {}
- o.direction = "horizontal"
- local lo = gui.layout:new(o, parent)
- lo.buttons = {}
- for i,v in ipairs(o.choices) do
- v.width = o.buttonWidth
- v.height = o.buttonHeight
- v.clip = true
- v.onClick = function(self)
- for i,v in ipairs(self.parent.buttons) do
- v.toggled = false
- end
- self.toggled = true
- self.parent.selected = self
- end
- local b = gui.button:new(v, lo)
- table.insert(lo.buttons, b)
- end
- return lo
- end
- return gui
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement