1+ #include " ../DevTools.hpp"
2+ #include " DragButton.hpp"
3+
4+ DragButton *DragButton::m_instance = nullptr ;
5+
6+ bool DragButton::init () {
7+ if (!CCMenu::init ())
8+ return false ;
9+ m_sprite = CircleButtonSprite::createWithSprite (" devtools.png" _spr, 1 ,
10+ CircleBaseColor::Green, CircleBaseSize::MediumAlt);
11+ m_sprite->setScale (.8f );
12+ m_sprite->setID (" sprite" );
13+ addChild (m_sprite);
14+ setContentSize (m_sprite->getScaledContentSize ());
15+ m_sprite->setPosition (getContentSize () / 2 );
16+
17+ CCScene::get ()->addChild (this );
18+ SceneManager::get ()->keepAcrossScenes (this );
19+ scheduleUpdate ();
20+
21+ setZOrder (300 );
22+
23+ auto x = Mod::get ()->getSavedValue <float >(" button-x" , 50 .f );
24+ auto y = Mod::get ()->getSavedValue <float >(" button-y" , 50 .f );
25+ x = std::clamp (x, -getContentWidth () / 2 , CCDirector::get ()->getWinSize ().width - getContentWidth () / 2 );
26+ y = std::clamp (y, -getContentHeight () / 2 , CCDirector::get ()->getWinSize ().height - getContentHeight () / 2 );
27+ setPosition ({x, y});
28+
29+ Mod::get ()->setSavedValue <float >(" button-x" , x);
30+ Mod::get ()->setSavedValue <float >(" button-y" , y);
31+ auto settings = DevTools::get ()->getSettings ();
32+ setOpacity (settings.buttonOpacity );
33+ setScale (settings.buttonScale );
34+
35+ setID (" drag-button" _spr);
36+
37+ return true ;
38+ };
39+
40+ DragButton *DragButton::get () {
41+ if (m_instance)
42+ return m_instance;
43+ m_instance = new DragButton ();
44+ if (m_instance && m_instance->init ()) {
45+ m_instance->autorelease ();
46+ return m_instance;
47+ } else {
48+ delete m_instance;
49+ return nullptr ;
50+ }
51+ }
52+
53+ void DragButton::registerWithTouchDispatcher () {
54+ CCTouchDispatcher::get ()->addTargetedDelegate (this , -512 , true );
55+ }
56+
57+ bool DragButton::ccTouchBegan (CCTouch *touch, CCEvent *evt) {
58+ if (!m_handleTouch || !m_bVisible)
59+ return false ;
60+ if (getScaledContentSize ().width / 2 <
61+ ccpDistance (m_sprite->getPosition (), convertToNodeSpace (touch->getLocation ()))) {
62+ return false ;
63+ }
64+
65+ m_diff = getPosition () - touch->getLocation ();
66+ m_startPos = new CCPoint (touch->getLocation ());
67+
68+ m_moving = false ;
69+
70+ m_sprite->stopAllActions ();
71+
72+ // For some reason I could not get a recreation of CCEaseSineOut working on ios.
73+ #ifdef GEODE_IS_IOS
74+ m_sprite->runAction (CCEaseOut::create (CCScaleTo::create (0 .3f , .8 * m_scale * m_multiplier), 1 .6f ));
75+ #else
76+ m_sprite->runAction (CCEaseSineOut::create (CCScaleTo::create (0 .3f , .8 * m_scale * m_multiplier)));
77+ #endif
78+ return true ;
79+ }
80+
81+ void DragButton::ccTouchCancelled (CCTouch *touch, CCEvent *event) {
82+ ccTouchEnded (touch, event);
83+ }
84+
85+ void DragButton::ccTouchEnded (CCTouch *touch, CCEvent *evt) {
86+ m_sprite->stopAllActions ();
87+
88+ // For some reason I could not get a recreation of CCEaseSineOut working on ios.
89+ #ifdef GEODE_IS_IOS
90+ m_sprite->runAction (CCEaseOut::create (CCScaleTo::create (0 .3f , .8 * m_scale), 1 .6f ));
91+ #else
92+ m_sprite->runAction (CCEaseSineOut::create (CCScaleTo::create (0 .3f , .8 * m_scale)));
93+ #endif
94+ if (m_moving) {
95+ Mod::get ()->setSavedValue <float >(" button-x" , getPositionX ());
96+ Mod::get ()->setSavedValue <float >(" button-y" , getPositionY ());
97+ return ;
98+ }
99+ activate ();
100+ }
101+
102+ void DragButton::ccTouchMoved (CCTouch *touch, CCEvent *evt) {
103+ if (!m_moving)
104+ if (ccpDistance (*m_startPos, touch->getLocation ()) > 3 )
105+ m_moving = true ;
106+ if (m_moving) {
107+ auto pos = touch->getLocation () + m_diff;
108+ pos.x = std::clamp (pos.x , -getContentWidth () / 2 , CCDirector::get ()->getWinSize ().width - getContentWidth () / 2 );
109+ pos.y = std::clamp (pos.y , -getContentHeight () / 2 , CCDirector::get ()->getWinSize ().height - getContentHeight () / 2 );
110+ setPosition (pos);
111+ }
112+ }
113+
114+ void DragButton::update (float delta) {
115+ static auto devtools = DevTools::get ();
116+ bool shouldRender = true ;
117+ if (auto pl = PlayLayer::get (); pl && !pl->m_isPaused ) {
118+ shouldRender = devtools->getSettings ().buttonInGameplay ;
119+ } else if (auto el = LevelEditorLayer::get ()) {
120+ if (devtools->getSettings ().buttonInEditor ) {
121+ shouldRender = el->m_playbackMode != PlaybackMode::Playing || devtools->getSettings ().buttonInGameplay ;
122+ } else {
123+ shouldRender = false ;
124+ }
125+ }
126+ setVisible (shouldRender && m_render);
127+ }
128+
129+ bool DragButton::isRendered () {
130+ return m_render;
131+ }
132+
133+ void DragButton::setRendered (bool render) {
134+ m_render = render;
135+ }
136+
137+ bool DragButton::isHandlingTouch () {
138+ return m_render && m_handleTouch;
139+ }
140+
141+ void DragButton::setHandlingTouch (bool handle) { m_handleTouch = handle; }
142+
143+ void DragButton::activate () {
144+ DevTools::get ()->toggle ();
145+ }
146+
147+ // Only make it show if on mobile
148+ #ifdef GEODE_IS_MOBILE
149+ #include < Geode/modify/CCScene.hpp>
150+
151+ class $modify(CCScene) {
152+ int getHighestChildZ () {
153+ int btnZ;
154+ auto btn = DragButton::get ();
155+ if (btn) {
156+ btnZ = btn->getZOrder ();
157+ btn->setZOrder (-1 );
158+ }
159+ auto highest = CCScene::getHighestChildZ ();
160+ if (btn) {
161+ btn->setZOrder (btnZ);
162+ }
163+ return highest;
164+ }
165+ };
166+
167+ #include < Geode/modify/MenuLayer.hpp>
168+
169+ class $modify(MenuLayer) {
170+ bool init () {
171+ if (!MenuLayer::init ()) return false ;
172+
173+ DragButton::get ();
174+ return true ;
175+ }
176+ };
177+ #endif
0 commit comments