chroma_solstice/level_editor/gui.lua
Your Name 5b7ea9ec20 Rebuild level editor sidebar with a fixed virtual-space layout
Replace the fraction-of-window positioning (which overlapped and didn't
scale) with a small layout system: the sidebar is authored in one fixed
virtual coordinate space and rendered at native panel resolution, so
element sizes stay constant relative to the panel at any window size and
fonts scale with it.

- level_editor/layout.lua: sections, scrolling list (with clip + hit-test
  by point), scrollbar. Clip rects are scaled to real canvas pixels.
- Room view split into non-overlapping divs: search/back header, a
  scrollable asset list (replaces the old row-paging + forward buttons),
  a status strip, and a compact bottom control cluster.
- Mouse wheel scrolls the list; clicks map from window coords into the
  virtual space via the same transform used to render.
- Sidebar canvas is panel-sized and blitted 1:1 (nearest filter, never
  averaged) to stay crisp; editorDraw runs under a scale transform.
- Center text-only fields (level name) in their rect.

Also carried in main.lua (share the file, can't split cleanly here):
narrator require path fixed via love.filesystem.setRequirePath; sfxr
static uses waveform=NOISE again after the field rename; low-pass +
lower volume on the static loop.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-08-11 12:24:54 -04:00

134 lines
3.1 KiB
Lua

GUI = class("level_editor/gui")
GUI.static.pressSound = love.audio.newSource("sounds/ui/button.wav", "static")
GUI.static.defaultCallbac = function() print("this button has not been configured") end
function GUI:initialize(t)
print("i exist", t.name, t.text)
self.offset = {x = 0, y = 0}
self.name = t.name
self.text = t.text
if not t.onClic then
t.onClic = {}
end
if not t.onClic.right then
t.onClic.right = GUI.defaultCallbac
end
if not t.onClic.left then
t.onClic.left = GUI.defaultCallbac
end
self.clic = t.onClic
self.x, self.y = t.x, t.y
if t.sprite then
print(self.name)
self.scale = t.scale or editorScale * 2 / 3
self.w = t.sprite:getWidth() * self.scale
self.h = t.sprite:getHeight() * self.scale
self.sprite = t.sprite
self.offset = {x = self.w / 2, y = self.h / 2}
self.x, self.y = t.x - self.offset.x, t.y - self.offset.y
elseif t.sprites then
self.sprites = t.sprites
local w, h
for color, sprite in pairs(t.sprites) do
w = sprite:getWidth()
h = sprite:getHeight()
end
if w > h then
self.scale = (editorScale * (2 / 3)) / (w / 16)
elseif w < h then
self.scale = (editorScale * (2 / 3)) / (h / 16)
else
self.scale = (editorScale * (2 / 3)) / (w / 16)
end
self.w = sb.w - (self.x * 2)
self.h = h * self.scale
else
-- this is text
self.x, self.y = t.x, t.y
self.w, self.h = sb.w - self.x * 2, 50
end
if self.name == "folder" then
self.w = sb.w - self.x * 2
end
end
function GUI:clicIsInBox(x, y)
if x > self.x and x < self.x + self.w and y > self.y and y < self.y + self.h then
return true
end
return false
end
function GUI:getBox()
return {x = self.x, y = self.y, w = self.w, h = self.h}
end
function GUI:editText(text)
self.text = text
end
function GUI:draw()
love.graphics.setColor(gColor.white:set())
love.graphics.setLineWidth(4)
local box = self:getBox()
box.x = box.x + self:sha()
box.y = box.y + self:sha()
if name == "forward" then
print(box.x, box.y)
end
if selectedColor == self.name then
love.graphics.rectangle("line", box.x, box.y, box.w, box.h)
end
if self.sprite then
love.graphics.draw(self.sprite, box.x, box.y, 0, self.scale, self.scale)
end
if self.sprites then
for color, sprite in pairs(self.sprites) do
love.graphics.setColor(gColor[color]:set())
love.graphics.draw(sprite, box.x, box.y, 0, self.scale, self.scale)
end
end
if self.text then
love.graphics.setColor(gColor.white:set())
if not self.sprites and not self.sprite then
-- text-only element (e.g. the level-name field): center in its rect
love.graphics.rectangle("line", box.x, box.y, box.w, box.h)
local th = love.graphics.getFont():getHeight()
love.graphics.printf(self.text, box.x, box.y + (box.h - th) / 2, box.w, "center")
else
-- label sitting to the right of an icon
love.graphics.print(self.text, box.x + 50, box.y + 15)
end
end
end
function GUI:onClic(button)
print(button)
print("hey!!! u cliced on me. my name is ", self.name, self.text)
GUI.pressSound:play()
if button == 1 then
self.clic:left()
elseif button == 2 then
self.clic:right()
end
end
function GUI:sha()
return math.random(-worldSha, worldSha) * .5
end