Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion w-engine/plugin.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
id = "tadomika_ari/w-engine"
name = "W Engine"
version = "1.3.0"
version = "1.4.0"
# Tile and control callbacks are Luau closures rather than named globals, which
# the host resolves from plugin API 9 onwards.
plugin_api = 9
Expand Down
1 change: 1 addition & 0 deletions w-engine/translations/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@
"label": "Sync shell colors with the wallpaper"
}
},
"no_more_page": "No more page available",
"widget": {
"cycling": "W Engine — cycling wallpapers",
"idle": "W Engine",
Expand Down
137 changes: 81 additions & 56 deletions w-engine/w-engine-panel.luau
Original file line number Diff line number Diff line change
Expand Up @@ -30,40 +30,12 @@ local columns = 4
local previewWidth = 168
local previewHeight = 93

local PAGE_SIZE = 48
local actualPage = 1

local workshopRoot = nil
local catalog = nil -- cached: the grid re-renders far more often than the disk changes
local catalogStamp = nil -- mtime of the Workshop dir the cache was built from

local isOpen = false
local outputName = nil
local multiSelect = false
local selected = {} -- ids, in the order they were picked
local minutesText = "15"
local order = "sequential"
local status = {}

-- Per-wallpaper configuration view.
local view = "grid" -- "grid" | "config" | "defaults"
local configId = nil
local configName = ""
local configProps = {}
local engineDraft = {} -- working copy of options[id].engine
local propsDraft = {} -- working copy of options[id].properties
local showUnlabeled = false

-- Global defaults view.
local defaultsDraft = {} -- working copy of defaults.engine
local clearOverrides = false

type Wallpaper = {
nb: string,
name: string,
path: string,
}

local thumbsRequested = false

-- Forward declaration: callbacks defined above the rendering section redraw
-- through this.
local render

Expand Down Expand Up @@ -139,11 +111,18 @@ local function requestThumbnails(thumbs)
end, 60000)
end

local function loadCatalog(): { Wallpaper }
local function isInTranch(index, actualPage)
if actualPage == 0 then
return false
end
local checkMax = PAGE_SIZE * actualPage
local checkMin = checkMax - PAGE_SIZE
return index > checkMin and index <= checkMax
end

local function loadCatalog(actualPage): { Wallpaper }
local items = {}
workshopRoot = nil
-- Several stock locations can exist at once, and last match wins, so a
-- personnalPath entry takes precedence.
for _, path in ipairs(candidateRoots()) do
if noctalia.listDir(path) then
workshopRoot = path
Expand All @@ -163,37 +142,48 @@ local function loadCatalog(): { Wallpaper }

local thumbs = thumbDir()
local missing = false
local numericIndex = 0

for _, entryName in entries do
if tonumber(entryName) then -- Workshop items are numeric ids
local content = noctalia.readFile(workshopRoot .. entryName .. "/project.json")
if content then
local value = noctalia.json.decode(content)
if type(value) == "table" then
-- Prefer the cached still: Workshop previews are often animated
-- GIFs, which the grid would decode and animate for as long as
-- the panel is open.
local path = workshopRoot .. entryName .. "/" .. (value.preview or "preview.jpg")
local thumb = thumbs and (thumbs .. "/" .. entryName .. ".jpg") or nil
if thumb and noctalia.fileExists(thumb) then
path = thumb
else
missing = true
if tonumber(entryName) then -- check if is workshop id
numericIndex = numericIndex + 1
if isInTranch(numericIndex, actualPage) then
local content = noctalia.readFile(workshopRoot .. entryName .. "/project.json")
if content then
local value = noctalia.json.decode(content)
if type(value) == "table" then
-- Prefer the cached still: Workshop previews are often animated
-- GIFs, which the grid would decode and animate for as long as
-- the panel is open.
local path = workshopRoot .. entryName .. "/" .. (value.preview or "preview.jpg")
local thumb = thumbs and (thumbs .. "/" .. entryName .. ".jpg") or nil
if thumb and noctalia.fileExists(thumb) then
path = thumb
else
missing = true
end
table.insert(items, {
nb = entryName,
name = value.title or entryName,
path = path,
})
end
table.insert(items, {
nb = entryName,
name = value.title or entryName,
path = path,
})
else
noctalia.notify(tr("panel.title"), tr("panel.missing_project_json", { name = entryName }))
end
else
noctalia.notify(tr("panel.title"), tr("panel.missing_project_json", { name = entryName }))
end
end
end

if missing then
requestThumbnails(thumbs)
end

if #items == 0 then
actualPage = actualPage - 1
noctalia.notify(tr("plugin_name") ,tr("no_more_page"))
render()
end
return items
end

Expand Down Expand Up @@ -1308,7 +1298,7 @@ render = function()
if not isOpen then
return
end
catalog = catalog or loadCatalog()
catalog = catalog or loadCatalog(actualPage)
if view == "defaults" then
panel.render(defaultsView())
return
Expand Down Expand Up @@ -1349,6 +1339,8 @@ render = function()

-- Single scroll for all list (Wallpaper and Favorite Wallpaper)
local scrollContent = {}

-- Favorite list part
table.insert(scrollContent, ui.label({ text = "Favorites", fontSize = 13, fontWeight = "bold", color = "on_surface" }))
if #FavoriteList == 0 then
table.insert(scrollContent, ui.label({ text = "No favorite", fontSize = 12, color = "on_surface_variant" }))
Expand All @@ -1362,6 +1354,7 @@ render = function()
ui.separator({ spacing = 12 }
))

-- All list part
table.insert(scrollContent,
ui.label({ text = "All wallpapers", fontSize = 13, fontWeight = "bold", color = "on_surface" }
))
Expand All @@ -1373,6 +1366,38 @@ render = function()
table.insert(body,
ui.scroll({ key = "grid-scroll", gap = 12, paddingRight = 8, align = "stretch", flexGrow = 1 }, scrollContent))


table.insert(body, ui.row({ align = "center", justify = "space_between", gap = 8 }, {
ui.button({
text = "previous page",
variant = "ghost",
controlSize = "sm",
onClick = function()
if actualPage > 1 then
actualPage = actualPage - 1
catalog = nil
render()
end
end,
}),
ui.button({
text = tostring(actualPage),
variant = "ghost",
controlSize = "sm",
onClick = "",
}),
ui.button({
text = "next page",
variant = "ghost",
controlSize = "sm",
onClick = function()
actualPage = actualPage + 1
catalog = nil
render()
end,
}),
}))

panel.render(ui.column({ flexGrow = 1, gap = 12 }, body))
end
-- ── Handlers ─────────────────────────────────────────────────────────────────
Expand Down