123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179 |
- return function(BOXUI)
- local utils = BOXUI.utils
- local includes = utils.includesPoint
- local intersects = utils.intersectsRect
- local newbox = utils.newbox
- local setbox = utils.setbox
- local M = utils.newclass("panel")
- M.init = function(self, x, y, width, height)
- x, y = (x or 0), (y or 0)
- width = width or love.graphics.getWidth()
- height = height or love.graphics.getHeight()
-
- self.theme = BOXUI.theme
- self.x, self.y = x, y
- self.width, self.height = width, height
-
- self.active = nil
- self.objects = {}
- self.mousepresses = {} -- track pressed buttons
- self.viewport = newbox("viewport", 0, 0, width, height)
- end
- M.find = function(self, object)
- local objects = self.objects
- for i, v in ipairs(objects) do
- if v == object then return i end
- end
- end
- M.remove = function(self, index)
- local object = self.objects[index]
- object.parent = nil
- if index == self.active then self.active = nil end
- table.remove(self.objects, index)
- if self.onRemove then self:onRemove(object) end
- end
- M.insert = function(self, object, index)
- local objects = self.objects
- object.parent = self
- if not index then return table.insert(objects, object) end
- print("inserting:", index)
- table.insert(objects, index, object)
- end
- M.maketop = function(self, index)
- local objects = self.objects
- if not index or index == #objects then return end
- table.insert(objects, objects[index])
- table.remove(objects, index)
- end
- M.wheelmoved = function(self, wx, wy)
- local active = self.active
- if active then return self.objects[active]:wheelmoved(wx, wy) end
- end
- M.mousemoved = function(self, x, y, dx, dy)
- local objects = self.objects
- local top = #objects
- if top == 0 then return end
- local relx, rely = x - self.x, y - self.y
- if objects[top].dragging then
- --self.dragging = true
- return objects[top]:mousemoved(relx, rely, dx, dy)
- end
-
- local prevactive, active = self.active, nil
- for i = top, 1, -1 do
- if includes(objects[i], relx, rely) then active = i; break end
- end
- self.active = active
-
- prevactive, active = objects[prevactive], objects[active]
- if prevactive ~= active then
- if prevactive and prevactive.unfocus then prevactive:unfocus() end
- if active and active.focus then active:focus() end
- end
-
- if active then
- return active:mousemoved(relx, rely, dx, dy)
- end
-
- objects[top]:mousemoved(relx, rely, dx, dy)
- end
- M.mousepressed = function(self, x, y, button)
- local objects = self.objects
- if #objects == 0 or not self.active then return end
-
- local active = objects[self.active]
- if active.movable and self.active ~= #objects then -- make active top object
- table.remove(objects, self.active)
- table.insert(objects, active)
- self.active = #objects
- end
- active:mousepressed(x - self.x, y - self.y, button)
-
- local waiters = self.mousepresses[button] or {}
- table.insert(waiters, active)
- self.mousepresses[button] = waiters
-
- end
- M.mousereleased = function(self, x, y, button)
- local waiters = self.mousepresses[button]
- if not waiters then return end -- prank call
-
- local objects = self.objects
- if #objects == 0 then return end
- local relx, rely = x - self.x, y - self.y
-
- for i, v in ipairs(waiters) do
- v:mousereleased(relx, rely, button)
- end
- self.mousepresses[button] = nil
-
- local dragged = objects[#objects].dragging
- if dragged then
- --self.dragging = false
- self:mousemoved(relx, rely, 0, 0)
- end
- end
- M.update = function(self, dt)
- local objects = self.objects
- if #objects == 0 or not self.active then return end
- objects[self.active]:update(dt)
- end
- M.draw = function(self, x, y)
- local vp = self.viewport
- x, y = self.x - vp.x + (x or 0), self.y - vp.y + (y or 0)
-
- local theme = self.theme
- local bt = theme.borderThickness
- local color = theme.borderFore
-
- love.graphics.setColor(theme.panelBack)
- --love.graphics.setLineWidth(2)
- love.graphics.rectangle("fill", x + bt, y + bt, self.width - 2 * bt , self.height - 2 * bt)
- local objects = self.objects
- for i, v in ipairs(objects) do
- if v.draw and intersects(v, 0, 0, self.width, self.height) then
- v:draw(x, y)
- end
- end
- end
- local dummyf = function() end
- --M.refresh = dummyf
- --M.expand = dummyf
- --M.redraw = dummyf
- --M.updateViewport = dummyf
- --M.focus = dummyf
- --M.unfocus = dummyf
- M.expand = function(self, width, height)
- self.width, self.height = width, height
- end
- M.updateViewport = function(self, vpx, vpy, vpw, vph)
- setbox(self.viewport, vpx, vpy, vpw, vph)
- end
- BOXUI.add(M)
- end
|