diff --git a/assets/fonts/Inter-Italic.otf b/assets/fonts/Inter-Italic.otf new file mode 100644 index 0000000..12319b0 Binary files /dev/null and b/assets/fonts/Inter-Italic.otf differ diff --git a/assets/textures/clipboard.png b/assets/textures/clipboard.png new file mode 100644 index 0000000..24f2f10 Binary files /dev/null and b/assets/textures/clipboard.png differ diff --git a/assets/textures/screenshot.png b/assets/textures/screenshot.png new file mode 100644 index 0000000..bb56f42 Binary files /dev/null and b/assets/textures/screenshot.png differ diff --git a/assets/textures/swap.png b/assets/textures/swap.png new file mode 100644 index 0000000..3df04b9 Binary files /dev/null and b/assets/textures/swap.png differ diff --git a/main.lua b/main.lua index ae4b5ea..08cc0d1 100644 --- a/main.lua +++ b/main.lua @@ -4,7 +4,41 @@ for k, v in pairs(_G) do end love.graphics.setDefaultFilter('nearest', 'nearest') -interfaceFont = love.graphics.newFont('assets/fonts/Inter-Regular.otf', 20) + +local fontSize = 20 +interfaceFont = love.graphics.newFont('assets/fonts/Inter-Regular.otf', fontSize) + +local fontCache = {} + +function getFont(size, italic) + if fontCache[size] and fontCache[size][italic] then return fontCache[size][italic] end + + fontCache[size] = fontCache[size] or {} + fontCache[size][italic] = love.graphics.newFont('assets/fonts/Inter-' .. (italic and 'Italic' or 'Regular') .. '.otf', math.floor(fontSize * size)) + return fontCache[size][italic] +end + +function getMousePosition() + local x, y = love.mouse.getPosition() + + local sx, sy, sw, sh = 0, 0, love.graphics.getWidth(), love.graphics.getHeight() + if love.isVersionCompatible('11.3') then sx, sy, sw, sh = love.window.getSafeArea() end + sx, sy, sw, sh = 100, 100, love.graphics.getWidth() - 200, love.graphics.getHeight() - 200 + + x, y = ((x - sx) / sw) * love.graphics.getWidth(), ((y - sy) / sh) * love.graphics.getHeight() + + return x, y +end + +function getMouseX() + local x, y = getMousePosition() + return x +end + +function getMouseY() + local x, y = getMousePosition() + return y +end ease = require 'src.ease' @@ -42,6 +76,8 @@ screenshot = false screenshotCanvas = nil screenshotsize = 512 +mobile = love.system.getOS() == 'iOS' or love.system.getOS() == 'Android' + -- global for convinience's sake mode = nil @@ -50,6 +86,10 @@ function love.load() love.graphics.setFont(interfaceFont) fontHeight = love.graphics.getFont():getHeight() createUI() + + if mobile then + love.window.setMode(640, 360, {borderless = true, resizable = false, minwidth = 705, minheight = 510, fullscreen = true}) + end end function love.update(dt) @@ -61,7 +101,9 @@ function love.update(dt) end function love.draw() - local sw, sh = love.graphics.getDimensions() + local sx, sy, sw, sh = 0, 0, love.graphics.getWidth(), love.graphics.getHeight() + if love.isVersionCompatible('11.3') then sx, sy, sw, sh = love.window.getSafeArea() end + local mx, my = love.mouse.getPosition() if screenshot then @@ -97,9 +139,15 @@ function love.draw() love.graphics.setLineWidth(2) love.graphics.setColor(0.09, 0.09, 0.12, 1) - love.graphics.rectangle('fill', 0, 0, sw, sh) + love.graphics.rectangle('fill', 0, 0, love.graphics.getWidth(), love.graphics.getHeight()) love.graphics.setColor(0.08, 0.08, 0.1, 1) - love.graphics.rectangle('line', 0, 0, sw, sh) + love.graphics.rectangle('line', 0, 0, love.graphics.getWidth(), love.graphics.getHeight()) + + love.graphics.push() + love.graphics.translate(sx, sy) + love.graphics.scale(sw/love.graphics.getWidth(), sh/love.graphics.getHeight()) + + sw, sh = love.graphics.getDimensions() love.graphics.setColor(0.2, 0.2, 0.3, 1) love.graphics.print('Box of Eases by oatmealine', outerpadding, sh - fontHeight - outerpadding) @@ -115,14 +163,26 @@ function love.draw() graph.render() tooltips.render() + + love.graphics.pop() end function love.mousepressed(x, y, m) + local sx, sy, sw, sh = 0, 0, love.graphics.getWidth(), love.graphics.getHeight() + if love.isVersionCompatible('11.3') then sx, sy, sw, sh = love.window.getSafeArea() end + + x, y = ((x - sx) / sw) * love.graphics.getWidth(), ((y - sy) / sh) * love.graphics.getHeight() + if dropdown.mousepressed(x, y, m) then return end button.mousepressed(x, y, m) end function love.mousereleased(x, y, m) + local sx, sy, sw, sh = 0, 0, love.graphics.getWidth(), love.graphics.getHeight() + if love.isVersionCompatible('11.3') then sx, sy, sw, sh = love.window.getSafeArea() end + + x, y = ((x - sx) / sw) * love.graphics.getWidth(), ((y - sy) / sh) * love.graphics.getHeight() + if dropdown.mousereleased(x, y, m) then return end end @@ -142,5 +202,11 @@ function love.keypressed(key) print(k, v) ::continue:: end + elseif key == 'f2' then -- mobile mode + mobile = not mobile end +end + +function love.resize() + createUI() end \ No newline at end of file diff --git a/src/button.lua b/src/button.lua index 4b13ece..9df96fc 100644 --- a/src/button.lua +++ b/src/button.lua @@ -1,5 +1,11 @@ local self = {} +local icon = { + clipboard = love.graphics.newImage('assets/textures/clipboard.png'), + screenshot = love.graphics.newImage('assets/textures/screenshot.png'), + swap = love.graphics.newImage('assets/textures/swap.png'), +} + local buttons = {} function self.get(index) @@ -40,6 +46,7 @@ function self.createButtons() name = 'clipboard', displayname = 'Copy to Clipboard', tooltip = 'Copy to Clipboard', + icon = 'clipboard', func = function() local s = '' @@ -122,6 +129,7 @@ function self.createButtons() name = 'screenshot', displayname = 'Screenshot', tooltip = 'Take a screenshot', + icon = 'screenshot', func = function() screenshot = true screenshotCanvas = love.graphics.newCanvas() @@ -129,12 +137,27 @@ function self.createButtons() }) end + if mode == modes.mix or mode == modes.multiply then + insertButton(s, { + x = outerpadding + dropdownWidth * 2 + padding, + y = outerpadding + fontHeight/2 - padding/2, + size = padding, + name = 'swap', + displayname = 'Swap', + icon = 'swap', + func = function() + dropdown.swap('ease1', 'ease2') + createUI() + end + }) + end + buttons = s end function self.update(dt) for i, v in ipairs(buttons) do - local mx, my = love.mouse.getPosition() + local mx, my = getMousePosition() local targetsize = 1 if mx > v.x and mx < v.x + v.size and my > v.y and my < v.y + v.size and dropdown.openDropdown == 0 then @@ -150,7 +173,7 @@ function self.update(dt) end function self.render() - local mx, my = love.mouse.getPosition() + local mx, my = getMousePosition() for i, v in ipairs(buttons) do local x, y, w, h = v.x, v.y, v.size, v.size @@ -165,12 +188,17 @@ function self.render() love.graphics.setColor(0, 0, 0, 1) if hovering or dragging then - love.graphics.setColor(0.2, 0.2, 0.3, 1) + love.graphics.setColor(0.4, 0.4, 1, 1) if v.tooltip then tooltips.show(v.tooltip) end end love.graphics.rectangle('fill', x, y, w, h) love.graphics.setColor(1, 1, 1, 1) love.graphics.rectangle('line', x, y, w, h) + + if v.icon and icon[v.icon] then + local icon = icon[v.icon] + love.graphics.draw(icon, x, y, 0, w / icon:getWidth(), h / icon:getHeight()) + end end end diff --git a/src/dropdown.lua b/src/dropdown.lua index 1bb96b9..edf8296 100644 --- a/src/dropdown.lua +++ b/src/dropdown.lua @@ -22,6 +22,8 @@ self.openDropdown = 0 local dropdownScroll = 0 local dropdownScrollE = 0 +local scrollbarSize = 6 + local function skeys(t) local k = {} for n,v in pairs(t) do table.insert(k, {n, v}) end @@ -71,6 +73,13 @@ function self.kselected(key) end end +function self.swap(key, key2) + local a, b = self.kget(key), self.kget(key2) + local s = a.selected + a.selected = b.selected + b.selected = s +end + local dropdownId local function insertDropdown(tab, f) dropdownId = dropdownId + 1 @@ -204,15 +213,27 @@ function self.update(dt) v.open = mix(v.open, 0, dt * 20) end end + + if love.mouse.isDown(1) then + local x, y = getMousePosition() + for i,v in ipairs(dropdowns) do + local h = fontHeight + margin + if self.openDropdown == i then + if x > v.x and x > v.x + v.width - scrollbarSize and y > v.y + h and y < v.y + h * (math.min(#v.options, maxDropdown) + 1) and not (#v.options < maxDropdown) then + dropdownScroll = ((y - (v.y + h)) / (h * (math.min(#v.options, maxDropdown)))) * -(#v.options - maxDropdown + 1) + end + end + end + end end function self.render() - local mx, my = love.mouse.getPosition() + local mx, my = getMousePosition() for i,v in ipairs(dropdowns) do local x, y, w, h = v.x, v.y, v.width, fontHeight + margin love.graphics.setColor(0.06, 0.06, 0.12, 0.6) - if love.mouse.getX() > x and love.mouse.getX() < x + w and love.mouse.getY() > y and love.mouse.getY() < y + h then + if mx > x and mx < x + w and my > y and my < y + h then love.graphics.setColor(0.8, 0.8, 1, love.mouse.isDown(1) and 0.4 or 0.3) if v.tooltip then tooltips.show(v.tooltip) end end @@ -274,13 +295,10 @@ function self.render() str = str .. ' ' .. string.sub(p.name, 1, 1) end - love.graphics.push() - love.graphics.translate(x + w, y + lineWidth/2) - love.graphics.shear(-0.2, 0) - love.graphics.scale(0.8, 0.8) + love.graphics.setFont(getFont(0.8, true)) love.graphics.setColor(0.8, 0.8, 1, 0.8 * a) - love.graphics.printf(str, -w, -lineWidth/2, w - 2, 'right') - love.graphics.pop() + love.graphics.printf(str, x, y, w - 2, 'right') + love.graphics.setFont(interfaceFont) end ::continue:: @@ -291,7 +309,7 @@ function self.render() if #v.options > maxDropdown then local displayed = maxDropdown / (#v.options) local scroll = math.abs(dropdownScrollE) / (#v.options - maxDropdown + 1) - local size = 3 + local size = scrollbarSize love.graphics.setColor(1, 1, 1, 0.8 * v.open) love.graphics.rectangle('fill', x + w - size, y + h + scroll * (1 - displayed) * (maxDropdown - 1) * h * v.open, size, displayed * (maxDropdown - 1) * h * v.open) @@ -334,7 +352,7 @@ function self.mousereleased(x, y, m) for i,v in ipairs(dropdowns) do local h = fontHeight + margin if self.openDropdown == i then - if x > v.x and x < v.x + v.width and y > v.y + h and y < v.y + h * (math.min(#v.options, maxDropdown) + 1) and m == 1 then + if x > v.x and x < v.x + v.width and y > v.y + h and y < v.y + h * (math.min(#v.options, maxDropdown) + 1) and m == 1 and (x < v.x + v.width - scrollbarSize or #v.options < maxDropdown) then v.selected = math.floor((y - v.y) / h - dropdownScrollE) self.openDropdown = 0 dropdownValueCache[v.name] = {selected = v.selected} @@ -349,7 +367,7 @@ function self.wheelmoved(x, y) if self.openDropdown ~= 0 then dropdownScroll = dropdownScroll + y else - local mx, my = love.mouse.getPosition() + local mx, my = getMousePosition() for i,v in ipairs(dropdowns) do local h = fontHeight + margin if mx > v.x and mx < v.x + v.width and my > v.y and my < v.y + h + margin then diff --git a/src/graph.lua b/src/graph.lua index 1f46cea..b4f0bac 100644 --- a/src/graph.lua +++ b/src/graph.lua @@ -37,7 +37,7 @@ function self.update(dt) local csize = 10 -- preview point size local size = math.min((sw - outerpadding) - ((dropdown.kget('ease2') or dropdown.kget('ease1')).x + dropdownWidth + padding), sh - outerpadding * 2 - padding * 3 - csize) local x, y, w, h = sw - outerpadding - size, outerpadding, size, size - local mx, my = love.mouse.getPosition() + local mx, my = getMousePosition() if not (love.mouse.isDown(1) and mx > x and mx < x + w and my > y and my < y + h) then timer = (timer + dt * ((slider.kvalue('bpm') or 120)/120)) % 2 @@ -68,7 +68,7 @@ function self.render() love.graphics.rectangle('line', x, y, w, h) -- grid - love.graphics.setColor(0.2, 0.2, 0.4, 0.2) + love.graphics.setColor(0.2, 0.2, 0.3, 0.2) local gridsize = 64 for gx = 1, gridsize - 2 do love.graphics.line(x + margin + gx * w/gridsize, y + margin, x + margin + gx * w/gridsize, y + h - margin) @@ -99,7 +99,7 @@ function self.render() -- polygone -- this isnt done with a polygon because else itd waste a Bunch of ram and i kinda, dont want to do that? love.graphics.setColor(1, 1, 1, 1) - love.graphics.setScissor(x + margin, y + margin, w - (margin * 2), h - (margin * 2)) + love.graphics.setScissor(x + margin, y + margin, math.abs(w - (margin * 2)), math.abs(h - (margin * 2))) local last = (((graph[1] or 0) - 0.5) * zoome) + 0.5 for gx = 1, quality - 1 do local a = gx/quality @@ -129,7 +129,7 @@ function self.render() -- preview if not screenshot then - love.graphics.setScissor(x - margin, 0, w + margin * 2, sh) + love.graphics.setScissor(x - margin, 0, math.abs(w + margin * 2), sh) love.graphics.setColor(0.16, 0.16, 0.17, 1) love.graphics.line(x + margin, y + h + padding * 2 + csize/2, x + w - margin, y + h + padding * 2 + csize/2) love.graphics.setColor(0.3, 0.3, 0.31, 1) @@ -153,7 +153,7 @@ function self.render() end function self.wheelmoved(wx, wy) - local mx, my = love.mouse.getPosition() + local mx, my = getMousePosition() -- may need to abstract this out, somehow -- todo diff --git a/src/slider.lua b/src/slider.lua index 9f70af6..acef733 100644 --- a/src/slider.lua +++ b/src/slider.lua @@ -77,13 +77,14 @@ function self.createSliders() for i,v in ipairs(param1) do insertSlider(s, { x = outerpadding + dropdownWidth + padding, - y = outerpadding + (fontHeight * 2.5 + padding) * i, + y = outerpadding + (fontHeight * 3 + padding) * i - padding, width = dropdownWidth, min = v.min, max = v.max, default = v.default, name = ease1.name .. 'param1' .. i, - displayname = 'Parameter ' .. v.name + topdisplayname = 'Parameter', + displayname = v.name }) end end @@ -91,13 +92,14 @@ function self.createSliders() for i,v in ipairs(param2) do insertSlider(s, { x = outerpadding + dropdownWidth + padding + dropdownWidth + padding, - y = outerpadding + (fontHeight * 2.5 + padding) * i, + y = outerpadding + (fontHeight * 3 + padding) * i - padding, width = dropdownWidth, min = v.min, max = v.max, default = v.default, name = ease2.name .. 'param2' .. i, - displayname = 'Parameter ' .. v.name + topdisplayname = 'Parameter', + displayname = v.name }) end end @@ -124,7 +126,7 @@ function self.update(dt) end function self.render() - local mx, my = love.mouse.getPosition() + local mx, my = getMousePosition() for i, v in ipairs(sliders) do local x, y, w, h = v.x, v.y, v.width, fontHeight * 1.25 @@ -168,6 +170,13 @@ function self.render() love.graphics.printf(v.displayname, v.x + margin * 2 - ssize * 6, v.y - ssize, ssize * 12, 'center') + if v.topdisplayname then + love.graphics.setColor(0.4, 0.4, 0.55, 1) + love.graphics.setFont(getFont(0.75, true)) + love.graphics.printf(v.topdisplayname, v.x - ssize * 6, v.y - ssize * 1.45, ssize * 12, 'center') + love.graphics.setFont(interfaceFont) + end + if dragging then v.value = ((mx - (x + 1)) / (w - 2)) * (v.max - v.min) + v.min if v.name == 'mix' then graph.touchtimer = 1 end -- sorry !!! diff --git a/src/tooltips.lua b/src/tooltips.lua index 1c98e7c..b5979f8 100644 --- a/src/tooltips.lua +++ b/src/tooltips.lua @@ -11,7 +11,7 @@ local tooltiptargetwidth = 0 local tooltipframe = false function self.update(dt) - local mx, my = love.mouse.getPosition() + local mx, my = getMousePosition() tooltipx = mix(tooltipx, mx, dt * 18) tooltipy = mix(tooltipy, my, dt * 18) @@ -36,7 +36,7 @@ local function softlimit(x, f) end function self.render() - local mx, my = love.mouse.getPosition() + local mx, my = getMousePosition() if not tooltipframe then tooltiptargetwidth = 0 end @@ -44,10 +44,10 @@ function self.render() if tooltipwidth > 1 then local a = math.min((tooltipwidth - 1) / 6, 1) - local x, y, w, h = mx + 8, my + 8, (tooltipwidth + 4 + margin), (fontHeight + margin) + local x, y, w, h = mx + 8, my + 8, (tooltipwidth + 4 + margin) * 0.8, (fontHeight + margin) * 0.8 local easiness = 3 -- hehe. magic numbers - local scale = 0.8 + local scale = 1 local sx, sy = ((w - softlimit(mx - tooltipx, w/easiness)/easiness) / w) * scale, ((h - softlimit(my - tooltipy, h/easiness)/easiness) / h) * scale love.graphics.push() @@ -61,7 +61,9 @@ function self.render() love.graphics.setScissor(0, 0, math.max(mx + (tooltipwidth + 2 + margin/2 + 16) * sx, 0), love.graphics.getHeight()) love.graphics.setColor(1, 1, 1, a) - love.graphics.print(tooltiptext, 2 + margin/2, 2 + margin/2) + love.graphics.setFont(getFont(0.8, false)) + love.graphics.print(tooltiptext, 2, 2) + love.graphics.setFont(interfaceFont) love.graphics.setScissor()