mirror of
https://github.com/geode-sdk/geode.git
synced 2024-11-14 19:15:05 -05:00
folder settings & allow picking which dialog to use
This commit is contained in:
parent
1a82d12b7b
commit
56f878ccb3
4 changed files with 71 additions and 56 deletions
|
@ -328,16 +328,11 @@ namespace geode {
|
|||
FileSettingV3(PrivateMarker);
|
||||
static Result<std::shared_ptr<FileSettingV3>> parse(std::string const& key, std::string const& modID, matjson::Value const& json);
|
||||
|
||||
enum class FileType {
|
||||
Any = 0,
|
||||
File = 1,
|
||||
Folder = 2,
|
||||
};
|
||||
|
||||
std::filesystem::path getDefaultValue() const override;
|
||||
Result<> isValid(std::filesystem::path const& value) const override;
|
||||
|
||||
FileType getFileType() const;
|
||||
bool isFolder() const;
|
||||
bool useSaveDialog() const;
|
||||
|
||||
std::optional<std::vector<utils::file::FilePickOptions::Filter>> getFilters() const;
|
||||
|
||||
|
|
|
@ -21,6 +21,7 @@ private:
|
|||
{ "float", &FloatSettingV3::parse },
|
||||
{ "string", &StringSettingV3::parse },
|
||||
{ "file", &FileSettingV3::parse },
|
||||
{ "folder", &FileSettingV3::parse },
|
||||
{ "path", &FileSettingV3::parse },
|
||||
{ "rgb", &Color3BSettingV3::parse },
|
||||
{ "color", &Color3BSettingV3::parse },
|
||||
|
|
|
@ -347,17 +347,17 @@ bool FileSettingNodeV3::init(std::shared_ptr<FileSettingV3> setting, float width
|
|||
labelBG->setScale(.25f);
|
||||
labelBG->setColor({ 0, 0, 0 });
|
||||
labelBG->setOpacity(90);
|
||||
labelBG->setContentSize({ 400, 80 });
|
||||
this->getButtonMenu()->addChildAtPosition(labelBG, Anchor::Center, ccp(-15, 0));
|
||||
labelBG->setContentSize({ 420, 80 });
|
||||
this->getButtonMenu()->addChildAtPosition(labelBG, Anchor::Center, ccp(-10, 0));
|
||||
|
||||
m_fileIcon = CCSprite::create();
|
||||
this->getButtonMenu()->addChildAtPosition(m_fileIcon, Anchor::Left, ccp(3, 0));
|
||||
this->getButtonMenu()->addChildAtPosition(m_fileIcon, Anchor::Left, ccp(5, 0));
|
||||
|
||||
m_nameLabel = CCLabelBMFont::create("", "bigFont.fnt");
|
||||
this->getButtonMenu()->addChildAtPosition(m_nameLabel, Anchor::Left, ccp(11, 0), ccp(0, .5f));
|
||||
this->getButtonMenu()->addChildAtPosition(m_nameLabel, Anchor::Left, ccp(13, 0), ccp(0, .5f));
|
||||
|
||||
auto selectSpr = CCSprite::createWithSpriteFrameName("GJ_plus2Btn_001.png");
|
||||
selectSpr->setScale(.75f);
|
||||
selectSpr->setScale(.7f);
|
||||
auto selectBtn = CCMenuItemSpriteExtra::create(
|
||||
selectSpr, this, menu_selector(FileSettingNodeV3::onPickFile)
|
||||
);
|
||||
|
@ -370,18 +370,21 @@ bool FileSettingNodeV3::init(std::shared_ptr<FileSettingV3> setting, float width
|
|||
|
||||
void FileSettingNodeV3::updateState() {
|
||||
SettingNodeV3::updateState();
|
||||
auto ty = this->getSetting()->getFileType();
|
||||
if (ty == FileSettingV3::FileType::Any) {
|
||||
ty = std::filesystem::is_directory(m_path) ?
|
||||
FileSettingV3::FileType::Folder :
|
||||
FileSettingV3::FileType::File;
|
||||
}
|
||||
m_fileIcon->setDisplayFrame(CCSpriteFrameCache::get()->spriteFrameByName(
|
||||
ty == FileSettingV3::FileType::File ? "file.png"_spr : "folderIcon_001.png"
|
||||
this->getSetting()->isFolder() ? "folderIcon_001.png" : "file.png"_spr
|
||||
));
|
||||
limitNodeSize(m_fileIcon, ccp(10, 10), 1.f, .1f);
|
||||
m_nameLabel->setString(m_path.filename().string().c_str());
|
||||
m_nameLabel->limitLabelWidth(75, .4f, .1f);
|
||||
if (m_path.empty()) {
|
||||
m_nameLabel->setString(this->getSetting()->isFolder() ? "No Folder Selected" : "No File Selected");
|
||||
m_nameLabel->setColor(ccGRAY);
|
||||
m_nameLabel->setOpacity(155);
|
||||
}
|
||||
else {
|
||||
m_nameLabel->setString(m_path.filename().string().c_str());
|
||||
m_nameLabel->setColor(ccWHITE);
|
||||
m_nameLabel->setOpacity(255);
|
||||
}
|
||||
m_nameLabel->limitLabelWidth(75, .35f, .1f);
|
||||
}
|
||||
|
||||
void FileSettingNodeV3::onCommit() {
|
||||
|
@ -407,9 +410,9 @@ void FileSettingNodeV3::onPickFile(CCObject*) {
|
|||
}
|
||||
});
|
||||
m_pickListener.setFilter(file::pick(
|
||||
this->getSetting()->getFileType() == FileSettingV3::FileType::Folder ?
|
||||
this->getSetting()->isFolder() ?
|
||||
file::PickMode::OpenFolder :
|
||||
file::PickMode::OpenFile,
|
||||
(this->getSetting()->useSaveDialog() ? file::PickMode::SaveFile : file::PickMode::OpenFile),
|
||||
{
|
||||
dirs::getGameDir(),
|
||||
this->getSetting()->getFilters().value_or(std::vector<file::FilePickOptions::Filter>())
|
||||
|
|
|
@ -609,7 +609,8 @@ class FileSettingV3::Impl final {
|
|||
public:
|
||||
std::filesystem::path value;
|
||||
std::filesystem::path defaultValue;
|
||||
FileType fileType;
|
||||
bool folder = false;
|
||||
bool useSaveDialog = false; // this option makes no sense if folder = true
|
||||
std::optional<std::vector<utils::file::FilePickOptions::Filter>> filters;
|
||||
};
|
||||
|
||||
|
@ -639,29 +640,41 @@ Result<std::shared_ptr<FileSettingV3>> FileSettingV3::parse(std::string const& k
|
|||
}
|
||||
ret->m_impl->value = ret->m_impl->defaultValue;
|
||||
|
||||
if (auto ty = root.has("filetype")) {
|
||||
ty.assertIsString();
|
||||
switch (hash(ty.template get<std::string>())) {
|
||||
case hash("any"): ret->m_impl->fileType = FileType::Any; break;
|
||||
case hash("file"): ret->m_impl->fileType = FileType::File; break;
|
||||
case hash("folder"): ret->m_impl->fileType = FileType::Folder; break;
|
||||
default: return Err(
|
||||
"Setting '{}' in mod {}: Invalid filetype \"{}\"",
|
||||
key, modID, ty.template get<std::string>()
|
||||
std::string type;
|
||||
root.needs("type").into(type);
|
||||
if (type == "folder") {
|
||||
ret->m_impl->folder = true;
|
||||
// folder-specific stuff if they ever exist
|
||||
}
|
||||
else if (type == "file" || type == "path") {
|
||||
if (type == "path") {
|
||||
log::warn(
|
||||
"Setting '{}' in mod {}: the \"path\" type has been "
|
||||
"deprecated, use \"type\": \"file\" or \"type\": \"folder\" instead",
|
||||
key, modID
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
if (auto controls = root.has("control")) {
|
||||
auto filters = std::vector<file::FilePickOptions::Filter>();
|
||||
for (auto& item : controls.has("filters").items()) {
|
||||
utils::file::FilePickOptions::Filter filter;
|
||||
item.has("description").into(filter.description);
|
||||
item.has("files").into(filter.files);
|
||||
filters.push_back(filter);
|
||||
std::string dialogType;
|
||||
root.has("dialog").into(dialogType);
|
||||
switch (hash(dialogType)) {
|
||||
case hash("save"): ret->m_impl->useSaveDialog = true; break;
|
||||
case hash("open"): ret->m_impl->useSaveDialog = false; break;
|
||||
case hash(""): break;
|
||||
default: return Err("Setting '{}' in mod {}: unknown \"dialog\" type \"{}\"", key, modID, dialogType);
|
||||
}
|
||||
if (!filters.empty()) {
|
||||
ret->m_impl->filters.emplace(filters);
|
||||
|
||||
// Filter controls only make sense for files but not for folders
|
||||
if (auto controls = root.has("control")) {
|
||||
auto filters = std::vector<file::FilePickOptions::Filter>();
|
||||
for (auto& item : controls.has("filters").items()) {
|
||||
utils::file::FilePickOptions::Filter filter;
|
||||
item.has("description").into(filter.description);
|
||||
item.has("files").into(filter.files);
|
||||
filters.push_back(filter);
|
||||
}
|
||||
if (!filters.empty()) {
|
||||
ret->m_impl->filters.emplace(filters);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -676,22 +689,25 @@ std::filesystem::path FileSettingV3::getDefaultValue() const {
|
|||
return m_impl->defaultValue;
|
||||
}
|
||||
Result<> FileSettingV3::isValid(std::filesystem::path const& value) const {
|
||||
if (m_impl->fileType != FileType::Any) {
|
||||
if (!std::filesystem::exists(value)) {
|
||||
return Err("{} must exist", m_impl->fileType == FileType::File ? "File" : "Folder");
|
||||
}
|
||||
if (m_impl->fileType == FileType::File && !std::filesystem::is_regular_file(value)) {
|
||||
return Err("Value must be a file");
|
||||
}
|
||||
if (m_impl->fileType == FileType::Folder && !std::filesystem::is_directory(value)) {
|
||||
std::error_code ec;
|
||||
if (m_impl->folder) {
|
||||
if (!std::filesystem::is_directory(value, ec)) {
|
||||
return Err("Value must be a folder");
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (!std::filesystem::is_regular_file(value, ec)) {
|
||||
return Err("Value must be a file");
|
||||
}
|
||||
}
|
||||
return Ok();
|
||||
}
|
||||
|
||||
FileSettingV3::FileType FileSettingV3::getFileType() const {
|
||||
return m_impl->fileType;
|
||||
bool FileSettingV3::isFolder() const {
|
||||
return m_impl->folder;
|
||||
}
|
||||
bool FileSettingV3::useSaveDialog() const {
|
||||
return m_impl->useSaveDialog;
|
||||
}
|
||||
|
||||
std::optional<std::vector<utils::file::FilePickOptions::Filter>> FileSettingV3::getFilters() const {
|
||||
|
|
Loading…
Reference in a new issue