1. 程式人生 > >[寒江孤葉丶的Cocos2d-x之旅_33]RichTextEx一款通過HTML標簽控制文字樣式的富文本控件

[寒江孤葉丶的Cocos2d-x之旅_33]RichTextEx一款通過HTML標簽控制文字樣式的富文本控件

ast number blink js版本號 領取 size 創建 sub require

RichTextEx一款通過HTML標簽控制文字樣式的富文本控件

原創文章,歡迎轉載。轉載請註明:文章來自[寒江孤葉丶的Cocos2d-x之旅系列]

博客地址:http://blog.csdn.net/qq446569365

下載地址

Github鏈接

這個是幹什麽的

將例如以下文字內容
"<#F37C2A><font Helvetica><30>【世】<#3AB5B3><underLine true>寒江孤葉<underLine false><#F8F4D7>:HelloWorld"


生成如圖所看到的樣式的RichText(支持圖片以及閃爍、旋轉和其它自己定義的效果、控件)

技術分享

關於它

這個是LUA版本號的。CPP版本號的沒寫,歡迎移植CPP和JS版本號
LUA文件是用一個別人寫的文件改動的(增加一些功能。修復幾個BUG……話說之前跑都跑不起來啊親……什麽鬼)
另外抱歉,找不到他的Github鏈接了……
· TTF字體支持描邊。系統字體是不支持的

使用說明

RichTextEx使用起來很easy,僅僅要將RichTextEx.lua拷貝到你的項目文件夾中,並require它就能夠了
比方這樣:

APUtils = APUtils or {}  
APUtils.RichTextEx = APUtils.RichTextEx or require("APUtils/gui/RichTextEx.lua")

使用RichText來創建一個富文本是很easy的:

local txt = RichTextEx:create() -- 或 RichTextEx:create(26, cc.c3b(10, 10, 10))
txt:setText("<outLine 5><underLine true><#EFB65C><font res/fonts/pw.ttf><24>您的元寶和銀券不足請<#FF0000><35>充值<#EFB65C><24>,或領取抽取元寶獎勵!")
-- 多行模式要同一時候設置 ignoreContentAdaptWithSize(false) 和 contentSize
txt:setMultiLineMode(true)  -- 這行事實上就是 ignoreContentAdaptWithSize(false)
txt:setContentSize(200, 400)
someNode:addChild(txt)

假設字符串是由用戶輸入的話,建議調用RichTextEx.htmlEncode("<ABC>")將用戶輸入內容編碼一下,以避免用戶輸入keyword符導致無法預知的錯誤
在生成字符串之前會自己主動調用RichTextEx.htmlDecode,假設你自己定義了用於顯示文字內容的控件,請記得調用它,以對字符串進行解碼

RichTextEx的基本選項

<#F00> = <#FF0000>  = 文字顏色
<32>                = 字體大小
<font Arial>        = 文字字體 支持TTF
<img filename>      = 圖片(filename 能夠是已經在 SpriteFrameCache 裏的 key。或磁盤文件)
<img_32*32 fname>   = 指定大小的圖片
<+2> <-2> <*2> </2> = 當前字體大小 +-*/
<!>                 = 顏色、字體和字體大小恢復默認
\n \t               = 換行 和 tab,可能臨時實現得不是很好 最好不要用 假設須要換行你能夠創建多個RichText然後依次放好
<outLine 1>         = 設置1像素描邊,僅僅支持TTF字體
<underLine true>    = 是否開啟下劃線

RichTextEx的演示樣例選項 (在 RichTextEx.defaultCb 中提供)

<blink 文字>      = (動畫)閃爍那些文字
<rotate 文字>     = (動畫)旋轉那些文字
<scale 文字>      = (動畫)縮放那些文字
(但假設你做了 setText(t, callback) 除非你在 callback 主動調用 defaultCb。否則以上選項會被忽略)   

你能夠對功能進行擴展

`<img_w*h http://path/image> 比如從網絡下載圖片`

同一時候支持自己定義特殊語法,增加 callback 回調就可,如

txt:setText("XXXXX <aaaa haha> <bbbb> <CCCC> xxx", function(text, sender) -- 第二個參數 sender 可選
    -- 對每個自己定義的 <***> 都會調用此 callback
    -- text 就等於 *** (不含<>)
    -- 簡單的返回一個 Node 的子實例就可,如
    -- 假設接收第二個參數 sender,就可獲取當前文字大小、顏色: sender._fontSize、sender._textColor

    if string.sub(text, 1, 4) == "aaaa" then
        return ccui.Text:create("aaa111" .. string.sub(text, 6)), "", 32)
        --這裏假設為了代碼的健壯性最好增加self:htmlDecode
        --return ccui.Text:create(self:htmlDecode("aaa111" .. string.sub(text, 6))), "", 32)
    elseif text == "bbbb" then
        -- 用當前文字大小和顏色
        local lbl = ccui.Text:create("bbb111", "", sender._fontSize)
        lbl:setTextColor(sender._textColor)
        return lbl
    elseif string.sub(text, 1, 4) == "CCCC" then
        local img = ccui.ImageView:create(....)
        img:setScale(...)
        img:runAction(...)
        return img
    end
