Skip to content

Commit 9fbfdef

Browse files
committed
Refactor UI code to follow Geode standards, fix mobile pause bug
- Extract magic numbers into src/constants.hpp with named constants - Fix mobile pause bug (issues #5, #6, #10, #14, #15): properly unregister touch delegates and force priority in cleanup() override, preventing stale touch state from blocking pause after zoom exit - Fix singleton leak in AndroidZoomLayer::create() — old instance is now properly cleaned up instead of just nulling the pointer - Fix potential crash on level complete while zoomed (issue #7): hook PlayLayer::levelComplete() to reset zoom before GD processes it - Replace custom clamp() with std::clamp, remove dead includes from main.cpp (#include <charconv>, unused modify headers) - Use addChildAtPosition with Anchor::TopLeft for back button instead of manual position calculations with ignoreAnchorPointForPosition - Add node IDs (_spr namespaced) to back-menu and back-button - Initialize all member variables (desktop.hpp, mobile.hpp, settings.hpp) - Fix redundant WindowsZoomManager::get() calls within own member functions - Extract getPlayLayer() helper to deduplicate 7 identical lookups - Remove dead code: onBackButton23 declaration, commented-out methods https://claude.ai/code/session_01NqsAjw4XEYgZMTjW1SKaze
1 parent cbc80d1 commit 9fbfdef

File tree

8 files changed

+143
-102
lines changed

8 files changed

+143
-102
lines changed

src/constants.hpp

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
#pragma once
2+
3+
namespace zoom {
4+
// Mobile UI
5+
constexpr float kBackButtonOpacity = 100.0f;
6+
constexpr float kBackButtonSizeMult = 1.15f;
7+
constexpr float kBackButtonScale = 0.6f;
8+
constexpr int kZoomLayerZOrder = 11;
9+
constexpr int kTouchPriority = -250;
10+
constexpr int kForcePriority = 2;
11+
constexpr float kTouchZoomDivisor = 100.0f;
12+
constexpr float kPauseZoomButtonScale = 0.6f;
13+
14+
// Desktop
15+
constexpr float kSensitivityScale = 0.1f;
16+
constexpr float kSmoothScrollDamping = 0.1f;
17+
constexpr float kAutoShowZoomThreshold = 1.01f;
18+
19+
// Shared
20+
constexpr float kMinZoom = 1.0f;
21+
constexpr float kDefaultZoom = 1.0f;
22+
}

src/desktop.cpp

Lines changed: 40 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
#include "utils.hpp"
44
#include "desktop.hpp"
55
#include "settings.hpp"
6+
#include "constants.hpp"
67

78
#include <geode.custom-keybinds/include/Keybinds.hpp>
89

@@ -27,6 +28,10 @@ WindowsZoomManager* WindowsZoomManager::get() {
2728
return inst;
2829
}
2930

31+
CCNode* WindowsZoomManager::getPlayLayer() {
32+
return CCScene::get()->getChildByID("PlayLayer");
33+
}
34+
3035
void WindowsZoomManager::togglePauseMenu() {
3136
if (!isPaused) return;
3237

@@ -44,26 +49,24 @@ void WindowsZoomManager::setPauseMenuVisible(bool visible) {
4449
}
4550

4651
void WindowsZoomManager::setZoom(float zoom) {
47-
CCNode* playLayer = CCScene::get()->getChildByID("PlayLayer");
52+
auto* playLayer = getPlayLayer();
4853
if (!playLayer) return;
4954

5055
playLayer->setScale(zoom);
5156
onScreenModified();
5257
}
5358

5459
void WindowsZoomManager::zoom(float delta) {
55-
CCNode* playLayer = CCScene::get()->getChildByID("PlayLayer");
60+
auto* playLayer = getPlayLayer();
5661
if (!playLayer) return;
5762

58-
// CCPoint mouseScreenPos = getMousePosOnScreen();
5963
CCPoint mousePos = getMousePos();
60-
6164
zoomPlayLayer(playLayer, delta, mousePos);
6265
onScreenModified();
6366
}
6467

6568
void WindowsZoomManager::move(CCPoint delta) {
66-
CCNode* playLayer = CCScene::get()->getChildByID("PlayLayer");
69+
auto* playLayer = getPlayLayer();
6770
if (!playLayer) return;
6871

6972
CCPoint pos = playLayer->getPosition();
@@ -73,7 +76,7 @@ void WindowsZoomManager::move(CCPoint delta) {
7376
}
7477

7578
void WindowsZoomManager::setPos(float x, float y) {
76-
CCNode* playLayer = CCScene::get()->getChildByID("PlayLayer");
79+
auto* playLayer = getPlayLayer();
7780
if (!playLayer) return;
7881

7982
playLayer->setPosition(CCPoint{ x, y });
@@ -82,8 +85,8 @@ void WindowsZoomManager::setPos(float x, float y) {
8285
}
8386

8487
float WindowsZoomManager::getZoom() {
85-
CCNode* playLayer = CCScene::get()->getChildByID("PlayLayer");
86-
if (!playLayer) return 1.0f;
88+
auto* playLayer = getPlayLayer();
89+
if (!playLayer) return zoom::kDefaultZoom;
8790

8891
return playLayer->getScale();
8992
}
@@ -92,49 +95,46 @@ CCPoint WindowsZoomManager::screenToWorld(CCPoint pos) {
9295
CCSize screenSize = getScreenSize();
9396
CCSize winSize = CCEGLView::get()->getFrameSize();
9497

95-
return CCPoint{ pos.x * (screenSize.width / winSize.width), pos.y * (screenSize.height / winSize.height) };
98+
return CCPoint{
99+
pos.x * (screenSize.width / winSize.width),
100+
pos.y * (screenSize.height / winSize.height)
101+
};
96102
}
97103

98-
// CCPoint WindowsZoomManager::getMousePosOnScreen() {
99-
// return screenToWorld(getMousePos());
100-
// }
101-
102104
CCPoint WindowsZoomManager::getMousePosOnNode(CCNode* node) {
103105
return node->convertToNodeSpace(getMousePos());
104106
}
105107

106108
void WindowsZoomManager::update(float dt) {
107109
auto mousePos = getMousePos();
108-
auto lastMousePos = WindowsZoomManager::get()->lastMousePos;
109110

110-
WindowsZoomManager::get()->deltaMousePos = CCPoint{ mousePos.x - lastMousePos.x, mousePos.y - lastMousePos.y };
111-
WindowsZoomManager::get()->lastMousePos = mousePos;
111+
deltaMousePos = CCPoint{ mousePos.x - lastMousePos.x, mousePos.y - lastMousePos.y };
112+
lastMousePos = mousePos;
112113

113114
if (!isPaused) return;
114115

115116
if (isPanning) {
116-
CCPoint delta = WindowsZoomManager::get()->deltaMousePos;
117-
move(delta);
117+
move(deltaMousePos);
118118
}
119119
}
120120

121121
void WindowsZoomManager::onResume() {
122-
setZoom(1.0f);
122+
setZoom(zoom::kDefaultZoom);
123123
setPos(0.0f, 0.0f);
124124

125125
isPaused = false;
126-
WindowsZoomManager::get()->isPanning = false;
126+
isPanning = false;
127127
}
128128

129129
void WindowsZoomManager::onPause() {
130130
isPaused = true;
131-
WindowsZoomManager::get()->isPanning = false;
131+
isPanning = false;
132132
}
133133

134134
void WindowsZoomManager::onScroll(float y, float x) {
135135
if (!isPaused) return;
136136

137-
CCNode* playLayer = CCScene::get()->getChildByID("PlayLayer");
137+
auto* playLayer = getPlayLayer();
138138
if (!playLayer) return;
139139

140140
if (SettingsManager::get()->altDisablesZoom) {
@@ -143,19 +143,20 @@ void WindowsZoomManager::onScroll(float y, float x) {
143143
return;
144144
}
145145
}
146-
147-
float zoomDelta = SettingsManager::get()->zoomSensitivity * 0.1f;
148-
146+
147+
float baseDelta = SettingsManager::get()->zoomSensitivity * zoom::kSensitivityScale;
148+
149149
if (Loader::get()->isModLoaded("prevter.smooth-scroll")) {
150-
zoom(-y * zoomDelta * 0.1f);
150+
zoom(-y * baseDelta * zoom::kSmoothScrollDamping);
151151
} else if (y > 0) {
152-
zoom(-zoomDelta);
152+
zoom(-baseDelta);
153153
} else {
154-
zoom(zoomDelta);
154+
zoom(baseDelta);
155155
}
156156

157157
if (y > 0) {
158-
if (SettingsManager::get()->autoShowMenu && playLayer->getScale() <= 1.01f) {
158+
if (SettingsManager::get()->autoShowMenu &&
159+
playLayer->getScale() <= zoom::kAutoShowZoomThreshold) {
159160
setPauseMenuVisible(true);
160161
}
161162
} else {
@@ -164,11 +165,10 @@ void WindowsZoomManager::onScroll(float y, float x) {
164165
}
165166

166167
void WindowsZoomManager::onScreenModified() {
167-
CCNode* playLayer = CCScene::get()->getChildByID("PlayLayer");
168+
auto* playLayer = getPlayLayer();
168169
if (!playLayer) return;
169170

170171
clampPlayLayerPos(playLayer);
171-
if (!isPaused) return;
172172
}
173173

174174
class $modify(PauseLayer) {
@@ -225,6 +225,11 @@ class $modify(PlayLayer) {
225225
WindowsZoomManager::get()->onResume();
226226
return PlayLayer::init(level, useReplay, dontCreateObjects);
227227
}
228+
229+
void levelComplete() {
230+
WindowsZoomManager::get()->onResume();
231+
PlayLayer::levelComplete();
232+
}
228233
};
229234

230235
class $modify(CCScheduler) {
@@ -250,6 +255,8 @@ class $modify(CCEGLView) {
250255
}
251256
};
252257
#else
258+
// macOS requires reinterpret_cast for objc_msgSend trampolines —
259+
// this is the standard pattern for calling ObjC methods from C++.
253260
void otherMouseDownHook(void* self, SEL sel, void* event) {
254261
WindowsZoomManager::get()->isPanning = true;
255262
reinterpret_cast<void(*)(void*, SEL, void*)>(objc_msgSend)(self, sel, event);
@@ -264,7 +271,7 @@ void otherMouseUpHook(void* self, SEL sel, void* event) {
264271
if (auto hook = ObjcHook::create("EAGLView", "otherMouseDown:", &otherMouseDownHook)) {
265272
(void) Mod::get()->claimHook(hook.unwrap());
266273
}
267-
274+
268275
if (auto hook = ObjcHook::create("EAGLView", "otherMouseUp:", &otherMouseUpHook)) {
269276
(void) Mod::get()->claimHook(hook.unwrap());
270277
}
@@ -277,4 +284,4 @@ class $modify(CCMouseDispatcher) {
277284
return CCMouseDispatcher::dispatchScrollMSG(y, x);
278285
}
279286
};
280-
#endif // GEODE_IS_DESKTOP
287+
#endif // GEODE_IS_DESKTOP

src/desktop.hpp

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,11 @@ using namespace geode::prelude;
77

88
class WindowsZoomManager {
99
public:
10-
CCPoint lastMousePos;
11-
CCPoint deltaMousePos;
10+
CCPoint lastMousePos{};
11+
CCPoint deltaMousePos{};
1212

13-
bool isPaused;
14-
bool isPanning;
13+
bool isPaused = false;
14+
bool isPanning = false;
1515

1616
static WindowsZoomManager* get();
1717

@@ -27,13 +27,13 @@ class WindowsZoomManager {
2727
void move(CCPoint delta);
2828

2929
float getZoom();
30-
// CCPoint getMousePosOnScreen();
3130
CCPoint getMousePosOnNode(CCNode* node);
32-
31+
3332
void onResume();
3433
void onPause();
3534
void onScroll(float y, float x);
3635
private:
36+
CCNode* getPlayLayer();
3737
void onScreenModified();
3838
};
39-
#endif // GEODE_IS_DESKTOP
39+
#endif // GEODE_IS_DESKTOP

src/main.cpp

Lines changed: 1 addition & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,5 @@
1-
#include <charconv>
2-
31
#include <Geode/Geode.hpp>
42

5-
#include <Geode/modify/MenuLayer.hpp>
6-
#include <Geode/modify/PauseLayer.hpp>
7-
#include <Geode/modify/CCKeyboardDispatcher.hpp>
8-
#include <Geode/modify/CCMouseDispatcher.hpp>
9-
#include <Geode/modify/PlayLayer.hpp>
10-
#include <Geode/modify/CCEGLView.hpp>
11-
#include <Geode/modify/CCApplication.hpp>
12-
#include <Geode/modify/CCScheduler.hpp>
13-
143
#include "settings.hpp"
154

165
#ifdef GEODE_IS_MOBILE
@@ -19,14 +8,9 @@
198

209
using namespace geode::prelude;
2110

22-
float clamp(float d, float min, float max) {
23-
const float t = d < min ? min : d;
24-
return t > max ? max : t;
25-
}
26-
2711
$execute {
2812
geode::log::info("Zoom mod loaded!");
2913
geode::log::info("Platform: " GEODE_PLATFORM_NAME);
3014

3115
SettingsManager::get()->init();
32-
}
16+
}

0 commit comments

Comments
 (0)