Scale9Sprite refactor (#16891)

* Squashed commit of the following:

commit 026eee59c9ece7fc59d71fead41104f375f72eb5
Author: Ricardo Quesada <ricardoquesada@gmail.com>
Date:   Tue Nov 22 21:45:12 2016 -0800

    yay!

    everything works!

commit a645c99d44f0d7674e6238afae7628d8d2a030b1
Author: Ricardo Quesada <ricardoquesada@gmail.com>
Date:   Tue Nov 22 14:55:31 2016 -0800

    more fixes in Scale9Sprite

commit 3a688f4ea70c0abe311232c65ed14a7e9acc7611
Author: Ricardo Quesada <ricardoquesada@gmail.com>
Date:   Mon Nov 21 23:06:45 2016 -0800

    rotated sprites

commit 45e2085df3aa4b52236c817f7db7c1f6602c1e95
Author: Ricardo Quesada <ricardoquesada@gmail.com>
Date:   Mon Nov 21 17:10:44 2016 -0800

    android patch 9: fixes

    is not 100% backward compatible since the previous version
    had some artifacts. fixed the artifacts. now it renders ok

commit 4655d894387fa40a7e63b074a36bfed20e41d5f9
Author: Ricardo Quesada <ricardoquesada@gmail.com>
Date:   Mon Nov 21 16:31:29 2016 -0800

    sprite: correct size for "fake scale9"

commit cb98aba27cc1c82a986268d5b74afb55b6cca2f3
Author: Ricardo Quesada <ricardoquesada@gmail.com>
Date:   Fri Nov 18 21:55:51 2016 -0800

    sprite: adds setStrechEnabled for backward compatibility

    and other fixes

commit c0fe67aac54cd62e3846810d56f87133f3a7343b
Author: Ricardo Quesada <ricardoquesada@gmail.com>
Date:   Fri Nov 18 18:49:42 2016 -0800

    implemts missing functions in scale9sprite

commit e471ef318725ccabc9eca2c062e285e9ca4f9a81
Author: Ricardo Quesada <ricardoquesada@gmail.com>
Date:   Fri Nov 18 18:42:30 2016 -0800

    "batched" works

commit 33124bfb14d1f275d4b0ffca8989975625a8a76d
Author: Ricardo Quesada <ricardoquesada@gmail.com>
Date:   Wed Nov 16 18:59:38 2016 -0800

    more fixes

commit 149f8206269843af63a1739885c00ed8d94c239c
Author: Ricardo Quesada <ricardoquesada@gmail.com>
Date:   Wed Nov 16 18:37:12 2016 -0800

    scale 9 rotated not fixed yet.

    but making progress

commit 27f98275d94ce00c8d5ff0b6f74b5c22723cc3c3
Author: Ricardo Quesada <ricardoquesada@gmail.com>
Date:   Wed Nov 16 15:32:57 2016 -0800

    sprite: streching works ok with normal sprites

commit 2519498cac8b77a32dee5bdf1805be56fbda5ed6
Author: Ricardo Quesada <ricardoquesada@gmail.com>
Date:   Wed Nov 16 12:12:28 2016 -0800

    somes fixes... still not working

commit 43580d0b4aa976b0200717611a286bf1035c472d
Author: Ricardo Quesada <ricardoquesada@gmail.com>
Date:   Tue Nov 15 23:15:22 2016 -0800

    more bug fixes related to untrimmed setCenterRect...

    ...in SCale9Sprite

commit 407247616e506afaa0415c58ad7fce38efed0cd9
Author: Ricardo Quesada <ricardoquesada@gmail.com>
Date:   Tue Nov 15 22:13:38 2016 -0800

    spritecale9: untrimmed vs. trimmed capInsets

    WIP. there still a few bugs

commit 3d845b2af3500be287fabb04bb6ba0ec04dbb401
Author: Ricardo Quesada <ricardoquesada@gmail.com>
Date:   Mon Nov 14 23:11:17 2016 -0800

    started progressbar

commit 0a44b00daf723869b7105689890f29cd53a62608
Author: Ricardo Quesada <ricardoquesada@gmail.com>
Date:   Mon Nov 14 17:43:23 2016 -0800

    adds EditBox test

commit 330304bd9b2e762de95c2f27f1ae3ceee83b2fbf
Author: Ricardo Quesada <ricardoquesada@gmail.com>
Date:   Wed Nov 9 16:57:08 2016 -0800

    adds elastic to scroll view

commit a06a35f8691ff56a143953c44acd947b519150b6
Author: Ricardo Quesada <ricardoquesada@gmail.com>
Date:   Wed Nov 9 15:58:29 2016 -0800

    yay! scrollview works

commit 37748a885c62eca8c00d2c9c11ee103f1d95e71c
Author: Ricardo Quesada <ricardoquesada@gmail.com>
Date:   Wed Nov 9 15:33:58 2016 -0800

    yet more scrollview fixes

commit a6e563b497adef7b141ac7c92c844d479b244c59
Author: Ricardo Quesada <ricardoquesada@gmail.com>
Date:   Wed Nov 9 14:48:28 2016 -0800

    initial scroll view

commit 4243edd7548e5533ca03c26d5042f8dc5517445a
Author: Ricardo Quesada <ricardoquesada@gmail.com>
Date:   Tue Nov 8 17:50:15 2016 -0800

    sanity check in frames.

    missing files

commit 159d88603ad22f3c01761b60bacec98d52b9041d
Author: Ricardo Quesada <ricardoquesada@gmail.com>
Date:   Mon Nov 7 19:21:00 2016 -0800

    three buttons working

commit 6764cfc7937a1a81d6993d5e32a21f17457b8e0d
Author: Ricardo Quesada <ricardoquesada@gmail.com>
Date:   Mon Nov 7 18:50:22 2016 -0800

    missing files

commit 11c1fa3812e706a7d34137fe2626f05ab73ee3e6
Author: Ricardo Quesada <ricardoquesada@gmail.com>
Date:   Mon Nov 7 18:49:59 2016 -0800

    button works!

commit 26b6de4c28fc973e332dd51fcd763a6249c0b4c2
Author: Ricardo Quesada <ricardoquesada@gmail.com>
Date:   Mon Nov 7 18:19:47 2016 -0800

    Scale9: more fixes.

    complies with odd Rect::ZERO behavior

commit ce561268096afe322f25034eeab3508a60027afd
Author: Ricardo Quesada <ricardoquesada@gmail.com>
Date:   Mon Nov 7 11:50:42 2016 -0800

    label: setTitleLabel

commit 51b5536cd2af36896002621f75c7310960c3f5e7
Author: Ricardo Quesada <ricardoquesada@gmail.com>
Date:   Wed Nov 2 17:41:08 2016 -0700

    UIButton kind of working

commit 7562a49a761ef70c383a99d2addefc63d77e279f
Author: Ricardo Quesada <ricardoquesada@gmail.com>
Date:   Wed Nov 2 11:11:42 2016 -0700

    missing resoruces

commit a9890dee5da0104bff6872cc04e8786a6c0a9018
Author: Ricardo Quesada <ricardoquesada@gmail.com>
Date:   Wed Nov 2 10:54:55 2016 -0700

    setCenterRect to .cpp file

commit c9c4bb55ed3fc55709eca46c43d1bfe5301c317f
Author: Ricardo Quesada <ricardoquesada@gmail.com>
Date:   Wed Nov 2 00:19:51 2016 -0700

    removed unused paramter

commit e47732934cca79c08e6fe96e46ebdf075508e568
Author: Ricardo Quesada <ricardoquesada@gmail.com>
Date:   Fri Oct 28 18:19:31 2016 -0700

    flipping works!

commit c9769bacd321aeddf84e1772dd270f12194d2f04
Author: Ricardo Quesada <ricardoquesada@gmail.com>
Date:   Fri Oct 28 17:57:53 2016 -0700

    spirte flip fixes... not finished yet

commit 1cbdc8e12cc6d0d2728c06dfabaada001784a178
Author: Ricardo Quesada <ricardoquesada@gmail.com>
Date:   Fri Oct 28 09:53:16 2016 -0700

    centerRect changes

commit aeb1b14c00331dabba640f52d79ab0e255fa3407
Author: Ricardo Quesada <ricardoquesada@gmail.com>
Date:   Fri Oct 28 09:10:41 2016 -0700

    changes from v3

commit e7a61c4a20d786c2bc1d6f57e33bf3ac95cb6f21
Author: Ricardo Quesada <ricardoquesada@gmail.com>
Date:   Wed Oct 26 17:01:15 2016 -0700

    sprite: rotated slice 9 works as expected

commit 91049389426051deb49a9d951364bf60abaf4532
Author: Ricardo Quesada <ricardoquesada@gmail.com>
Date:   Wed Oct 26 15:39:54 2016 -0700

    more bug fixes in scale9sprite support

commit 9feb12449078441c439df16dc7bcfb4506c7a226
Author: Ricardo Quesada <ricardoquesada@gmail.com>
Date:   Wed Oct 26 13:22:52 2016 -0700

    Android's Patch 9 works as expected

commit 1cf46afe3e7f7f5f714d30779caefc25a9bb1b3b
Author: Ricardo Quesada <ricardoquesada@gmail.com>
Date:   Wed Oct 26 10:18:47 2016 -0700

    Sprite: uses capInsets instead of centerRect

    just to share the same API as Scale9Sprite

commit e944fa0248a7eb58012aacb229de1a9b814e0aef
Author: Ricardo Quesada <ricardoquesada@gmail.com>
Date:   Tue Oct 25 18:59:42 2016 -0700

    scale9sprite support fixes

commit b08765740d480b6ae1491800161b40d88f458767
Author: Ricardo Quesada <ricardoquesada@gmail.com>
Date:   Tue Oct 25 17:38:47 2016 -0700

    more scale9sprite fixes

commit 388a34d93de5e6007a2cecea959c929f26427cab
Author: Ricardo Quesada <ricardoquesada@gmail.com>
Date:   Tue Oct 25 17:20:01 2016 -0700

    UI::Scale9Sprite refactoring

    subclass of Sprite... much cleaner!

commit c84ec8ee654f74d4b38be2d0a3d7ffe6adbc6faf
Author: Ricardo Quesada <ricardoquesada@gmail.com>
Date:   Mon Oct 24 20:58:36 2016 -0700

    supports tiled sprites

commit d2b18eb47a647b29319488bd53edac9f304acb84
Author: Ricardo Quesada <ricardoquesada@gmail.com>
Date:   Mon Oct 24 19:21:57 2016 -0700

    testing tiled sprite

commit b4832ab2facc01cbb624db587ede01fe7acf23e8
Author: Ricardo Quesada <ricardoquesada@gmail.com>
Date:   Mon Oct 24 16:53:19 2016 -0700

    using correct top-left coordinates for setCenterRect

commit 29d8de86a71cc597b2338f59f7951a28ee0c93b2
Author: Ricardo Quesada <ricardoquesada@gmail.com>
Date:   Mon Oct 24 16:46:13 2016 -0700

    fixes from scale_sprite9 branch

commit ccbe1063bea7db75397ecaf9046aac3dd977a621
Author: Ricardo Quesada <ricardoquesada@gmail.com>
Date:   Thu Oct 20 19:01:50 2016 -0700

    updated example

commit 24f7f85d4eba80f8e543810dcbc1a02447900bdc
Author: Ricardo Quesada <ricardoquesada@gmail.com>
Date:   Thu Oct 20 18:47:28 2016 -0700

    more fixes in nine slice

commit df3358fae68f2d81baf3a8cbe033a4c400ea50da
Author: Ricardo Quesada <ricardoquesada@gmail.com>
Date:   Thu Oct 20 18:22:14 2016 -0700

    anchor point fixes

commit 4ac7409bc72425abb0dc747b956ec346fbd1b2fa
Author: Ricardo Quesada <ricardoquesada@gmail.com>
Date:   Thu Oct 20 17:01:48 2016 -0700

    support for slice-9 from creator

commit a3221375d3a9defc2e03df0b1c2da1b36dfdd491
Merge: 73e5389 d7490d9
Author: Ricardo Quesada <ricardoquesada@gmail.com>
Date:   Thu Oct 20 14:13:38 2016 -0700

    Merge branch 'sprite_scale9' into creator_cpp_support

commit d7490d94896ad0ce8705dc0695252cee34329b5e
Author: Ricardo Quesada <ricardoquesada@gmail.com>
Date:   Thu Oct 13 14:34:52 2016 -0700

    Adds slice9 support for Sprite.

    how to use it:

    // points coords
    sprite->setCenterRect(Rect(x,y,w,h));

    // normalized coords
    sprite->setCenterRectNormalized(Rect(x,y,w,h));
    starts scale9sprite in sprite

    more slice 9 changes

    sprite 9 slice works?

    kind of works

    correct anchor point

    slice 9 works, at least with non-rotated atlases

    streched works ok

    better Y invert code.

    cleaner, compatible with the previous code

    yay, scaling workings...

    need a better api now

    sets scale correctly

    yay! works as expected!

    more fixes and tests

    better test for box

    setContentSize() changes size in non-9-slice mode sprites as well

    setCenterRect() -> setCenterRectNormalized()

    yet another test

    adds setPositionNormalized()

    adds setCenterRect() tests

    remove devel team from xcode

    tests: add one more tests

    fun test!

    improved test

    yet another test for slice 9

commit 73e5389ef719880096067d0f7d0bffd6e1f3cfd1
Author: Ricardo Quesada <ricardoquesada@gmail.com>
Date:   Sun Oct 9 18:54:22 2016 -0700

    kind of ProgressBar support

commit 4db5e9e7369e93ceba1d9512ab88c26b843c43d5
Author: Ricardo Quesada <ricardoquesada@gmail.com>
Date:   Fri Oct 7 16:23:54 2016 -0700

    new generatred ui files

commit 75aa06f3d39df8c6aa898d5e6810b3cd8015c07b
Author: Ricardo Quesada <ricardoquesada@gmail.com>
Date:   Thu Oct 6 10:44:59 2016 -0700

    bette canvas support

commit 89beacac478fc7f58ef930963b6393f3da4a743c
Author: Ricardo Quesada <ricardoquesada@gmail.com>
Date:   Wed Oct 5 21:47:11 2016 -0700

    sprites tests

commit 5fe930ad50c2c1b6d868982709c7b659176f9889
Author: Ricardo Quesada <ricardoquesada@gmail.com>
Date:   Wed Oct 5 18:35:44 2016 -0700

    more label tests

commit d3f615a097d080d78f2ebd95f3e2388da45f92db
Author: Ricardo Quesada <ricardoquesada@gmail.com>
Date:   Wed Oct 5 18:08:24 2016 -0700

    label tests

commit 2a4018922ce8d36117f7092fc324e37cf75fdeab
Author: Ricardo Quesada <ricardoquesada@gmail.com>
Date:   Tue Oct 4 21:52:56 2016 -0700

    label fixes

commit 41fafbd023de63e376d014311605f2b156add307
Author: Ricardo Quesada <ricardoquesada@gmail.com>
Date:   Tue Oct 4 19:14:58 2016 -0700

    updated test

commit 06919fc28fffbc5a20cd14bdcc2ad2ff997e0da1
Author: Ricardo Quesada <ricardoquesada@gmail.com>
Date:   Tue Oct 4 18:50:45 2016 -0700

    creator tests: works

commit 6e362e7cc7f68dc216b569a7f7f90aaa110c0e4a
Author: Ricardo Quesada <ricardoquesada@gmail.com>
Date:   Tue Sep 27 23:15:56 2016 -0700

    autogen: new data

commit e78078b2ad84b4e364827a66f1c459de7384a91d
Author: Ricardo Quesada <ricardoquesada@gmail.com>
Date:   Mon Sep 26 18:18:57 2016 -0700

    fix: initial test for CPP support for Creator

* adds more documentation

* adds more documentation
This commit is contained in:
Ricardo Quesada 2016-11-23 17:59:00 -08:00 committed by minggo
parent cc3da8e5d8
commit e63a2d0dc2
11 changed files with 885 additions and 1838 deletions

View File

@ -49,6 +49,7 @@
useCustomWorkingDirectory = "NO"
ignoresPersistentStateOnLaunch = "NO"
debugDocumentVersioning = "YES"
enableAddressSanitizer = "YES"
debugServiceExtension = "internal"
allowLocationSimulation = "YES">
<BuildableProductRunnable

View File

@ -118,13 +118,13 @@ Sprite* Sprite::createWithSpriteFrame(SpriteFrame *spriteFrame)
Sprite* Sprite::createWithSpriteFrameName(const std::string& spriteFrameName)
{
SpriteFrame *frame = SpriteFrameCache::getInstance()->getSpriteFrameByName(spriteFrameName);
#if COCOS2D_DEBUG > 0
char msg[256] = {0};
sprintf(msg, "Invalid spriteFrameName: %s", spriteFrameName.c_str());
CCASSERT(frame != nullptr, msg);
#endif
return createWithSpriteFrame(frame);
}
@ -143,7 +143,7 @@ Sprite* Sprite::create()
bool Sprite::init()
{
initWithTexture(nullptr, Rect::ZERO);
return true;
}
@ -196,7 +196,7 @@ bool Sprite::initWithFile(const std::string &filename, const Rect& rect)
{
return false;
}
_fileName = filename;
_fileType = 0;
@ -219,7 +219,7 @@ bool Sprite::initWithSpriteFrameName(const std::string& spriteFrameName)
{
return false;
}
_fileName = spriteFrameName;
_fileType = 1;
@ -234,7 +234,7 @@ bool Sprite::initWithSpriteFrame(SpriteFrame *spriteFrame)
{
return false;
}
bool bRet = initWithTexture(spriteFrame->getTexture(), spriteFrame->getRect());
setSpriteFrame(spriteFrame);
@ -244,7 +244,7 @@ bool Sprite::initWithSpriteFrame(SpriteFrame *spriteFrame)
bool Sprite::initWithPolygon(const cocos2d::PolygonInfo &info)
{
bool ret = false;
Texture2D *texture = _director->getTextureCache()->addImage(info.getFilename());
if(texture && initWithTexture(texture))
{
@ -252,7 +252,7 @@ bool Sprite::initWithPolygon(const cocos2d::PolygonInfo &info)
Node::setContentSize(_polyInfo.getRect().size / _director->getContentScaleFactor());
ret = true;
}
return ret;
}
@ -263,25 +263,25 @@ bool Sprite::initWithTexture(Texture2D *texture, const Rect& rect, bool rotated)
if (Node::init())
{
_batchNode = nullptr;
_recursiveDirty = false;
setDirty(false);
_opacityModifyRGB = true;
_blendFunc = BlendFunc::ALPHA_PREMULTIPLIED;
_flippedX = _flippedY = false;
// default transform anchor: center
setAnchorPoint(Vec2::ANCHOR_MIDDLE);
// zwoptex default values
_offsetPosition.setZero();
// clean the Quad
memset(&_quad, 0, sizeof(_quad));
// Atlas: Color
_quad.bl.colors = Color4B::WHITE;
_quad.br.colors = Color4B::WHITE;
@ -291,16 +291,16 @@ bool Sprite::initWithTexture(Texture2D *texture, const Rect& rect, bool rotated)
// update texture (calls updateBlendFunc)
setTexture(texture);
setTextureRect(rect, rotated, rect.size);
// by default use "Self Render".
// if the sprite is added to a batchnode, then it will automatically switch to "batchnode Render"
setBatchNode(nullptr);
result = true;
}
_recursiveDirty = true;
setDirty(true);
return result;
}
@ -316,6 +316,7 @@ Sprite::Sprite(void)
, _quads(nullptr)
, _strechFactor(Vec2::ONE)
, _originalContentSize(Size::ZERO)
, _strechEnabled(true)
{
#if CC_SPRITE_DEBUG_DRAW
_debugDrawNode = DrawNode::create();
@ -425,20 +426,87 @@ void Sprite::setTextureRect(const Rect& rect, bool rotated, const Size& untrimme
void Sprite::updatePoly()
{
// There are 3 cases:
//
// A) a non 9-sliced, non streched
// contentsize doesn't not affect the streching, since there is no streching
// this was the original behavior, and we keep it for backwards compatibility reasons
// When non-streching is enabled, we have to change the offset in order to "fill the empty" space at the
// left-top of the texture
// B) non 9-sliced, streched
// the texture is streched to the content size
// C) 9-sliced, streched
// the sprite is 9-sliced and streched.
if (_numberOfSlices == 1) {
setTextureCoords(_rect, &_quad);
const Rect copyRect(0, 0, _rect.size.width * _strechFactor.x, _rect.size.height * _strechFactor.y);
setVertexCoords(copyRect, _rect.size, &_quad);
Rect copyRect;
if (_strechEnabled) {
// case B)
copyRect = Rect(0, 0, _rect.size.width * _strechFactor.x, _rect.size.height * _strechFactor.y);
} else {
// case A)
// modify origin to put the sprite in the correct offset
copyRect = Rect((_contentSize.width - _originalContentSize.width) / 2.0f,
(_contentSize.height - _originalContentSize.height) / 2.0f,
_rect.size.width,
_rect.size.height);
}
setVertexCoords(copyRect, &_quad);
_polyInfo.setQuad(&_quad);
} else {
// case C)
// in theory it can support 3 slices as well, but let's stick to 9 only
CCASSERT(_numberOfSlices == 9, "Invalid number of slices");
// How the texture is split
//
// u,v: are the texture coordinates
// w,h: are the width and heights
//
// w0 w1 w2
// v2 +----+------+--+
// | | | |
// | | | |
// | 6 | 7 | 8| h2
// | | | |
// v1 +----+------+--|
// | | | |
// | 3 | 4 | 5| h1
// v0 +----+------+--|
// | | | |
// | 0 | 1 | 2| h0
// | | | |
// +----+------+--+
// u0 u1 u2
//
//
// and when the texture is rotated, it will get transformed.
// not only the rects have a different position, but also u,v
// points to the bottom-left and not top-right of the texture
// so some swaping/origin/reordering needs to be done in order
// to support rotated slice-9 correctly
//
// w0 w1 w2
// v2 +------+----+--------+
// | | | |
// | 0 | 3 | 6 | h2
// v1 +------+----+--------+
// | | | |
// | 1 | 4 | 7 | h1
// | | | |
// v0 +------+----+--------+
// | 2 | 5 | 8 | h0
// +------+----+--------+
// u0 u1 u2
// center rect
const float cx1 = _centerRectNormalized.origin.x;
const float cy1 = _centerRectNormalized.origin.y;
const float cx2 = _centerRectNormalized.origin.x + _centerRectNormalized.size.width;
const float cy2 = _centerRectNormalized.origin.y + _centerRectNormalized.size.height;
float cx1 = _centerRectNormalized.origin.x;
float cy1 = _centerRectNormalized.origin.y;
float cx2 = _centerRectNormalized.origin.x + _centerRectNormalized.size.width;
float cy2 = _centerRectNormalized.origin.y + _centerRectNormalized.size.height;
// "O"riginal rect
const float oox = _rect.origin.x;
@ -446,7 +514,20 @@ void Sprite::updatePoly()
const float osw = _rect.size.width;
const float osh = _rect.size.height;
if (_rectRotated) {
std::swap(cx1, cy1);
std::swap(cx2, cy2);
// when the texture is rotated, then the centerRect starts from the "bottom" (left)
// but when it is not rotated, it starts from the top, so invert it
cy2 = 1 - cy2;
cy1 = 1 - cy1;
std::swap(cy1, cy2);
}
//
// textCoords Data: Y must be inverted.
//
const float u0 = oox + osw * 0;
const float u1 = oox + osw * cx1;
const float u2 = oox + osw * cx2;
@ -454,21 +535,56 @@ void Sprite::updatePoly()
const float v1 = ooy + osh * (1 - cy2);
const float v2 = ooy + osh * 0;
const Rect texRects[9] = {
Rect(u0, v0, osw * cx1, osh * cy1), // bottom-left
Rect(u1, v0, osw * (cx2-cx1), osh * cy1), // bottom
Rect(u2, v0, osw * (1-cx2), osh * cy1), // bottom-right
const float w0 = osw * cx1;
const float w1 = osw * (cx2-cx1);
const float w2 = osw * (1-cx2);
const float h0 = osh * cy1;
const float h1 = osh * (cy2-cy1);
const float h2 = osh * (1-cy2);
Rect(u0, v1, osw * cx1, osh * (cy2-cy1)), // left
Rect(u1, v1, osw * (cx2-cx1), osh * (cy2-cy1)), // center
Rect(u2, v1, osw * (1-cx2), osh * (cy2-cy1)), // right
const Rect texRects_normal[9] = {
Rect(u0, v0, w0, h0), // bottom-left
Rect(u1, v0, w1, h0), // bottom
Rect(u2, v0, w2, h0), // bottom-right
Rect(u0, v2, osw * cx1, osh * (1-cy2)), // top-left
Rect(u1, v2, osw * (cx2-cx1), osh * (1-cy2)), // top
Rect(u2, v2, osw * (1-cx2), osh * (1-cy2)), // top-right
Rect(u0, v1, w0, h1), // left
Rect(u1, v1, w1, h1), // center
Rect(u2, v1, w2, h1), // right
Rect(u0, v2, w0, h2), // top-left
Rect(u1, v2, w1, h2), // top
Rect(u2, v2, w2, h2), // top-right
};
// swap width and height because setTextureCoords()
// will expects the hight and width to be swapped
const Rect texRects_rotated[9] = {
Rect(u0, v2, h2, w0), // top-left
Rect(u0, v1, h1, w0), // left
Rect(u0, v0, h0, w0), // bottom-left
Rect(u1, v2, h2, w1), // top
Rect(u1, v1, h1, w1), // center
Rect(u1, v0, h0, w1), // bottom
Rect(u2, v2, h2, w2), // top-right
Rect(u2, v1, h1, w2), // right
Rect(u2, v0, h0, w2), // bottom-right
};
const Rect* texRects = _rectRotated ? texRects_rotated : texRects_normal;
//
// vertex Data.
//
// reset center rect since it is altered when when the texture
// is rotated
cx1 = _centerRectNormalized.origin.x;
cy1 = _centerRectNormalized.origin.y;
cx2 = _centerRectNormalized.origin.x + _centerRectNormalized.size.width;
cy2 = _centerRectNormalized.origin.y + _centerRectNormalized.size.height;
// sizes
float x0_s = osw * cx1;
@ -478,10 +594,8 @@ void Sprite::updatePoly()
float y1_s = osh * (cy2-cy1) * _strechFactor.y;
float y2_s = osh * (1-cy2);
// It is easier to call "updateXY", but it will be slower.
// so the flipping is calculated here at the cost of adding
// just a little bit more of complexity.
// is it flipped?
// swap sizes to calculate offset correctly
if (_flippedX)
std::swap(x0_s, x2_s);
@ -520,21 +634,9 @@ void Sprite::updatePoly()
Rect(x2, y2, x2_s, y2_s), // top-right
};
static const int normalIdx[] = {
0, 1, 2,
3, 4, 5,
6, 7 ,8
};
static const int rotatedIdx[] = {
6, 3, 0,
7, 4, 1,
8, 5, 2};
const int* idx = _rectRotated ? rotatedIdx : normalIdx;
for (int i=0; i<_numberOfSlices; ++i) {
int texIdx = idx[i];
setTextureCoords(texRects[texIdx], &_quads[i]);
setVertexCoords(verticesRects[i], _rect.size, &_quads[i]);
setTextureCoords(texRects[i], &_quads[i]);
setVertexCoords(verticesRects[i], &_quads[i]);
}
_polyInfo.setQuads(_quads, _numberOfSlices);
}
@ -581,6 +683,7 @@ void Sprite::setCenterRect(const cocos2d::Rect &rectInPoints)
if (!_originalContentSize.equals(Size::ZERO))
{
Rect rect = rectInPoints;
const float x = rect.origin.x / _rect.size.width;
const float y = rect.origin.y / _rect.size.height;
const float w = rect.size.width / _rect.size.width;
@ -628,37 +731,52 @@ void Sprite::setTextureCoords(const Rect& rectInPoints, V3F_C4B_T2F_Quad* outQua
return;
}
auto rectInPixels = CC_RECT_POINTS_TO_PIXELS(rectInPoints);
const auto rectInPixels = CC_RECT_POINTS_TO_PIXELS(rectInPoints);
float atlasWidth = (float)tex->getPixelsWide();
float atlasHeight = (float)tex->getPixelsHigh();
const float atlasWidth = (float)tex->getPixelsWide();
const float atlasHeight = (float)tex->getPixelsHigh();
float left, right, top, bottom;
float rw = rectInPixels.size.width;
float rh = rectInPixels.size.height;
// if the rect is rotated, it means that the frame is rotated 90 degrees (clockwise) and:
// - rectInpoints: origin will be the bottom-left of the frame (and not the top-right)
// - size: represents the unrotated texture size
//
// so what we have to do is:
// - swap texture width and height
// - take into account the origin
// - flip X instead of Y when flipY is enabled
// - flip Y instead of X when flipX is enabled
if (_rectRotated)
std::swap(rw, rh);
#if CC_FIX_ARTIFACTS_BY_STRECHING_TEXEL
float left = (2*rectInPixels.origin.x+1) / (2*atlasWidth);
float right = left+(rw*2-2) / (2*atlasWidth);
float top = (2*rectInPixels.origin.y+1) / (2*atlasHeight);
float bottom = top+(rh*2-2) / (2*atlasHeight);
#else
float left = rectInPixels.origin.x / atlasWidth;
float right = (rectInPixels.origin.x + rw) / atlasWidth;
float top = rectInPixels.origin.y / atlasHeight;
float bottom = (rectInPixels.origin.y + rh) / atlasHeight;
#endif // CC_FIX_ARTIFACTS_BY_STRECHING_TEXEL
if ((_flippedX && !_rectRotated) || (_flippedY && _rectRotated))
{
std::swap(left, right);
}
if ((_flippedY && !_rectRotated) || (_flippedX && _rectRotated))
{
std::swap(top, bottom);
}
if (_rectRotated)
{
#if CC_FIX_ARTIFACTS_BY_STRECHING_TEXEL
left = (2*rectInPixels.origin.x+1) / (2*atlasWidth);
right = left+(rectInPixels.size.height*2-2) / (2*atlasWidth);
top = (2*rectInPixels.origin.y+1) / (2*atlasHeight);
bottom = top+(rectInPixels.size.width*2-2) / (2*atlasHeight);
#else
left = rectInPixels.origin.x / atlasWidth;
right = (rectInPixels.origin.x + rectInPixels.size.height) / atlasWidth;
top = rectInPixels.origin.y / atlasHeight;
bottom = (rectInPixels.origin.y + rectInPixels.size.width) / atlasHeight;
#endif // CC_FIX_ARTIFACTS_BY_STRECHING_TEXEL
if (_flippedX)
{
std::swap(top, bottom);
}
if (_flippedY)
{
std::swap(left, right);
}
outQuad->bl.texCoords.u = left;
outQuad->bl.texCoords.v = top;
outQuad->br.texCoords.u = left;
@ -670,28 +788,6 @@ void Sprite::setTextureCoords(const Rect& rectInPoints, V3F_C4B_T2F_Quad* outQua
}
else
{
#if CC_FIX_ARTIFACTS_BY_STRECHING_TEXEL
left = (2*rectInPixels.origin.x+1) / (2*atlasWidth);
right = left + (rectInPixels.size.width*2-2) / (2*atlasWidth);
top = (2*rectInPixels.origin.y+1) / (2*atlasHeight);
bottom = top + (rectInPixels.size.height*2-2) / (2*atlasHeight);
#else
left = rectInPixels.origin.x / atlasWidth;
right = (rectInPixels.origin.x + rectInPixels.size.width) / atlasWidth;
top = rectInPixels.origin.y / atlasHeight;
bottom = (rectInPixels.origin.y + rectInPixels.size.height) / atlasHeight;
#endif // ! CC_FIX_ARTIFACTS_BY_STRECHING_TEXEL
if(_flippedX)
{
std::swap(left, right);
}
if(_flippedY)
{
std::swap(top, bottom);
}
outQuad->bl.texCoords.u = left;
outQuad->bl.texCoords.v = bottom;
outQuad->br.texCoords.u = right;
@ -703,10 +799,8 @@ void Sprite::setTextureCoords(const Rect& rectInPoints, V3F_C4B_T2F_Quad* outQua
}
}
void Sprite::setVertexCoords(const Rect& rect, const Size& imageSize, V3F_C4B_T2F_Quad* outQuad)
void Sprite::setVertexCoords(const Rect& rect, V3F_C4B_T2F_Quad* outQuad)
{
// container size is the Size that contains the "unsliced" sprite
float relativeOffsetX = _unflippedOffsetPositionFromCenter.x;
float relativeOffsetY = _unflippedOffsetPositionFromCenter.y;
@ -720,8 +814,15 @@ void Sprite::setVertexCoords(const Rect& rect, const Size& imageSize, V3F_C4B_T2
relativeOffsetY = -relativeOffsetY;
}
_offsetPosition.x = relativeOffsetX + (_originalContentSize.width - imageSize.width) / 2;
_offsetPosition.y = relativeOffsetY + (_originalContentSize.height - imageSize.height) / 2;
_offsetPosition.x = relativeOffsetX + (_originalContentSize.width - _rect.size.width) / 2;
_offsetPosition.y = relativeOffsetY + (_originalContentSize.height - _rect.size.height) / 2;
// FIXME: Streching should be applied to the "offset" as well
// but probably it should be calculated in the caller function. It will be tidier
if (_numberOfSlices == 1) {
_offsetPosition.x *= _strechFactor.x;
_offsetPosition.y *= _strechFactor.y;
}
// rendering using batch node
if (_batchNode)
@ -793,7 +894,7 @@ void Sprite::updateTransform(void)
float x2 = x1 + size.width;
float y2 = y1 + size.height;
float x = _transformToBatch.m[12];
float y = _transformToBatch.m[13];
@ -849,7 +950,7 @@ void Sprite::draw(Renderer *renderer, const Mat4 &transform, uint32_t flags)
{
return;
}
#if CC_USE_CULLING
// Don't calculate the culling if the transform was not updated
auto visitingCamera = Camera::getVisitingCamera();
@ -866,16 +967,16 @@ void Sprite::draw(Renderer *renderer, const Mat4 &transform, uint32_t flags)
if(_insideBounds)
#endif
{
_trianglesCommand.init(_globalZOrder,
_texture,
getGLProgramState(),
_blendFunc,
_polyInfo.triangles,
transform,
flags);
_trianglesCommand.init(_globalZOrder,
_texture,
getGLProgramState(),
_blendFunc,
_polyInfo.triangles,
transform,
flags);
renderer->addCommand(&_trianglesCommand);
#if CC_SPRITE_DEBUG_DRAW
_debugDrawNode->clear();
auto count = _polyInfo.triangles.indexCount/3;
@ -887,11 +988,11 @@ void Sprite::draw(Renderer *renderer, const Mat4 &transform, uint32_t flags)
Vec3 from =verts[indices[i*3]].vertices;
Vec3 to = verts[indices[i*3+1]].vertices;
_debugDrawNode->drawLine(Vec2(from.x, from.y), Vec2(to.x,to.y), Color4F::WHITE);
from =verts[indices[i*3+1]].vertices;
to = verts[indices[i*3+2]].vertices;
_debugDrawNode->drawLine(Vec2(from.x, from.y), Vec2(to.x,to.y), Color4F::WHITE);
from =verts[indices[i*3+2]].vertices;
to = verts[indices[i*3]].vertices;
_debugDrawNode->drawLine(Vec2(from.x, from.y), Vec2(to.x,to.y), Color4F::WHITE);
@ -909,7 +1010,7 @@ void Sprite::addChild(Node *child, int zOrder, int tag)
{
return;
}
if (_batchNode)
{
Sprite* childSprite = dynamic_cast<Sprite*>(child);
@ -934,7 +1035,7 @@ void Sprite::addChild(Node *child, int zOrder, const std::string &name)
{
return;
}
if (_batchNode)
{
Sprite* childSprite = dynamic_cast<Sprite*>(child);
@ -943,7 +1044,7 @@ void Sprite::addChild(Node *child, int zOrder, const std::string &name)
"childSprite's texture name should be equal to _textureAtlas's texture name.");
//put it in descendants array of batch node
_batchNode->appendChild(childSprite);
if (!_reorderChildDirty)
{
setReorderChildDirtyRecursively();
@ -1068,7 +1169,7 @@ void Sprite::setPosition(float x, float y)
void Sprite::setRotation(float rotation)
{
Node::setRotation(rotation);
SET_DIRTY_RECURSIVELY();
}
@ -1152,17 +1253,35 @@ void Sprite::setContentSize(const Size& size)
updatePoly();
}
void Sprite::setStrechEnabled(bool enabled)
{
if (_strechEnabled != enabled) {
_strechEnabled = enabled;
// disabled centerrect / number of slices if disabled
if (!enabled)
setCenterRectNormalized(Rect(0,0,1,1));
updateStretchFactor();
updatePoly();
}
}
bool Sprite::isStrechEnabled() const
{
return _strechEnabled;
}
void Sprite::updateStretchFactor()
{
const Size size = getContentSize();
const float adjustedWidth = size.width - (_originalContentSize.width - _rect.size.width);
const float adjustedHeight = size.height - (_originalContentSize.height - _rect.size.height);
if (_numberOfSlices == 1)
{
const float x_factor = adjustedWidth / _rect.size.width;
const float y_factor = adjustedHeight / _rect.size.height;
// If strech is disabled, calculate the strech anyway
// since it is needed to calculate the offset
const float x_factor = size.width / _originalContentSize.width;
const float y_factor = size.height / _originalContentSize.height;
_strechFactor = Vec2(x_factor, y_factor);
}
else
@ -1175,6 +1294,10 @@ void Sprite::updateStretchFactor()
const float y2 = _rect.size.height * _centerRectNormalized.size.height;
const float y3 = _rect.size.height * (1 - _centerRectNormalized.origin.y - _centerRectNormalized.size.height);
// adjustedSize = the new _rect size
const float adjustedWidth = size.width - (_originalContentSize.width - _rect.size.width);
const float adjustedHeight = size.height - (_originalContentSize.height - _rect.size.height);
const float x_factor = (adjustedWidth - x1 - x3) / x2;
const float y_factor = (adjustedHeight - y1 - y3) / y2;
@ -1188,13 +1311,10 @@ void Sprite::setFlippedX(bool flippedX)
{
_flippedX = flippedX;
for (ssize_t i = 0; i < _polyInfo.triangles.vertCount; i++) {
auto& v = _polyInfo.triangles.verts[i].vertices;
v.x = _contentSize.width - v.x;
}
if (_textureAtlas) {
if (_batchNode) {
setDirty(true);
} else {
updatePoly();
}
}
}
@ -1210,13 +1330,10 @@ void Sprite::setFlippedY(bool flippedY)
{
_flippedY = flippedY;
for (ssize_t i = 0; i < _polyInfo.triangles.vertCount; i++) {
auto& v = _polyInfo.triangles.verts[i].vertices;
v.y = _contentSize.height - v.y;
}
if (_textureAtlas) {
if (_batchNode) {
setDirty(true);
} else {
updatePoly();
}
}
}
@ -1233,7 +1350,7 @@ bool Sprite::isFlippedY(void) const
void Sprite::updateColor(void)
{
Color4B color4( _displayedColor.r, _displayedColor.g, _displayedColor.b, _displayedOpacity );
// special opacity for premultiplied textures
if (_opacityModifyRGB)
{
@ -1288,7 +1405,7 @@ void Sprite::setSpriteFrame(const std::string &spriteFrameName)
{
return;
}
SpriteFrameCache *cache = SpriteFrameCache::getInstance();
SpriteFrame *spriteFrame = cache->getSpriteFrameByName(spriteFrameName);
@ -1319,7 +1436,7 @@ void Sprite::setSpriteFrame(SpriteFrame *spriteFrame)
// update rect
_rectRotated = spriteFrame->isRotated();
setTextureRect(spriteFrame->getRect(), _rectRotated, spriteFrame->getOriginalSize());
if (spriteFrame->hasPolygonInfo())
{
_polyInfo = spriteFrame->getPolygonInfo();
@ -1341,7 +1458,7 @@ void Sprite::setDisplayFrameWithAnimationName(const std::string& animationName,
{
return;
}
Animation *a = AnimationCache::getInstance()->getAnimation(animationName);
CCASSERT(a, "CCSprite#setDisplayFrameWithAnimationName: Frame not found");

View File

@ -451,6 +451,13 @@ public:
* @param PolygonInfo the polygon information object
*/
void setPolygonInfo(const PolygonInfo& info);
/** whether or not contentSize streches the sprite's texture */
void setStrechEnabled(bool enabled);
/** returns whether or not contentSize streches the sprite's texture */
bool isStrechEnabled() const;
//
// Overrides
//
@ -623,7 +630,7 @@ protected:
void updateColor() override;
virtual void setTextureCoords(const Rect& rect);
virtual void setTextureCoords(const Rect& rect, V3F_C4B_T2F_Quad* outQuad);
virtual void setVertexCoords(const Rect& rect, const Size& imageSize, V3F_C4B_T2F_Quad* outQuad);
virtual void setVertexCoords(const Rect& rect, V3F_C4B_T2F_Quad* outQuad);
virtual void updateBlendFunc();
virtual void setReorderChildDirtyRecursively();
virtual void setDirtyRecursively(bool value);
@ -688,6 +695,8 @@ protected:
std::string _fileName;
int _fileType;
bool _strechEnabled;
private:
CC_DISALLOW_COPY_AND_ASSIGN(Sprite);
};

View File

@ -28,6 +28,7 @@ THE SOFTWARE.
#include "renderer/CCTextureCache.h"
#include "2d/CCSpriteFrame.h"
#include "base/CCDirector.h"
#include "platform/CCFileUtils.h"
NS_CC_BEGIN
@ -54,19 +55,24 @@ SpriteFrame* SpriteFrame::createWithTexture(Texture2D *texture, const Rect& rect
SpriteFrame* SpriteFrame::createWithTexture(Texture2D* texture, const Rect& rect, bool rotated, const Vec2& offset, const Size& originalSize)
{
SpriteFrame *spriteFrame = new (std::nothrow) SpriteFrame();
spriteFrame->initWithTexture(texture, rect, rotated, offset, originalSize);
spriteFrame->autorelease();
if (spriteFrame && spriteFrame->initWithTexture(texture, rect, rotated, offset, originalSize)) {
spriteFrame->autorelease();
return spriteFrame;
}
return spriteFrame;
delete spriteFrame;
return nullptr;
}
SpriteFrame* SpriteFrame::create(const std::string& filename, const Rect& rect, bool rotated, const Vec2& offset, const Size& originalSize)
{
SpriteFrame *spriteFrame = new (std::nothrow) SpriteFrame();
spriteFrame->initWithTextureFilename(filename, rect, rotated, offset, originalSize);
spriteFrame->autorelease();
return spriteFrame;
if (spriteFrame && spriteFrame->initWithTextureFilename(filename, rect, rotated, offset, originalSize)) {
spriteFrame->autorelease();
return spriteFrame;
}
delete spriteFrame;
return nullptr;
}
SpriteFrame::SpriteFrame()
@ -111,19 +117,21 @@ bool SpriteFrame::initWithTexture(Texture2D* texture, const Rect& rect, bool rot
bool SpriteFrame::initWithTextureFilename(const std::string& filename, const Rect& rect, bool rotated, const Vec2& offset, const Size& originalSize)
{
_texture = nullptr;
_textureFilename = filename;
_rectInPixels = rect;
_rect = CC_RECT_PIXELS_TO_POINTS( rect );
_offsetInPixels = offset;
_offset = CC_POINT_PIXELS_TO_POINTS( _offsetInPixels );
_originalSizeInPixels = originalSize;
_originalSize = CC_SIZE_PIXELS_TO_POINTS( _originalSizeInPixels );
_rotated = rotated;
_anchorPoint = Vec2(NAN, NAN);
_centerRect = Rect(NAN, NAN, NAN, NAN);
return true;
if (FileUtils::getInstance()->isFileExist(filename)) {
_texture = nullptr;
_textureFilename = filename;
_rectInPixels = rect;
_rect = CC_RECT_PIXELS_TO_POINTS( rect );
_offsetInPixels = offset;
_offset = CC_POINT_PIXELS_TO_POINTS( _offsetInPixels );
_originalSizeInPixels = originalSize;
_originalSize = CC_SIZE_PIXELS_TO_POINTS( _originalSizeInPixels );
_rotated = rotated;
_anchorPoint = Vec2(NAN, NAN);
_centerRect = Rect(NAN, NAN, NAN, NAN);
return true;
}
return false;
}
SpriteFrame::~SpriteFrame()

View File

@ -446,6 +446,7 @@ bool SpriteFrameCache::isSpriteFramesWithFileLoaded(const std::string& plist) co
void SpriteFrameCache::addSpriteFrame(SpriteFrame* frame, const std::string& frameName)
{
CCASSERT(frame, "frame should not be nil");
_spriteFrames.insert(frameName, frame);
}

View File

@ -25,7 +25,7 @@ ui::Scale9Sprite* Scale9SpriteLoader::createNode(cocos2d::Node* /*pParent*/, coc
void Scale9SpriteLoader::onHandlePropTypeSpriteFrame(Node * pNode, Node * pParent, const char * pPropertyName, SpriteFrame * pSpriteFrame, CCBReader * ccbReader) {
if(strcmp(pPropertyName, PROPERTY_SPRITEFRAME) == 0) {
((cocos2d::ui::Scale9Sprite *)pNode)->setSpriteFrame(pSpriteFrame);
static_cast<cocos2d::ui::Scale9Sprite*>(pNode)->setSpriteFrame(pSpriteFrame);
} else {
NodeLoader::onHandlePropTypeSpriteFrame(pNode, pParent, pPropertyName, pSpriteFrame, ccbReader);
}

View File

@ -158,6 +158,25 @@ void Button::createTitleRenderer()
addProtectedChild(_titleRenderer, TITLE_RENDERER_Z, -1);
}
/** replaces the current Label node with a new one */
void Button::setTitleLabel(Label* label)
{
if (_titleRenderer != label) {
CC_SAFE_RELEASE(_titleRenderer);
_titleRenderer = label;
CC_SAFE_RETAIN(_titleRenderer);
addProtectedChild(_titleRenderer, TITLE_RENDERER_Z, -1);
updateTitleLocation();
}
}
/** returns the current Label being used */
Label* Button::getTitleLabel() const
{
return _titleRenderer;
}
void Button::setScale9Enabled(bool able)
{
if (_scale9Enabled == able)
@ -453,7 +472,7 @@ void Button::onPressStateChangedToNormal()
_buttonNormalRenderer->setScale(1.0);
_buttonClickedRenderer->setScale(1.0);
if(nullptr != _titleRenderer)
if (nullptr != _titleRenderer)
{
_titleRenderer->stopAllActions();
if (_unifySize)
@ -474,7 +493,7 @@ void Button::onPressStateChangedToNormal()
_buttonNormalRenderer->stopAllActions();
_buttonNormalRenderer->setScale(1.0);
if(nullptr != _titleRenderer)
if (nullptr != _titleRenderer)
{
_titleRenderer->stopAllActions();
_titleRenderer->setScaleX(1.0f);
@ -507,7 +526,7 @@ void Button::onPressStateChangedToPressed()
_buttonNormalRenderer->setScale(1.0f + _zoomScale,
1.0f + _zoomScale);
if(nullptr != _titleRenderer)
if (nullptr != _titleRenderer)
{
_titleRenderer->stopAllActions();
Action *zoomTitleAction = ScaleTo::create(ZOOM_ACTION_TIME_STEP,
@ -525,7 +544,7 @@ void Button::onPressStateChangedToPressed()
_buttonNormalRenderer->stopAllActions();
_buttonNormalRenderer->setScale(1.0f +_zoomScale, 1.0f + _zoomScale);
if(nullptr != _titleRenderer)
if (nullptr != _titleRenderer)
{
_titleRenderer->stopAllActions();
_titleRenderer->setScaleX(1.0f + _zoomScale);
@ -586,7 +605,7 @@ void Button::updateContentSize()
void Button::onSizeChanged()
{
Widget::onSizeChanged();
if(nullptr != _titleRenderer)
if (nullptr != _titleRenderer)
{
updateTitleLocation();
}

View File

@ -263,6 +263,13 @@ public:
*/
void setTitleAlignment(TextHAlignment hAlignment, TextVAlignment vAlignment);
/** replaces the current Label node with a new one */
void setTitleLabel(Label* label);
/** returns the current Label being used */
Label* getTitleLabel() const;
/** @brief When user pressed the button, the button will zoom to a scale.
* The final scale of the button equals (button original scale + _zoomScale)
* @since v3.3

File diff suppressed because it is too large Load Diff

View File

@ -1,18 +1,18 @@
/****************************************************************************
Copyright (c) 2013-2016 Chukong Technologies Inc.
http://www.cocos2d-x.org
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
@ -25,7 +25,7 @@
#ifndef __cocos2d_libs__UIScale9Sprite__
#define __cocos2d_libs__UIScale9Sprite__
#include "2d/CCNode.h"
#include "2d/CCSprite.h"
#include "2d/CCSpriteFrame.h"
#include "2d/CCSpriteBatchNode.h"
#include "platform/CCPlatformMacros.h"
@ -38,9 +38,10 @@
*/
NS_CC_BEGIN
class DrawNode;
class Texture2D;
namespace ui {
/**
*@brief A 9-slice sprite for cocos2d-x.
*
@ -53,7 +54,7 @@ namespace ui {
* Then you could call any methods of Sprite class with the return pointers.
*
*/
class CC_GUI_DLL Scale9Sprite : public Node , public cocos2d::BlendProtocol
class CC_GUI_DLL Scale9Sprite : public Sprite
{
public:
/**
@ -69,7 +70,7 @@ namespace ui {
* @lua NA
*/
virtual ~Scale9Sprite();
/**
* Builtin shader state.
* Currently support Normal and Gray state.
@ -79,22 +80,22 @@ namespace ui {
NORMAL,
GRAY
};
enum class RenderingType
{
SIMPLE,
SLICE
};
public:
/**
* @brief Create an empty Scale9Sprite.
*
* @return A Scale9Sprite instance.
*/
static Scale9Sprite* create();
/**
* Creates a 9-slice sprite with a texture file, a delimitation zone and
* with the specified cap insets.
@ -106,7 +107,7 @@ namespace ui {
* @return A Scale9Sprite instance.
*/
static Scale9Sprite* create(const std::string& file, const Rect& rect, const Rect& capInsets);
/**
* Creates a 9-slice sprite with a texture file. The whole texture will be
* broken down into a 3×3 grid of equal blocks.
@ -117,7 +118,7 @@ namespace ui {
* @return A Scale9Sprite instance.
*/
static Scale9Sprite* create(const Rect& capInsets, const std::string& file);
/**
* Creates a 9-slice sprite with a texture file and a delimitation zone. The
* texture will be broken down into a 3×3 grid of equal blocks.
@ -128,7 +129,7 @@ namespace ui {
* @return A Scale9Sprite instance.
*/
static Scale9Sprite* create(const std::string& file, const Rect& rect);
/**
* Creates a 9-slice sprite with a texture file. The whole texture will be
* broken down into a 3×3 grid of equal blocks.
@ -138,7 +139,7 @@ namespace ui {
* @return A Scale9Sprite instance.
*/
static Scale9Sprite* create(const std::string& file);
/**
* Creates a 9-slice sprite with an sprite frame.
* Once the sprite is created, you can then call its "setContentSize:" method
@ -150,7 +151,7 @@ namespace ui {
* @return A Scale9Sprite instance.
*/
static Scale9Sprite* createWithSpriteFrame(SpriteFrame* spriteFrame);
/**
* Creates a 9-slice sprite with an sprite frame and the centre of its zone.
* Once the sprite is created, you can then call its "setContentSize:" method
@ -163,7 +164,7 @@ namespace ui {
* @return A Scale9Sprite instance.
*/
static Scale9Sprite* createWithSpriteFrame(SpriteFrame* spriteFrame, const Rect& capInsets);
/**
* Creates a 9-slice sprite with an sprite frame name.
* Once the sprite is created, you can then call its "setContentSize:" method
@ -175,7 +176,7 @@ namespace ui {
* @return A Scale9Sprite instance.
*/
static Scale9Sprite* createWithSpriteFrameName(const std::string& spriteFrameName);
/**
* Creates a 9-slice sprite with an sprite frame name and the centre of its zone.
* Once the sprite is created, you can then call its "setContentSize:" method
@ -188,7 +189,13 @@ namespace ui {
* @return A Scale9Sprite instance.
*/
static Scale9Sprite* createWithSpriteFrameName(const std::string& spriteFrameName, const Rect& capInsets);
// overriden methods that takes different parameters
using Sprite::initWithFile;
using Sprite::initWithSpriteFrame;
using Sprite::initWithSpriteFrameName;
using Sprite::setSpriteFrame;
/**
* Initializes a 9-slice sprite with a texture file, a delimitation zone and
* with the specified cap insets.
@ -204,22 +211,7 @@ namespace ui {
* @return True if initialize success, false otherwise.
*/
virtual bool initWithFile(const std::string& file, const Rect& rect, const Rect& capInsets);
/**
* Initializes a 9-slice sprite with a texture file and a delimitation zone. The
* texture will be broken down into a 3×3 grid of equal blocks.
* Once the sprite is created, you can then call its "setContentSize:" method
* to resize the sprite will all it's 9-slice goodness intract.
* It respects the anchorPoint too.
*
* @param file The name of the texture file.
* @param rect The rectangle that describes the sub-part of the texture that
* is the whole image. If the shape is the whole texture, set this to the
* texture's full rect.
* @return True if initializes success, false otherwise.
*/
virtual bool initWithFile(const std::string& file, const Rect& rect);
/**
* Initializes a 9-slice sprite with a texture file and with the specified cap
* insets.
@ -232,19 +224,7 @@ namespace ui {
* @return True if initializes success, false otherwise.
*/
virtual bool initWithFile(const Rect& capInsets, const std::string& file);
/**
* Initializes a 9-slice sprite with a texture file. The whole texture will be
* broken down into a 3×3 grid of equal blocks.
* Once the sprite is created, you can then call its "setContentSize:" method
* to resize the sprite will all it's 9-slice goodness intract.
* It respects the anchorPoint too.
*
* @param file The name of the texture file.
* @return True if initializes success, false otherwise.
*/
virtual bool initWithFile(const std::string& file);
/**
* Initializes a 9-slice sprite with an sprite frame and with the specified
* cap insets.
@ -257,18 +237,7 @@ namespace ui {
* @return True if initializes success, false otherwise.
*/
virtual bool initWithSpriteFrame(SpriteFrame* spriteFrame, const Rect& capInsets);
/**
* Initializes a 9-slice sprite with an sprite frame.
* Once the sprite is created, you can then call its "setContentSize:" method
* to resize the sprite will all it's 9-slice goodness intract.
* It respects the anchorPoint too.
*
* @param spriteFrame The sprite frame object.
* @return True if initializes success, false otherwise.
*/
virtual bool initWithSpriteFrame(SpriteFrame* spriteFrame);
/**
* Initializes a 9-slice sprite with an sprite frame name and with the specified
* cap insets.
@ -281,18 +250,7 @@ namespace ui {
* @return True if initializes success, false otherwise.
*/
virtual bool initWithSpriteFrameName(const std::string& spriteFrameName, const Rect& capInsets);
/**
* Initializes a 9-slice sprite with an sprite frame name.
* Once the sprite is created, you can then call its "setContentSize:" method
* to resize the sprite will all it's 9-slice goodness intract.
* It respects the anchorPoint too.
*
* @param spriteFrameName The sprite frame name.
* @return True if initializes success, false otherwise.
*/
virtual bool initWithSpriteFrameName(const std::string& spriteFrameName);
//override function
virtual bool init() override;
@ -343,7 +301,7 @@ namespace ui {
const Vec2 &offset,
const Size &originalSize,
const Rect& capInsets);
/**
* @brief Initializes a 9-slice sprite with a sprite batchnode.
* Once the sprite is created, you can then call its "setContentSize:" method
@ -357,10 +315,10 @@ namespace ui {
* @param capInsets The values to use for the cap insets.
* @return True if initializes success, false otherwise.
*/
CC_DEPRECATED(v3) virtual bool initWithBatchNode(SpriteBatchNode* batchnode,
const Rect& rect,
bool rotated,
const Rect& capInsets);
CC_DEPRECATED(v3) virtual bool initWithBatchNode(SpriteBatchNode* batchnode,
const Rect& rect,
bool rotated,
const Rect& capInsets);
/**
* @brief Initializes a 9-slice sprite with a sprite batch node.
* Once the sprite is created, you can then call its "setContentSize:" method
@ -374,24 +332,6 @@ namespace ui {
* @return True if initializes success, false otherwise.
*/
CC_DEPRECATED(v3) virtual bool initWithBatchNode(SpriteBatchNode* batchnode, const Rect& rect, const Rect& capInsets);
/**
* Sets the source blending function.
*
* @param blendFunc A structure with source and destination factor to specify pixel arithmetic. e.g. {GL_ONE, GL_ONE}, {GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA}.
* @js NA
* @lua NA
*/
virtual void setBlendFunc(const BlendFunc &blendFunc) override;
/**
* Returns the blending function that is currently being used.
*
* @return A BlendFunc structure with source and destination factor which specified pixel arithmetic.
* @js NA
* @lua NA
*/
virtual const BlendFunc &getBlendFunc() const override;
/**
* Creates and returns a new sprite object with the specified cap insets.
@ -403,8 +343,8 @@ namespace ui {
* @return A Scale9Sprite instance.
*/
Scale9Sprite* resizableSpriteWithCapInsets(const Rect& capInsets) const;
/**
* @brief Update Scale9Sprite with a specified sprite.
*
@ -454,18 +394,14 @@ namespace ui {
bool rotated,
const Rect& capInsets);
/**
* @brief Change inner sprite's sprite frame.
*
* @param spriteFrame A sprite frame pointer.
* @param capInsets The values to use for the cap insets.
*/
virtual void setSpriteFrame(SpriteFrame * spriteFrame, const Rect& capInsets = Rect::ZERO);
// overrides
virtual void setContentSize(const Size & size) override;
virtual void setAnchorPoint(const Vec2& anchorPoint) override;
virtual void setSpriteFrame(SpriteFrame * spriteFrame, const Rect& capInsets);
/**
* Change the state of 9-slice sprite.
@ -474,106 +410,92 @@ namespace ui {
* @since v3.4
*/
void setState(State state);
/**
* Query the current bright state.
* @return @see `State`
* @since v3.7
*/
State getState()const;
State getState() const;
/**
* @brief Query the sprite's original size.
*
* @return Sprite size.
*/
Size getOriginalSize() const;
/**
* @brief Change the preferred size of Scale9Sprite.
*
* @param size A delimitation zone.
*/
void setPreferredSize(const Size& size);
/**
* @brief Query the Scale9Sprite's preferred size.
*
* @return Scale9Sprite's preferred size.
*/
Size getPreferredSize() const;
/**
* @brief Change the cap inset size.
*
* @param rect A delimitation zone.
*/
void setCapInsets(const Rect& rect);
/**
* @brief Query the Scale9Sprite's preferred size.
*
* @return Scale9Sprite's cap inset.
*/
Rect getCapInsets()const;
/**
* @brief Change the left sprite's cap inset.
*
* @param leftInset The values to use for the cap inset.
*/
void setInsetLeft(float leftInset);
/**
* @brief Query the left sprite's cap inset.
*
* @return The left sprite's cap inset.
*/
float getInsetLeft()const;
float getInsetLeft() const;
/**
* @brief Change the top sprite's cap inset.
*
* @param topInset The values to use for the cap inset.
*/
void setInsetTop(float topInset);
/**
* @brief Query the top sprite's cap inset.
*
* @return The top sprite's cap inset.
*/
float getInsetTop()const;
float getInsetTop() const;
/**
* @brief Change the right sprite's cap inset.
*
* @param rightInset The values to use for the cap inset.
*/
void setInsetRight(float rightInset);
/**
* @brief Query the right sprite's cap inset.
*
* @return The right sprite's cap inset.
*/
float getInsetRight()const;
float getInsetRight() const;
/**
* @brief Change the bottom sprite's cap inset.
*
* @param bottomInset The values to use for the cap inset.
*/
void setInsetBottom(float bottomInset);
/**
* @brief Query the bottom sprite's cap inset.
*
* @return The bottom sprite's cap inset.
*/
float getInsetBottom()const;
float getInsetBottom() const;
/**
* @brief Toggle 9-slice feature.
* If Scale9Sprite is 9-slice disabled, the Scale9Sprite will rendered as a normal sprite.
@ -583,84 +505,24 @@ namespace ui {
* @js NA
*/
void setScale9Enabled(bool enabled);
/**
* @brief Query whether the Scale9Sprite is enable 9-slice or not.
*
* @return True if 9-slice is enabled, false otherwise.
* @js NA
*/
bool isScale9Enabled()const;
bool isScale9Enabled() const;
/// @} end of Children and Parent
virtual void draw(Renderer *renderer, const Mat4 &transform, uint32_t flags) override;
virtual void visit(Renderer *renderer, const Mat4 &parentTransform, uint32_t parentFlags) override;
virtual void updateDisplayedOpacity(GLubyte parentOpacity) override;
virtual void updateDisplayedColor(const Color3B& parentColor) override;
virtual void disableCascadeColor() override;
virtual void disableCascadeOpacity() override;
virtual void setGLProgram(GLProgram *glprogram) override;
virtual void setGLProgramState(GLProgramState *glProgramState) override;
/**
* @brief Get the original no 9-sliced sprite
*
* @return A sprite instance.
*/
Sprite* getSprite()const;
/**
* Sets whether the widget should be flipped horizontally or not.
*
* @param flippedX true if the widget should be flipped horizontally, false otherwise.
*/
virtual void setFlippedX(bool flippedX);
/**
* Returns the flag which indicates whether the widget is flipped horizontally or not.
*
* It only flips the texture of the widget, and not the texture of the widget's children.
* Also, flipping the texture doesn't alter the anchorPoint.
* If you want to flip the anchorPoint too, and/or to flip the children too use:
* widget->setScaleX(sprite->getScaleX() * -1);
*
* @return true if the widget is flipped horizontally, false otherwise.
*/
virtual bool isFlippedX()const;
/**
* Sets whether the widget should be flipped vertically or not.
*
* @param flippedY true if the widget should be flipped vertically, false otherwise.
*/
virtual void setFlippedY(bool flippedY);
Sprite* getSprite();
/**
* Return the flag which indicates whether the widget is flipped vertically or not.
*
* It only flips the texture of the widget, and not the texture of the widget's children.
* Also, flipping the texture doesn't alter the anchorPoint.
* If you want to flip the anchorPoint too, and/or to flip the children too use:
* widget->setScaleY(widget->getScaleY() * -1);
*
* @return true if the widget is flipped vertically, false otherwise.
*/
virtual bool isFlippedY()const;
//override the setScale function of Node
virtual void setScaleX(float scaleX) override;
virtual void setScaleY(float scaleY) override;
virtual void setScale(float scale) override;
virtual void setScale(float scaleX, float scaleY) override;
using Node::setScaleZ;
virtual float getScaleX() const override;
virtual float getScaleY() const override;
virtual float getScale() const override;
using Node::getScaleZ;
virtual void setCameraMask(unsigned short mask, bool applyChildren = true) override;
virtual void setGlobalZOrder(float globalZOrder) override;
/**
* Set the slice sprite rendering type.
@ -669,70 +531,38 @@ namespace ui {
* @see RenderingType
*/
void setRenderingType(RenderingType type);
/**
* Return the slice sprite rendering type.
*/
RenderingType getRenderingType()const;
RenderingType getRenderingType() const;
/**
* Set the Cap Insets in Points using the untrimmed size as reference
*/
void setCapInsets(const Rect& insets);
/**
* Returns the Cap Insets
*/
Rect getCapInsets() const;
void resetRender();
protected:
void updateCapInset();
void createSlicedSprites();
void cleanupSlicedSprites();
void adjustNoneScale9ImagePosition();
void configureSimpleModeRendering();
void applyBlendFunc();
void updateBlendFunc(Texture2D *texture);
std::vector<Vec2> calculateUV(Texture2D *tex, const Rect& capInsets,
const Size& originalSize, const Vec4& offsets);
std::vector<Vec2> calculateVertices(const Rect& capInsets, const Size& originalSize, const Vec4& offsets);
TrianglesCommand::Triangles calculateTriangles(const std::vector<Vec2>& uv,
const std::vector<Vec2>& vertices);
Rect _spriteRect;
bool _spriteFrameRotated;
Rect _capInsetsInternal;
Sprite* _scale9Image; //the original sprite
bool _scale9Enabled;
BlendFunc _blendFunc;
/** Original sprite's size. */
Size _originalSize;
Vec2 _offset;
/** Preferred sprite's size. By default the preferred size is the original size. */
//if the preferredSize component is given as -1, it is ignored
Size _preferredSize;
/** Sets the left side inset */
float _insetLeft;
/** Sets the top side inset */
float _insetTop;
/** Sets the right side inset */
float _insetRight;
/** Sets the bottom side inset */
float _insetBottom;
bool _flippedX;
bool _flippedY;
bool _isPatch9;
State _brightState;
Vec2 _nonSliceSpriteAnchor;
void setupSlice9(Texture2D* texture, const Rect& capInsets);
V3F_C4B_T2F* _sliceVertices;
unsigned short* _sliceIndices;
bool _sliceSpriteDirty;
RenderingType _renderingType;
#if CC_SPRITE_DEBUG_DRAW
DrawNode *_debugDrawNode;
#endif //CC_SPRITE_DEBUG_DRAW
bool _insideBounds; /// whether or not the sprite was inside bounds the previous frame
TrianglesCommand _trianglesCommand; ///
bool _isPatch9;
Rect _previousCenterRectNormalized;
float _insetLeft;
float _insetRight;
float _insetTop;
float _insetBottom;
Scale9Sprite::State _brightState;
Scale9Sprite::RenderingType _renderingType;
};
}} //end of namespace

View File

@ -110,7 +110,7 @@ bool UIScale9SpriteTest::init()
sp1->setColor(Color3B::GREEN);
this->addChild(sp1);
sp1->runAction((FiniteTimeAction*)action2);
cocos2d::ui::Scale9Sprite *sp2 = ui::Scale9Sprite::create("cocosui/animationbuttonnormal.png");
sp2->setPosition(350, 160);
sp2->setPreferredSize(sp1->getContentSize() * 1.2f);
@ -120,7 +120,7 @@ bool UIScale9SpriteTest::init()
this->addChild(sp2);
auto action3 = action->clone();
sp2->runAction((FiniteTimeAction*)action3);
return true;
}
return false;
@ -177,7 +177,7 @@ bool UIScale9SpriteHierarchialTest::init()
sp2->setColor(Color3B::GREEN);
sp2->setFlippedX(true);
sp2->setContentSize(Size(100,100));
sp1->addChild(sp2);
return true;
@ -661,15 +661,15 @@ bool UIS9FrameNameSpriteSheetRotatedSetCapInsetLater::init()
auto winSize = Director::getInstance()->getWinSize();
float x = winSize.width / 2;
float y = 0 + (winSize.height / 2);
auto blocks_scaled_with_insets = ui::Scale9Sprite::createWithSpriteFrameName("blocks9r.png");
blocks_scaled_with_insets->setInsetLeft(32);
blocks_scaled_with_insets->setInsetRight(32);
blocks_scaled_with_insets->setPreferredSize(Size(32*5.5f, 32*4));
blocks_scaled_with_insets->setPosition(Vec2(x, y));
this->addChild(blocks_scaled_with_insets);
return true;
}
@ -944,14 +944,14 @@ bool UIS9NinePatchTest::init()
playerSprite->setPosition(x, y);
playerSprite->setContentSize(preferedSize);
auto capInsets = playerSprite->getCapInsets();
CCLOG("player sprite capInset = %f, %f %f, %f", capInsets.origin.x,
CCLOG("player sprite capInset = %g, %g %g, %g", capInsets.origin.x,
capInsets.origin.y, capInsets.size.width, capInsets.size.height);
this->addChild(playerSprite);
auto animationBtnSprite = ui::Scale9Sprite::createWithSpriteFrameName("animationbuttonpressed.png");
animationBtnSprite->setPosition(x-100, y-100);
capInsets = animationBtnSprite->getCapInsets();
CCLOG("animationBtnSprite capInset = %f, %f %f, %f", capInsets.origin.x,
CCLOG("animationBtnSprite capInset = %g, %g %g, %g", capInsets.origin.x,
capInsets.origin.y, capInsets.size.width, capInsets.size.height);
this->addChild(animationBtnSprite);
@ -960,7 +960,7 @@ bool UIS9NinePatchTest::init()
monsterSprite->setPosition(x+100, y-100);
capInsets = monsterSprite->getCapInsets();
monsterSprite->setContentSize(preferedSize);
CCLOG("monsterSprite capInset = %f, %f %f, %f", capInsets.origin.x,
CCLOG("monsterSprite capInset = %g, %g %g, %g", capInsets.origin.x,
capInsets.origin.y, capInsets.size.width, capInsets.size.height);
this->addChild(monsterSprite);
@ -1189,4 +1189,4 @@ void UIS9GrayStateOpacityTest::sliderEvent(cocos2d::Ref *sender, cocos2d::ui::Sl
auto scale9Sprite = (Scale9Sprite*)this->getChildByName("GrayScale9");
scale9Sprite->setOpacity(1.0 * percent / maxPercent * 255.0);
}
}
}