end)

你還要做什麽

為了支持描邊和下劃線還要改動一下Cocos的源代碼
UIRichText.h和UIRichText.cpp放到項目源代碼文件夾 替換原來的
路徑:frameworks/cocos2d-x/cocos/ui
(改動內容主要三個方面:增加下劃線設置,增加描邊設置,RichText能夠自己主動更改高度了)
另外還須要改動toLua文件
frameworks/cocos2d-x/cocos/scripting/lua-bindings/auto/lua_cocos2dx_ui_auto.cpp
18878行左右能看到兩個函數
int lua_cocos2dx_ui_RichElementText_init(lua_State* tolua_S)

int lua_cocos2dx_ui_RichElementText_create(lua_State* tolua_S)
將這兩個函數的實現替換為例如以下形式:

int lua_cocos2dx_ui_RichElementText_init(lua_State* tolua_S)
{
    int argc = 0;
    cocos2d::ui::RichElementText* cobj = nullptr;
    bool ok  = true;

#if COCOS2D_DEBUG >= 1
    tolua_Error tolua_err;
#endif


#if COCOS2D_DEBUG >= 1
    if (!tolua_isusertype(tolua_S,1,"ccui.RichElementText",0,&tolua_err)) goto tolua_lerror;
#endif

    cobj = (cocos2d::ui::RichElementText*)tolua_tousertype(tolua_S,1,0);

#if COCOS2D_DEBUG >= 1
    if (!cobj) 
    {
        tolua_error(tolua_S,"invalid ‘cobj‘ in function ‘lua_cocos2dx_ui_RichElementText_init‘", nullptr);
        return 0;
    }
#endif

    argc = lua_gettop(tolua_S)-1;
    if (argc == 8)
    {
        int arg0;
        cocos2d::Color3B arg1;
        uint16_t arg2;
        std::string arg3;
        std::string arg4;
        double arg5;
        int arg6;
        bool arg7;

        ok &= luaval_to_int32(tolua_S, 2,(int *)&arg0, "ccui.RichElementText:init");

        ok &= luaval_to_color3b(tolua_S, 3, &arg1, "ccui.RichElementText:init");

        ok &= luaval_to_uint16(tolua_S, 4,&arg2, "ccui.RichElementText:init");

        ok &= luaval_to_std_string(tolua_S, 5,&arg3, "ccui.RichElementText:init");

        ok &= luaval_to_std_string(tolua_S, 6,&arg4, "ccui.RichElementText:init");

        ok &= luaval_to_number(tolua_S, 7,&arg5, "ccui.RichElementText:init");

        ok &= luaval_to_int32(tolua_S, 8,&arg6, "ccui.RichElementText:init");

        ok &= luaval_to_boolean(tolua_S, 9,&arg7, "ccui.RichElementText:init");
        if(!ok)
        {
            tolua_error(tolua_S,"invalid arguments in function ‘lua_cocos2dx_ui_RichElementText_init‘", nullptr);
            return 0;
        }
        bool ret = cobj->init(arg0, arg1, arg2, arg3, arg4, arg5,arg6,arg7);
        tolua_pushboolean(tolua_S,(bool)ret);
        return 1;
    }
    luaL_error(tolua_S, "%s has wrong number of arguments: %d, was expecting %d \n", "ccui.RichElementText:init",argc, 6);
    return 0;

#if COCOS2D_DEBUG >= 1
    tolua_lerror:
    tolua_error(tolua_S,"#ferror in function ‘lua_cocos2dx_ui_RichElementText_init‘.",&tolua_err);
#endif

    return 0;
}
int lua_cocos2dx_ui_RichElementText_create(lua_State* tolua_S)
{
    int argc = 0;
    bool ok  = true;

#if COCOS2D_DEBUG >= 1
    tolua_Error tolua_err;
#endif

#if COCOS2D_DEBUG >= 1
    if (!tolua_isusertable(tolua_S,1,"ccui.RichElementText",0,&tolua_err)) goto tolua_lerror;
#endif

    argc = lua_gettop(tolua_S) - 1;

    if (argc == 6)
    {
        int arg0;
        cocos2d::Color3B arg1;
        uint16_t arg2;
        std::string arg3;
        std::string arg4;
        double arg5;
        ok &= luaval_to_int32(tolua_S, 2,(int *)&arg0, "ccui.RichElementText:create");
        ok &= luaval_to_color3b(tolua_S, 3, &arg1, "ccui.RichElementText:create");
        ok &= luaval_to_uint16(tolua_S, 4,&arg2, "ccui.RichElementText:create");
        ok &= luaval_to_std_string(tolua_S, 5,&arg3, "ccui.RichElementText:create");
        ok &= luaval_to_std_string(tolua_S, 6,&arg4, "ccui.RichElementText:create");
        ok &= luaval_to_number(tolua_S, 7,&arg5, "ccui.RichElementText:create");
        if(!ok)
        {
            tolua_error(tolua_S,"invalid arguments in function ‘lua_cocos2dx_ui_RichElementText_create‘", nullptr);
            return 0;
        }
        cocos2d::ui::RichElementText* ret = cocos2d::ui::RichElementText::create(arg0, arg1, arg2, arg3, arg4, arg5);
        object_to_luaval<cocos2d::ui::RichElementText>(tolua_S, "ccui.RichElementText",(cocos2d::ui::RichElementText*)ret);
        return 1;
    }
    if (argc == 7)
    {
        int arg0;
        cocos2d::Color3B arg1;
        uint16_t arg2;
        std::string arg3;
        std::string arg4;
        double arg5;
        int arg6;
        ok &= luaval_to_int32(tolua_S, 2,(int *)&arg0, "ccui.RichElementText:create");
        ok &= luaval_to_color3b(tolua_S, 3, &arg1, "ccui.RichElementText:create");
        ok &= luaval_to_uint16(tolua_S, 4,&arg2, "ccui.RichElementText:create");
        ok &= luaval_to_std_string(tolua_S, 5,&arg3, "ccui.RichElementText:create");
        ok &= luaval_to_std_string(tolua_S, 6,&arg4, "ccui.RichElementText:create");
        ok &= luaval_to_number(tolua_S, 7,&arg5, "ccui.RichElementText:create");
        ok &= luaval_to_int32(tolua_S, 8,&arg6, "ccui.RichElementText:create");
        if(!ok)
        {
            tolua_error(tolua_S,"invalid arguments in function ‘lua_cocos2dx_ui_RichElementText_create‘", nullptr);
            return 0;
        }
        cocos2d::ui::RichElementText* ret = cocos2d::ui::RichElementText::create(arg0, arg1, arg2, arg3, arg4, arg5, arg6);
        object_to_luaval<cocos2d::ui::RichElementText>(tolua_S, "ccui.RichElementText",(cocos2d::ui::RichElementText*)ret);
        return 1;
    }
    if (argc == 8)
    {
        int arg0;
        cocos2d::Color3B arg1;
        uint16_t arg2;
        std::string arg3;
        std::string arg4;
        double arg5;
        int arg6;
        bool arg7;
        ok &= luaval_to_int32(tolua_S, 2,(int *)&arg0, "ccui.RichElementText:create");
        ok &= luaval_to_color3b(tolua_S, 3, &arg1, "ccui.RichElementText:create");
        ok &= luaval_to_uint16(tolua_S, 4,&arg2, "ccui.RichElementText:create");
        ok &= luaval_to_std_string(tolua_S, 5,&arg3, "ccui.RichElementText:create");
        ok &= luaval_to_std_string(tolua_S, 6,&arg4, "ccui.RichElementText:create");
        ok &= luaval_to_number(tolua_S, 7,&arg5, "ccui.RichElementText:create");
        ok &= luaval_to_int32(tolua_S, 8,&arg6, "ccui.RichElementText:create");
        ok &= luaval_to_boolean(tolua_S, 9,&arg7, "ccui.RichElementText:create");
        if(!ok)
        {
            tolua_error(tolua_S,"invalid arguments in function ‘lua_cocos2dx_ui_RichElementText_create‘", nullptr);
            return 0;
        }
        cocos2d::ui::RichElementText* ret = cocos2d::ui::RichElementText::create(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7);
        object_to_luaval<cocos2d::ui::RichElementText>(tolua_S, "ccui.RichElementText",(cocos2d::ui::RichElementText*)ret);
        return 1;
    }
    luaL_error(tolua_S, "%s has wrong number of arguments: %d, was expecting %d\n ", "ccui.RichElementText:create",argc, 6);
    return 0;
#if COCOS2D_DEBUG >= 1
    tolua_lerror:
    tolua_error(tolua_S,"#ferror in function ‘lua_cocos2dx_ui_RichElementText_create‘.",&tolua_err);
#endif
    return 0;
}  

又一次編譯一下項目,然後就能夠在項目裏用了

下個版本號要更新的內容

1.繼續改動Cocos2d-x的RichText的源代碼。使其更好的支持tab和換行
2.增加可點擊的文字,以及點擊後變色
3.為系統字體增加描邊(推斷為系統字體時,描邊採用陰影替代)

其它

下劃線實現的很拙略,假設你有更好的方法一定要告訴我。
或許您希望得到一個不須要改動Cocos2d-x源代碼的版本號(此版本號支持描邊和下劃線)
歡迎交流QQ:446569365

[寒江孤葉丶的Cocos2d-x之旅_33]RichTextEx一款通過HTML標簽控制文字樣式的富文本控件