Cocos2D-X 3.10通用窗口控件 Ctl_WinForm

可以自由拖拽的小窗口

 

#define RS_BREAK_IF(RF)        if(RF) break

 

 

/

//CTL_WinForm.h


class Ctl_WinForm : public Sprite
{
public:
    static Ctl_WinForm * create();
    static Ctl_WinForm * create(std::string &_title, Color4B _title_color, float _title_height, Color4B _layer_tile_color, float _win_width, float _win_height, Color4B _win_color);
    Ctl_WinForm();
    virtual ~Ctl_WinForm();
    virtual bool init();
    virtual bool init(std::string &_title, Color4B _title_color, float _title_height, Color4B _layer_tile_color, float _win_width, float _win_height, Color4B _win_color);    // 初始化


    //
    // 控制功能
public:
    void SetTitle(std::string _title);
    void SetTitleColor(Color4B _color);
    void SetLayerTitleColor(Color4B _color);
    void SetWinFormSize(float _width, float _height, float _title_height);
    void SetWinFormColor(Color4B _color);

    //
    // 增加 addChild_winform
    virtual void addChild_winform(Node * child);
    virtual void addChild_winform(Node * child, int localZOrder);
    virtual void addChild_winform(Node* child, int localZOrder, int tag);
    virtual void addChild_winform(Node* child, int localZOrder, const std::string &name);
private:
    //
    // 布置控件
    bool LayoutControl(std::string &_title, Color4B _title_color, float _title_height, Color4B _layer_tile_color, float _win_width, float _win_height, Color4B _win_color);


    //
    // Layer 控件
    cocos2d::LayerColor * layer_win;
    cocos2d::LayerColor * layer_title;

    // Label 控件
    cocos2d::Label * label_title;

    //
    // 坐标变量
    cocos2d::Point currentPoint;    // 当前坐标
    cocos2d::Point offsetRange;        // 移动偏移

    //
    // layer_win 防穿透
    bool swallow;

    //
    // 静态数组 窗口管理
    static std::vector<Ctl_WinForm *> vec_winform;

    //
    // 触屏监听 函数
    bool onTouchBegan(Touch * _touch, Event * _event);
    void onTouchMoved(Touch * _touch, Event * _event);
    void onTouchEnded(Touch * _touch, Event * _event);

    void moveLayer(Point _offset);
};

 

/

//CTL_WinForm.cpp


//
// 静态数组 窗口管理
std::vector<Ctl_WinForm *> Ctl_WinForm::vec_winform;


Ctl_WinForm * Ctl_WinForm::create()
{
    Ctl_WinForm * sprite = new (std::nothrow) Ctl_WinForm;
    if (sprite && sprite->init())
    {
        sprite->autorelease();
        return sprite;
    }
    CC_SAFE_DELETE(sprite);
    return nullptr;
}

Ctl_WinForm * Ctl_WinForm::create(std::string &_title, Color4B _title_color, float _title_height, Color4B _layer_tile_color, float _win_width, float _win_height, Color4B _win_color)
{
    Ctl_WinForm * sprite = new (std::nothrow) Ctl_WinForm;
    if (sprite && sprite->init(_title, _title_color, _title_height, _layer_tile_color, _win_width, _win_height, _win_color))
    {
        sprite->autorelease();
        return sprite;
    }
    CC_SAFE_DELETE(sprite);
    return nullptr;
}


Ctl_WinForm::Ctl_WinForm()
{
    layer_win = nullptr;    // Layer 控件
    layer_title = nullptr;

    currentPoint = Point::ZERO;    // 当前坐标
    offsetRange = Point::ZERO;    // 移动偏移

    vec_winform.push_back(this);    // 注册窗口
}

Ctl_WinForm::~Ctl_WinForm()
{
    // 删除窗口
    std::vector<Ctl_WinForm *>::iterator it = vec_winform.begin();
    for (; it != vec_winform.end(); it++)
    {
        if (*it == this)
        {
            vec_winform.erase(it);
            break;
        }
    }
}


bool Ctl_WinForm::init()
{
    return init(std::string("unknow")
        , Color4B(51, 51, 51, 255)
        , 30.0f
        , Color4B(255, 153, 51, 255)
        , 600
        , 400
        , Color4B(153, 204, 204, 255));
}


bool Ctl_WinForm::init(std::string &_title, Color4B _title_color, float _title_height, Color4B _layer_tile_color, float _win_width, float _win_height, Color4B _win_color)
{
    if (!Sprite::init())
        return false;

    do
    {
        //
        // 布置控件
        RS_BREAK_IF(LayoutControl(_title, _title_color, _title_height, _layer_tile_color, _win_width, _win_height, _win_color) == false);

        return true;

    } while (0);

    //
    // 日志省略

    return false;
}

//
// 控制功能

void Ctl_WinForm::SetTitle(std::string _title)
{
    label_title->setString(_title);
}
void Ctl_WinForm::SetTitleColor(Color4B _color)
{
    label_title->setColor(Color3B(_color));
}
void Ctl_WinForm::SetLayerTitleColor(Color4B _color)
{
    layer_title->setColor(Color3B(_color));
}
void Ctl_WinForm::SetWinFormSize(float _width, float _height, float _title_height)
{
    layer_win->setContentSize(Size(_width, _height));
    layer_title->setContentSize(Size(_width, _title_height));
}
void Ctl_WinForm::SetWinFormColor(Color4B _color)
{
    layer_win->setColor(Color3B(_color));
}

