Skip to content

Commit

Permalink
Merge pull request #1 from camila314/main
Browse files Browse the repository at this point in the history
Cleaner method of scale9 sprite fix
  • Loading branch information
Alphalaneous authored May 7, 2024
2 parents 5e294a6 + 6c1ce2c commit 419d9e1
Showing 1 changed file with 34 additions and 173 deletions.
207 changes: 34 additions & 173 deletions src/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,20 +6,6 @@
#include <Geode/modify/CCSpriteBatchNode.hpp>
#include <Geode/modify/CCScale9Sprite.hpp>

#define public_cast(value, member) [](auto* v) { \
class FriendClass__; \
using T = typename std::remove_pointer<decltype(v)>::type; \
class FriendeeClass__: public T { \
protected: \
friend FriendClass__; \
}; \
class FriendClass__ { \
public: \
auto& get(FriendeeClass__* v) { return v->member; } \
} c; \
return c.get(reinterpret_cast<FriendeeClass__*>(v)); \
}(value)

using namespace geode::prelude;

bool s_isInCreateTextLayers = false;
Expand All @@ -35,177 +21,52 @@ class $modify(GJBaseGameLayer) {
}
};

class $modify(MyCCScale9Sprite, CCScale9Sprite){

void visit(){

if(this->*(&MyCCScale9Sprite::m_positionsAreDirty)){
updateSprites();
this->*(&MyCCScale9Sprite::m_positionsAreDirty) = false;
class $modify(CCScale9Sprite) {
bool m_hasFixed = false;
void visit() {
CCScale9Sprite::visit();
if (!m_fields->m_hasFixed) {
fixSprites();
m_fields->m_hasFixed = true;
}
CCNode::visit();
}

void updateSprites(){

CCSprite* topLeft = public_cast(this, _topLeft);
topLeft->setID("top-left");
CCSprite* top = public_cast(this, _top);
top->setID("top");
CCSprite* topRight = public_cast(this, _topRight);
topRight->setID("top-right");
CCSprite* left = public_cast(this, _left);
left->setID("left");
CCSprite* center = public_cast(this, _centre);
center->setID("center");
CCSprite* right = public_cast(this, _right);
right->setID("right");
CCSprite* bottomLeft = public_cast(this, _bottomLeft);
bottomLeft->setID("bottom-left");
CCSprite* bottom = public_cast(this, _bottom);
bottom->setID("bottom");
CCSprite* bottomRight = public_cast(this, _bottomRight);
bottomRight->setID("bottom-right");

if(!(topLeft && topRight && bottomRight && bottomLeft && center)) {
return;
}

CCSize size = this->m_obContentSize;

float edgeHeight = top->getContentSize().height + bottom->getContentSize().height;

float edgeWidth = left->getContentSize().width + right->getContentSize().width;

bool isSquishedVertically = false;
bool isSquishedHorizontally = false;

if(edgeHeight >= size.height){
isSquishedVertically = true;
}

if(edgeWidth >= size.width){
isSquishedHorizontally = true;
}

float sizableWidth = size.width - topLeft->getContentSize().width - topRight->getContentSize().width;
float sizableHeight = size.height - topLeft->getContentSize().height - bottomRight->getContentSize().height;

float horizontalScale = sizableWidth / center->getContentSize().width;
float verticalScale = sizableHeight / center->getContentSize().height;

center->setScaleX(horizontalScale);
center->setScaleY(verticalScale);

float rescaledWidth = center->getContentSize().width * horizontalScale;
float rescaledHeight = center->getContentSize().height * verticalScale;

float leftWidth = bottomLeft->getContentSize().width;
float bottomHeight = bottomLeft->getContentSize().height;

bottomLeft->setAnchorPoint({0, 0});
bottomRight->setAnchorPoint({0, 0});
topLeft->setAnchorPoint({0, 0});
topRight->setAnchorPoint({0, 0});
left->setAnchorPoint({0, 0});
right->setAnchorPoint({0, 0});
top->setAnchorPoint({0, 0});
bottom->setAnchorPoint({0, 0});
center->setAnchorPoint({0, 0});

bottomLeft->setPosition({0, 0});
bottomRight->setPosition({leftWidth+rescaledWidth, 0});

topLeft->setPosition({0, bottomHeight+rescaledHeight});
topRight->setPosition({leftWidth+rescaledWidth, bottomHeight + rescaledHeight});

left->setPosition({0, bottomHeight});
left->setScaleY(verticalScale);

right->setPosition({leftWidth+rescaledWidth, bottomHeight});
right->setScaleY(verticalScale);

bottom->setPosition({leftWidth, 0});
bottom->setScaleX(horizontalScale);

top->setPosition({leftWidth, bottomHeight + rescaledHeight});
top->setScaleX(horizontalScale);
void transformSprite(CCSprite* sprite, CCSize transform, int idx) {
auto tRect = sprite->getTextureRect();

center->setPosition({leftWidth, bottomHeight});
tRect.size -= transform;

left->setVisible(true);
right->setVisible(true);
top->setVisible(true);
bottom->setVisible(true);
center->setVisible(true);
if (idx == 0)
sprite->setPosition(sprite->getPosition() + transform);
else if (idx == 1 && (transform.width > 0 || transform.height > 0))
sprite->setVisible(false);
else if (idx == 2)
tRect.origin += transform;

if(isSquishedVertically || isSquishedHorizontally){
center->setVisible(false);
}

if(isSquishedVertically){
left->setVisible(false);
right->setVisible(false);

fixTopSprite(top);
fixTopSprite(topRight);
fixTopSprite(topLeft);

fixBottomSprite(bottom);
fixBottomSprite(bottomRight);
fixBottomSprite(bottomLeft);
}

if(isSquishedHorizontally){
top->setVisible(false);
bottom->setVisible(false);

fixLeftSprite(left);
fixLeftSprite(topLeft);
fixLeftSprite(bottomLeft);

fixRightSprite(right);
fixRightSprite(topRight);
fixRightSprite(bottomRight);
}
sprite->setTextureRect(tRect);
}

void fixTopSprite(CCSprite* spr){
float overlappingHeight = spr->getContentSize().height*2 - this->getContentSize().height;

auto rect = spr->getTextureRect();
rect.size = CCSize{rect.size.width, rect.size.height - overlappingHeight/2};
spr->setPositionY(spr->getPositionY() + overlappingHeight/2);
spr->setTextureRect(rect);
}
void fixSprites() {
CCSprite* sprites[3][3] = {
{_topLeft, _top, _topRight},
{_left, _centre, _right},
{_bottomLeft, _bottom, _bottomRight}
};

void fixBottomSprite(CCSprite* spr){
float overlappingHeight = spr->getContentSize().height*2 - this->getContentSize().height;

auto rect = spr->getTextureRect();
rect.size = CCSize{rect.size.width, rect.size.height - overlappingHeight/2};
rect.origin = CCPoint{rect.origin.x, rect.origin.y + overlappingHeight/2};
auto halfSize = getContentSize() / 2;

spr->setTextureRect(rect);
}
for (int i = 0; i < 3; ++i) {
for (int j = 0; j < 3; ++j) {
auto sprite = sprites[i][j];

void fixRightSprite(CCSprite* spr){
float overlappingWidth = spr->getContentSize().width*2 - this->getContentSize().width;

auto rect = spr->getTextureRect();
rect.size = CCSize{rect.size.width - overlappingWidth/2, rect.size.height};
spr->setPositionX(spr->getPositionX() + overlappingWidth/2);
spr->setTextureRect(rect);
}
auto tRect = sprite->getTextureRect();
auto diff = tRect.size - halfSize;
diff = CCSize(fmax(0, diff.width), fmax(0, diff.height));

void fixLeftSprite(CCSprite* spr){
float overlappingWidth = spr->getContentSize().width*2 - this->getContentSize().width;

auto rect = spr->getTextureRect();
rect.size = CCSize{rect.size.width - overlappingWidth/2, rect.size.height};
rect.origin = CCPoint{rect.origin.x + overlappingWidth/2, rect.origin.y};

spr->setTextureRect(rect);
transformSprite(sprite, CCSize(diff.width, 0), j);
transformSprite(sprite, CCSize(0, diff.height), i);
}
}
}
};

Expand Down

0 comments on commit 419d9e1

Please sign in to comment.