|
| 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(70000); |
| 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