mirror of
https://github.com/geode-sdk/geode.git
synced 2025-03-25 04:11:42 -04:00
Merge branch 'ui' of https://github.com/geode-sdk/geode into ui
This commit is contained in:
commit
02023afe0c
19 changed files with 185 additions and 95 deletions
|
@ -1,6 +1,6 @@
|
|||
cmake_minimum_required(VERSION 3.21 FATAL_ERROR)
|
||||
|
||||
project(geode-sdk VERSION 0.2.0 LANGUAGES CXX C)
|
||||
project(geode-sdk VERSION 0.2.1 LANGUAGES CXX C)
|
||||
|
||||
set(CMAKE_CXX_STANDARD 20)
|
||||
set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
cmake_minimum_required(VERSION 3.21 FATAL_ERROR)
|
||||
|
||||
project(geode-loader VERSION 0.2.0 LANGUAGES C CXX)
|
||||
project(geode-loader VERSION 0.2.1 LANGUAGES C CXX)
|
||||
set(PROJECT_VERSION_TYPE Alpha)
|
||||
|
||||
# Package info file for internal representation
|
||||
|
|
|
@ -77,7 +77,7 @@ namespace geode {
|
|||
* and has downloaded a mod from the
|
||||
* future.
|
||||
*/
|
||||
static constexpr VersionInfo s_supportedVersionMax { 0, 2, 0 };
|
||||
static constexpr VersionInfo s_supportedVersionMax { 0, 2, 1 };
|
||||
|
||||
Result<std::string> createTempDirectoryForMod(ModInfo const& info);
|
||||
Result<Mod*> loadModFromFile(std::string const& file);
|
||||
|
|
|
@ -101,27 +101,27 @@ namespace geode {
|
|||
* Short & concise description of the
|
||||
* mod.
|
||||
*/
|
||||
std::string m_description = "";
|
||||
std::optional<std::string> m_description;
|
||||
/**
|
||||
* Detailed description of the mod, writtenin Markdown (see
|
||||
* <Geode/ui/MDTextArea.hpp>) for more info
|
||||
*/
|
||||
std::string m_details = "";
|
||||
std::optional<std::string> m_details;
|
||||
/**
|
||||
* Changelog for the mod, written in Markdown (see
|
||||
* <Geode/ui/MDTextArea.hpp>) for more info
|
||||
*/
|
||||
std::string m_changelog = "";
|
||||
std::optional<std::string> m_changelog;
|
||||
/**
|
||||
* Support info for the mod; this means anything to show ways to
|
||||
* support the mod's development, like donations. Written in Markdown
|
||||
* (see <Geode/ui/MDTextArea.hpp>) for more info
|
||||
*/
|
||||
std::string m_supportInfo = "";
|
||||
std::optional<std::string> m_supportInfo;
|
||||
/**
|
||||
* Git Repository of the mod
|
||||
*/
|
||||
std::string m_repository = "";
|
||||
std::optional<std::string> m_repository;
|
||||
/**
|
||||
* Info about where users should report issues and request help
|
||||
*/
|
||||
|
@ -321,8 +321,8 @@ namespace geode {
|
|||
std::string getID() const;
|
||||
std::string getName() const;
|
||||
std::string getDeveloper() const;
|
||||
std::string getDescription() const;
|
||||
std::string getDetails() const;
|
||||
std::optional<std::string> getDescription() const;
|
||||
std::optional<std::string> getDetails() const;
|
||||
std::string getPath() const;
|
||||
VersionInfo getVersion() const;
|
||||
bool isEnabled() const;
|
||||
|
|
|
@ -27,6 +27,8 @@ namespace geode {
|
|||
bool vertical
|
||||
);
|
||||
|
||||
bool ccTouchBegan(cocos2d::CCTouch*, cocos2d::CCEvent*) override;
|
||||
|
||||
public:
|
||||
static ScrollLayer* create(
|
||||
cocos2d::CCRect const& rect,
|
||||
|
|
|
@ -214,6 +214,11 @@ namespace geode {
|
|||
return this->intoAs<T, T>(target);
|
||||
}
|
||||
|
||||
template<class T>
|
||||
JsonMaybeValue<Json> into(std::optional<T>& target) {
|
||||
return this->intoAs<T, std::optional<T>>(target);
|
||||
}
|
||||
|
||||
template<class A, class T>
|
||||
JsonMaybeValue<Json> intoAs(T& target) {
|
||||
this->inferType<A>();
|
||||
|
|
|
@ -63,6 +63,22 @@ namespace geode::cocos {
|
|||
result = node;
|
||||
return *this;
|
||||
}
|
||||
template<class... Args>
|
||||
SafeCreate<T>& make(Args... args) {
|
||||
result = T::create(args...);
|
||||
return *this;
|
||||
}
|
||||
// convenience for CCSprite
|
||||
template<class... Args>
|
||||
SafeCreate<T>& makeWithFrame(Args... args) {
|
||||
result = T::createWithSpriteFrameName(args...);
|
||||
return *this;
|
||||
}
|
||||
template<class... Args>
|
||||
SafeCreate<T>& makeUsing(T*(*func)(Args...), Args... args) {
|
||||
result = func(args...);
|
||||
return *this;
|
||||
}
|
||||
template<class O = T, class... Args>
|
||||
T* orMakeUsing(O*(*func)(Args...), Args... args) {
|
||||
if (result) return result;
|
||||
|
@ -73,6 +89,11 @@ namespace geode::cocos {
|
|||
if (result) return result;
|
||||
return O::create(args...);
|
||||
}
|
||||
template<class O = T, class... Args>
|
||||
T* orMakeWithFrame(Args... args) {
|
||||
if (result) return result;
|
||||
return O::createWithSpriteFrameName(args...);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
BIN
loader/resources/changelog.png
Normal file
BIN
loader/resources/changelog.png
Normal file
Binary file not shown.
After ![]() (image error) Size: 1 KiB |
|
@ -182,7 +182,9 @@ class $modify(CustomMenuLayer, MenuLayer) {
|
|||
}
|
||||
|
||||
// show crash info
|
||||
if (Loader::get()->didLastLaunchCrash()) {
|
||||
static bool shownLastCrash = false;
|
||||
if (Loader::get()->didLastLaunchCrash() && !shownLastCrash) {
|
||||
shownLastCrash = true;
|
||||
auto popup = createQuickPopup(
|
||||
"Crashed",
|
||||
"It appears that the last session crashed. Would you like to "
|
||||
|
|
|
@ -89,7 +89,8 @@ void InternalLoader::platformMessageBox(const char* title, std::string const& in
|
|||
|
||||
void InternalLoader::openPlatformConsole() {
|
||||
if (m_platformConsoleOpen) return;
|
||||
if (AllocConsole() == 0) return;
|
||||
if (AllocConsole() == 0) return;
|
||||
SetConsoleCP(CP_UTF8);
|
||||
// redirect console output
|
||||
freopen_s(reinterpret_cast<FILE**>(stdout), "CONOUT$", "w", stdout);
|
||||
freopen_s(reinterpret_cast<FILE**>(stdin), "CONIN$", "r", stdin);
|
||||
|
|
|
@ -44,7 +44,7 @@ DataStore::~DataStore() {
|
|||
}
|
||||
|
||||
Mod::Mod(ModInfo const& info) {
|
||||
this->m_info = info;
|
||||
m_info = info;
|
||||
}
|
||||
|
||||
Mod::~Mod() {
|
||||
|
@ -142,16 +142,16 @@ void Mod::postDSUpdate() {
|
|||
}
|
||||
|
||||
Result<> Mod::createTempDir() {
|
||||
ZipFile unzip(this->m_info.m_path.string());
|
||||
ZipFile unzip(m_info.m_path.string());
|
||||
|
||||
if (!unzip.isLoaded()) {
|
||||
return Err<>("Unable to unzip " + this->m_info.m_path.string());
|
||||
return Err<>("Unable to unzip " + m_info.m_path.string());
|
||||
}
|
||||
|
||||
if (!unzip.fileExists(this->m_info.m_binaryName)) {
|
||||
if (!unzip.fileExists(m_info.m_binaryName)) {
|
||||
return Err<>(
|
||||
"Unable to find platform binary under the name \"" +
|
||||
this->m_info.m_binaryName + "\""
|
||||
m_info.m_binaryName + "\""
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -162,7 +162,7 @@ Result<> Mod::createTempDir() {
|
|||
}
|
||||
}
|
||||
|
||||
auto tempPath = ghc::filesystem::path(tempDir) / this->m_info.m_id;
|
||||
auto tempPath = ghc::filesystem::path(tempDir) / m_info.m_id;
|
||||
if (!ghc::filesystem::exists(tempPath) && !ghc::filesystem::create_directories(tempPath)) {
|
||||
return Err<>("Unable to create temp directory");
|
||||
}
|
||||
|
@ -190,20 +190,20 @@ Result<> Mod::createTempDir() {
|
|||
if (!wrt) return Err<>("Unable to write \"" + file + "\": " + wrt.error());
|
||||
}
|
||||
|
||||
this->m_addResourcesToSearchPath = true;
|
||||
m_addResourcesToSearchPath = true;
|
||||
|
||||
return Ok<>(tempPath);
|
||||
}
|
||||
|
||||
Result<> Mod::load() {
|
||||
if (this->m_loaded) {
|
||||
if (m_loaded) {
|
||||
return Ok<>();
|
||||
}
|
||||
#define RETURN_LOAD_ERR(str) \
|
||||
{m_loadErrorInfo = str; \
|
||||
return Err<>(m_loadErrorInfo);}
|
||||
|
||||
if (!this->m_tempDirName.string().size()) {
|
||||
if (!m_tempDirName.string().size()) {
|
||||
auto err = this->createTempDir();
|
||||
if (!err) RETURN_LOAD_ERR("Unable to create temp directory: " + err.error());
|
||||
}
|
||||
|
@ -213,23 +213,23 @@ Result<> Mod::load() {
|
|||
}
|
||||
auto err = this->loadPlatformBinary();
|
||||
if (!err) RETURN_LOAD_ERR(err.error());
|
||||
if (this->m_implicitLoadFunc) {
|
||||
auto r = this->m_implicitLoadFunc(this);
|
||||
if (m_implicitLoadFunc) {
|
||||
auto r = m_implicitLoadFunc(this);
|
||||
if (!r) {
|
||||
this->unloadPlatformBinary();
|
||||
RETURN_LOAD_ERR("Implicit mod entry point returned an error");
|
||||
}
|
||||
}
|
||||
if (this->m_loadFunc) {
|
||||
auto r = this->m_loadFunc(this);
|
||||
if (m_loadFunc) {
|
||||
auto r = m_loadFunc(this);
|
||||
if (!r) {
|
||||
this->unloadPlatformBinary();
|
||||
RETURN_LOAD_ERR("Mod entry point returned an error");
|
||||
}
|
||||
}
|
||||
this->m_loaded = true;
|
||||
if (this->m_loadDataFunc) {
|
||||
if (!this->m_loadDataFunc(this->m_saveDirPath.string().c_str())) {
|
||||
m_loaded = true;
|
||||
if (m_loadDataFunc) {
|
||||
if (!m_loadDataFunc(m_saveDirPath.string().c_str())) {
|
||||
this->logInfo("Mod load data function returned false", Severity::Error);
|
||||
}
|
||||
}
|
||||
|
@ -239,7 +239,7 @@ Result<> Mod::load() {
|
|||
}
|
||||
|
||||
Result<> Mod::unload() {
|
||||
if (!this->m_loaded) {
|
||||
if (!m_loaded) {
|
||||
return Ok<>();
|
||||
}
|
||||
|
||||
|
@ -247,63 +247,63 @@ Result<> Mod::unload() {
|
|||
return Err<>("Mod does not support unloading");
|
||||
}
|
||||
|
||||
if (this->m_saveDataFunc) {
|
||||
if (!this->m_saveDataFunc(this->m_saveDirPath.string().c_str())) {
|
||||
if (m_saveDataFunc) {
|
||||
if (!m_saveDataFunc(m_saveDirPath.string().c_str())) {
|
||||
this->logInfo("Mod save data function returned false", Severity::Error);
|
||||
}
|
||||
}
|
||||
|
||||
if (this->m_unloadFunc) {
|
||||
this->m_unloadFunc();
|
||||
if (m_unloadFunc) {
|
||||
m_unloadFunc();
|
||||
}
|
||||
|
||||
for (auto const& hook : this->m_hooks) {
|
||||
for (auto const& hook : m_hooks) {
|
||||
auto d = this->disableHook(hook);
|
||||
if (!d) return d;
|
||||
delete hook;
|
||||
}
|
||||
this->m_hooks.clear();
|
||||
m_hooks.clear();
|
||||
|
||||
for (auto const& patch : this->m_patches) {
|
||||
for (auto const& patch : m_patches) {
|
||||
if (!patch->restore()) {
|
||||
return Err<>("Unable to restore patch at " + std::to_string(patch->getAddress()));
|
||||
}
|
||||
delete patch;
|
||||
}
|
||||
this->m_patches.clear();
|
||||
m_patches.clear();
|
||||
|
||||
auto res = this->unloadPlatformBinary();
|
||||
if (!res) {
|
||||
return res;
|
||||
}
|
||||
this->m_loaded = false;
|
||||
m_loaded = false;
|
||||
Loader::get()->updateAllDependencies();
|
||||
return Ok<>();
|
||||
}
|
||||
|
||||
Result<> Mod::enable() {
|
||||
if (!this->m_loaded) {
|
||||
if (!m_loaded) {
|
||||
return Err<>("Mod is not loaded");
|
||||
}
|
||||
|
||||
if (this->m_enableFunc) {
|
||||
if (!this->m_enableFunc()) {
|
||||
if (m_enableFunc) {
|
||||
if (!m_enableFunc()) {
|
||||
return Err<>("Mod enable function returned false");
|
||||
}
|
||||
}
|
||||
|
||||
for (auto const& hook : this->m_hooks) {
|
||||
for (auto const& hook : m_hooks) {
|
||||
auto d = this->enableHook(hook);
|
||||
if (!d) return d;
|
||||
}
|
||||
|
||||
for (auto const& patch : this->m_patches) {
|
||||
for (auto const& patch : m_patches) {
|
||||
if (!patch->apply()) {
|
||||
return Err<>("Unable to apply patch at " + std::to_string(patch->getAddress()));
|
||||
}
|
||||
}
|
||||
|
||||
this->m_enabled = true;
|
||||
m_enabled = true;
|
||||
|
||||
return Ok<>();
|
||||
}
|
||||
|
@ -313,24 +313,24 @@ Result<> Mod::disable() {
|
|||
return Err<>("Mod does not support disabling");
|
||||
}
|
||||
|
||||
if (this->m_disableFunc) {
|
||||
if (!this->m_disableFunc()) {
|
||||
if (m_disableFunc) {
|
||||
if (!m_disableFunc()) {
|
||||
return Err<>("Mod disable function returned false");
|
||||
}
|
||||
}
|
||||
|
||||
for (auto const& hook : this->m_hooks) {
|
||||
for (auto const& hook : m_hooks) {
|
||||
auto d = this->disableHook(hook);
|
||||
if (!d) return d;
|
||||
}
|
||||
|
||||
for (auto const& patch : this->m_patches) {
|
||||
for (auto const& patch : m_patches) {
|
||||
if (!patch->restore()) {
|
||||
return Err<>("Unable to restore patch at " + std::to_string(patch->getAddress()));
|
||||
}
|
||||
}
|
||||
|
||||
this->m_enabled = false;
|
||||
m_enabled = false;
|
||||
|
||||
return Ok<>();
|
||||
}
|
||||
|
@ -359,15 +359,15 @@ bool Mod::isUninstalled() const {
|
|||
}
|
||||
|
||||
bool Dependency::isUnresolved() const {
|
||||
return this->m_required &&
|
||||
(this->m_state == ModResolveState::Unloaded ||
|
||||
this->m_state == ModResolveState::Unresolved ||
|
||||
this->m_state == ModResolveState::Disabled);
|
||||
return m_required &&
|
||||
(m_state == ModResolveState::Unloaded ||
|
||||
m_state == ModResolveState::Unresolved ||
|
||||
m_state == ModResolveState::Disabled);
|
||||
}
|
||||
|
||||
bool Mod::updateDependencyStates() {
|
||||
bool hasUnresolved = false;
|
||||
for (auto & dep : this->m_info.m_dependencies) {
|
||||
for (auto & dep : m_info.m_dependencies) {
|
||||
if (!dep.m_mod) {
|
||||
dep.m_mod = Loader::get()->getLoadedMod(dep.m_id);
|
||||
}
|
||||
|
@ -404,15 +404,15 @@ bool Mod::updateDependencyStates() {
|
|||
dep.m_state = ModResolveState::Unloaded;
|
||||
}
|
||||
if (dep.isUnresolved()) {
|
||||
this->m_resolved = false;
|
||||
m_resolved = false;
|
||||
this->unload();
|
||||
hasUnresolved = true;
|
||||
}
|
||||
}
|
||||
if (!hasUnresolved && !this->m_resolved) {
|
||||
if (!hasUnresolved && !m_resolved) {
|
||||
Log::get() << Severity::Debug << "All dependencies for " << m_info.m_id << " found";
|
||||
this->m_resolved = true;
|
||||
if (this->m_enabled) {
|
||||
m_resolved = true;
|
||||
if (m_enabled) {
|
||||
Log::get() << Severity::Debug << "Resolved & loading " << m_info.m_id;
|
||||
auto r = this->load();
|
||||
if (!r) {
|
||||
|
@ -432,7 +432,7 @@ bool Mod::updateDependencyStates() {
|
|||
}
|
||||
|
||||
bool Mod::hasUnresolvedDependencies() const {
|
||||
for (auto const& dep : this->m_info.m_dependencies) {
|
||||
for (auto const& dep : m_info.m_dependencies) {
|
||||
if (dep.isUnresolved()) {
|
||||
return true;
|
||||
}
|
||||
|
@ -442,7 +442,7 @@ bool Mod::hasUnresolvedDependencies() const {
|
|||
|
||||
std::vector<Dependency> Mod::getUnresolvedDependencies() {
|
||||
std::vector<Dependency> res;
|
||||
for (auto const& dep : this->m_info.m_dependencies) {
|
||||
for (auto const& dep : m_info.m_dependencies) {
|
||||
if (dep.isUnresolved()) {
|
||||
res.push_back(dep);
|
||||
}
|
||||
|
@ -451,27 +451,27 @@ std::vector<Dependency> Mod::getUnresolvedDependencies() {
|
|||
}
|
||||
|
||||
ghc::filesystem::path Mod::getSaveDir() const {
|
||||
return this->m_saveDirPath;
|
||||
return m_saveDirPath;
|
||||
}
|
||||
|
||||
decltype(ModInfo::m_id) Mod::getID() const {
|
||||
return this->m_info.m_id;
|
||||
return m_info.m_id;
|
||||
}
|
||||
|
||||
decltype(ModInfo::m_name) Mod::getName() const {
|
||||
return this->m_info.m_name;
|
||||
return m_info.m_name;
|
||||
}
|
||||
|
||||
decltype(ModInfo::m_developer) Mod::getDeveloper() const {
|
||||
return this->m_info.m_developer;
|
||||
return m_info.m_developer;
|
||||
}
|
||||
|
||||
decltype(ModInfo::m_description) Mod::getDescription() const {
|
||||
return this->m_info.m_description;
|
||||
return m_info.m_description;
|
||||
}
|
||||
|
||||
decltype(ModInfo::m_details) Mod::getDetails() const {
|
||||
return this->m_info.m_details;
|
||||
return m_info.m_details;
|
||||
}
|
||||
|
||||
ModInfo Mod::getModInfo() const {
|
||||
|
@ -487,27 +487,27 @@ ghc::filesystem::path Mod::getBinaryPath() const {
|
|||
}
|
||||
|
||||
std::string Mod::getPath() const {
|
||||
return this->m_info.m_path.string();
|
||||
return m_info.m_path.string();
|
||||
}
|
||||
|
||||
VersionInfo Mod::getVersion() const {
|
||||
return this->m_info.m_version;
|
||||
return m_info.m_version;
|
||||
}
|
||||
|
||||
bool Mod::isEnabled() const {
|
||||
return this->m_enabled;
|
||||
return m_enabled;
|
||||
}
|
||||
|
||||
bool Mod::isLoaded() const {
|
||||
return this->m_loaded;
|
||||
return m_loaded;
|
||||
}
|
||||
|
||||
bool Mod::supportsDisabling() const {
|
||||
return this->m_info.m_supportsDisabling;
|
||||
return m_info.m_supportsDisabling;
|
||||
}
|
||||
|
||||
bool Mod::supportsUnloading() const {
|
||||
return this->m_info.m_supportsUnloading;
|
||||
return m_info.m_supportsUnloading;
|
||||
}
|
||||
|
||||
bool Mod::wasSuccesfullyLoaded() const {
|
||||
|
@ -515,7 +515,7 @@ bool Mod::wasSuccesfullyLoaded() const {
|
|||
}
|
||||
|
||||
std::vector<Hook*> Mod::getHooks() const {
|
||||
return this->m_hooks;
|
||||
return m_hooks;
|
||||
}
|
||||
|
||||
Log Mod::log() {
|
||||
|
@ -532,7 +532,7 @@ void Mod::logInfo(
|
|||
|
||||
bool Mod::depends(std::string const& id) const {
|
||||
return utils::vector::contains<Dependency>(
|
||||
this->m_info.m_dependencies,
|
||||
m_info.m_dependencies,
|
||||
[id](Dependency t) -> bool { return t.m_id == id; }
|
||||
);
|
||||
}
|
||||
|
@ -542,8 +542,8 @@ const char* Mod::expandSpriteName(const char* name) {
|
|||
if (expanded.count(name)) {
|
||||
return expanded[name];
|
||||
}
|
||||
auto exp = new char[strlen(name) + 2 + this->m_info.m_id.size()];
|
||||
auto exps = this->m_info.m_id + "/" + name;
|
||||
auto exp = new char[strlen(name) + 2 + m_info.m_id.size()];
|
||||
auto exps = m_info.m_id + "/" + name;
|
||||
memcpy(exp, exps.c_str(), exps.size() + 1);
|
||||
expanded[name] = exp;
|
||||
return exp;
|
||||
|
|
|
@ -161,7 +161,7 @@ Result<ModInfo> ModInfo::create(ModJson const& json) {
|
|||
}
|
||||
|
||||
// Handle mod.json data based on target
|
||||
if (schema <= VersionInfo(0, 2, 0)) {
|
||||
if (schema <= VersionInfo(0, 2, 1)) {
|
||||
return ModInfo::createFromSchemaV010(json);
|
||||
}
|
||||
|
||||
|
@ -233,7 +233,7 @@ Result<ModInfo> ModInfo::createFromGeodeFile(ghc::filesystem::path const& path)
|
|||
info.m_path = path;
|
||||
|
||||
// unzip known MD files
|
||||
using God = std::initializer_list<std::pair<std::string, std::string*>>;
|
||||
using God = std::initializer_list<std::pair<std::string, std::optional<std::string>*>>;
|
||||
for (auto [file, target] : God {
|
||||
{ "about.md", &info.m_details },
|
||||
{ "changelog.md", &info.m_changelog },
|
||||
|
|
|
@ -164,8 +164,8 @@ bool ModInfoLayer::init(ModObject* obj, ModListView* list) {
|
|||
this->registerWithTouchDispatcher();
|
||||
|
||||
auto details = MDTextArea::create(
|
||||
m_info.m_details.size() ?
|
||||
m_info.m_details :
|
||||
m_info.m_details ?
|
||||
m_info.m_details.value() :
|
||||
"### No description provided.",
|
||||
{ 350.f, 137.5f }
|
||||
);
|
||||
|
@ -182,6 +182,59 @@ bool ModInfoLayer::init(ModObject* obj, ModListView* list) {
|
|||
);
|
||||
m_mainLayer->addChild(detailsBar);
|
||||
|
||||
// changelog
|
||||
if (m_info.m_changelog) {
|
||||
auto changelog = MDTextArea::create(
|
||||
m_info.m_changelog.value(),
|
||||
{ 350.f, 137.5f }
|
||||
);
|
||||
changelog->setPosition(
|
||||
-5000.f,
|
||||
winSize.height / 2 - changelog->getScaledContentSize().height / 2 - 20.f
|
||||
);
|
||||
changelog->setVisible(false);
|
||||
m_mainLayer->addChild(changelog);
|
||||
|
||||
auto changelogBtnOffSpr = ButtonSprite::create(
|
||||
CCSprite::createWithSpriteFrameName("changelog.png"_spr),
|
||||
0x20, true, 32.f, "GJ_button_01.png", 1.f
|
||||
);
|
||||
changelogBtnOffSpr->setScale(.65f);
|
||||
|
||||
auto changelogBtnOnSpr = ButtonSprite::create(
|
||||
CCSprite::createWithSpriteFrameName("changelog.png"_spr),
|
||||
0x20, true, 32.f, "GJ_button_02.png", 1.f
|
||||
);
|
||||
changelogBtnOnSpr->setScale(.65f);
|
||||
|
||||
auto changelogBtn = CCMenuItemToggler::create(
|
||||
changelogBtnOffSpr,
|
||||
changelogBtnOnSpr,
|
||||
this,
|
||||
makeMenuSelector([
|
||||
this, winSize, details, detailsBar, changelog
|
||||
](CCMenuItemToggler* toggle) {
|
||||
details->setVisible(toggle->isToggled());
|
||||
// as it turns out, cocos2d is stupid and still passes touch
|
||||
// events to invisible nodes
|
||||
details->setPositionX(toggle->isToggled() ?
|
||||
winSize.width / 2 - details->getScaledContentSize().width / 2 :
|
||||
-5000.f
|
||||
);
|
||||
|
||||
changelog->setVisible(!toggle->isToggled());
|
||||
// as it turns out, cocos2d is stupid and still passes touch
|
||||
// events to invisible nodes
|
||||
changelog->setPositionX(!toggle->isToggled() ?
|
||||
winSize.width / 2 - changelog->getScaledContentSize().width / 2 :
|
||||
-5000.f
|
||||
);
|
||||
})
|
||||
);
|
||||
changelogBtn->setPosition(-size.width / 2 + 21.5f, .0f);
|
||||
m_buttonMenu->addChild(changelogBtn);
|
||||
}
|
||||
|
||||
|
||||
auto infoSpr = CCSprite::createWithSpriteFrameName("GJ_infoIcon_001.png");
|
||||
infoSpr->setScale(.85f);
|
||||
|
@ -231,11 +284,11 @@ bool ModInfoLayer::init(ModObject* obj, ModListView* list) {
|
|||
);
|
||||
}
|
||||
|
||||
if (m_mod->getModInfo().m_repository.size()) {
|
||||
if (m_mod->getModInfo().m_repository) {
|
||||
auto repoBtn = CCMenuItemSpriteExtra::create(
|
||||
CCSprite::createWithSpriteFrameName("github.png"_spr),
|
||||
this, makeMenuSelector([this](CCObject*) {
|
||||
web::openLinkInBrowser(m_mod->getModInfo().m_repository);
|
||||
web::openLinkInBrowser(m_mod->getModInfo().m_repository.value());
|
||||
})
|
||||
);
|
||||
repoBtn->setPosition(
|
||||
|
@ -245,13 +298,13 @@ bool ModInfoLayer::init(ModObject* obj, ModListView* list) {
|
|||
m_buttonMenu->addChild(repoBtn);
|
||||
}
|
||||
|
||||
if (m_mod->getModInfo().m_supportInfo.size()) {
|
||||
if (m_mod->getModInfo().m_supportInfo) {
|
||||
auto supportBtn = CCMenuItemSpriteExtra::create(
|
||||
CCSprite::createWithSpriteFrameName("gift.png"_spr),
|
||||
this, makeMenuSelector([this](CCObject*) {
|
||||
MDPopup::create(
|
||||
"Support " + m_mod->getName(),
|
||||
m_mod->getModInfo().m_supportInfo,
|
||||
m_mod->getModInfo().m_supportInfo.value(),
|
||||
"OK"
|
||||
)->show();
|
||||
})
|
||||
|
|
|
@ -193,7 +193,7 @@ void ModCell::loadFromObject(ModObject* modobj) {
|
|||
default: return;
|
||||
}
|
||||
|
||||
bool hasDesc = m_expanded && info.m_description.size();
|
||||
bool hasDesc = m_expanded && info.m_description.has_value();
|
||||
|
||||
auto titleLabel = CCLabelBMFont::create(info.m_name.c_str(), "bigFont.fnt");
|
||||
titleLabel->setAnchorPoint({ .0f, .5f });
|
||||
|
@ -254,7 +254,7 @@ void ModCell::loadFromObject(ModObject* modobj) {
|
|||
m_mainLayer->addChild(descBG);
|
||||
|
||||
auto descText = CCLabelBMFont::create(
|
||||
info.m_description.c_str(),
|
||||
info.m_description.value().c_str(),
|
||||
"chatFont.fnt"
|
||||
);
|
||||
descText->setAnchorPoint({ .0f, .5f });
|
||||
|
@ -451,8 +451,8 @@ bool ModListView::filter(ModInfo const& info, ModListQuery const& query) {
|
|||
if (check(SearchFlag::Name, info.m_name)) return true;
|
||||
if (check(SearchFlag::ID, info.m_id)) return true;
|
||||
if (check(SearchFlag::Developer, info.m_developer)) return true;
|
||||
if (check(SearchFlag::Description, info.m_description)) return true;
|
||||
if (check(SearchFlag::Details, info.m_details)) return true;
|
||||
if (check(SearchFlag::Description, info.m_description.value_or(""))) return true;
|
||||
if (check(SearchFlag::Details, info.m_details.value_or(""))) return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
|
@ -38,6 +38,13 @@ void ScrollLayer::enableScrollWheel(bool enable) {
|
|||
m_scrollWheelEnabled = enable;
|
||||
}
|
||||
|
||||
bool ScrollLayer::ccTouchBegan(CCTouch* touch, CCEvent* event) {
|
||||
if (this->isVisible()) {
|
||||
return CCScrollLayerExt::ccTouchBegan(touch, event);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
ScrollLayer::ScrollLayer(
|
||||
CCRect const& rect,
|
||||
bool scrollWheelEnabled,
|
||||
|
|
|
@ -34,7 +34,7 @@ Result<std::string> utils::file::readString(std::wstring const& path) {
|
|||
#endif
|
||||
|
||||
Result<std::string> utils::file::readString(ghc::filesystem::path const& path) {
|
||||
std::ifstream in(path.string(), std::ios::in | std::ios::binary);
|
||||
std::ifstream in(path.wstring(), std::ios::in | std::ios::binary);
|
||||
if (in) {
|
||||
std::string contents;
|
||||
in.seekg(0, std::ios::end);
|
||||
|
@ -66,7 +66,7 @@ Result<byte_array> utils::file::readBinary(std::wstring const& path) {
|
|||
#endif
|
||||
|
||||
Result<byte_array> utils::file::readBinary(ghc::filesystem::path const& path) {
|
||||
std::ifstream in(path.string(), std::ios::in | std::ios::binary);
|
||||
std::ifstream in(path.wstring(), std::ios::in | std::ios::binary);
|
||||
if (in) {
|
||||
return Ok(byte_array (std::istreambuf_iterator<char>(in), {}));
|
||||
}
|
||||
|
@ -103,7 +103,7 @@ Result<> utils::file::writeString(std::wstring const& path, std::string const& d
|
|||
|
||||
Result<> utils::file::writeString(ghc::filesystem::path const& path, std::string const& data) {
|
||||
std::ofstream file;
|
||||
file.open(path.string());
|
||||
file.open(path.wstring());
|
||||
if (file.is_open()) {
|
||||
file << data;
|
||||
file.close();
|
||||
|
@ -144,7 +144,7 @@ Result<> utils::file::writeBinary(std::wstring const& path, byte_array const& da
|
|||
|
||||
Result<> utils::file::writeBinary(ghc::filesystem::path const& path, byte_array const& data) {
|
||||
std::ofstream file;
|
||||
file.open(path.string(), std::ios::out | std::ios::binary);
|
||||
file.open(path.wstring(), std::ios::out | std::ios::binary);
|
||||
if (file.is_open()) {
|
||||
file.write(reinterpret_cast<const char*>(data.data()), data.size());
|
||||
file.close();
|
||||
|
|
|
@ -219,7 +219,6 @@ Result<> nfdPick(
|
|||
)) {
|
||||
return Err("Could not get path from result");
|
||||
}
|
||||
|
||||
*reinterpret_cast<Path*>(result) = filePath;
|
||||
CoTaskMemFree(filePath);
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
{
|
||||
"geode": "v0.2.0",
|
||||
"geode": "v0.2.1",
|
||||
"version": "v1.0.0",
|
||||
"id": "geode.testdep",
|
||||
"name": "Geode Test Dependency",
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
{
|
||||
"geode": "v0.2.0",
|
||||
"geode": "v0.2.1",
|
||||
"version": "v1.0.0",
|
||||
"id": "geode.test",
|
||||
"name": "Geode Test",
|
||||
|
|
Loading…
Add table
Reference in a new issue