Skip to content

Commit d2b0e9e

Browse files
authored
Merge branch 'main' into main
2 parents 9c9c623 + a18550d commit d2b0e9e

15 files changed

Lines changed: 194 additions & 49 deletions

File tree

CMakeLists.txt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,10 @@ add_library(${PROJECT_NAME} SHARED ${SOURCES} src/platform/Mac.mm)
1717

1818
set_source_files_properties(src/platform/Mac.mm PROPERTIES SKIP_PRECOMPILE_HEADERS ON)
1919

20+
if ("${CMAKE_SYSTEM_NAME}" STREQUAL "iOS" OR IOS)
21+
target_link_libraries(${PROJECT_NAME} "-framework CoreGraphics")
22+
endif()
23+
2024
if (NOT DEFINED ENV{GEODE_SDK})
2125
message(FATAL_ERROR "Unable to find Geode SDK! Please define GEODE_SDK environment variable to point to Geode")
2226
else()

README.md

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,8 @@ public:
2727
};
2828

2929
static void registerDevTools() {
30-
//
30+
// The lambda provided will run every frame (given the node is selected)
31+
// for any node that is typeinfo_cast able into MySprite
3132
devtools::registerNode<MySprite>([](MySprite* node) {
3233
devtools::label("My Sprite");
3334
devtools::property("Some Flag", node->m_someFlag);
@@ -60,6 +61,8 @@ private:
6061
$on_mod(Loaded) {
6162
// makes sure DevTools is loaded before registering
6263
devtools::waitForDevTools([] {
64+
// use a static method on the class itself
65+
// so it can access private members
6366
MySprite::registerDevTools();
6467
});
6568
}

changelog.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,8 @@
1+
## v1.11.0
2+
* Made properties api use drag inputs
3+
* Fix waitForDevTools on mods that load before DevTools
4+
* Add screenshot button to nodes (#65)
5+
16
## v1.10.0
27
* Add node properties api (#63)
38
* Fix a crash when removing layouts and layout options (#58)

include/API.hpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@ namespace devtools {
6868
callback();
6969
} else {
7070
auto devtools = geode::Loader::get()->getInstalledMod("geode.devtools");
71-
if (!devtools || !devtools->isEnabled()) return;
71+
if (!devtools) return;
7272

7373
new geode::EventListener(
7474
[callback = std::forward<F>(callback)](geode::ModStateEvent*) {

mod.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
2-
"geode": "4.8.0",
3-
"version": "v1.10.0",
2+
"geode": "4.9.0",
3+
"version": "v1.11.0",
44
"gd": {
55
"win": "2.2074",
66
"android": "*",

src/API.cpp

Lines changed: 13 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -9,12 +9,15 @@ template <typename T>
99
static void handleType() {
1010
new EventListener<EventFilter<devtools::PropertyFnEvent<T>>>(+[](devtools::PropertyFnEvent<T>* event) {
1111
constexpr bool isSigned = std::is_signed_v<T>;
12-
constexpr ImGuiDataType dataType = sizeof(T) == 1 ? (isSigned ? ImGuiDataType_S8 : ImGuiDataType_U8) :
13-
sizeof(T) == 2 ? (isSigned ? ImGuiDataType_S16 : ImGuiDataType_U16) :
14-
sizeof(T) == 4 ? (isSigned ? ImGuiDataType_S32 : ImGuiDataType_U32) :
15-
isSigned ? ImGuiDataType_S64 : ImGuiDataType_U64;
12+
constexpr ImGuiDataType dataType =
13+
std::is_same_v<T, float> ? ImGuiDataType_Float :
14+
std::is_same_v<T, double> ? ImGuiDataType_Double :
15+
sizeof(T) == 1 ? (isSigned ? ImGuiDataType_S8 : ImGuiDataType_U8) :
16+
sizeof(T) == 2 ? (isSigned ? ImGuiDataType_S16 : ImGuiDataType_U16) :
17+
sizeof(T) == 4 ? (isSigned ? ImGuiDataType_S32 : ImGuiDataType_U32) :
18+
isSigned ? ImGuiDataType_S64 : ImGuiDataType_U64;
1619
event->fn = +[](const char* name, T& prop) {
17-
return ImGui::InputScalar(name, dataType, &prop);
20+
return ImGui::DragScalar(name, dataType, &prop);
1821
};
1922
return ListenerResult::Stop;
2023
});
@@ -57,6 +60,8 @@ static void handleType() {
5760
handleType<unsigned long long>();
5861
handleType<long>();
5962
handleType<unsigned long>();
63+
handleType<float>();
64+
handleType<double>();
6065

6166
// checkbox
6267
new EventListener<EventFilter<devtools::PropertyFnEvent<bool>>>(+[](devtools::PropertyFnEvent<bool>* event) {
@@ -66,20 +71,6 @@ static void handleType() {
6671
return ListenerResult::Stop;
6772
});
6873

69-
// float and double
70-
new EventListener<EventFilter<devtools::PropertyFnEvent<float>>>(+[](devtools::PropertyFnEvent<float>* event) {
71-
event->fn = +[](const char* name, float& prop) {
72-
return ImGui::InputFloat(name, &prop);
73-
};
74-
return ListenerResult::Stop;
75-
});
76-
new EventListener<EventFilter<devtools::PropertyFnEvent<double>>>(+[](devtools::PropertyFnEvent<double>* event) {
77-
event->fn = +[](const char* name, double& prop) {
78-
return ImGui::InputDouble(name, &prop);
79-
};
80-
return ListenerResult::Stop;
81-
});
82-
8374
// string
8475
new EventListener<EventFilter<devtools::PropertyFnEvent<std::string>>>(+[](devtools::PropertyFnEvent<std::string>* event) {
8576
event->fn = +[](const char* name, std::string& prop) {
@@ -136,20 +127,20 @@ static void handleType() {
136127
// points/sizes
137128
new EventListener<EventFilter<devtools::PropertyFnEvent<CCPoint>>>(+[](devtools::PropertyFnEvent<CCPoint>* event) {
138129
event->fn = +[](const char* name, CCPoint& prop) {
139-
return ImGui::InputFloat2(name, reinterpret_cast<float*>(&prop));
130+
return ImGui::DragFloat2(name, reinterpret_cast<float*>(&prop));
140131
};
141132
return ListenerResult::Stop;
142133
});
143134

144135
new EventListener<EventFilter<devtools::PropertyFnEvent<CCSize>>>(+[](devtools::PropertyFnEvent<CCSize>* event) {
145136
event->fn = +[](const char* name, CCSize& prop) {
146-
return ImGui::InputFloat2(name, reinterpret_cast<float*>(&prop));
137+
return ImGui::DragFloat2(name, reinterpret_cast<float*>(&prop));
147138
};
148139
return ListenerResult::Stop;
149140
});
150141
new EventListener<EventFilter<devtools::PropertyFnEvent<CCRect>>>(+[](devtools::PropertyFnEvent<CCRect>* event) {
151142
event->fn = +[](const char* name, CCRect& prop) {
152-
return ImGui::InputFloat4(name, reinterpret_cast<float*>(&prop));
143+
return ImGui::DragFloat4(name, reinterpret_cast<float*>(&prop));
153144
};
154145
return ListenerResult::Stop;
155146
});

src/DevTools.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -289,6 +289,10 @@ void DevTools::toggle() {
289289
this->show(!m_visible);
290290
}
291291

292+
bool DevTools::isVisible() {
293+
return m_visible;
294+
}
295+
292296
void DevTools::sceneChanged() {
293297
m_selectedNode = nullptr;
294298
}

src/DevTools.hpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -124,4 +124,6 @@ class DevTools {
124124

125125
void show(bool visible);
126126
void toggle();
127+
128+
bool isVisible();
127129
};

src/main.cpp

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
#include <Geode/modify/CCDirector.hpp>
77
#include <Geode/modify/CCEGLView.hpp>
88
#include <Geode/modify/CCNode.hpp>
9+
#include <Geode/modify/GameToolbox.hpp>
910
#include "DevTools.hpp"
1011
#include <imgui.h>
1112
#include "ImGui.hpp"
@@ -55,6 +56,31 @@ class $modify(CCScene) {
5556

5657
#endif
5758

59+
class $modify(GameToolbox) {
60+
static void preVisitWithClippingRect(CCNode* node, CCRect clipRect) {
61+
if (!node->isVisible() || !DevTools::get()->isVisible())
62+
return GameToolbox::preVisitWithClippingRect(node, clipRect);
63+
64+
glEnable(GL_SCISSOR_TEST);
65+
66+
clipRect.origin = node->convertToWorldSpace(clipRect.origin);
67+
68+
kmMat4 mat;
69+
kmGLGetMatrix(KM_GL_PROJECTION, &mat);
70+
if (mat.mat[5] < 0) {
71+
auto ws = CCDirector::get()->getWinSize();
72+
clipRect.origin.y = ws.height - (clipRect.origin.y + node->getContentSize().height);
73+
}
74+
75+
CCEGLView::get()->setScissorInPoints(
76+
clipRect.origin.x,
77+
clipRect.origin.y,
78+
clipRect.size.width,
79+
clipRect.size.height
80+
);
81+
}
82+
83+
};
5884

5985

6086
class $modify(CCDirector) {

src/pages/Attributes.cpp

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,13 +7,15 @@
77
#include <ccTypes.h>
88
#include <Geode/ui/SimpleAxisLayout.hpp>
99
#include <Geode/ui/Layout.hpp>
10+
#include <Geode/utils/file.hpp>
1011

1112
using namespace geode::prelude;
1213

1314
#define AXIS_GET(Name_) \
1415
&AxisLayoutOptions::get##Name_, \
1516
&AxisLayoutOptions::set##Name_
1617

18+
1719
template <class T, class R>
1820
bool checkbox(const char* text, T* ptr, bool(T::* get)(), R(T::* set)(bool)) {
1921
bool value = (ptr->*get)();
@@ -72,8 +74,26 @@ void DevTools::drawBasicAttributes(CCNode* node) {
7274
}
7375
ImGui::SameLine();
7476
if (ImGui::Button(U8STR(FEATHER_COPY " Copy Class Name"))) {
75-
clipboard::write(getNodeName(node));
77+
clipboard::write(std::string(geode::cocos::getObjectName(node)));
78+
}
79+
ImGui::SameLine();
80+
if (ImGui::Button(U8STR(FEATHER_SAVE " Screenshot"))) {
81+
file::pick(file::PickMode::SaveFile, file::FilePickOptions {
82+
.filters = {{ .description = "PNG Image", .files = {"*.png"} }}
83+
}).listen([node](auto choice) {
84+
if (auto file = choice->ok()) {
85+
int width, height;
86+
auto bytes = renderToBytes(node, width, height);
87+
88+
auto path = string::pathToString(*file);
89+
if (!path.ends_with(".png")) {
90+
path += ".png";
91+
}
92+
saveRenderToFile(bytes, width, height, path.c_str());
93+
}
94+
});
7695
}
96+
7797
ImGui::Text("Address: %s", fmt::to_string(fmt::ptr(node)).c_str());
7898
ImGui::SameLine();
7999
if (ImGui::Button(U8STR(FEATHER_COPY " Copy"))) {

0 commit comments

Comments
 (0)