diff --git a/include/API.hpp b/include/API.hpp index c87f071..23f93e0 100644 --- a/include/API.hpp +++ b/include/API.hpp @@ -27,30 +27,20 @@ namespace devtools { template concept UnderlyingIntegral = std::is_integral_v || std::is_integral_v>; - struct RegisterNodeEvent final : geode::SimpleEvent> { - using SimpleEvent::SimpleEvent; + struct RegisterNodeEvent final : geode::Event)> { + using Event::Event; }; template - struct PropertyFnEvent final : geode::SimpleEvent, bool(*&)(const char* name, T&)> { - using Fn = bool(const char* name, T&); - using geode::SimpleEvent::SimpleEvent; - }; - - struct DrawLabelFnEvent final : geode::SimpleEvent { - using Fn = void(const char* text); - using SimpleEvent::SimpleEvent; + struct PropertyFnEvent final : geode::Event, bool(bool(*&)(geode::ZStringView name, T&))> { + using Fn = bool(geode::ZStringView name, T&); + using geode::Event::Event; }; template - struct EnumerableFnEvent final : geode::SimpleEvent, bool(*&)(const char* label, T* value, std::span const>)> { - using Fn = bool(const char* label, T* value, std::span const>); - using geode::SimpleEvent::SimpleEvent; - }; - - struct ButtonFnEvent final : geode::SimpleEvent { - using Fn = bool(const char* label); - using SimpleEvent::SimpleEvent; + struct EnumerableFnEvent final : geode::Event, bool(bool(*&)(geode::ZStringView label, T* value, std::span const>))> { + using Fn = bool(geode::ZStringView label, T* value, std::span const>); + using geode::Event::Event; }; /// @brief Checks if DevTools is currently loaded. @@ -95,7 +85,7 @@ namespace devtools { /// @return True if the property was changed, false otherwise. /// @warning This function should only ever be called from within a registered node callback. template requires SupportedProperty - bool property(const char* name, T& prop) { + bool property(geode::ZStringView name, T& prop) { static auto fn = ([] { typename PropertyFnEvent::Fn* fnPtr = nullptr; PropertyFnEvent().send(fnPtr); @@ -107,14 +97,7 @@ namespace devtools { /// @brief Renders a label in the DevTools UI. /// @param text The text to display in the label. /// @warning This function should only ever be called from within a registered node callback. - inline void label(const char* text) { - static auto fn = ([] { - DrawLabelFnEvent::Fn* fnPtr = nullptr; - DrawLabelFnEvent().send(fnPtr); - return fnPtr; - })(); - if (fn) fn(text); - } + inline void label(geode::ZStringView text) GEODE_EVENT_EXPORT_NORES(&label, (text)); /// @brief Renders an enumerable property editor using radio buttons for the given value in the DevTools UI. /// @param label The label for the enumerable property. @@ -123,7 +106,7 @@ namespace devtools { /// @return True if the value was changed, false otherwise. /// @warning This function should only ever be called from within a registered node callback. template - bool enumerable(const char* label, T& value, std::initializer_list> items) { + bool enumerable(geode::ZStringView label, T& value, std::initializer_list> items) { using ValueType = std::underlying_type_t; static auto fn = ([] { typename EnumerableFnEvent::Fn* fnPtr = nullptr; @@ -134,8 +117,8 @@ namespace devtools { label, reinterpret_cast(&value), std::span( - reinterpret_cast const*>(&*items.begin()), - reinterpret_cast const*>(&*items.end()) + reinterpret_cast const*>(&*items.begin()), + reinterpret_cast const*>(&*items.end()) ) ) : false; } @@ -144,21 +127,14 @@ namespace devtools { /// @param label The label for the button. /// @return True if the button was clicked, false otherwise. /// @warning This function should only ever be called from within a registered node callback. - inline bool button(const char* label) { - static auto fn = ([] { - ButtonFnEvent::Fn* fnPtr = nullptr; - ButtonFnEvent().send(fnPtr); - return fnPtr; - })(); - return fn ? fn(label) : false; - } + inline bool button(geode::ZStringView label) GEODE_EVENT_EXPORT_NORES(&button, (label)); /// @brief Renders a button in the DevTools UI and calls the provided callback if the button is clicked. /// @param label The label for the button. /// @param callback The function to call when the button is clicked. /// @warning This function should only ever be called from within a registered node callback. template - void button(const char* label, F&& callback) { + void button(geode::ZStringView label, F&& callback) { if (button(label)) { callback(); } @@ -172,31 +148,31 @@ namespace devtools { inline void unindent() GEODE_EVENT_EXPORT_NORES(&unindent, ()); inline bool combo( - char const* label, + geode::ZStringView label, int& current, std::span items, int maxHeight = -1 ) GEODE_EVENT_EXPORT_NORES(&combo, (label, current, items, maxHeight)); - template > + template > requires std::ranges::range && - std::same_as().begin())> const, char const* const> - bool combo(char const* label, T& current, R&& range, int maxHeight = -1) { + std::same_as().begin())> const, geode::ZStringView const> + bool combo(geode::ZStringView label, T& current, R&& range, int maxHeight = -1) { return combo( label, reinterpret_cast(current), - std::span(const_cast(&*range.begin()), const_cast(&*range.end())), + std::span(const_cast(&*range.begin()), const_cast(&*range.end())), maxHeight ); } - inline bool radio(char const* label, int& current, int num) GEODE_EVENT_EXPORT_NORES(&radio, (label, current, num)); + inline bool radio(geode::ZStringView label, int& current, int num) GEODE_EVENT_EXPORT_NORES(&radio, (label, current, num)); template - bool radio(char const* label, T& current, U value) { + bool radio(geode::ZStringView label, T& current, U value) { return radio(label, reinterpret_cast(current), reinterpret_cast(value)); } - inline void inputMultiline(char const* label, std::string& text) GEODE_EVENT_EXPORT_NORES(&inputMultiline, (label, text)); + inline void inputMultiline(geode::ZStringView label, std::string& text) GEODE_EVENT_EXPORT_NORES(&inputMultiline, (label, text)); } diff --git a/src/API.cpp b/src/API.cpp index 7634cda..3e77335 100644 --- a/src/API.cpp +++ b/src/API.cpp @@ -17,19 +17,19 @@ static void handleType() { sizeof(T) == 2 ? (isSigned ? ImGuiDataType_S16 : ImGuiDataType_U16) : sizeof(T) == 4 ? (isSigned ? ImGuiDataType_S32 : ImGuiDataType_U32) : isSigned ? ImGuiDataType_S64 : ImGuiDataType_U64; - fnPtr = +[](const char* name, T& prop) { - return ImGui::DragScalar(name, dataType, &prop); + fnPtr = +[](ZStringView name, T& prop) { + return ImGui::DragScalar(name.c_str(), dataType, &prop); }; return ListenerResult::Stop; }).leak(); devtools::EnumerableFnEvent().listen([](typename devtools::EnumerableFnEvent::Fn*& fnPtr) { - fnPtr = +[](const char* label, T* value, std::span const> items) { - ImGui::Text("%s:", label); + fnPtr = +[](ZStringView label, T* value, std::span const> items) { + ImGui::Text("%s:", label.c_str()); size_t i = 0; bool changed = false; for (auto& [itemValue, itemLabel] : items) { - if (ImGui::RadioButton(itemLabel, *value == itemValue)) { + if (ImGui::RadioButton(itemLabel.c_str(), *value == itemValue)) { *value = itemValue; changed = true; } @@ -62,20 +62,28 @@ void devtools::indent() { void devtools::unindent() { ImGui::Unindent(16.f); } -bool devtools::combo(char const* label, int& current, std::span items, int maxHeight) { +bool devtools::combo(ZStringView label, int& current, std::span items, int maxHeight) { return ImGui::Combo( - label, + label.c_str(), ¤t, &*items.begin(), static_cast(items.size()), maxHeight ); } -bool devtools::radio(const char* label, int& current, int num) { - return ImGui::RadioButton(label, ¤t, num); +bool devtools::radio(ZStringView label, int& current, int num) { + return ImGui::RadioButton(label.c_str(), ¤t, num); } -void devtools::inputMultiline(const char* label, std::string& str) { - ImGui::InputTextMultiline(label, &str); +void devtools::inputMultiline(ZStringView label, std::string& str) { + ImGui::InputTextMultiline(label.c_str(), &str); +} + +void devtools::label(ZStringView text) { + ImGui::Text("%s", text.c_str()); +} + +bool devtools::button(ZStringView label) { + return ImGui::Button(label.c_str()); } $execute { @@ -100,30 +108,30 @@ void devtools::inputMultiline(const char* label, std::string& str) { // checkbox devtools::PropertyFnEvent().listen([](devtools::PropertyFnEvent::Fn*& fnPtr) { - fnPtr = +[](const char* name, bool& prop) { - return ImGui::Checkbox(name, &prop); + fnPtr = +[](ZStringView name, bool& prop) { + return ImGui::Checkbox(name.c_str(), &prop); }; return ListenerResult::Stop; }).leak(); // string devtools::PropertyFnEvent().listen([](devtools::PropertyFnEvent::Fn*& fnPtr) { - fnPtr = +[](const char* name, std::string& prop) { - return ImGui::InputText(name, &prop); + fnPtr = +[](ZStringView name, std::string& prop) { + return ImGui::InputText(name.c_str(), &prop); }; return ListenerResult::Stop; }).leak(); // colors devtools::PropertyFnEvent().listen([](devtools::PropertyFnEvent::Fn*& fnPtr) { - fnPtr = +[](const char* name, ccColor3B& prop) { + fnPtr = +[](ZStringView name, ccColor3B& prop) { auto color = ImVec4( prop.r / 255.f, prop.g / 255.f, prop.b / 255.f, 1.0f ); - if (ImGui::ColorEdit3(name, &color.x)) { + if (ImGui::ColorEdit3(name.c_str(), &color.x)) { prop.r = static_cast(color.x * 255); prop.g = static_cast(color.y * 255); prop.b = static_cast(color.z * 255); @@ -134,14 +142,14 @@ void devtools::inputMultiline(const char* label, std::string& str) { return ListenerResult::Stop; }).leak(); devtools::PropertyFnEvent().listen([](devtools::PropertyFnEvent::Fn*& fnPtr) { - fnPtr = +[](const char* name, ccColor4B& prop) { + fnPtr = +[](ZStringView name, ccColor4B& prop) { auto color = ImVec4( prop.r / 255.f, prop.g / 255.f, prop.b / 255.f, prop.a / 255.f ); - if (ImGui::ColorEdit4(name, &color.x)) { + if (ImGui::ColorEdit4(name.c_str(), &color.x)) { prop.r = static_cast(color.x * 255); prop.g = static_cast(color.y * 255); prop.b = static_cast(color.z * 255); @@ -153,45 +161,29 @@ void devtools::inputMultiline(const char* label, std::string& str) { return ListenerResult::Stop; }).leak(); devtools::PropertyFnEvent().listen([](devtools::PropertyFnEvent::Fn*& fnPtr) { - fnPtr = +[](const char* name, ccColor4F& prop) { - return ImGui::ColorEdit4(name, reinterpret_cast(&prop)); + fnPtr = +[](ZStringView name, ccColor4F& prop) { + return ImGui::ColorEdit4(name.c_str(), reinterpret_cast(&prop)); }; return ListenerResult::Stop; }).leak(); // points/sizes devtools::PropertyFnEvent().listen([](devtools::PropertyFnEvent::Fn*& fnPtr) { - fnPtr = +[](const char* name, CCPoint& prop) { - return ImGui::DragFloat2(name, reinterpret_cast(&prop)); + fnPtr = +[](ZStringView name, CCPoint& prop) { + return ImGui::DragFloat2(name.c_str(), reinterpret_cast(&prop)); }; return ListenerResult::Stop; }).leak(); devtools::PropertyFnEvent().listen([](devtools::PropertyFnEvent::Fn*& fnPtr) { - fnPtr = +[](const char* name, CCSize& prop) { - return ImGui::DragFloat2(name, reinterpret_cast(&prop)); + fnPtr = +[](ZStringView name, CCSize& prop) { + return ImGui::DragFloat2(name.c_str(), reinterpret_cast(&prop)); }; return ListenerResult::Stop; }).leak(); devtools::PropertyFnEvent().listen([](devtools::PropertyFnEvent::Fn*& fnPtr) { - fnPtr = +[](const char* name, CCRect& prop) { - return ImGui::DragFloat4(name, reinterpret_cast(&prop)); - }; - return ListenerResult::Stop; - }).leak(); - - // label - devtools::DrawLabelFnEvent().listen([](devtools::DrawLabelFnEvent::Fn*& fnPtr) { - fnPtr = +[](const char* text) { - ImGui::Text("%s", text); - }; - return ListenerResult::Stop; - }).leak(); - - // button - devtools::ButtonFnEvent().listen([](devtools::ButtonFnEvent::Fn*& fnPtr) { - fnPtr = +[](const char* label) { - return ImGui::Button(label); + fnPtr = +[](ZStringView name, CCRect& prop) { + return ImGui::DragFloat4(name.c_str(), reinterpret_cast(&prop)); }; return ListenerResult::Stop; }).leak(); diff --git a/src/main.cpp b/src/main.cpp index 3924c9e..a210de8 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -90,7 +90,7 @@ class $modify(CCDirector) { if (!DevTools::get()->shouldUseGDWindow()) { return CCDirector::drawScene(); } - + DevTools::get()->setup(); static GLRenderCtx* gdTexture = nullptr; @@ -153,8 +153,8 @@ class $modify(CCEGLView) { }; // For the one eclipse shortcut -struct ToggleDevToolsEvent : SimpleEvent { - using SimpleEvent::SimpleEvent; +struct ToggleDevToolsEvent : Event { + using Event::Event; }; $execute { diff --git a/src/pages/Advanced.cpp b/src/pages/Advanced.cpp index c5e6c0c..3d2eb79 100644 --- a/src/pages/Advanced.cpp +++ b/src/pages/Advanced.cpp @@ -94,13 +94,7 @@ ModMetadata DevTools::inputMetadata(void* treePtr, ModMetadata metadata) { continue; } ImGui::Text("version: %s", item.getVersion().toString().c_str()); - const char* importance = ""; - switch (item.getImportance()) { - case geode::ModMetadata::Dependency::Importance::Required: importance = "required"; break; - case geode::ModMetadata::Dependency::Importance::Recommended: importance = "recommended"; break; - case geode::ModMetadata::Dependency::Importance::Suggested: importance = "suggested"; break; - } - ImGui::Text("importance: %s", importance); + ImGui::Text("required: %s", item.isRequired() ? "true" : "false"); ImGui::Text("isResolved: %s", item.isResolved() ? "true" : "false"); if (item.getMod()) drawModGraphNode(item.getMod()); @@ -120,13 +114,7 @@ ModMetadata DevTools::inputMetadata(void* treePtr, ModMetadata metadata) { continue; } ImGui::Text("version: %s", item.getVersion().toString().c_str()); - const char* importance = ""; - switch (item.getImportance()) { - case geode::ModMetadata::Incompatibility::Importance::Breaking: importance = "breaking"; break; - case geode::ModMetadata::Incompatibility::Importance::Conflicting: importance = "conflicting"; break; - case geode::ModMetadata::Incompatibility::Importance::Superseded: importance = "superseded"; break; - } - ImGui::Text("importance: %s", importance); + ImGui::Text("breaking: %s", item.isBreaking() ? "true" : "false"); ImGui::Text("isResolved: %s", item.isResolved() ? "true" : "false"); if (item.getMod()) drawModGraphNode(item.getMod()); @@ -165,7 +153,7 @@ void DevTools::drawModGraphNode(Mod* node) { ImColor color = ImColor(1.f, 1.f, 1.f); if (node->isUninstalled()) color = ImColor(0.1f, 0.1f, 0.1f); - else if (!node->isEnabled()) + else if (!node->isLoaded()) color = ImColor(0.7f, 0.7f, 0.7f); ImGui::PushStyleColor(ImGuiCol_Text, (ImU32)color);