Skip to content

Commit a77c339

Browse files
committed
Merge branch '1.4.0-dev' into android
2 parents f563c46 + 017f8aa commit a77c339

File tree

4 files changed

+300
-9
lines changed

4 files changed

+300
-9
lines changed

.github/workflows/test-offsets.yml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,9 @@ name: Test Offsets
33
on:
44
workflow_dispatch:
55
push:
6+
paths:
7+
- 'bindings/**' # only when adjusting bindings
8+
- 'loader/test/members/**'
69
branches:
710
- '**' # every branch
811
- '!no-build-**' # unless marked as no-build

bindings/GeometryDash.bro

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1002,15 +1002,15 @@ class CreateMenuItem : CCMenuItemSpriteExtra {
10021002
class CreatorLayer : cocos2d::CCLayer, cocos2d::CCSceneTransitionDelegate, DialogDelegate {
10031003
void onBack(cocos2d::CCObject*) = win 0x4fae0;
10041004
void onChallenge(cocos2d::CCObject*) = mac 0x142960, win 0x4f1b0;
1005-
void onLeaderboards(cocos2d::CCObject*) = win 0x4ed20;
1005+
void onLeaderboards(cocos2d::CCObject*) = mac 0x142920, win 0x4ed20;
10061006
void onMyLevels(cocos2d::CCObject*) = mac 0x142b70, win 0x4eaa0;
10071007
void onSavedLevels(cocos2d::CCObject*) = mac 0x142860, win 0x4ebe0;
1008-
void onDailyLevel(cocos2d::CCObject*) = win 0x4f170;
1009-
void onWeeklyLevel(cocos2d::CCObject*) = win 0x4f190;
1010-
void onFeaturedLevels(cocos2d::CCObject*) = win 0x4edf0;
1011-
void onFameLevels(cocos2d::CCObject*) = win 0x4ee70;
1012-
void onMapPacks(cocos2d::CCObject*) = win 0x4efb0;
1013-
void onOnlineLevels(cocos2d::CCObject*) = win 0x4ef60;
1008+
void onDailyLevel(cocos2d::CCObject*) = mac 0x142980, win 0x4f170;
1009+
void onWeeklyLevel(cocos2d::CCObject*) = mac 0x1429a0, win 0x4f190;
1010+
void onFeaturedLevels(cocos2d::CCObject*) = mac 0x142a20, win 0x4edf0;
1011+
void onFameLevels(cocos2d::CCObject*) = mac 0x142a80, win 0x4ee70;
1012+
void onMapPacks(cocos2d::CCObject*) = mac 0x1429c0, win 0x4efb0;
1013+
void onOnlineLevels(cocos2d::CCObject*) = mac 0x142ae0, win 0x4ef60;
10141014
void onGauntlets(cocos2d::CCObject*) = mac 0x142b20, win 0x4f0a0;
10151015
void onSecretVault(cocos2d::CCObject*) = win 0x4f1d0;
10161016
void onTreasureRoom(cocos2d::CCObject*) = win 0x4f540;
@@ -1138,7 +1138,7 @@ class CustomizeObjectLayer : FLAlertLayer, TextInputDelegate, HSVWidgetPopupDele
11381138

11391139
[[link(android)]]
11401140
class DailyLevelPage : FLAlertLayer, FLAlertLayerProtocol, GJDailyLevelDelegate, LevelDownloadDelegate {
1141-
static DailyLevelPage* create(bool weekly) = win 0x6a860;
1141+
static DailyLevelPage* create(bool weekly) = mac 0x108ac0, win 0x6a860;
11421142
bool init(bool weekly) = mac 0x108C90, win 0x6a900;
11431143
void updateTimers(float) = mac 0x109780, win 0x6bef0;
11441144
virtual void show() = mac 0x10a4b0, win 0x3f360;
@@ -3694,7 +3694,8 @@ class GameStatsManager : cocos2d::CCNode {
36943694
int getBaseCurrencyForLevel(GJGameLevel*) = mac 0x43470, win 0xf8530;
36953695
GJChallengeItem* getChallenge(int id) = mac 0x451f0, win 0xa2fb0;
36963696
void getSecretCoinKey(char const*) = mac 0x429f0;
3697-
int getStat(char const*) = mac 0x3d310, win 0xf3580;
3697+
int getStat(char const* type) = mac 0x3d310, win 0xf3580;
3698+
void setStat(char const* type, int amount) = win 0xf3690;
36983699
void hasPendingUserCoin(char const*) = mac 0x42730, win 0xf7c50;
36993700
void hasSecretCoin(char const*) = mac 0x40730, win 0xf7dc0;
37003701
void hasUserCoin(char const*) = mac 0x427e0, win 0xf7ae0;
@@ -3706,6 +3707,7 @@ class GameStatsManager : cocos2d::CCNode {
37063707
void storeSecretCoin(char const*) = mac 0x42a10;
37073708
void storeUserCoin(char const*) = mac 0x42890;
37083709
bool isItemUnlocked(UnlockType type, int id) = win 0xfbb80;
3710+
void checkAchievement(char const* type) = win 0xf37c0;
37093711

37103712
PAD = mac 0x50, win 0x28, android 0x24;
37113713
cocos2d::CCDictionary* m_dailyChests;

loader/include/Geode/ui/TextArea.hpp

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
#pragma once
2+
3+
#include <Geode/DefaultInclude.hpp>
4+
#include <cocos2d.h>
5+
6+
namespace geode {
7+
/**
8+
* A class which provides a textarea with proper alignment and some extra features like:
9+
*
10+
* - Max lines
11+
* - Changing all aspects after creation
12+
* - Custom text alignment
13+
* - Automatic line wrapping and cutoff
14+
* - Line padding
15+
*
16+
* Contact me on Discord (\@smjs) if you have any questions, suggestions or bugs.
17+
*/
18+
class GEODE_DLL SimpleTextArea : public cocos2d::CCNode {
19+
cocos2d::CCMenu* m_container;
20+
std::string m_font;
21+
std::string m_text;
22+
std::vector<cocos2d::CCLabelBMFont*> m_lines;
23+
cocos2d::CCTextAlignment m_alignment;
24+
size_t m_maxLines;
25+
float m_scale;
26+
float m_lineHeight;
27+
float m_linePadding;
28+
bool m_artificialWidth;
29+
public:
30+
static SimpleTextArea* create(const std::string& font, const std::string& text, const float scale);
31+
static SimpleTextArea* create(const std::string& font, const std::string& text, const float scale, const float width);
32+
33+
void setFont(const std::string& font);
34+
std::string getFont();
35+
void setAlignment(const cocos2d::CCTextAlignment alignment);
36+
cocos2d::CCTextAlignment getAlignment();
37+
void setText(const std::string& text);
38+
std::string getText();
39+
void setMaxLines(const size_t maxLines);
40+
size_t getMaxLines();
41+
void setWidth(const float width);
42+
float getWidth();
43+
void setScale(const float scale);
44+
float getScale();
45+
void setLinePadding(const float padding);
46+
float getLinePadding();
47+
std::vector<cocos2d::CCLabelBMFont*> getLines();
48+
float getHeight();
49+
float getLineHeight();
50+
private:
51+
static SimpleTextArea* create(const std::string& font, const std::string& text, const float scale, const float width, const bool artificialWidth);
52+
53+
SimpleTextArea(const std::string& font, const std::string& text, const float scale, const float width, const bool artificialWidth);
54+
cocos2d::CCLabelBMFont* createLabel(const std::string& text, const float top);
55+
cocos2d::CCLabelBMFont* moveOverflow(cocos2d::CCLabelBMFont* line, const char c, const float top);
56+
float calculateOffset(cocos2d::CCLabelBMFont* label);
57+
void updateLines();
58+
void updateContents();
59+
};
60+
}

loader/src/ui/nodes/TextArea.cpp

Lines changed: 226 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,226 @@
1+
#include <Geode/ui/TextArea.hpp>
2+
3+
using namespace geode::prelude;
4+
5+
SimpleTextArea* SimpleTextArea::create(const std::string& font, const std::string& text, const float scale = 1) {
6+
return SimpleTextArea::create(font, text, scale, 500, false);
7+
}
8+
9+
SimpleTextArea* SimpleTextArea::create(const std::string& font, const std::string& text, const float scale, const float width) {
10+
return SimpleTextArea::create(font, text, scale, width, true);
11+
}
12+
13+
SimpleTextArea* SimpleTextArea::create(const std::string& font, const std::string& text, const float scale, const float width, const bool artificialWidth) {
14+
SimpleTextArea* instance = new SimpleTextArea(font, text, scale, width, artificialWidth);
15+
16+
if (instance && instance->init()) {
17+
instance->autorelease();
18+
19+
return instance;
20+
} else {
21+
CC_SAFE_DELETE(instance);
22+
23+
return nullptr;
24+
}
25+
}
26+
27+
SimpleTextArea::SimpleTextArea(const std::string& font, const std::string& text, const float scale, const float width, const bool artificialWidth) {
28+
m_font = font;
29+
m_text = text;
30+
m_maxLines = 0;
31+
m_scale = scale;
32+
m_linePadding = 0;
33+
m_alignment = kCCTextAlignmentLeft;
34+
m_artificialWidth = artificialWidth;
35+
m_container = CCMenu::create();
36+
37+
this->setAnchorPoint({ 0.5f, 0.5f });
38+
m_container->setPosition({ 0, 0 });
39+
m_container->setAnchorPoint({ 0, 1 });
40+
m_container->setContentSize({ width, 0 });
41+
42+
this->addChild(m_container);
43+
this->updateContents();
44+
}
45+
46+
void SimpleTextArea::setFont(const std::string& font) {
47+
m_font = font;
48+
49+
this->updateContents();
50+
}
51+
52+
std::string SimpleTextArea::getFont() {
53+
return m_font;
54+
}
55+
56+
void SimpleTextArea::setAlignment(const CCTextAlignment alignment) {
57+
m_alignment = alignment;
58+
59+
this->updateContents();
60+
}
61+
62+
CCTextAlignment SimpleTextArea::getAlignment() {
63+
return m_alignment;
64+
}
65+
66+
void SimpleTextArea::setText(const std::string& text) {
67+
m_text = text;
68+
69+
this->updateContents();
70+
}
71+
72+
std::string SimpleTextArea::getText() {
73+
return m_text;
74+
}
75+
76+
void SimpleTextArea::setMaxLines(const size_t maxLines) {
77+
m_maxLines = maxLines;
78+
79+
this->updateContents();
80+
}
81+
82+
size_t SimpleTextArea::getMaxLines() {
83+
return m_maxLines;
84+
}
85+
86+
void SimpleTextArea::setWidth(const float width) {
87+
m_artificialWidth = true;
88+
89+
this->setContentSize({ width, this->getContentSize().height });
90+
m_container->setContentSize(this->getContentSize());
91+
}
92+
93+
float SimpleTextArea::getWidth() {
94+
return m_container->getContentSize().width;
95+
}
96+
97+
void SimpleTextArea::setScale(const float scale) {
98+
m_scale = scale;
99+
100+
this->updateContents();
101+
}
102+
103+
float SimpleTextArea::getScale() {
104+
return m_scale;
105+
}
106+
107+
void SimpleTextArea::setLinePadding(const float padding) {
108+
m_linePadding = padding;
109+
110+
this->updateContents();
111+
}
112+
113+
float SimpleTextArea::getLinePadding() {
114+
return m_linePadding;
115+
}
116+
117+
std::vector<CCLabelBMFont*> SimpleTextArea::getLines() {
118+
return m_lines;
119+
}
120+
121+
float SimpleTextArea::getHeight() {
122+
return m_container->getContentSize().height;
123+
}
124+
125+
float SimpleTextArea::getLineHeight() {
126+
return m_lineHeight;
127+
}
128+
129+
CCLabelBMFont* SimpleTextArea::createLabel(const std::string& text, const float top) {
130+
CCLabelBMFont* label = CCLabelBMFont::create(text.c_str(), m_font.c_str());
131+
132+
label->setScale(m_scale);
133+
label->setPosition({ 0, top });
134+
135+
return label;
136+
}
137+
138+
CCLabelBMFont* SimpleTextArea::moveOverflow(CCLabelBMFont* line, const char c, const float top) {
139+
const std::string text = line->getString();
140+
const char back = text.back();
141+
const bool lastIsSpace = back == ' ';
142+
CCLabelBMFont* newLine = this->createLabel(std::string(!lastIsSpace, back).append(std::string(c != ' ', c)), top);
143+
144+
if (!lastIsSpace) {
145+
if (text[text.size() - 2] == ' ') {
146+
line->setString(text.substr(0, text.size() - 1).c_str());
147+
} else {
148+
line->setString((text.substr(0, text.size() - 1) + '-').c_str());
149+
}
150+
}
151+
152+
m_lines.push_back(newLine);
153+
154+
return newLine;
155+
}
156+
157+
float SimpleTextArea::calculateOffset(CCLabelBMFont* label) {
158+
return m_linePadding + label->getContentSize().height * m_scale;
159+
}
160+
161+
void SimpleTextArea::updateLines() {
162+
float top = 0;
163+
CCLabelBMFont* line = this->createLabel("", top);
164+
m_lines = { line };
165+
166+
for (const char c : m_text) {
167+
if (m_maxLines && m_lines.size() > m_maxLines) {
168+
CCLabelBMFont* last = m_lines.at(m_maxLines - 1);
169+
const std::string text = last->getString();
170+
171+
m_lines.pop_back();
172+
last->setString(text.substr(0, text.size() - 3).append("...").c_str());
173+
174+
break;
175+
} else if (c == '\n') {
176+
line = this->createLabel("", top -= this->calculateOffset(line));
177+
178+
m_lines.push_back(line);
179+
} else if (m_artificialWidth && line->getContentSize().width >= this->getWidth()) {
180+
line = this->moveOverflow(line, c, top -= this->calculateOffset(line));
181+
} else {
182+
const std::string text = line->getString();
183+
184+
line->setString((text + c).c_str());
185+
}
186+
}
187+
}
188+
189+
void SimpleTextArea::updateContents() {
190+
this->updateLines();
191+
const size_t lineCount = m_lines.size();
192+
const float width = this->getWidth();
193+
194+
if (lineCount > 0) {
195+
m_lineHeight = m_lines.back()->getContentSize().height * m_scale;
196+
} else {
197+
m_lineHeight = 0;
198+
}
199+
200+
float height = m_lineHeight * lineCount + m_linePadding * (lineCount - 1);
201+
202+
this->setContentSize({ width, height });
203+
m_container->setContentSize(this->getContentSize());
204+
m_container->removeAllChildren();
205+
206+
for (CCLabelBMFont* line : m_lines) {
207+
const float y = height + line->getPositionY();
208+
209+
switch (m_alignment) {
210+
case kCCTextAlignmentLeft: {
211+
line->setAnchorPoint({ 0, 1 });
212+
line->setPosition({ 0, y });
213+
} break;
214+
case kCCTextAlignmentCenter: {
215+
line->setAnchorPoint({ 0.5f, 1 });
216+
line->setPosition({ width / 2, y });
217+
} break;
218+
case kCCTextAlignmentRight: {
219+
line->setAnchorPoint({ 1, 1 });
220+
line->setPosition({ width, y });
221+
} break;
222+
}
223+
224+
m_container->addChild(line);
225+
}
226+
}

0 commit comments

Comments
 (0)