Skip to content

Commit

Permalink
Added file picker dialog to path fields
Browse files Browse the repository at this point in the history
Thanks to Flagpole1up for the folder icons
Small themes cleanup, default theme name is now in a variable
Current theme is set to the theme table, and not just the theme name
  • Loading branch information
Cruor committed Aug 12, 2022
1 parent 04be92e commit 1142565
Show file tree
Hide file tree
Showing 6 changed files with 167 additions and 4 deletions.
Binary file added src/ui/assets/icons/folder-16.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added src/ui/assets/icons/folder-24.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
71 changes: 70 additions & 1 deletion src/ui/forms/fields/path.lua
Original file line number Diff line number Diff line change
@@ -1,12 +1,54 @@
local ui = require("ui")
local uiElements = require("ui.elements")
local uiUtils = require("ui.utils")

local utils = require("utils")
local mods = require("mods")
local loadedState = require("loaded_state")
local stringField = require("ui.forms.fields.string")
local iconUtils = require("ui.utils.icons")
local fileLocations = require("file_locations")

local pathField = {}

pathField.fieldType = "path"

local function openFileDialog(textField, options)
local relativeToMod = options.relativeToMod
local allowedExtensions = options.allowedExtensions

local filter
local startingPath = fileLocations.getCelesteDir()

if allowedExtensions then
filter = table.concat(allowedExtensions, ",")
end

if relativeToMod ~= false then
local modPath = mods.getFilenameModPath(loadedState.filename)

if not modPath then
return false
end

startingPath = modPath
end

utils.openDialog(startingPath, filter, function(filename)
if relativeToMod ~= false then
local modPath = mods.getFilenameModPath(filename)

if not modPath then
return false
end

filename = string.sub(filename, #modPath + 2)
end

textField:setText(filename)
end)
end

function pathField.getElement(name, value, options)
-- Add extra options and pass it onto string field

Expand Down Expand Up @@ -63,7 +105,34 @@ function pathField.getElement(name, value, options)
return true
end

return stringField.getElement(name, value, options)
local stringElement = stringField.getElement(name, value, options)
local textfield = stringElement.field

if textfield.height == -1 then
textfield:layout()
end

local iconMaxSize = textfield.label.height
local parentHeight = textfield.height
local folderIcon, iconSize = iconUtils.getIcon("folder", iconMaxSize)

if folderIcon then
local centerOffset = math.floor((parentHeight - iconSize) / 2)
local folderImage = uiElements.image(folderIcon):with(uiUtils.rightbound(0)):with(uiUtils.at(0, centerOffset))

folderImage.interactive = 1
folderImage:hook({
onClick = function(orig, self)
orig(self)

openFileDialog(textfield, options)
end
})

textfield:addChild(folderImage)
end

return stringElement
end

return pathField
3 changes: 2 additions & 1 deletion src/ui/themes.lua
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ local themes = {}

themes.themes = {}
themes.currentTheme = nil
themes.defaultThemeName = "dark"

function themes.unloadThemes()
themes.themes = {}
Expand Down Expand Up @@ -75,7 +76,7 @@ end

function themes.useTheme(name)
if name and themes.themes[name] then
themes.currentTheme = name
themes.currentTheme = themes.themes[name]

themer.apply(themes.themes[name])

Expand Down
4 changes: 2 additions & 2 deletions src/ui/ui_device.lua
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ function debugUtils.reloadUI()
themes.unloadThemes()
themes.loadInternalThemes()
themes.loadExternalThemes()
themes.useTheme(themes.currentTheme)
themes.useTheme(themes.currentTheme.name)

uiRoot.updateWindows(windows.getLoadedWindows())

Expand All @@ -62,7 +62,7 @@ function ui.initializeDevice()
local appliedTheme = themes.useTheme(configTheme)

if not appliedTheme then
themes.useTheme("dark")
themes.useTheme(themes.defaultThemeName)
end
end

Expand Down
93 changes: 93 additions & 0 deletions src/ui/utils/icons.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
local themes = require("ui.themes")
local utils = require("utils")

local iconUtils = {}

local iconSizes = {64, 32, 24, 16}
local iconCache = {}

local previousThemeName = themes.defaultThemeName

function iconUtils.clearCache(name)
if name then
for _, size in ipairs(iconSizes) do
local cacheKey = string.format("%s-%s", name, size)

iconCache[cacheKey] = nil
end

else
iconCache = {}
end
end

function iconUtils.getBestSize(maxSize)
for _, size in ipairs(iconSizes) do
if size <= maxSize then
return size
end
end
end

function iconUtils.getIcon(name, maxSize, allowCustom)
local currentTheme = themes.currentTheme

-- Invalidate all icons if theme has changed
if currentTheme.name ~= previousThemeName then
iconUtils.clearCache()

previousThemeName = currentTheme.name
end

local targetSize = iconUtils.getBestSize(maxSize)
local cacheKey = string.format("%s-%s", name, targetSize)

if iconCache[cacheKey] then
return unpack(iconCache[cacheKey])
end

local iconsPath = "ui/assets/icons/"

if currentTheme and currentTheme.iconsPath then
if allowCustom ~= false then
iconsPath = currentTheme.iconsPath
end
end

-- Add image to cache for all sizes that fit
local image
local actualSize
local relevantSizes = {}

for _, size in ipairs(iconSizes) do
if size <= maxSize then
table.insert(relevantSizes, size)

local path = utils.joinpath(iconsPath, string.format("%s-%s.png", name, size))
local fileInfo = love.filesystem.getInfo(path) or utils.pathAttributes(path)

if fileInfo then
image = love.graphics.newImage(path)
actualSize = size

break
end
end
end

if image then
for _, size in ipairs(relevantSizes) do
cacheKey = string.format("%s-%s", name, size)
iconCache[cacheKey] = {image, actualSize}
end

return image, actualSize
end

-- Fallback to default theme
if allowCustom ~= false then
return iconUtils.getIcon(name, maxSize, false)
end
end

return iconUtils

0 comments on commit 1142565

Please sign in to comment.