Skip to content

Commit 6404485

Browse files
committed
modernize circle-tool to geode::Popup and such
1 parent 69c732e commit 6404485

4 files changed

Lines changed: 82 additions & 119 deletions

File tree

circle-tool/CHANGELOG.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
## 1.2.3
2+
- Remake the popup using Geode's classes, preventing a touch handler leak
3+
- This fixes an issue with the Better Touch Prio mod
4+
- Add changelog
5+
6+
## 1.2.2 - 1.0.0
7+
- Port to newer GD versions

circle-tool/README.md

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,4 +6,11 @@ The tool can be found in the edit tab of the editor, which will run on the selec
66

77
![screenshot of the mod](mat.circle-tool/screenshot.png)
88

9-
Credit to [alkatreize](user:5625235) for the button texture!
9+
Credit to [alkatreize](user:5625235) for the button texture!
10+
11+
## Usage
12+
13+
Select some objects in the editor (ideally 2) and press the button to open the popup. \
14+
The mod will essentially run a macro that repeatedly copy pastes your object selection and slightly rotates it, following the options specified.
15+
16+
For convenience, the mod selects the newly created objects, and groups them into a single undo-able action.

circle-tool/main.cpp

Lines changed: 66 additions & 117 deletions
Original file line numberDiff line numberDiff line change
@@ -6,168 +6,117 @@ using namespace geode;
66
using namespace cocos2d;
77
using geode::cocos::CCArrayExt;
88

