diff --git a/README.md b/README.md index 9658786..38f897f 100644 --- a/README.md +++ b/README.md @@ -10,12 +10,12 @@ only it has been largely refactored and edited to allow for scaling and proper t ## How to use ```lua -local LightWorld = require "lib/light_world" +local LightWorld = require "lib" --the path to where light_world is (in this repo "lib") -- create light world lightWorld = LightWorld({ drawBackground = drawBackground, --the callback to use for drawing the background - drawForground = drawForground, --the callback to use for drawing the foreground + drawForeground = drawForeground, --the callback to use for drawing the foreground ambient = {55,55,55}, --the general ambient light in the environment }) diff --git a/conf.lua b/conf.lua index 87841a8..91544ec 100644 --- a/conf.lua +++ b/conf.lua @@ -32,4 +32,4 @@ function love.conf(t) t.modules.system = true -- Enable the system module (boolean) t.modules.timer = true -- Enable the timer module (boolean) t.modules.window = true -- Enable the window module (boolean) -end \ No newline at end of file +end diff --git a/examples/complex.lua b/examples/complex.lua index cfc4824..c5e5b57 100644 --- a/examples/complex.lua +++ b/examples/complex.lua @@ -1,5 +1,5 @@ -- Example: Complex Example -local LightWorld = require "lib/light_world" +local LightWorld = require "lib" function initScene() -- physic world @@ -94,7 +94,7 @@ function love.load() refractionStrength = 16.0, reflectionVisibility = 0.75, drawBackground = drawBackground, - drawForground = drawForground + drawForeground = drawForeground }) mouseLight = lightWorld:newLight(0, 0, 255, 191, 127, lightRange) @@ -131,9 +131,11 @@ end function love.update(dt) love.window.setTitle("Light vs. Shadow Engine (FPS:" .. love.timer.getFPS() .. ")") - mouseLight:setPosition(love.mouse.getX(), love.mouse.getY(), 16.0 + (math.sin(lightDirection) + 1.0) * 64.0) - mx = love.mouse.getX() - my = love.mouse.getY() + + mx, my = (love.mouse.getX() - offsetX)/scale, (love.mouse.getY() - offsetY)/scale + + mouseLight:setPosition(mx, my, 16.0 + (math.sin(lightDirection) + 1.0) * 64.0) + lightDirection = lightDirection + dt colorAberration = math.max(0.0, colorAberration - dt * 10.0) @@ -357,7 +359,7 @@ function drawBackground(l,t,w,h) end end -function drawForground(l,t,w,h) +function drawForeground(l,t,w,h) love.graphics.setBlendMode("alpha") for i = 1, phyCnt do if phyLight[i]:getType() == "polygon" then diff --git a/examples/normalMap.lua b/examples/normalMap.lua index d4cc948..0d4634e 100644 --- a/examples/normalMap.lua +++ b/examples/normalMap.lua @@ -1,18 +1,18 @@ -- Example: Normal map Example -local LightWorld = require "lib/light_world" +local LightWorld = require "lib" function love.load() x = 0 y = 0 scale = 1 -- load images - image = love.graphics.newImage("gfx/crossColor.jpg") - image_normal = love.graphics.newImage("gfx/crossnrm.jpg") + image = love.graphics.newImage("gfx/rock.png") + image_normal = love.graphics.newImage("gfx/rock_n.png") -- create light world lightWorld = LightWorld({ drawBackground = drawBackground, - drawForground = drawForground, + drawForeground = drawForeground, ambient = {55,55,55}, refractionStrength = 32.0, reflectionVisibility = 0.75, @@ -21,6 +21,7 @@ function love.load() -- create light lightMouse = lightWorld:newLight(0, 0, 160, 160, 160, 300) lightMouse:setGlowStrength(0.3) + --lightMouse.normalInvert = true -- create shadow bodys local w, h = love.graphics.getWidth(), love.graphics.getHeight() @@ -65,7 +66,7 @@ function drawBackground(l,t,w,h) love.graphics.rectangle("fill", -l/scale, -t/scale, w/scale, h/scale) end -function drawForground(l,t,w,h) +function drawForeground(l,t,w,h) love.graphics.setColor(255, 255, 255) local w, h = love.graphics.getWidth(), love.graphics.getHeight() love.graphics.draw(image, w/2-(image:getWidth()/2), h/2-(image:getHeight()/2)) diff --git a/examples/short.lua b/examples/short.lua index 1fd0800..342fcdf 100644 --- a/examples/short.lua +++ b/examples/short.lua @@ -1,5 +1,5 @@ -- Example: Short Example -local LightWorld = require "lib/light_world" +local LightWorld = require "lib" function love.load() testShader = 0 @@ -16,7 +16,7 @@ function love.load() -- create light world lightWorld = LightWorld({ drawBackground = drawBackground, - drawForground = drawForground, + drawForeground = drawForeground, ambient = {55,55,55}, refractionStrength = 32.0, reflectionVisibility = 0.75, @@ -77,6 +77,12 @@ function love.keypressed(k) if colorAberration == 0.0 then colorAberration = 3.0 end + elseif k == "f" then + lightWorld:remove(lightMouse) + elseif k == "g" then + lightWorld:remove(circleTest) + elseif k == "h" then + lightWorld:remove(rectangleTest) end end @@ -110,7 +116,7 @@ function love.update(dt) lightWorld.post_shader:removeEffect("chromatic_aberration") end - lightMouse:setPosition(love.mouse.getX()/scale, love.mouse.getY()/scale) + lightMouse:setPosition((love.mouse.getX() - x)/scale, (love.mouse.getY() - y)/scale) end function love.draw() @@ -132,7 +138,7 @@ function drawBackground(l,t,w,h) love.graphics.rectangle("fill", -l/scale, -t/scale, w/scale, h/scale) end -function drawForground(l,t,w,h) +function drawForeground(l,t,w,h) love.graphics.setColor(63, 255, 127) local cx, cy = circleTest:getPosition() love.graphics.circle("fill", cx, cy, circleTest:getRadius()) diff --git a/gfx/rock.png b/gfx/rock.png new file mode 100644 index 0000000..1f683b4 Binary files /dev/null and b/gfx/rock.png differ diff --git a/gfx/rock_n.png b/gfx/rock_n.png new file mode 100644 index 0000000..b91467e Binary files /dev/null and b/gfx/rock_n.png differ diff --git a/lib/body.lua b/lib/body.lua index fea2a87..4ce0dd4 100644 --- a/lib/body.lua +++ b/lib/body.lua @@ -109,6 +109,17 @@ function body:setPosition(x, y) end end +-- move position +function body:move(x, y) + if x then + self.x = self.x + x + end + if y then + self.y = self.y + y + end + self:refresh() +end + -- get x position function body:getPosition() return self.x, self.y @@ -617,10 +628,12 @@ function body:calculateCircleShadow(light) curShadowGeometry[6] = y3 - (light.y - y3) * shadowLength curShadowGeometry[7] = x2 - (light.x - x2) * shadowLength curShadowGeometry[8] = y2 - (light.y - y2) * shadowLength - curShadowGeometry.alpha = self.alpha + curShadowGeometry.red = self.red curShadowGeometry.green = self.green curShadowGeometry.blue = self.blue + curShadowGeometry.alpha = self.alpha + return curShadowGeometry else return nil diff --git a/lib/light_world.lua b/lib/init.lua similarity index 89% rename from lib/light_world.lua rename to lib/init.lua index de44e5f..1a1c124 100644 --- a/lib/light_world.lua +++ b/lib/init.lua @@ -21,21 +21,24 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ]] -local _PACKAGE = (...):match("^(.+)[%./][^%./]+") or "" -local class = require(_PACKAGE..'/class') -local Light = require(_PACKAGE..'/light') -local Body = require(_PACKAGE..'/body') -local util = require(_PACKAGE..'/util') -local normal_map = require(_PACKAGE..'/normal_map') -local PostShader = require(_PACKAGE..'/postshader') -require(_PACKAGE..'/postshader') +local _PACKAGE = string.gsub(...,"%.","/") or "" +if string.len(_PACKAGE) > 0 then + _PACKAGE = _PACKAGE .. "/" +end +local class = require(_PACKAGE..'class') +local Light = require(_PACKAGE..'light') +local Body = require(_PACKAGE..'body') +local util = require(_PACKAGE..'util') +local normal_map = require(_PACKAGE..'normal_map') +local PostShader = require(_PACKAGE..'postshader') +require(_PACKAGE..'postshader') local light_world = class() -light_world.blurv = love.graphics.newShader(_PACKAGE.."/shaders/blurv.glsl") -light_world.blurh = love.graphics.newShader(_PACKAGE.."/shaders/blurh.glsl") -light_world.refractionShader = love.graphics.newShader(_PACKAGE.."/shaders/refraction.glsl") -light_world.reflectionShader = love.graphics.newShader(_PACKAGE.."/shaders/reflection.glsl") +light_world.blurv = love.graphics.newShader(_PACKAGE.."shaders/blurv.glsl") +light_world.blurh = love.graphics.newShader(_PACKAGE.."shaders/blurh.glsl") +light_world.refractionShader = love.graphics.newShader(_PACKAGE.."shaders/refraction.glsl") +light_world.reflectionShader = love.graphics.newShader(_PACKAGE.."shaders/reflection.glsl") function light_world:init(options) self.lights = {} @@ -55,7 +58,7 @@ function light_world:init(options) self.glowDown = false self.drawBackground = function() end - self.drawForground = function() end + self.drawForeground = function() end options = options or {} for k, v in pairs(options) do self[k] = v end @@ -99,7 +102,7 @@ function light_world:draw(l,t,s) util.drawto(self.render_buffer, l, t, s, function() self.drawBackground( l,t,w,h,s) self:drawShadow( l,t,w,h,s) - self.drawForground( l,t,w,h,s) + self.drawForeground( l,t,w,h,s) self:drawMaterial( l,t,w,h,s) self:drawShine( l,t,w,h,s) self:drawPixelShadow(l,t,w,h,s) @@ -177,7 +180,7 @@ function light_world:drawPixelShadow(l,t,w,h,s) self.pixelShadow2:clear() for i = 1, #self.lights do - self.lights[i]:drawPixelShadow(l,t,w,h, self.normalMap, self.pixelShadow2) + self.lights[i]:drawPixelShadow(l,t,w,h,s, self.normalMap, self.pixelShadow2) end self.pixelShadow:clear(255, 255, 255) @@ -185,7 +188,7 @@ function light_world:drawPixelShadow(l,t,w,h,s) util.drawto(self.pixelShadow, l, t, s, function() love.graphics.setBlendMode("additive") love.graphics.setColor({self.ambient[1], self.ambient[2], self.ambient[3]}) - love.graphics.rectangle("fill", l/s,t/s,w/s,h/s) + love.graphics.rectangle("fill", -l/s, -t/s, w/s,h/s) end) util.drawCanvasToCanvas(self.pixelShadow, self.render_buffer, {blendmode = "multiplicative"}) @@ -277,7 +280,7 @@ end function light_world:clear() light_world:clearLights() - light_world:clearBodys() + light_world:clearBodies() end -- clear lights @@ -287,7 +290,7 @@ function light_world:clearLights() end -- clear objects -function light_world:clearBodys() +function light_world:clearBodies() self.body = {} self.isShadows = false self.isRefraction = false @@ -299,7 +302,7 @@ function light_world:setBackgroundMethod(fn) end function light_world:setForegroundMethod(fn) - self.drawForground = fn or function() end + self.drawForeground = fn or function() end end -- set ambient color @@ -340,7 +343,7 @@ end -- new rectangle function light_world:newRectangle(x, y, w, h) self.isShadows = true - return self:newBody("rectangle", x, y, width, height) + return self:newBody("rectangle", x, y, w, h) end -- new circle @@ -414,4 +417,25 @@ function light_world:getLight(n) return self.lights[n] end +function light_world:remove(to_kill) + if to_kill:is_a(Body) then + for i = 1, #self.body do + if self.body[i] == to_kill then + table.remove(self.body, i) + return true + end + end + elseif to_kill:is_a(Light) then + for i = 1, #self.lights do + if self.lights[i] == to_kill then + table.remove(self.lights, i) + return true + end + end + end + + -- failed to find it + return false +end + return light_world diff --git a/lib/light.lua b/lib/light.lua index f5db6c8..a463ac8 100644 --- a/lib/light.lua +++ b/lib/light.lua @@ -32,6 +32,8 @@ function light:refresh(w, h) self.shadow = love.graphics.newCanvas(w, h) self.shine = love.graphics.newCanvas(w, h) + self.normalInvertShader:send('screenResolution', {w, h}) + self.normalShader:send('screenResolution', {w, h}) end -- set position @@ -47,7 +49,7 @@ end -- get x function light:getPosition() - return self.x, self.y + return self.x, self.y, self.z end -- set color @@ -105,15 +107,17 @@ function light:setGlowStrength(strength) self.glowStrength = strength end -function light:inRange(l,t,w,h) - return self.x + self.range > l and - self.x - self.range < (l+w) and - self.y + self.range > t and - self.y - self.range < (t+h) +function light:inRange(l,t,w,h,s) + local lx, ly, rs = (self.x + l/s) * s, (self.y + t/s) * s, self.range * s + + return (lx + rs) > 0 and + (lx - rs) < w/s and + (ly + rs) > 0 and + (ly - rs) < h/s end function light:drawShadow(l,t,w,h,s,bodies, canvas) - if self.visible and self:inRange(l,t,w,h) then + if self.visible and self:inRange(l,t,w,h,s) then -- calculate shadows local shadow_geometry = {} for i = 1, #bodies do @@ -126,7 +130,8 @@ function light:drawShadow(l,t,w,h,s,bodies, canvas) -- draw shadow self.shadow:clear() util.drawto(self.shadow, l, t, s, function() - self.shader:send("lightPosition", {self.x*s, (h/s - self.y)*s, self.z}) + + self.shader:send("lightPosition", {(self.x + l/s) * s, (h/s - (self.y + t/s)) * s, self.z/255.0}) self.shader:send("lightRange", self.range*s) self.shader:send("lightColor", {self.red / 255.0, self.green / 255.0, self.blue / 255.0}) self.shader:send("lightSmooth", self.smooth) @@ -164,7 +169,7 @@ function light:drawShadow(l,t,w,h,s,bodies, canvas) end function light:drawShine(l,t,w,h,s,bodies,canvas) - if self.visible then + if self.visible and self:inRange(l,t,w,h,s) then --update shine self.shine:clear(255, 255, 255) util.drawto(self.shine, l, t, s, function() @@ -179,21 +184,19 @@ function light:drawShine(l,t,w,h,s,bodies,canvas) end end -function light:drawPixelShadow(l,t,w,h, normalMap, canvas) - if self.visible then +function light:drawPixelShadow(l,t,w,h,s, normalMap, canvas) + if self.visible and self:inRange(l,t,w,h,s) then if self.normalInvert then - self.normalInvertShader:send('screenResolution', {w, h}) self.normalInvertShader:send('lightColor', {self.red / 255.0, self.green / 255.0, self.blue / 255.0}) - self.normalInvertShader:send('lightPosition',{self.x, lh - self.y, self.z / 255.0}) + self.normalInvertShader:send("lightPosition", {(self.x + l/s) * s, (h/s - (self.y + t/s)) * s, self.z / 255.0}) self.normalInvertShader:send('lightRange',{self.range}) self.normalInvertShader:send("lightSmooth", self.smooth) self.normalInvertShader:send("lightAngle", math.pi - self.angle / 2.0) self.normalInvertShader:send("lightDirection", self.direction) util.drawCanvasToCanvas(normalMap, canvas, {shader = self.normalInvertShader}) else - self.normalShader:send('screenResolution', {w, h}) self.normalShader:send('lightColor', {self.red / 255.0, self.green / 255.0, self.blue / 255.0}) - self.normalShader:send('lightPosition',{self.x, h - self.y, self.z / 255.0}) + self.normalShader:send("lightPosition", {(self.x + l/s) * s, (h/s - (self.y + t/s)) * s, self.z / 255.0}) self.normalShader:send('lightRange',{self.range}) self.normalShader:send("lightSmooth", self.smooth) self.normalShader:send("lightAngle", math.pi - self.angle / 2.0) @@ -203,4 +206,8 @@ function light:drawPixelShadow(l,t,w,h, normalMap, canvas) end end +function light:setVisible(visible) + self.visible = visible +end + return light diff --git a/lib/shaders/glow.glsl b/lib/shaders/glow.glsl index 2b5d456..2e302ce 100644 --- a/lib/shaders/glow.glsl +++ b/lib/shaders/glow.glsl @@ -1,5 +1,4 @@ extern Image glowImage; - extern float glowTime; vec4 effect(vec4 color, Image texture, vec2 texture_coords, vec2 pixel_coords) { @@ -17,4 +16,4 @@ vec4 effect(vec4 color, Image texture, vec2 texture_coords, vec2 pixel_coords) { } return vec4(Texel(texture, texture_coords).rgb * glowInfo.r, 1.0); -} \ No newline at end of file +} diff --git a/main.lua b/main.lua index 50e1420..962cda2 100644 --- a/main.lua +++ b/main.lua @@ -7,7 +7,7 @@ -- Updated by Dresenpai require "lib/postshader" -local LightWorld = require "lib/light_world" +local LightWorld = require "lib" exf = {} exf.current = nil @@ -15,32 +15,32 @@ exf.current = nil exf.available = {} function love.load() - exf.list = List:new() - exf.smallfont = love.graphics.newFont(love._vera_ttf,12) - exf.bigfont = love.graphics.newFont(love._vera_ttf, 24) - exf.list.font = exf.smallfont + exf.list = List:new() + exf.smallfont = love.graphics.newFont(love._vera_ttf,12) + exf.bigfont = love.graphics.newFont(love._vera_ttf, 24) + exf.list.font = exf.smallfont - exf.bigball = love.graphics.newImage("gfx/love-big-ball.png") + exf.bigball = love.graphics.newImage("gfx/love-big-ball.png") - -- Find available demos. - local files = love.filesystem.getDirectoryItems("examples") + -- Find available demos. + local files = love.filesystem.getDirectoryItems("examples") local n = 0 - for i, v in ipairs(files) do - n = n + 1 - table.insert(exf.available, v); - local file = love.filesystem.newFile(v, love.file_read) - file:open("r") - local contents = love.filesystem.read("examples/" .. v, 100) - local s, e, c = string.find(contents, "Example: ([%a%p ]-)[\r\n]") - file:close(file) - if not c then c = "Untitled" end - local title = exf.getn(n) .. " " .. c .. " (" .. v .. ")" - exf.list:add(title, v) - end + for i, v in ipairs(files) do + n = n + 1 + table.insert(exf.available, v); + local file = love.filesystem.newFile(v, love.file_read) + file:open("r") + local contents = love.filesystem.read("examples/" .. v, 100) + local s, e, c = string.find(contents, "Example: ([%a%p ]-)[\r\n]") + file:close(file) + if not c then c = "Untitled" end + local title = exf.getn(n) .. " " .. c .. " (" .. v .. ")" + exf.list:add(title, v) + end - exf.list:done() - exf.resume() + exf.list:done() + exf.resume() end function love.update(dt) end @@ -49,7 +49,6 @@ function love.keypressed(k) end function love.keyreleased(k) end function love.mousepressed(x, y, b) end function love.mousereleased(x, y, b) end - function exf.empty() end function exf.update(dt) @@ -77,7 +76,7 @@ function exf.drawBackground() exf.list:draw() end -function exf.drawForground() +function exf.drawForeground() love.graphics.setColor(255, 255, 255) love.graphics.draw(exf.bigball, 800 - 128, 600 - 128, love.timer.getTime(), 1, 1, exf.bigball:getWidth() * 0.5, exf.bigball:getHeight() * 0.5) end @@ -89,32 +88,32 @@ function exf.keyreleased(k) end function exf.mousepressed(x, y, b) - exf.list:mousepressed(x, y, b) + exf.list:mousepressed(x, y, b) end function exf.mousereleased(x, y, b) - exf.list:mousereleased(x, y, b) + exf.list:mousereleased(x, y, b) end function exf.getn(n) - local s = "" - n = tonumber(n) - local r = n - if r <= 0 then error("Example IDs must be bigger than 0. (Got: " .. r .. ")") end - if r >= 10000 then error("Example IDs must be less than 10000. (Got: " .. r .. ")") end - while r < 1000 do - s = s .. "0" - r = r * 10 - end - s = s .. n - return s + local s = "" + n = tonumber(n) + local r = n + if r <= 0 then error("Example IDs must be bigger than 0. (Got: " .. r .. ")") end + if r >= 10000 then error("Example IDs must be less than 10000. (Got: " .. r .. ")") end + while r < 1000 do + s = s .. "0" + r = r * 10 + end + s = s .. n + return s end function exf.intable(t, e) - for k, v in ipairs(t) do - if v == e then return true end - end - return false + for k, v in ipairs(t) do + if v == e then return true end + end + return false end function exf.start(item, file) @@ -159,32 +158,30 @@ function exf.start(item, file) end function exf.clear() - love.graphics.setBackgroundColor(0,0,0) - love.graphics.setColor(255, 255, 255) + love.graphics.setBackgroundColor(0,0,0) + love.graphics.setColor(255, 255, 255) love.graphics.setLineWidth(1) love.graphics.setLineStyle("smooth") - --love.graphics.setLine(1, "smooth") - --love.graphics.setColorMode("replace") - love.graphics.setBlendMode("alpha") - love.mouse.setVisible(true) + love.graphics.setBlendMode("alpha") + love.mouse.setVisible(true) end function exf.resume() - load = nil - love.update = exf.update - love.draw = exf.draw - love.keypressed = exf.keypressed - love.keyreleased = exf.keyreleased - love.mousepressed = exf.mousepressed - love.mousereleased = exf.mousereleased + load = nil + love.update = exf.update + love.draw = exf.draw + love.keypressed = exf.keypressed + love.keyreleased = exf.keyreleased + love.mousepressed = exf.mousepressed + love.mousereleased = exf.mousereleased - love.mouse.setVisible(true) - love.window.setTitle("LOVE Example Browser") + love.mouse.setVisible(true) + love.window.setTitle("LOVE Example Browser") -- create light world lightWorld = LightWorld({ drawBackground = exf.drawBackground, - drawForground = exf.drawForground + drawForeground = exf.drawForeground }) lightWorld:setAmbientColor(127, 127, 127) @@ -197,7 +194,7 @@ function exf.resume() end function inside(mx, my, x, y, w, h) - return mx >= x and mx <= (x+w) and my >= y and my <= (y+h) + return mx >= x and mx <= (x+w) and my >= y and my <= (y+h) end @@ -208,29 +205,29 @@ end List = {} function List:new() - o = {} - setmetatable(o, self) - self.__index = self + o = {} + setmetatable(o, self) + self.__index = self - o.items = {} + o.items = {} o.files = {} - o.x = 50 - o.y = 70 + o.x = 50 + o.y = 70 - o.width = 400 - o.height = 500 + o.width = 400 + o.height = 500 - o.item_height = 23 - o.sum_item_height = 0 + o.item_height = 23 + o.sum_item_height = 0 - o.bar_size = 20 - o.bar_pos = 0 - o.bar_max_pos = 0 - o.bar_width = 15 - o.bar_lock = nil + o.bar_size = 20 + o.bar_pos = 0 + o.bar_max_pos = 0 + o.bar_width = 15 + o.bar_lock = nil - return o + return o end function List:add(item, file) @@ -239,161 +236,164 @@ function List:add(item, file) end function List:done() - self.items.n = #self.items + self.items.n = #self.items - -- Recalc bar size. - self.bar_pos = 0 + -- Recalc bar size. + self.bar_pos = 0 - local num_items = (self.height/self.item_height) - local ratio = num_items/self.items.n - self.bar_size = self.height * ratio - self.bar_max_pos = self.height - self.bar_size - 3 + local num_items = (self.height/self.item_height) + local ratio = num_items/self.items.n + self.bar_size = self.height * ratio + self.bar_max_pos = self.height - self.bar_size - 3 - -- Calculate height of everything. - self.sum_item_height = (self.item_height+1) * self.items.n + 2 + -- Calculate height of everything. + self.sum_item_height = (self.item_height+1) * self.items.n + 2 end function List:hasBar() - return self.sum_item_height > self.height + return self.sum_item_height > self.height end function List:getBarRatio() - return self.bar_pos/self.bar_max_pos + return self.bar_pos/self.bar_max_pos end function List:getOffset() - local ratio = self.bar_pos/self.bar_max_pos - return math.floor((self.sum_item_height-self.height)*ratio + 0.5) + local ratio = self.bar_pos/self.bar_max_pos + return math.floor((self.sum_item_height-self.height)*ratio + 0.5) end function List:update(dt) - if self.bar_lock then - local dy = math.floor(love.mouse.getY()-self.bar_lock.y+0.5) - self.bar_pos = self.bar_pos + dy + if self.bar_lock then + local dy = math.floor(love.mouse.getY()-self.bar_lock.y+0.5) + self.bar_pos = self.bar_pos + dy - if self.bar_pos < 0 then + if self.bar_pos < 0 then self.bar_pos = 0 - elseif self.bar_pos > self.bar_max_pos then + elseif self.bar_pos > self.bar_max_pos then self.bar_pos = self.bar_max_pos - end + end - self.bar_lock.y = love.mouse.getY() - - end + self.bar_lock.y = love.mouse.getY() + end end function List:mousepressed(mx, my, b) - if self:hasBar() then - if b == "l" then + if self:hasBar() then + if b == "l" then local x, y, w, h = self:getBarRect() if inside(mx, my, x, y, w, h) then - self.bar_lock = { x = mx, y = my } + self.bar_lock = { x = mx, y = my } end - end + end - local per_pixel = (self.sum_item_height-self.height)/self.bar_max_pos - local bar_pixel_dt = math.floor(((self.item_height)*3)/per_pixel + 0.5) + local per_pixel = (self.sum_item_height-self.height)/self.bar_max_pos + local bar_pixel_dt = math.floor(((self.item_height)*3)/per_pixel + 0.5) - if b == "wd" then + if b == "wd" then self.bar_pos = self.bar_pos + bar_pixel_dt - if self.bar_pos > self.bar_max_pos then self.bar_pos = self.bar_max_pos end - elseif b == "wu" then + if self.bar_pos > self.bar_max_pos then + self.bar_pos = self.bar_max_pos + end + elseif b == "wu" then self.bar_pos = self.bar_pos - bar_pixel_dt - if self.bar_pos < 0 then self.bar_pos = 0 end - end - end + if self.bar_pos < 0 then + self.bar_pos = 0 + end + end + end - if b == "l" and inside(mx, my, self.x+2, self.y+1, self.width-3, self.height-3) then - local tx, ty = mx-self.x, my + self:getOffset() - self.y - local index = math.floor((ty/self.sum_item_height)*self.items.n) - local i = self.items[index+1] - local f = self.files[index+1] - if f then - exf.start(i, f) - end + if b == "l" and inside(mx, my, self.x+2, self.y+1, self.width-3, self.height-3) then + local tx, ty = mx-self.x, my + self:getOffset() - self.y + local index = math.floor((ty/self.sum_item_height)*self.items.n) + local i = self.items[index+1] + local f = self.files[index+1] + if f then + exf.start(i, f) end + end end function List:mousereleased(x, y, b) - if self:hasBar() then - if b == "l" then + if self:hasBar() then + if b == "l" then self.bar_lock = nil - end - end + end + end end function List:getBarRect() - return - self.x+self.width+2, self.y+1+self.bar_pos, - self.bar_width-3, self.bar_size + return self.x+self.width+2, self.y+1+self.bar_pos, + self.bar_width-3, self.bar_size end function List:getItemRect(i) - return - self.x+2, self.y+((self.item_height+1)*(i-1)+1)-self:getOffset(), - self.width-3, self.item_height + return self.x+2, self.y+((self.item_height+1)*(i-1)+1)-self:getOffset(), + self.width-3, self.item_height end function List:draw() - love.graphics.setLineWidth(2) - love.graphics.setLineStyle("rough") - love.graphics.setFont(self.font) + love.graphics.setLineWidth(2) + love.graphics.setLineStyle("rough") + love.graphics.setFont(self.font) - love.graphics.setColor(48, 156, 225) + love.graphics.setColor(48, 156, 225) - local mx, my = love.mouse.getPosition() + local mx, my = love.mouse.getPosition() - -- Get interval to display. - local start_i = math.floor( self:getOffset()/(self.item_height+1) ) + 1 - local end_i = start_i+math.floor( self.height/(self.item_height+1) ) + 1 - if end_i > self.items.n then end_i = self.items.n end + -- Get interval to display. + local start_i = math.floor( self:getOffset()/(self.item_height+1) ) + 1 + local end_i = start_i+math.floor( self.height/(self.item_height+1) ) + 1 + + if end_i > self.items.n then + end_i = self.items.n + end + love.graphics.setScissor(self.x, self.y, self.width, self.height) - love.graphics.setScissor(self.x, self.y, self.width, self.height) + -- Items. + for i = start_i,end_i do + local x, y, w, h = self:getItemRect(i) + local hover = inside(mx, my, x, y, w, h) - -- Items. - for i = start_i,end_i do - local x, y, w, h = self:getItemRect(i) - local hover = inside(mx, my, x, y, w, h) - - if hover then - love.graphics.setColor(0, 0, 0, 127) - else - love.graphics.setColor(0, 0, 0, 63) - end - - love.graphics.rectangle("fill", x+1, y+i+1, w-3, h) - - if hover then - love.graphics.setColor(255, 255, 255) - else - love.graphics.setColor(255, 255, 255, 127) - end - - local e_id = string.sub(self.items[i], 1, 5) - local e_rest = string.sub(self.items[i], 5) - - love.graphics.print(e_id, x+10, y+i+6) --Updated y placement -- Used to change position of Example IDs - love.graphics.print(e_rest, x+50, y+i+6) --Updated y placement -- Used to change position of Example Titles + if hover then + love.graphics.setColor(0, 0, 0, 127) + else + love.graphics.setColor(0, 0, 0, 63) end - love.graphics.setScissor() + love.graphics.rectangle("fill", x+1, y+i+1, w-3, h) - -- Bar. - if self:hasBar() then - local x, y, w, h = self:getBarRect() - local hover = inside(mx, my, x, y, w, h) - - if hover or self.bar_lock then - love.graphics.setColor(0, 0, 0, 127) - else - love.graphics.setColor(0, 0, 0, 63) - end - love.graphics.rectangle("fill", x, y, w, h) + if hover then + love.graphics.setColor(255, 255, 255) + else + love.graphics.setColor(255, 255, 255, 127) end - -- Border. - love.graphics.setColor(0, 0, 0, 63) - love.graphics.rectangle("line", self.x+self.width, self.y, self.bar_width, self.height) - love.graphics.rectangle("line", self.x, self.y, self.width, self.height) + local e_id = string.sub(self.items[i], 1, 5) + local e_rest = string.sub(self.items[i], 5) + + love.graphics.print(e_id, x+10, y+i+6) --Updated y placement -- Used to change position of Example IDs + love.graphics.print(e_rest, x+50, y+i+6) --Updated y placement -- Used to change position of Example Titles + end + + love.graphics.setScissor() + + -- Bar. + if self:hasBar() then + local x, y, w, h = self:getBarRect() + local hover = inside(mx, my, x, y, w, h) + + if hover or self.bar_lock then + love.graphics.setColor(0, 0, 0, 127) + else + love.graphics.setColor(0, 0, 0, 63) + end + love.graphics.rectangle("fill", x, y, w, h) + end + + -- Border. + love.graphics.setColor(0, 0, 0, 63) + love.graphics.rectangle("line", self.x+self.width, self.y, self.bar_width, self.height) + love.graphics.rectangle("line", self.x, self.y, self.width, self.height) end