461 lines
12 KiB
Lua
461 lines
12 KiB
Lua
ui = {}
|
|
ui.textureTree = nil
|
|
|
|
local layout = require("lua.layout")
|
|
local utils = require("shared.utils")
|
|
local fonts = require("shared.fonts")
|
|
|
|
ui.speedText = {
|
|
love.graphics.newText(fonts.normalFont, "0000"),
|
|
love.graphics.newText(fonts.normalFont, "0000"),
|
|
love.graphics.newText(fonts.normalFont, "0000"),
|
|
love.graphics.newText(fonts.normalFont, "0000")
|
|
}
|
|
|
|
ui.sidebarScale = 1
|
|
ui.sidebarWidth = 13 * 16
|
|
function ui.update_scale(p_scale)
|
|
scale = p_scale
|
|
end
|
|
|
|
function ui.updateSpeed(xspeed, yspeed, xpos, ypos)
|
|
ui.speedText = {
|
|
love.graphics.newText(fonts.normalFont, "XSpeed: " .. xspeed),
|
|
love.graphics.newText(fonts.normalFont, "YSpeed: " .. yspeed),
|
|
love.graphics.newText(fonts.normalFont, "X: " .. xpos),
|
|
love.graphics.newText(fonts.normalFont, "X: " .. ypos)
|
|
}
|
|
end
|
|
|
|
ui.helptext = [[[P] toggle fly
|
|
{A/D} Move
|
|
{Shift} Move faster
|
|
[Space] Jump
|
|
{A/S/DW} Move (flying)
|
|
[C] Clear canvas
|
|
[F] Fill foreground
|
|
[G] Fill background
|
|
{Mouse1} Draw
|
|
{Mouse2} Delete
|
|
{ctrl} Background draw
|
|
[PGUP/PGDWN] Zoom canvas
|
|
{Cursor keys} Move camera
|
|
]]
|
|
|
|
local menuVisible = false
|
|
local textEnabled = false
|
|
local textEntry = ""
|
|
function ui.keyreleased(key, _)
|
|
if key == "escape" then
|
|
menuVisible = not menuVisible
|
|
if menuVisible then
|
|
love.visible = function(visible)
|
|
if visible then
|
|
love.update = function(dt)
|
|
levelloop.networkSync(dt)
|
|
physics.update(dt)
|
|
camera.update(dt)
|
|
love.timer.sleep((1/60) -dt)
|
|
end
|
|
else
|
|
love.update = function(dt)
|
|
levelloop.networkSync(dt)
|
|
physics.update(dt)
|
|
end
|
|
end
|
|
end
|
|
ui.drawMenu(window.x, window.y)
|
|
else
|
|
love.visible = function(visible)
|
|
if visible then
|
|
love.update = levelloop.normalVisible
|
|
else
|
|
love.update = levelloop.reducedVisible
|
|
end
|
|
end
|
|
ui.draw(window.x, window.y)
|
|
end
|
|
love.visible(true)
|
|
return
|
|
end
|
|
if key == "return" and not love.keyboard.isDown("lalt") then
|
|
textEnabled = true
|
|
love.keyboard.setTextInput(true)
|
|
ui.draw(window.x, window.y)
|
|
end
|
|
if textEnabled then
|
|
love.visible = function(visible)
|
|
if visible then
|
|
love.update = function(dt)
|
|
levelloop.networkSync(dt)
|
|
drawing.input(dt)
|
|
physics.update(dt)
|
|
camera.update(dt)
|
|
end
|
|
else
|
|
love.update = function(dt)
|
|
levelloop.networkSync(dt)
|
|
physics.update(dt)
|
|
end
|
|
end
|
|
end
|
|
love.visible(true)
|
|
love.keyreleased = function(key, _)
|
|
if key == "return" and not love.keyboard.isDown("lalt") then
|
|
textEnabled = false
|
|
if textEntry ~= "" then
|
|
levelloop.remoteCall("chatMessage", textEntry)
|
|
textEntry = ""
|
|
end
|
|
ui.draw(window.x, window.y)
|
|
love.keyboard.setTextInput(false)
|
|
love.keyreleased = levelloop.keyreleased
|
|
love.keypressed = levelloop.keypressed
|
|
love.update = levelloop.normalVisible
|
|
elseif key == "backspace" then
|
|
textEntry = string.sub(textEntry, 0, #textEntry -1)
|
|
ui.draw(window.x, window.y)
|
|
end
|
|
end
|
|
love.keypressed = function(key, _) return end
|
|
else
|
|
love.keyreleased = levelloop.keyreleased
|
|
love.keypressed = levelloop.keypressed
|
|
end
|
|
end
|
|
|
|
|
|
function love.textinput(text)
|
|
textEntry = textEntry .. text
|
|
ui.draw(window.x, window.y)
|
|
end
|
|
|
|
|
|
function ui.chatEntry()
|
|
local passedEntry = ""
|
|
if textEntry == "" then passedEntry = "Start typing your message." else passedEntry = textEntry end
|
|
local chatEntry =
|
|
{name = "copySize",
|
|
{name = "rect",
|
|
fill = "fill",
|
|
color = { r = .1, g = .1, b = .1, .7 }
|
|
},
|
|
{name = "frame",
|
|
{name = "label",
|
|
text = passedEntry
|
|
}
|
|
}
|
|
}
|
|
return chatEntry
|
|
end
|
|
|
|
|
|
chatentries = {name = "vertical", {name = "spacer", width = 0}}
|
|
function ui.chatlog()
|
|
return chatentries
|
|
end
|
|
|
|
|
|
function ui.addChatEntry(user, message)
|
|
if #chatentries > 10 then
|
|
table.remove(chatentries, 1)
|
|
end
|
|
local chatText
|
|
if user ~= "" then
|
|
chatText = user .. ": " .. message
|
|
else
|
|
chatText = message
|
|
end
|
|
local entry = {name = "rotate",
|
|
rotation = 0, -- OKAY DIEGO >:(
|
|
{name = "copySize",
|
|
{name = "rect",
|
|
fill = "fill",
|
|
color = { r = .1, g = .1, b = .1, a = .6 }
|
|
},
|
|
{name = "vertical",
|
|
{name = "label",
|
|
text = chatText,
|
|
font = fonts.smallFont
|
|
},
|
|
{name = "spacer",
|
|
height = 2
|
|
}
|
|
}
|
|
}
|
|
}
|
|
table.insert(chatentries, entry)
|
|
ui.draw(window.x, window.y)
|
|
end
|
|
|
|
|
|
function ui.loadTextures(directory, container)
|
|
if not container then container = {} end
|
|
local entries = love.filesystem.getDirectoryItems(directory)
|
|
if #entries == 0 then return container end
|
|
for i, file in pairs(entries) do
|
|
local path = directory .."/".. file
|
|
local entry = love.filesystem.getInfo(path)
|
|
if entry.type == "directory" and file ~= ".git" then
|
|
container[file] = {}
|
|
container[file] = ui.loadTextures(path, container[file])
|
|
elseif entry.type == "file" or entry.type == "symlink" then
|
|
local status, imageData = pcall(love.image.newImageData, path);
|
|
if status then
|
|
local hash = love.data.hash("sha512", imageData:getString())
|
|
levelloop.textures[hash] = {data = imageData}
|
|
container[file] = hash
|
|
end
|
|
end
|
|
end
|
|
return container
|
|
end
|
|
|
|
|
|
function textureEntry(hash)
|
|
local texture = levelloop.textures[hash]
|
|
assert(texture, "No texture found for textureentry?")
|
|
assert(texture.data, "No imagedata found for textureentry?")
|
|
if not texture.image then
|
|
texture.image = love.graphics.newImage(texture.data)
|
|
end
|
|
local width = texture.image:getWidth()
|
|
local height = texture.image:getHeight()
|
|
if drawing and drawing.cursorHash and hash == drawing.cursorHash then
|
|
return {name = "overlayRect",
|
|
fill = "line",
|
|
{name = "drawHash",
|
|
hash = hash,
|
|
scale = ui.sidebarScale
|
|
}
|
|
}
|
|
else
|
|
return {name = "cursorSelect", uiSelect = "GameUI",
|
|
identifier = hash,
|
|
kind = "picker",
|
|
{name = "drawHash",
|
|
hash = hash,
|
|
scale = ui.sidebarScale
|
|
}
|
|
}
|
|
end
|
|
end
|
|
|
|
|
|
function textureRun(entryTable, width)
|
|
local textures = levelloop.textures
|
|
local entries = {name = "naiveGrid", width = width - 20}
|
|
local entryTableSorted = {}
|
|
|
|
-- Sort the entries alphapetically (or well, probably more... "byte compared") :)
|
|
-- This implies that in <author>/<packname>/<fileName> the fileName controls where
|
|
-- the texture lands in the block drawer, smaller lands further left.
|
|
for iter, entry in pairs(entryTable) do
|
|
table.insert(entryTableSorted, {name = iter, entry = entry})
|
|
end
|
|
table.sort(entryTableSorted, function(k1, k2) return k1.name < k2.name end)
|
|
|
|
for iter, entry in pairs(entryTableSorted) do
|
|
if not textures[entry.entry].image then
|
|
textures[entry.entry].image = love.graphics.newImage(textures[entry.entry].data)
|
|
end
|
|
table.insert(entries, textureEntry(entry.entry))
|
|
end
|
|
return entries
|
|
end
|
|
|
|
|
|
function ui.blockDrawer(textureTree, w, h, container)
|
|
if not textureTree then return {name = "label", text = "Loading textures..."} end
|
|
local pointSize = 8
|
|
if ui.sidebarScale == 2 then pointSize = 16 end
|
|
if not container then container = {name="vertical",
|
|
{name = "colorPicker", kind = "colorpicker",
|
|
granularity = 0.25, pointSize = pointSize},
|
|
{name = "spacer", height = 5 * ui.sidebarScale},
|
|
{name = "bwColorPicker", kind = "bwColorPicker",
|
|
pointSize = pointSize}}
|
|
end
|
|
local textureTreeSorted = {}
|
|
for author, tree in pairs(textureTree) do
|
|
table.insert(textureTreeSorted, {author = author, tree = tree})
|
|
end
|
|
table.sort(textureTreeSorted, function(k1, k2) return k1.author < k2.author end)
|
|
for author, tree in pairs(textureTreeSorted) do
|
|
for pack, subTree in pairs(tree.tree) do
|
|
container.name = "vertical"
|
|
table.insert(container, {name = "label", text = pack})
|
|
table.insert(container,
|
|
{name = "color",
|
|
color = drawing.color or {1, 1, 1},
|
|
--[[ HACK! remove the 1, 1, 1.
|
|
drawing.color should be set!
|
|
]]--
|
|
textureRun(subTree, w)
|
|
})
|
|
end
|
|
end
|
|
return container
|
|
end
|
|
|
|
|
|
function ui.menuDrawer(w, h)
|
|
return {name = "horizontal",
|
|
{name = "vertical",
|
|
{name = "button",
|
|
identifier = "save",
|
|
uiSelect = "Menu",
|
|
buttonColor = "greenTranslucent",
|
|
text = "Save world"
|
|
},
|
|
{name = "spacer",
|
|
height = 10,
|
|
},
|
|
{name = "button",
|
|
identifier = "disconnect",
|
|
uiSelect = "Menu",
|
|
buttonColor = "pinkTranslucent",
|
|
text = "Disconnect"
|
|
},
|
|
{name = "spacer",
|
|
height = 25,
|
|
},
|
|
{name = "button",
|
|
identifier = "sideBarScaleTwo",
|
|
uiSelect = "Menu",
|
|
buttonColor = "grayTranslucent",
|
|
text = "Ui scale x2"
|
|
},
|
|
{name = "spacer",
|
|
height = 4,
|
|
},
|
|
{name = "button",
|
|
identifier = "sideBarScaleOne",
|
|
uiSelect = "Menu",
|
|
buttonColor = "grayTranslucent",
|
|
text = "Ui scale x1"
|
|
},
|
|
},
|
|
{name = "spacer",
|
|
width = 80,
|
|
},
|
|
{name = "label",
|
|
text = ui.helptext,
|
|
font = fonts.normallFont
|
|
}
|
|
}
|
|
end
|
|
|
|
|
|
function ui.draw(w, h)
|
|
window.x, window.y = w, h
|
|
love.graphics.setCanvas(ui.buffer)
|
|
layout.uiState.GameUI = {}
|
|
love.graphics.clear( )
|
|
local blockDrawer = ui.blockDrawer(ui.textureTree, w, h)
|
|
blockMaxX, blockMaxY = layout.handle(blockDrawer, 0, 0, true)
|
|
local blockDrawerAdjusted = ui.blockDrawer(ui.textureTree, blockMaxX, blockMaxY)
|
|
layout.handle(blockDrawerAdjusted, window.x - blockMaxX, 0)
|
|
layout.handle(ui.chatlog(), 25, 90)
|
|
love.graphics.setCanvas()
|
|
end
|
|
|
|
|
|
function ui.drawMenu(w, h)
|
|
window.x, window.y = w, h
|
|
layout.uiState.Menu = {}
|
|
love.graphics.setCanvas(ui.buffer)
|
|
love.graphics.clear()
|
|
local menuDrawer = ui.menuDrawer(w, h)
|
|
menux, menuy = layout.handle(menuDrawer, 0, 0, true)
|
|
layout.handle(menuDrawer, (window.x - menux) /2, (window.y - menuy)/2)
|
|
love.graphics.setCanvas()
|
|
end
|
|
|
|
|
|
function ui.mousepressed(mousex, mousey)
|
|
local textures = levelloop.textures
|
|
if menuVisible then
|
|
for i, v in ipairs(layout.uiState.Menu) do
|
|
if mousex >= v.x and mousex <= v.x2 and --hit testing
|
|
mousey >= v.y and mousey <= v.y2 then
|
|
if v.kind == "button" then
|
|
if v.identifier == "save" then
|
|
levelloop.networkSend("saveWorld")
|
|
ui.keyreleased("escape")
|
|
elseif v.identifier == "disconnect" then
|
|
levelloop.remoteCall("playerLeave")
|
|
|
|
menu.init()
|
|
elseif v.identifier == "sideBarScaleTwo" then
|
|
ui.sidebarScale = 2
|
|
ui.draw(window.x, window.y)
|
|
ui.keyreleased("escape")
|
|
elseif v.identifier == "sideBarScaleOne" then
|
|
ui.sidebarScale = 1
|
|
ui.draw(window.x, window.y)
|
|
ui.keyreleased("escape")
|
|
end
|
|
end
|
|
return -- Return after the first hit...
|
|
end
|
|
end
|
|
else
|
|
for i, v in ipairs(layout.uiState.GameUI) do
|
|
if mousex >= v.x and mousex <= v.x2 and
|
|
mousey >= v.y and mousey <= v.y2 then
|
|
if v.kind == "picker" then
|
|
assert(v.identifier, "No identifier in picker!")
|
|
drawing.cursorHash = v.identifier
|
|
drawing.cursor = textures[v.identifier]
|
|
assert(drawing.cursor, "No cursor texture found!")
|
|
ui.draw(window.x, window.y)
|
|
return
|
|
elseif v.kind == "tab" then
|
|
selectedTab = v.identifier
|
|
ui.draw(window.x, window.y)
|
|
return
|
|
elseif v.kind == "colorpicker" then
|
|
print("Picker hit :D")
|
|
local scale = ui.sidebarScale / granularity
|
|
local red = math.floor((mousey - v.y) / v.pointSize) / scale
|
|
local green = math.floor((mousex - v.x) / v.pointSize / (scale + 1)) / scale
|
|
local blue = (math.floor((mousex - v.x) / v.pointSize) % (scale + 1)) / scale
|
|
print("I think the color is " .. red .. ":" .. green .. ":" .. blue)
|
|
drawing.color = {red, green, blue, 1}
|
|
ui.draw(window.x, window.y)
|
|
return
|
|
elseif v.kind == "bwColorPicker" then
|
|
local scale = 1.0 / granularity
|
|
local saturation = math.floor((mousex - v.x) / v.pointSize) / scale
|
|
drawing.color = {saturation, saturation, saturation, 1}
|
|
ui.draw(window.x, window.y)
|
|
return
|
|
end
|
|
return
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
|
|
ui.init = function()
|
|
love.keyboard.setTextInput( false )
|
|
local w,h = love.window.getMode()
|
|
ui.textureTree = ui.loadTextures("textures/blocks")
|
|
|
|
ui.draw(w, h)
|
|
ui.resize = function()
|
|
local w,h = love.window.getMode()
|
|
ui.buffer = love.graphics.newCanvas(w, h)
|
|
love.graphics.setCanvas(ui.buffer)
|
|
love.graphics.clear()
|
|
ui.draw(w, h)
|
|
love.graphics.setCanvas()
|
|
end
|
|
end
|
|
|
|
local w, h = love.window.getMode()
|
|
ui.buffer = love.graphics.newCanvas(w, h)
|
|
ui.space = 300
|