stuff YAY, xavier. work on the engine
This commit is contained in:
parent
b46bfc32d6
commit
539ef72c81
7
.vscode/settings.json
vendored
7
.vscode/settings.json
vendored
@ -1,10 +1,13 @@
|
||||
{
|
||||
"Lua.workspace.library": [
|
||||
"${addons}/love2d/module/library"
|
||||
".vscode/love2d"
|
||||
],
|
||||
"Lua.runtime.version": "LuaJIT",
|
||||
"Lua.runtime.special": {
|
||||
"love.filesystem.load": "loadfile"
|
||||
},
|
||||
"Lua.workspace.checkThirdParty": false
|
||||
"Lua.workspace.checkThirdParty": false,
|
||||
"Lua.diagnostics.globals": [
|
||||
"love"
|
||||
]
|
||||
}
|
||||
10
.vscode/tasks.json
vendored
Normal file
10
.vscode/tasks.json
vendored
Normal file
@ -0,0 +1,10 @@
|
||||
{
|
||||
"version": "2.0.0",
|
||||
"tasks": [{
|
||||
"label": "Run Love2D",
|
||||
"type": "shell",
|
||||
"command": "love .",
|
||||
"options": { "cwd": "${workspaceFolder}" },
|
||||
"group": { "kind": "build", "isDefault": true }
|
||||
}]
|
||||
}
|
||||
241
editor/ui.lua
241
editor/ui.lua
@ -3,119 +3,194 @@ local ui = {}
|
||||
ui.theme = {
|
||||
bg = {0.13, 0.13, 0.14},
|
||||
panel = {0.17, 0.17, 0.19},
|
||||
border = {0.28, 0.28, 0.30}, -- also known as outline
|
||||
border = {0.28, 0.28, 0.30},
|
||||
borderwidth = 3,
|
||||
text = {0.90, 0.90, 0.90},
|
||||
text_dim = {0.50, 0.50, 0.55}, -- low-key forgot
|
||||
accent = {0.27, 0.52, 0.90}, -- low-key also forgot
|
||||
text_dim = {0.50, 0.50, 0.55},
|
||||
accent = {0.27, 0.52, 0.90},
|
||||
hover = {0.22, 0.25, 0.35},
|
||||
active = {0.20, 0.40, 0.75}, -- i low-key forgot again, probably made for when a toggle or something is turned on
|
||||
active = {0.20, 0.40, 0.75},
|
||||
}
|
||||
|
||||
ui.events = {}
|
||||
ui._wasDown = false
|
||||
ui._focused = nil
|
||||
ui._inputs = {}
|
||||
ui._claimedFocus = false
|
||||
-- per-frame state (most/all gets reset if i remember)
|
||||
ui._wasDown = false
|
||||
ui._focused = nil
|
||||
ui._inputs = {}
|
||||
ui._claimedFocus = false
|
||||
ui._clickConsumed = false
|
||||
ui._elements = {} -- queue of UI elements, processed at end of frame
|
||||
ui._hoverConsumed = false -- so it sets hovered to the correct thing
|
||||
|
||||
function ui.emit(event)
|
||||
ui.events[event] = true -- should change to a custom ID soon to prevent conflicts.
|
||||
end
|
||||
|
||||
function ui.on(event)
|
||||
return ui.events[event] == true
|
||||
end
|
||||
|
||||
function ui.flush() -- all issues is because of this btw (joke, kinda. bunch of bugs from it)
|
||||
local isDown = love.mouse.isDown(1)
|
||||
if isDown and not ui._wasDown and not ui._claimedFocus then
|
||||
ui._focused = nil
|
||||
end
|
||||
ui._wasDown = isDown -- update AFTER using it
|
||||
ui._claimedFocus = false
|
||||
ui.events = {}
|
||||
ui._clickConsumed = false
|
||||
end
|
||||
|
||||
function ui.panel(x, y, w, h) -- this thingy magic panel creator makes a ui with outline. (x pos, y pos, width, height)
|
||||
-- draws a basic bordered panel
|
||||
function ui._draw_panel(e)
|
||||
love.graphics.setColor(ui.theme.panel)
|
||||
love.graphics.rectangle("fill", x, y, w, h)
|
||||
love.graphics.rectangle("fill", e.x, e.y, e.w, e.h)
|
||||
love.graphics.setColor(ui.theme.border)
|
||||
love.graphics.setLineWidth(ui.theme.borderwidth)
|
||||
love.graphics.rectangle("line", x, y, w, h)
|
||||
love.graphics.rectangle("line", e.x, e.y, e.w, e.h)
|
||||
end
|
||||
|
||||
function ui.button(x, y, w, h, text)
|
||||
local mousex, mousey = love.mouse.getPosition()
|
||||
local hovered = mousex > x and mousex < x + w and mousey > y and mousey < y + h -- calculaters if its touching the box
|
||||
if hovered then
|
||||
-- makes dimed panel then text ontop
|
||||
love.graphics.setColor(ui.theme.hover)
|
||||
love.graphics.rectangle("fill", x, y, w, h)
|
||||
love.graphics.setColor(ui.theme.border)
|
||||
love.graphics.setLineWidth(ui.theme.borderwidth)
|
||||
love.graphics.rectangle("line", x, y, w, h)
|
||||
ui.text(x, y, w, h, text)
|
||||
else
|
||||
ui.textPanel(x, y, w, h, text) -- just normal text with a background
|
||||
end
|
||||
|
||||
if hovered and love.mouse.isDown(1) and not ui._wasDown and not ui._clickConsumed then
|
||||
ui.emit(text)
|
||||
ui._clickConsumed = true
|
||||
end
|
||||
|
||||
return hovered -- returns hovered, this means hovered is returned. and hovered being returned means it returns what hovered is
|
||||
end
|
||||
|
||||
function ui.textPanel(x, y, w, h, text) -- expand on this, havent fully read the text documentation so i dont know if i should have more
|
||||
ui.panel(x, y, w, h)
|
||||
ui.text(x, y, w, h, text)
|
||||
end
|
||||
|
||||
function ui.text(x, y, w, h, text)
|
||||
-- draws centered, wrapped, clipped text inside a box
|
||||
function ui._draw_text(e)
|
||||
local font = love.graphics.getFont()
|
||||
local _, lines = font:getWrap(text, w)
|
||||
local lineCount = #lines
|
||||
local lineHeight = font:getHeight()
|
||||
local totalHeight = lineCount * lineHeight
|
||||
local startY = y + (h - totalHeight) / 2
|
||||
local _, lines = font:getWrap(e.text, e.w)
|
||||
local totalHeight = #lines * font:getHeight()
|
||||
local startY = e.y + (e.h - totalHeight) / 2
|
||||
|
||||
love.graphics.setScissor(x, y, w, h)
|
||||
love.graphics.setScissor(e.x, e.y, e.w, e.h) -- clip to box bounds
|
||||
love.graphics.setColor(ui.theme.text)
|
||||
love.graphics.printf(text, x, startY, w, "center")
|
||||
love.graphics.setScissor() -- limits drawing space.
|
||||
love.graphics.printf(e.text, e.x, startY, e.w, "center")
|
||||
love.graphics.setScissor() -- reset clip
|
||||
end
|
||||
|
||||
function ui.textInput(x, y, w, h, placeholder) -- two days for this to work...
|
||||
local text = ui._inputs[placeholder] or ""
|
||||
local focused = ui._focused == placeholder
|
||||
local mousex, mousey = love.mouse.getPosition()
|
||||
local clickedInside = mousex > x and mousex < x + w and mousey > y and mousey < y + h
|
||||
-- draws a button, highlighted on hover
|
||||
function ui._draw_button(e)
|
||||
local mx, my = love.mouse.getPosition()
|
||||
local hovered = not ui._hoverConsumed and mx > e.x and mx < e.x + e.w and my > e.y and my < e.y + e.h
|
||||
|
||||
if love.mouse.isDown(1) and not ui._wasDown and clickedInside then
|
||||
ui._focused = placeholder
|
||||
ui._claimedFocus = true
|
||||
end
|
||||
love.graphics.setColor(e._hovered and ui.theme.hover or ui.theme.panel)
|
||||
love.graphics.rectangle("fill", e.x, e.y, e.w, e.h)
|
||||
love.graphics.setColor(ui.theme.border)
|
||||
love.graphics.setLineWidth(ui.theme.borderwidth)
|
||||
love.graphics.rectangle("line", e.x, e.y, e.w, e.h)
|
||||
ui._draw_text(e)
|
||||
end
|
||||
|
||||
-- draws a text input, changes appearance based on focus state
|
||||
function ui._draw_textInput(e)
|
||||
local focused = ui._focused == e.placeholder
|
||||
local text = ui._inputs[e.placeholder] or ""
|
||||
|
||||
if focused then
|
||||
ui.panel(x, y, w, h)
|
||||
love.graphics.setColor(ui.theme.panel)
|
||||
love.graphics.rectangle("fill", e.x, e.y, e.w, e.h)
|
||||
love.graphics.setColor(ui.theme.accent)
|
||||
love.graphics.setLineWidth(ui.theme.borderwidth)
|
||||
love.graphics.rectangle("line", e.x, e.y, e.w, e.h)
|
||||
|
||||
if text == "" then
|
||||
-- show dimmed placeholder text when empty
|
||||
local font = love.graphics.getFont()
|
||||
local lineHeight = font:getHeight()
|
||||
local startY = y + (h - lineHeight) / 2
|
||||
local startY = e.y + (e.h - font:getHeight()) / 2
|
||||
love.graphics.setColor(ui.theme.text_dim)
|
||||
love.graphics.printf(placeholder, x + 4, startY, w - 8, "left")
|
||||
love.graphics.printf(e.placeholder, e.x + 4, startY, e.w - 8, "left")
|
||||
else
|
||||
ui.text(x, y, w, h, text)
|
||||
ui._draw_text({ x=e.x, y=e.y, w=e.w, h=e.h, text=text })
|
||||
end
|
||||
else
|
||||
ui.button(x, y, w, h, text == "" and placeholder or text)
|
||||
-- unfocused
|
||||
local display = text == "" and e.placeholder or text
|
||||
ui._draw_button({ x=e.x, y=e.y, w=e.w, h=e.h, text=display })
|
||||
end
|
||||
end
|
||||
|
||||
-- bordered panel, no interaction
|
||||
function ui.panel(x, y, w, h)
|
||||
table.insert(ui._elements, {
|
||||
type = "panel",
|
||||
x=x, y=y, w=w, h=h
|
||||
})
|
||||
end
|
||||
|
||||
-- centered text inside a box, no background
|
||||
function ui.text(x, y, w, h, text)
|
||||
table.insert(ui._elements, {
|
||||
type = "text",
|
||||
x=x, y=y, w=w, h=h, text=text
|
||||
})
|
||||
end
|
||||
|
||||
-- panel with centered text inside (justs draws a panel and puts text ontop, dependant on ui.text)
|
||||
function ui.textPanel(x, y, w, h, text)
|
||||
table.insert(ui._elements, {
|
||||
type = "textPanel",
|
||||
x=x, y=y, w=w, h=h, text=text
|
||||
})
|
||||
end
|
||||
|
||||
-- clickable button. callback is called when clicked (optional)
|
||||
-- example: ui.button(x, y, w, h, "Click me", function() print("hi") end)
|
||||
function ui.button(x, y, w, h, text, callback)
|
||||
table.insert(ui._elements, {
|
||||
type = "button",
|
||||
x=x, y=y, w=w, h=h, text=text,
|
||||
callback = callback
|
||||
})
|
||||
end
|
||||
|
||||
-- text input field. placeholder is also used as its unique ID
|
||||
-- read typed text with: ui._inputs["placeholder"]
|
||||
function ui.textInput(x, y, w, h, placeholder)
|
||||
table.insert(ui._elements, {
|
||||
type = "textInput",
|
||||
x=x, y=y, w=w, h=h,
|
||||
placeholder = placeholder
|
||||
})
|
||||
end
|
||||
|
||||
function ui.process()
|
||||
local mx, my = love.mouse.getPosition()
|
||||
local clicked = love.mouse.isDown(1) and not ui._wasDown
|
||||
for i = #ui._elements, 1, -1 do
|
||||
local e = ui._elements[i]
|
||||
local inside = mx > e.x and mx < e.x + e.w and my > e.y and my < e.y + e.h
|
||||
|
||||
-- consume hover for top thing
|
||||
if inside and not ui._hoverConsumed then
|
||||
e._hovered = true
|
||||
ui._hoverConsumed = true
|
||||
else
|
||||
e._hovered = false
|
||||
end
|
||||
end
|
||||
|
||||
-- reverse hit test so topmost element gets the click, similar to above but just for clicking
|
||||
for i = #ui._elements, 1, -1 do
|
||||
local e = ui._elements[i]
|
||||
if clicked and not ui._clickConsumed then
|
||||
local inside = mx > e.x and mx < e.x + e.w and my > e.y and my < e.y + e.h
|
||||
if inside then
|
||||
if e.type == "button" then
|
||||
if e.callback then e.callback() end -- fire callback if provided
|
||||
ui._clickConsumed = true
|
||||
|
||||
elseif e.type == "textInput" then
|
||||
ui._focused = e.placeholder
|
||||
ui._claimedFocus = true
|
||||
ui._clickConsumed = true
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- clicked outside everything, clear focus
|
||||
if clicked and not ui._claimedFocus then
|
||||
ui._focused = nil
|
||||
end
|
||||
|
||||
-- draw in order
|
||||
for i = 1, #ui._elements do
|
||||
local e = ui._elements[i]
|
||||
if e.type == "panel" then ui._draw_panel(e)
|
||||
elseif e.type == "text" then ui._draw_text(e)
|
||||
elseif e.type == "textPanel" then ui._draw_panel(e) ui._draw_text(e)
|
||||
elseif e.type == "button" then ui._draw_button(e)
|
||||
elseif e.type == "textInput" then ui._draw_textInput(e)
|
||||
end
|
||||
end
|
||||
|
||||
-- clear queue/list for next frame (leave at end)
|
||||
ui._elements = {}
|
||||
end
|
||||
|
||||
function ui.flush()
|
||||
ui._wasDown = love.mouse.isDown(1)
|
||||
ui._claimedFocus = false
|
||||
ui._clickConsumed = false
|
||||
ui._hoverConsumed = false
|
||||
end
|
||||
|
||||
-- text things, both used in the process of rendering text
|
||||
function ui.textinput_char(t)
|
||||
if ui._focused then
|
||||
ui._inputs[ui._focused] = (ui._inputs[ui._focused] or "") .. t
|
||||
|
||||
24
main.lua
24
main.lua
@ -1,3 +1,5 @@
|
||||
-- ctrl+shift+b for launching game
|
||||
|
||||
local ui = require("editor.ui")
|
||||
|
||||
function love.load()
|
||||
@ -19,12 +21,20 @@ function love.update(dt)
|
||||
end
|
||||
|
||||
function love.draw()
|
||||
ui.panel(50,50,50,50)
|
||||
ui.button(100,200,100,100,"hello world")
|
||||
if ui.on("hello world") then -- detect if the button is pressed.
|
||||
ui.panel(250,250,100,100)
|
||||
end
|
||||
ui.textInput(50,400,100,100,"textInput")
|
||||
ui.panel(50, 50, 50, 50)
|
||||
|
||||
ui.button(100, 200, 100, 100, "hello world", function()
|
||||
print("clicked!")
|
||||
end)
|
||||
|
||||
ui.flush() -- KEEP AT END
|
||||
ui.textInput(50, 400, 100, 100, "textInput")
|
||||
ui.button(200,200,100,100, "test", function ()
|
||||
print("below")
|
||||
end)
|
||||
ui.button(200,250,100,100, "test2", function ()
|
||||
print("on top")
|
||||
end)
|
||||
|
||||
ui.process() -- hit test + draw
|
||||
ui.flush() -- reset input state
|
||||
end
|
||||
Loading…
Reference in New Issue
Block a user