9-
class CircleToolPopup : public FLAlertLayer, TextInputDelegate, FLAlertLayerProtocol {
9+
class CircleToolPopup : public geode::Popup {
1010
public:
1111
static float m_angle;
1212
static float m_step;
1313
static float m_fat;
1414
CCLabelBMFont* m_label = nullptr;
1515

16-
static auto* create() {
17-
auto* node = new (std::nothrow) CircleToolPopup();
18-
if (node && node->init()) {
16+
static CircleToolPopup* create() {
17+
auto* node = new CircleToolPopup();
18+
if (node->init()) {
1919
node->autorelease();
20+
return node;
2021
} else {
2122
delete node;
22-
node = nullptr;
23+
return nullptr;
2324
}
24-
return node;
2525
}
2626

2727
bool init() override {
28-
if (!this->initWithColor({0, 0, 0, 75})) return false;
28+
if (!Popup::init(300, 220)) return false;
2929

30-
this->m_noElasticity = true;
30+
this->setTitle("Circle Tool");
3131

32-
auto* director = CCDirector::sharedDirector();
33-
geode::cocos::handleTouchPriority(this);
34-
// director->getTouchDispatcher()->incrementForcePrio(69);
35-
this->registerWithTouchDispatcher();
32+
auto* layer = m_mainLayer;
33+
auto* menu = m_buttonMenu;
3634

37-
auto layer = CCLayer::create();
38-
auto menu = CCMenu::create();
39-
this->m_mainLayer = layer;
40-
this->m_buttonMenu = menu;
41-
42-
layer->addChild(menu);
43-
this->addChild(layer);
44-
45-
const float width = 300, height = 220;
46-
47-
const CCPoint offset = director->getWinSize() / 2.f;
48-
auto bg = extension::CCScale9Sprite::create("GJ_square01.png");
49-
bg->setContentSize({width, height});
50-
bg->setPosition(offset);
51-
menu->setPosition(offset);
52-
bg->setZOrder(-2);
53-
layer->addChild(bg);
54-
55-
auto close_btn = CCMenuItemSpriteExtra::create(
56-
CCSprite::createWithSpriteFrameName("GJ_closeBtn_001.png"),
57-
this, menu_selector(CircleToolPopup::on_close)
58-
);
59-
60-
close_btn->setPosition(ccp(25.f, director->getWinSize().height - 25.f) - offset);
61-
menu->addChild(close_btn);
62-
63-
this->setKeypadEnabled(true);
64-
65-
66-
layer->addChild(
67-
NodeFactory<CCLabelBMFont>::start("Circle Tool", "goldFont.fnt")
68-
.setPosition(ccp(0, 95) + offset)
69-
.setScale(0.75f)
70-
);
71-
72-
layer->addChild(
35+
layer->addChildAtPosition(
7336
NodeFactory<CCLabelBMFont>::start("Arc", "goldFont.fnt")
74-
.setPosition(ccp(-60, 64) + offset)
75-
.setScale(0.75f)
37+
.setScale(0.75f),
38+
Anchor::Center, ccp(-60, 64)
7639
);
77-
auto angle_input = FloatInputNode::create(CCSize(60, 30), 2.f, "bigFont.fnt");
78-
angle_input->set_value(m_angle);
79-
angle_input->setPosition(ccp(-60, 38) + offset);
80-
angle_input->callback = [&](FloatInputNode& input) {
81-
m_angle = input.get_value().value_or(m_angle);
40+
auto angle_input = geode::TextInput::create(60.f, "");
41+
angle_input->setCommonFilter(CommonFilter::Float);
42+
angle_input->setString(fmt::to_string(m_angle));
43+
angle_input->setCallback([this](std::string const& str) {
44+
m_angle = geode::utils::numFromString<float>(str).unwrapOr(m_angle);
8245
this->update_labels();
83-
};
84-
this->addChild(angle_input);
85-
86-
layer->addChild(
46+
});
47+
layer->addChildAtPosition(angle_input, Anchor::Center, ccp(-60, 38));
48+
49+
layer->addChildAtPosition(
8750
NodeFactory<CCLabelBMFont>::start("Step", "goldFont.fnt")
88-
.setPosition(ccp(60, 64) + offset)
89-
.setScale(0.75f)
51+
.setScale(0.75f),
52+
Anchor::Center, ccp(60, 64)
9053
);
91-
auto step_input = FloatInputNode::create(CCSize(60, 30), 2.f, "bigFont.fnt");
92-
step_input->set_value(m_step);
93-
step_input->setPosition(ccp(60, 38) + offset);
94-
step_input->callback = [&](FloatInputNode& input) {
95-
m_step = input.get_value().value_or(m_step);
54+
auto step_input = geode::TextInput::create(60.f, "");
55+
step_input->setCommonFilter(CommonFilter::Float);
56+
step_input->setString(fmt::to_string(m_step));
57+
step_input->setCallback([this](std::string const& str) {
58+
m_step = geode::utils::numFromString<float>(str).unwrapOr(m_step);
9659
if (m_step == 0.f) m_step = 1.f;
9760
this->update_labels();
98-
};
99-
this->addChild(step_input);
61+
});
62+
layer->addChildAtPosition(step_input, Anchor::Center, ccp(60, 38));
10063

101-
layer->addChild(
64+
layer->addChildAtPosition(
10265
NodeFactory<CCLabelBMFont>::start("Squish", "goldFont.fnt")
103-
.setPosition(ccp(60, 10) + offset)
104-
.setScale(0.75f)
66+
.setScale(0.75f),
67+
Anchor::Center, ccp(60, 10)
10568
);
106-
auto fat_input = FloatInputNode::create(CCSize(60, 30), 2.f, "bigFont.fnt");
107-
fat_input->set_value(m_fat);
108-
fat_input->setPosition(ccp(60, -16) + offset);
109-
fat_input->callback = [&](FloatInputNode& input) {
110-
m_fat = input.get_value().value_or(m_fat);
69+
auto fat_input = geode::TextInput::create(60.f, "");
70+
fat_input->setCommonFilter(CommonFilter::Float);
71+
fat_input->setString(fmt::to_string(m_fat));
72+
fat_input->setCallback([this](std::string const& str) {
73+
m_fat = geode::utils::numFromString<float>(str).unwrapOr(m_fat);
11174
this->update_labels();
112-
};
113-
this->addChild(fat_input);
75+
});
76+
layer->addChildAtPosition(fat_input, Anchor::Center, ccp(60, -16));
11477

11578
float button_width = 68;
116-
menu->addChild(
117-
make_factory(CCMenuItemSpriteExtra::create(
79+
menu->addChildAtPosition(
80+
CCMenuItemSpriteExtra::create(
11881
ButtonSprite::create("Apply", button_width, true, "goldFont.fnt", "GJ_button_01.png", 0, 0.75f),
11982
this, menu_selector(CircleToolPopup::on_apply)
120-
))
121-
.setPosition(button_width / 2.f + 20, -85)
83+
),
84+
Anchor::Center, ccp(button_width / 2.f + 20, -85)
12285
);
12386

124-
menu->addChild(
125-
make_factory(CCMenuItemSpriteExtra::create(
87+
menu->addChildAtPosition(
88+
CCMenuItemSpriteExtra::create(
12689
ButtonSprite::create("Cancel", button_width, true, "goldFont.fnt", "GJ_button_01.png", 0, 0.75f),
127-
this, menu_selector(CircleToolPopup::on_close)
128-
))
129-
.setPosition(button_width / -2.f - 20, -85)
90+
this, menu_selector(CircleToolPopup::onClose)
91+
),
92+
Anchor::Center, ccp(button_width / -2.f - 20, -85)
13093
);
13194

13295
m_label = CCLabelBMFont::create("copies: 69\nobjects: 69420", "chatFont.fnt");
13396
m_label->setAlignment(kCCTextAlignmentLeft);
134-
m_label->setPosition(ccp(-83, -41) + offset);
135-
layer->addChild(m_label);
97+
layer->addChildAtPosition(m_label, Anchor::Center, ccp(-83, -41));
13698
this->update_labels();
13799

138100
auto info_btn = CCMenuItemSpriteExtra::create(
139101
CCSprite::createWithSpriteFrameName("GJ_infoIcon_001.png"), this, menu_selector(CircleToolPopup::on_info)
140102
);
141-
info_btn->setPosition(ccp(-width / 2, height / 2) + ccp(20, -20));
142-
menu->addChild(info_btn);
103+
menu->addChildAtPosition(info_btn, Anchor::TopRight, ccp(-19, -19));
143104

144105
info_btn = CCMenuItemSpriteExtra::create(
145106
NodeFactory<CCSprite>::start(CCSprite::createWithSpriteFrameName("GJ_infoIcon_001.png"))
146107
.setScale(0.6f),
147108
this, menu_selector(CircleToolPopup::on_info2)
148109
);
149-
info_btn->setPosition(ccp(60, 10) + ccp(42, -1.5));
150-
menu->addChild(info_btn);
151-
152-
this->setTouchEnabled(true);
110+
menu->addChildAtPosition(info_btn, Anchor::Center, ccp(60, 10) + ccp(42, -1.5));
153111

154112
return true;
155113
}
156114

157-
void keyBackClicked() override {
158-
this->setTouchEnabled(false);
159-
this->removeFromParentAndCleanup(true);
160-
}
161-
162-
void on_close(CCObject*) {
163-
this->keyBackClicked();
164-
}
165-
166115
void update_labels() {
167116
auto objs = GameManager::sharedState()->getEditorLayer()->m_editorUI->getSelectedObjects();
168117
const auto amt = static_cast<size_t>(std::ceilf(m_angle / m_step) - 1.f);
169118
const auto obj_count = amt * objs->count();
170-
m_label->setString(("Copies: " + std::to_string(amt) + "\nObjects: " + std::to_string(obj_count)).c_str());
119+
m_label->setString(fmt::format("Copies: {}\nObjects: {}", amt, obj_count).c_str());
171120
}
172121

173122
void on_apply(CCObject*) {
@@ -177,21 +126,21 @@ class CircleToolPopup : public FLAlertLayer, TextInputDelegate, FLAlertLayerProt
177126
if (objs && objs->count()) {
178127
const auto obj_count = objs->count() * amt;
179128
if (obj_count > 5000) {
180-
FLAlertLayer::create(this, "Warning",
181-
"This will create <cy>" + std::to_string(obj_count) + "</c> objects, are you sure?",
182-
"Cancel", "Ok"
183-
)->show();
129+
createQuickPopup("Warning",
130+
fmt::format("This will create <cy>{}</c> objects, are you sure?", obj_count),
131+
"Cancel", "Ok",
132+
[this](auto*, bool btn2) {
133+
if (btn2) {
134+
this->perform();
135+
}
136+
}
137+
);
184138
} else {
185139
perform();
186140
}
187141
}
188142
}
189143

190-
void FLAlert_Clicked(FLAlertLayer*, bool btn2) override {
191-
if (btn2)
192-
perform();
193-
}
194-
195144
void perform() {
196145
auto* editor = GameManager::sharedState()->getEditorLayer();
197146
auto* editor_ui = editor->m_editorUI;
@@ -204,7 +153,7 @@ class CircleToolPopup : public FLAlertLayer, TextInputDelegate, FLAlertLayerProt
204153
editor_ui->onDuplicate(nullptr);
205154
auto selected = editor_ui->getSelectedObjects();
206155
editor_ui->rotateObjects(selected, m_step, {0.f, 0.f});
207-
156+
208157
const float angle = i * m_step;
209158

210159
if (m_fat != 0.f) {
@@ -228,15 +177,15 @@ class CircleToolPopup : public FLAlertLayer, TextInputDelegate, FLAlertLayerProt
228177
}
229178

230179
void on_info(CCObject*) {
231-
FLAlertLayer::create(this, "info",
180+
FLAlertLayer::create(nullptr, "info",
232181
"This will repeatedly copy-paste and rotate the selected objects,\n"
233182
"rotating by <cy>Step</c> degrees each time, until it gets to <cy>Arc</c> degrees.",
234183
"ok", nullptr, 300.f
235184
)->show();
236185
}
237186

238187
void on_info2(CCObject*) {
239-
FLAlertLayer::create(this, "info",
188+
FLAlertLayer::create(nullptr, "info",
240189
"This will move the selection up and down with the rotation angle, as to create an <cy>ellipse</c>.\n"
241190
"This number will control how much it goes up and down, thus controlling how <cg>\"squished\"</c> the circle is.\n"
242191
"This works best with a single object as the center, marked as <co>group parent</c>.",

circle-tool/mod.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
"mac": "2.2081",
77
"ios": "2.2081"
88
},
9-
"version": "v1.2.2",
9+
"version": "v1.2.3",
1010
"id": "mat.circle-tool",
1111
"name": "Circle Tool",
1212
"developer": "mat",

0 commit comments

Comments
 (0)