//
// 增加 addChild_winform
void Ctl_WinForm::addChild_winform(Node * child)
{
    if (layer_win != nullptr)
    {
        layer_win->addChild(child);
    }
}
void Ctl_WinForm::addChild_winform(Node * child, int localZOrder)
{
    if (layer_win != nullptr)
    {
        layer_win->addChild(child, localZOrder);
    }
}
void Ctl_WinForm::addChild_winform(Node* child, int localZOrder, int tag)
{
    if (layer_win != nullptr)
    {
        layer_win->addChild(child, localZOrder, tag);
    }
}
void Ctl_WinForm::addChild_winform(Node* child, int localZOrder, const std::string &name)
{
    if (layer_win != nullptr)
    {
        layer_win->addChild(child, localZOrder, name);
    }
}

bool Ctl_WinForm::LayoutControl(std::string &_title, Color4B _title_color, float _title_height, Color4B _layer_tile_color, float _win_width, float _win_height, Color4B _win_color)
{
    do
    {
        //
        // 获取窗口信息(可视尺寸、起始点、中心点)
        Size visible = Director::getInstance()->getVisibleSize();
        Vec2 origin = Director::getInstance()->getVisibleOrigin();
        Point center = Point(visible.width * 0.5f + origin.x, visible.height * 0.5f + origin.y);

        //
        // 窗体
        layer_win = LayerColor::create(_win_color, _win_width, _win_height);
        layer_win->setPosition(0, 0);
        this->addChild(layer_win, 1);

        //
        // 标题栏
        layer_title = LayerColor::create(_layer_tile_color, _win_width, _title_height);
        layer_title->setPosition(0, _win_height);
        this->addChild(layer_title, 2);

        //
        // 标题
        label_title = Label::createWithTTF(_title, std::string("fonts/msyh.ttc"), 16);
        label_title->setIgnoreAnchorPointForPosition(false);
        label_title->setAnchorPoint(Point::ZERO);
        label_title->setColor(Color3B(_title_color));
        label_title->setPosition(10, 6);
        layer_title->addChild(label_title, 1);

        //
        // 触屏监听
        auto listener = EventListenerTouchOneByOne::create();
        listener->setSwallowTouches(true);
        listener->onTouchBegan = CC_CALLBACK_2(Ctl_WinForm::onTouchBegan, this);
        listener->onTouchMoved = CC_CALLBACK_2(Ctl_WinForm::onTouchMoved, this);
        listener->onTouchEnded = CC_CALLBACK_2(Ctl_WinForm::onTouchEnded, this);
        _eventDispatcher->addEventListenerWithSceneGraphPriority(listener, this);

        return true;

    } while (0);
    // 日志省略
    return false;
}

bool Ctl_WinForm::onTouchBegan(Touch* _touch, Event* _event)
{
    do
    {
        RS_BREAK_IF(layer_win == nullptr);
        RS_BREAK_IF(layer_title == nullptr);

        Point P = this->getParent()->convertToNodeSpace(_touch->getLocation());
        Rect R = layer_title->getBoundingBox();
        Rect R_2 = layer_win->getBoundingBox();

        // 调整窗口显示顺序
        if (R.containsPoint(P)== true || R_2.containsPoint(P) == true)
        {
            for (auto it : vec_winform)
                it->setLocalZOrder(1);
            this->setLocalZOrder(2);
        }

        // 拖动功能
        if (R.containsPoint(P) == true)
        {            
            swallow = false;
            offsetRange = Point::ZERO;
            currentPoint = P;

            return true;
        }

        // layer_win 防穿透
        if (R_2.containsPoint(P) == true)
        {
            swallow = true;
            return true;
        }

    } while (0);
    return false;
}
void Ctl_WinForm::onTouchMoved(Touch* _touch, Event* _event)
{
    do
    {
        RS_BREAK_IF(swallow == true);    // layer_win 防穿透

        Point P = _touch->getLocation();

        if (currentPoint != P)
        {
            Rect R = this->getParent()->getBoundingBox();
            if (R.containsPoint(P) == true)
            {
                offsetRange = P - currentPoint;
                currentPoint = P;
                moveLayer(offsetRange);
            }
        }

        return;

    } while (0);
}

void Ctl_WinForm::moveLayer(Point _offset)
{
    do
    {
        // layer_title
        Point np = layer_title->getPosition() + _offset;
        layer_title->setPosition(np);

        // layer_win
        layer_win->setPosition(layer_title->getPosition() - Point(0, layer_win->getContentSize().height));

    } while (0);

}

void Ctl_WinForm::onTouchEnded(Touch* _touch, Event* _event)
{
    currentPoint = Point::ZERO;
    offsetRange = Point::ZERO;
}

 

 

///

//使用方式

Ctl_WinForm * rs_winform = Ctl_WinForm::create();

Sprite * _example = Sprite::create(...);

rs_winform ->addChild_winform(_example );

this->addChild(rs_winform);

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值