cocos2d-lua 3.x版本 公司项目 创建可滑动的富文本

image.png
    --local ttt = "对#C(#46a5fe)3#C(#FFFFFF)格范围造成%s点伤害并眩晕#C(#46a5fe)3#C(#FFFFFF)秒"
    local szDesc = string.format(groupData.u_desc[1][1],Msd.getValueByType(_groupId, skillLv + 1))

    self.m_ListView_SkiDepict:removeAllItems()  
    local item = self:createItem(szDesc)
    g_insertItemInListView(self.m_ListView_SkiDepict, item)

--[[
创建描述的每一项    UITaskBar
str 文本描述
space 间距
]]
function PXUISkill:createItem(str,space,fontSize)
    local fontSize = fontSize or 18
    local space = space or 0
    local FONT_WIDTH = 340
    local layout = ccui.Layout:create()
    local nameLabel = g_createUIRichText(str,cc.size(FONT_WIDTH,0),fontSize,nil,nil,2)
    layout:addChild(nameLabel) 
    nameLabel:setTag(1114)

    local h = nameLabel:getContentSize().height 
    layout:setContentSize(cc.size(FONT_WIDTH, h))
    g_setObjectApPosition(nameLabel,cc.p(0,0),cc.p(space,-1))
    local size = nameLabel:getContentSize()
    return layout,nameLabel
end

-- g_createUIRichText(" #C(#EE7600)【1级】前sdfasdfsadfa世今生#B#C(#00EE00)(可接)#H#B#C(#EE7600)【1级】前世今生#H #B#C(#EE7600)【2级】前世今生 #C(#EE7600)【20级】毛毛雨啦#H #B#C(#EE7600)【2级】前世}今生 #H#C(#FFFFFF)哇哈哈哈#H#U#{102038956}#D#C(#EE9A00)龙骑梦境#n#H#U[主]#C(#EE9A00)龙骑梦境#n我前世今生知道#C(#EE9A00)自定义#H#n系统字体",cc.size(-1,0))
-- 创建 一个多颜色文本
-- @text 文本
-- @size 显示大小
-- @fontSize = 文字大小
-- @userEffect = 1 描边 2 阴影
-- @return Node
function g_createUIRichText(text,size,fontSize,defaultTextColor,defaultLineColor,userEffect)
    local rt = UIRichTextNew:create(text,size,fontSize,defaultTextColor,defaultLineColor,userEffect) 
    -- setOutlineSize 设置描边大小
    -- setIsUseSystemFont(true) 设置使用系统字体
    return rt
end

UIRichTextNew

--[[
-- UIRichTextNew 多颜色文本
-- zq 
--]] 
local UIRichTextNew = class(UIRichTextNew,function()
    local node = ccui.Layout:create()
    node:setAnchorPoint(cc.p(0,0))
    return node
end )
local InitColor = nil
local LineColor = nil
local sub = string.sub
local len = string.len
local ofh = 0
local lineSize = 2
local max = math.max 
local min = math.min 
local floor = math.floor
local abs = math.abs
--[[
-- #C 颜色     #C(#FFFFFF)    isColorFormat
-- #n 结束位置 并清空 当前所有状态 
-- #D 结束 不清空当前状态
-- #S @tableStr #D 
#字符串参数 
#该字段一般使用在 下划线文本中使用 如查看战斗回放
#会在回调中传入参数   func(btn,eventType,tableStr) 
#tableStr 的具体作用使用者自己定义, 
#默认的作用是 table.tostring() 返回tabel table.loadstring
--#H 强制换行 最多一行空
--#U 默认颜色的下划线 #U(#FFFFFF) 带颜色的下划线
--#B 加粗
-- ------------------------
-- 函数 
-- @ addLabelTouchEventListeners(func)  传入function  
-- func 会在所有有下滑的文本位置 有响应  
-- 回调的时候会下传递的参数有 @btn,@eventType,@tableStr 
-- btn 按钮 里面有一个tag 代表下划线的数量,第一个出现tag 为1  往下递增
-- eventType 事件 点击 移动 取消 结束 btn 一样
-- tableStr #默认的作用是 table.tostring() 返回tabel table.loadstring
--]]

UIRichTextNew.colorFormat = "#C(#%s)"
UIRichTextNew.wrapFormat = "#n"

function UIRichTextNew:create(text,size,fontSize,defaultTextColor,defaultLineColor,userEffect)

    local rt = UIRichTextNew.new(text,size,fontSize,defaultTextColor,defaultLineColor,userEffect) 

    return rt
end 

function UIRichTextNew:ctor(text,size,fontSize,defaultTextColor,defaultLineColor,userEffect)

    local function uiEventHandler(eventType)

        if eventType == "enter" then--enterTransitionFinish 会在 addChild 的调用   
            -- self:setString(self._text or text) 
        elseif eventType == "exit" then--exitTransitionStart 会在 removeFromParent  的时候调用
        elseif eventType == "cleanup" then
        end

    end

    self:registerScriptHandler(uiEventHandler)

    self._userEffect = userEffect
    self._fontSize = fontSize or 30
    self._showSize = size or cc.size(100,300)
    
    self._isEndless = self._showSize.width == -1  

    if not self._isEndless then 
        if self._showSize.width < self._fontSize then 
            self._showSize.width = self._fontSize*2
        end 
    end 

    self._defaultTextColor = defaultTextColor 
    self._defaultLineColor = defaultLineColor 
    self.m_distanceFieldEnabled = false -- 默认开启描边 
    self.m_fontFilePath = nil
    self.m_isUseSystemFont = false
    InitColor = cc3WHITE 
    LineColor = cc4WHITE
    self:init()  
    self:setString(self._text or text) 
end 


function UIRichTextNew:init()
    self._contentNode = cc.Node:create()
    self:addChild(self._contentNode)
    
    self:setCascadeOpacityEnabled(true)
    self._contentNode:setCascadeOpacityEnabled(true)
end 

function UIRichTextNew:getDefaultTextColor()
    return self._defaultTextColor or InitColor
end 

function UIRichTextNew:getDefaultLineColor()
    return self._defaultLineColor or LineColor
end 

function UIRichTextNew:setAdditionalKerning(additionalKerning)
    self._additionalKerning = additionalKerning
end 

function UIRichTextNew:setLineHeight(lineHeight)
    self._lineHeight = lineHeight
end 

function UIRichTextNew:setTextColor(color)
    self._defaultTextColor = color   
end 

function UIRichTextNew:setLineColor(color)
    self._defaultLineColor = color 
end 

-- 初始化
function UIRichTextNew:initRichNode()
    
    local fieldList = self._fieldList
    local color = self:getDefaultTextColor() 
    local lineColor = self:getDefaultLineColor()
    local funcName = nil
    local isBold = false 
    local isLinkLine = false 
    local isWrap = false
    local linklineColor = cc4YELLOW 
    local linklineSize = 1  
    self._onLabel = nil
    self._leftSpaceWidth = self._showSize.width  

    local function initRichNode() 
        local i = fieldList[self._readIndex]
        if not i then 
            return 
        end 
        local length = i + 1
        if self._readlength < length then 
            self._readlength = length
            return initRichNode()
        end 
        local head = self:read(1,utf8)
        if self.m_isReadColor then 
            head = ""
        end 
        self.m_isReadColor = false 
        --cclogError({"head",head,self._readlength,length,self._readIndex,#fieldList})
        if head == "C" then --颜色
            self:readMoveBy(1)
            color = self:color() 
        elseif head == "B" then --加粗 
            self:readMoveBy(1)
            isBold = self:Bold()
        elseif head == "H" then --换行
            isWrap = true 
            self:readMoveBy(1)
        elseif head == "U" then --下划线
            self:readMoveBy(1)
            isLinkLine = true 
            lineColor = self:linkLine() or self:getDefaultLineColor()
            self._lineCount = self._lineCount + 1  
        elseif head == "n" then --结束标志 状态清空
            self:readMoveBy(1)
            color = self:getDefaultTextColor()  
            isBold = false 
            isLinkLine = false
            isWrap = false
            lineColor = self:getDefaultLineColor() 
            funcName = nil
            self._tableStr = nil
        elseif head == "F" then  -- 读取一个funcName
            self:readMoveBy(1)
            funcName = self:funcName()  
        elseif head == "S" then --tableStr 
            self:readMoveBy(1)
            self._tableStr = self:readShowStr() 
            if self._tableStr then 
                self:readMoveBy(len(self._tableStr))
            end 
        elseif head == "D" then --结束标志 不清空
            self:readMoveBy(1)
        end 

        self._color = color
        self._isBold = isBold
        self._isLinkLine = isLinkLine
        self._lineColor = lineColor

        local showStr = self:readShowStr() 
        if showStr then    
            if isWrap then 
                self:addNewLine()
            end 

            self:subStringByWidth(showStr) 
            
            isWrap = false 
        end 

        self._readIndex = self._readIndex + 1
        return initRichNode()
    end 
    --local time = socket:gettime()
    initRichNode()
    --cclogError({"initRichNode  时间 ", socket:gettime() - time},true)
end 

function UIRichTextNew:addNewLine()

    if not self._isEndless  then
        self._newLineState = true  
    end 
    self._leftSpaceWidth = self._showSize.width   

end

function UIRichTextNew:addNextNewLine()

    if not self._isEndless  then
        self._newNextLineState = true  
    end 

end 

function UIRichTextNew:updateNextNewLine()
    
    if self._newNextLineState then 
        self._newNextLineState = false 
        self:addNewLine() 
    end 
    
end

function UIRichTextNew:getResidueLength(label)
    local width = self._leftSpaceWidth - label:getContentSize().width 
    return width
end 

-- 如果返回的是长度 就是大于 文本的长
function UIRichTextNew:isLongLine(label) 
    
    if self._isEndless  then 
        return false 
    end 
    local width = self:getResidueLength(label)
    if width<=0 then 
        return true 
    end 
end 

function UIRichTextNew:isShortLine(label)
    if self._isEndless  then 
        return false 
    end 
    local width = self:getResidueLength(label)
    if width >= 0 then 
        return true 
    end 
end 

--[[
-- 优化 逻辑 
-- #一开始进来判断是否大于 总宽度 如果大于 根据大于的百分比 减少文本的长度
-- 如果个数小于等于2 就一个一个往下减少
-- 如果减少后发现小于宽度 就一个一个往上增加
-- #如果小于 那就直接返回 不需要处理
--
--]]
function UIRichTextNew:loadBestLabel(label)
    local text = label:getString()
    if self._isEndless then 
        return text
    end 
     
    local endSize = 1 -- 结束位置 
    local subSize = 1 
    local len = utf8.len 
    local sub = utf8.sub

    --cclogError({" UIRichTextNew:loadBestLabel(label)",text})
    local strLen = len(text) -- 当前文本长度
    local width = self:getResidueLength(label)
    local maxWidth = self._leftSpaceWidth

    if width>=0 then 
        return text
    else 
        subSize =  strLen - floor(maxWidth/abs(width)*strLen*1)-1
        subSize = max(subSize,1) 
    end 

    local str = sub(text,1,-subSize)
    label:setString(str)
    --print_t({"loadBestLabel",subSize,width,maxWidth,strLen,str})
    local addState = 0 -- 是否减少过 
    local subState = 0 --是否增加过

    local function loadBestLabel() 
        --print(label:getString())
        --cclog(addState and "true" or "false",subState and "true" or "false")
        if self:isLongLine(label) then -- -
            if subState == 1 then 
                 str = sub(text,1,-(subSize+1))
                return str 
            end 
            str = sub(text,1,-(subSize+1))
            subSize = subSize + 1  
            if addState == 0 then 
                addState = 1
                self:addNextNewLine()
            end 
        elseif self:isShortLine(label) then -- + 
            if addState == 1 then 
                return str 
            end 
            str = sub(text,1,-(subSize-1))
            subSize = subSize - 1  
            if subState == 0 then 
                subState = 1
            end 
        else 
            return str
        end  

        --[[local strSize = len(str)
        --cclogError({str,subSize,addState,subState,strSize})
        if strSize == 0 then
            self:addNewLine()
            return ""
        end ]]
        label:setString(str) 
        return loadBestLabel()
    end 

    return loadBestLabel()
end 

-- 是否需要描边 
function UIRichTextNew:setOutlineSize(outlineSize)
    self.m_outlineSize = outlineSize or 0 
    if self.m_outlineSize ~= 0 then 
        self.m_distanceFieldEnabled = false 
    else 
        self.m_distanceFieldEnabled = false 
    end 
end 

-- 当字体路径 
function UIRichTextNew:setFontPath(fontFilePath)
    self.m_fontFilePath = fontFilePath
end 

function UIRichTextNew:setIsUseSystemFont(isUseSystemFont)
    self.m_isUseSystemFont = isUseSystemFont 
end 

function UIRichTextNew:setLabelParameter(str,label)
    local parameter = {label = label ,str = str,fontSize = self._fontSize,textColor = self._color,outColor = cc4BLACK,outlineSize = self.m_outlineSize,distanceFieldEnabled = self.m_distanceFieldEnabled,fontFilePath = self.m_fontFilePath,isUseSystemFont = self.m_isUseSystemFont,userEffect = self._userEffect }
    return g_setLabelParameter(parameter)
    
    --[[if userEffect == 1 then 
        g_labelSetEffect(label)
    elseif userEffect == 2 then 
        g_labelSystemFontSetEffect(label)
    elseif userEffect == 0 then 
        label1:disableEffect()
    end

    label:setSystemFontSize(self._fontSize) 
    label:setTextColor(self._color or cc3WHITE)
    label:setString(str)]]
end 

function UIRichTextNew:createLabel(str)
    local label = g_createFont(str,self.m_isUseSystemFont)
    label:setAnchorPoint(cc.p(0,0))
    --[[label.getContentSizeI = label.getContentSize
    label["getContentSize"] = function()
        return label:getContentSizeI()
    end ]]
    return label
end 

local boldSize = 0
function UIRichTextNew:cloneLabel(str) 
    --local time = socket:gettime() 
    --local str = label:getString() 
    local fontSize = self._fontSize 
    local l = self:createLabel("")
    self:setLabelParameter(str,l)
    --print_t({"克隆 一个LABEL 花费的时间",socket:gettime()-time})
    return l 
end  

function UIRichTextNew:setL_A(label)
    if self._additionalKerning then 
        label:setAdditionalKerning(self._additionalKerning)
    end 
    if self._lineHeight then 
        label:setLineHeight(self._lineHeight)
    end 
end 

function UIRichTextNew:cloneBold(label)
    local str = label:getString() 
    local fontSize = self._fontSize + boldSize
    local l = self:createLabel(str)
    self:setL_A(label)
    g_exchange(label,l)
    self:setLabelParameter(str,l)
    label:getParent():addChild(l)
    label._cloneLabelList = label._cloneLabelList or {}
    table.insert(label._cloneLabelList,l)
end 

function UIRichTextNew:doCloneLabelEvent(label,eventName,...)
    label[eventName](label,...)
    if label._cloneLabelList then 
        for i,v in ipairs(label._cloneLabelList) do 
            v[eventName](v,...)
        end 
    end 
end 

-- 创建 线
function UIRichTextNew:createLine(label,color,borderWidth)
    local size = label:getContentSize()
    local borderColor = {}

    for i,v in pairs(color) do 
        borderColor[i] = v/255
    end 

    local shape3 = display.newLine({{0,0}, {size.width,0}},
    {borderColor = borderColor,
    borderWidth = borderWidth}) 
    return shape3
end 

--
function UIRichTextNew:addCenterLineLayer(label,color4f)
    local layer = self:createLine(label,cc4BLACK,2)  
    g_exchange(label,layer)

    local lySize = layer:getContentSize()
    local lbSize = label:getContentSize()
    lySize.height = lineSize 
    layer:setContentSize(lySize)

    layer:setPositionY(layer:getPositionY()-lbSize.height/2+lySize.height/2)
    g_setPositionSpriteCenter( label,layer,nil,nil,nil,true) 
    label:getParent():addChild(layer)
    return layer
end 

function UIRichTextNew:addBottomLineLayer(label)

    self:registerLabelTouchEventListener(label)
    label:enableUnderline()
    --[[local layer = self:createLine(label,self._lineColor,1)  
    g_exchange(label,layer)
    local lySize = layer:getContentSize()
    lySize.height = lineSize 
    layer:setContentSize(lySize)
    g_setNodeByOntherNodePosition2(label,layer,g_NODEDOWN,-lineSize)
    label:getParent():addChild(layer)]]
    return layer
end 

-- 给label 注册点击事件 
function UIRichTextNew:registerLabelTouchEventListener(label)
    local tableStr = self._tableStr
    local function func(btn,eventType)

        if eventType == ccui.TouchEventType.began then
            self:doCloneLabelEvent(label,"setScale",1.1)
        elseif eventType == ccui.TouchEventType.ended then
            self:doCloneLabelEvent(label,"setScale",1)
        elseif eventType == ccui.TouchEventType.canceled then
            self:doCloneLabelEvent(label,"setScale",1)
        end 

        local func = self._touchFunc
        if func then 
            func(btn,eventType,tableStr)
        end 
        --cclogError({"fName", fName})
    end    

    local btn = UIBase:createNodeBtn(label,func)  
    btn:setTag(self._lineCount) 
    g_exchange(label,btn)
    g_setPositionSpriteCenter( label,btn,nil,nil,nil,true) 
    label:getParent():addChild(btn)
    return btn
end 

-- 给label:添加事件  
-- @fName #U的位置,第一次出现就填1 
-- @func btn事件一样
function UIRichTextNew:addLabelTouchEventListeners(func)
    self._touchFunc = func 
end 

-- 添加 Label  
function UIRichTextNew:setLabelPosition(str)

    --print_t({"UIRichTextNew:setLabelPosition",str})
    local label = self:cloneLabel(str)
    local outlineColor = self._color 
    local outlineSize = 1
    local isBold = self._isBold
    local labelSize = label:getContentSize()

    if outlineColor then 
        outlineColor.a = outlineColor.a or 255
    end 

    if not self._contentSize then 
        self._contentSize = cc.size(0,labelSize.height)
    end 
 
    --label:setAnchorPoint(cc.p(0,0))
    local labelArp = cc.p(0,0)--label:getAnchorPoint()
    local basePosY = (labelArp.y-1)*labelSize.height 
    local basePosX = labelSize.width*labelArp.x  

    if self._newLineState then 
        if self._onLabel then 
            g_setNodeByOntherNodePosition2(self._onLabel,label,g_NODEDOWN,ofh)
        end 
        label:setPositionX(labelSize.width*labelArp.x)
    else 
        if self._onLabel then 
            g_setNodeByOntherNodePosition2(self._onLabel,label,g_NODERIGHT,ofh)
        else 
            label:setPosition(cc.p(basePosX,basePosY))
        end 
    end    

    self._leftSpaceWidth = self._leftSpaceWidth - labelSize.width
    local width = self._leftSpaceWidth
    if not self._newLineState then   
        if width <= 0 then 
            self:addNewLine()
        end 
    end 

    self._contentSize.height = -label:getPositionY() + labelSize.height + basePosY
    self._contentSize.width = max(self._contentSize.width,label:getPositionX()+labelSize.width-basePosX) 
    --cclogError({cc.p(label:getPosition()),self._contentSize,labelSize})
    self._newLineState = false 
    self._onLabel = label
    self:setL_A(label)
    self._contentNode:addChild(label)

    if isBold then -- 加粗 
        --[[local boldScale = 1.4 
        g_setFontSize(label,{fontSize = self._fontSize*boldScale,fontFilePath = "common/bhzg.ttf"})
        label:setScale(1/1.4*1.1)]]
        label:disableEffect(1)
        label:enableBold()
        --self:cloneBold(label)
    end 

    if self._isLinkLine then -- 下划线 
        --label:enableUnderline() -- jobType_icon
        self:addBottomLineLayer(label) 
    end 

end 

function UIRichTextNew:_subStringByWidth(str) 

    local label = self._baseLabel--label or self:createLabel(str) 
    label:setString(str)
    --label:setDimensions(self._leftSpaceWidth, self._fontSize)
    self:updateNextNewLine()
    --print_t({"_subStringByWidth",str})
    if true then
        --local time = socket:gettime()
        local str = self:loadBestLabel(label)
        if str~="" then
            --print_t({"setLabelPosition ",str})
            self:setLabelPosition(str)
        end 
        --print_t({"*****************",socket:gettime()-time})
        return str

    else 
        local strSize = len(str)
        if strSize == 0 then
            self:addNewLine()
            return str
        end 

        if self:isLongLine(label) then 
            str = sub(str,1,-2)
            return self:_subStringByWidth(str)
        else 
            self:setLabelPosition(str)
            return str  
        end 
    end 
end 

-- 耗时间的地方 
function UIRichTextNew:subStringByWidth(text)

    --local time = socket:gettime()
    --local list = {}
    local began = 1 
    --local len = utf8.len 
    --local sub = utf8.sub 
    local maxSize = len(text)
    --self:setLabelParameter(str,self._baseLabel)
    local label = self._baseLabel--self:createLabel(str)  

    local nextText = nil 
    local str = nil
    while true do 
        nextText = sub(text,began) 
        if len(nextText) <= 0 then 
            break
        end 
        --local time = socket:gettime()
        str = self:_subStringByWidth(nextText)   
        --local t = socket:gettime()-time
        --print_t({str,t})
        began = len(str) + began 
        --table.insert(list,str)

        if began > maxSize then 
            break
        end 
        
    end
    --local t = socket:gettime()-time
    --print_t({"",t})
    --cclogError({list,text})
    --return list 
end

function UIRichTextNew:isEmpty() 
    return self._text == "#n" or self._text == ""
end

function UIRichTextNew:setString(text)

    text =  tostring(text)
    --local time = socket:gettime()
    if text then 
        local typeStr = "#"
        local ch = sub(text,1,1)
        if ch~=typeStr then
            text = "#n"..text
        end
    end 

    if self._text == text then 
        return 
    end 
 
    self._text = text -- 文本
    if self:isEmpty() then 
        return 
    end  
 
    --print_t({"=====UIRichTextNew==setString======",text})

    if not UIRichTextNew._baseLabel then -- userEffect 1  
        UIRichTextNew._baseLabel = UIRichTextNew:createLabel("") 
        UIRichTextNew._baseLabel:retain()
        --UIRichTextNew.parameter = self:setLabelParameter(str,UIRichTextNew._baseLabel)
        --print_t("创建富文本  ------------------- ")
    else 
        --[[local ttfConfig = UIRichTextNew.parameter
        ttfConfig.fontSize = self._fontSize
        UIRichTextNew._baseLabel:setTTFConfig(ttfConfig)]]
        --self:setLabelParameter(str,UIRichTextNew._baseLabel)
    end 

    self:setLabelParameter(str,UIRichTextNew._baseLabel)
    self._baseLabel = UIRichTextNew._baseLabel
    self._lineCount = 0
    self._touchFunc = nil 
    self._fieldList = {} -- 查找#的位置
    self._readIndex = 1 -- 读取fieldList下表位置
    self._readlength = 1 -- 读取 text 位置
    self._texteSize = 0 -- 实际显示文本 条数
    self._newLineState = false  
    self:formatNode()
    --print_t({"创建富文本的时间 ",socket:gettime()-time})
    --cclogError("",true)
end 

function UIRichTextNew:getString()
    return self._text
end 

function UIRichTextNew:formatNode() 

    --local time = socket:gettime()
    if self._contentNode then 
        self._contentNode:removeFromParent()
        self._contentNode = nil 
    end 

    self._contentNode = cc.Node:create()
    self._contentNode:setAnchorPoint(cc.p(0,0))
    self:addChild(self._contentNode)
    self._contentNode:setCascadeOpacityEnabled(true)
    --print_t({"富文本  ----------------",self._text})
    --self._contentNode:removeAllChildren() 
    self._fieldList = self:findFieldList(self._text,typeStr)
    self._contentSize = cc.size(0,0) 

    --print_t({"时间一",socket:gettime()-time})
    self:initRichNode()
    
    if self._contentSize then 
        self:setContentSize(self._contentSize) 
        self._contentNode:setPosition(cc.p(0,self._contentSize.height))
    end 
end 

-- 加粗 
function UIRichTextNew:Bold()
    return true 
end 

-- 下划线 
function UIRichTextNew:linkLine() 
    local lineColor = self:color()
    if lineColor then 
        lineColor.a = 255
    end 
    return lineColor 
end 

-- 点击事件
function UIRichTextNew:downCallBack()
    return true 
end 

-- 颜色 #F(#name) 固定 7位长度
function UIRichTextNew:funcName()
    local length = 7
    local str = self:read(length) 
    local fName = self:findFuncName(str) 
    if fName then 
        self:readMoveBy(length)
        return fName 
    end 
    return nil
end 

function UIRichTextNew:findFuncName(str) 
    if self:isFuncNameFormat(str) then  
        local fName = sub(str,3,6)
        return fName 
    end 
end 

-- 判断是否为颜色格式
function UIRichTextNew:isFuncNameFormat(str)
    local length = len(str) 
    if length == 7 then 
        local isLeftBracket,isRightBracket = string.find(str, "%b()")
        local isSType = string.find(str, "#")
        if isLeftBracket == 1 and  isRightBracket == 7 and isSType == 2 then 
            return true 
        end 
        --[[local isLeftBracket = sub(str,1,1) == "("
        local isRightBracket = sub(str,7,7) == ")"
        local isSType = sub(str,2,2) == "#" 
        if isLeftBracket and isRightBracket and isSType then 
            return true  
        end ]]
    end 
    return false 
end 

-- 颜色 #C(#EE7600)
function UIRichTextNew:color()
    local length = 9
    local str = self:read(length) 
    local color = self:findColor(str) 
    if color then 
        self:readMoveBy(length)
        self.m_isReadColor = true 
        --self._readIndex = self._readIndex + 1
        return color 
    end 
    return self:getDefaultTextColor() 
end 

function UIRichTextNew:findColor(str)
    if self:isColorFormat(str) then  
        local str = sub(str,3,8)
        local color = g_16To10(str)
        return color 
    end 
end 

-- 判断是否为颜色格式
function UIRichTextNew:isColorFormat(str)
    local length = len(str) 
    if length == 9 then 
        local isLeftBracket,isRightBracket = string.find(str, "%b()")
        local isSType = string.find(str, "#")
        if isLeftBracket == 1 and  isRightBracket == 9 and isSType == 2 then 
            return true 
        end 
        --[[local isLeftBracket = sub(str,1,1) == "("
        local isRightBracket = sub(str,9,9) == ")"
        local isSType = sub(str,2,2) == "#" 
        if isLeftBracket and isRightBracket and isSType then 
            return true  
        end ]]
    end 
    return false 
end 

-- 只读
function UIRichTextNew:read(size,isUtf8)
    local l = self._readlength
    local length = l + size - 1
    local str = sub(self._text,l,length)
    return str 
end 

-- 读文字 并且 移动位置
function UIRichTextNew:readTo(size)
    local l = self._readlength
    local length = l + size - 1  
    local str = sub(self._text,l,length)
    self:readMoveBy(size)
    return str 
end 

-- 读取 当条显示的文本
function UIRichTextNew:readShowStr()
    local showStr = nil 
    local _began = self._readlength
    local readIndex = self._readIndex
    local fieldList = self._fieldList

    local text = self._text
    local _end = fieldList[readIndex+1]
    if not _end then 
        _end = len(text)
    else 
        _end = _end - 1 
    end 

    if _began <= _end then 
        self._texteSize = self._texteSize + 1
        showStr = sub(text,_began,_end)
    end 

    return showStr
end 

-- 移动位置
function UIRichTextNew:readMoveTo(length)
    self._readlength = length
end 

-- 移动位置
function UIRichTextNew:readMoveBy(length)
    self:readMoveTo(self._readlength + length)
end

-- 字符串  转颜色
function g_16To10(c)
    local a = c or "369119"
  
    local color = {255,255,255}
    local colorCount = 1 
    local as = sub(tostring(a),1)
    local c16 = nil 
    while as and as~="" do 

        c16 = sub(as,1,2)

        as = sub(as,3)
        color[colorCount] = tonumber(string.format("%d","0x"..c16))
        colorCount = colorCount + 1
    end 

    --cclogError({"转换后的数值",color})

    return cc.c3b(color[1],color[2],color[3])
end 

-- 字符串  转颜色
function g_10To16(c3)
    local r = c3.r
    local g = c3.g
    local b = c3.b
    local headStr = ""

    local function to16(s)
        local str = string.format("%#x",s)
        local c16 = sub(str,3)
        local lenth = len(c16)
        if lenth == 0 then 
            c16 = "00"
        elseif lenth == 1 then 
            c16 = "0"..c16
        end 
        --cclogError({s,str,c16})
        return c16
    end 
    
    local rs = to16(r)
    local gs = to16(g)
    local bs = to16(b)

    return headStr..rs..gs..bs
end 

-- 把一段字符串 拆分为N段字符串
function UIRichTextNew:subStringList(s,sType)

    sType = sType or "#"
    local t = {}
    local i = 0 
    local began = 0 
    local str = nil 
    while true do
        i = string.find(s, "#", i+1)
        if i == nil then break end
        str = sub(s,began,i) 
        table.insert(t,str)
        began = i 
    end

    return t
end 

-- 找到位置 有特殊 字符的位置
function UIRichTextNew:findFieldList1(s,sType)

    sType = sType or "#"
    local t = {}
    local i = 0 
    while true do
        i = string.find(s, "#", i+1)
        if i == nil then break end
        table.insert(t,i)
    end
    return t
end 

function UIRichTextNew:findFieldList(str,typeStr)

    typeStr = typeStr or "#"

    local strList={}
    local time = socket:gettime()
    strList = string.splitPos(str, typeStr)
    local time1 = socket:gettime()
    --print_t({"111111111111",str,strList,time1-time})
    --[[strList={} 
    local begin=1
    local count=1
    local lenth = len(str)

    for  i=1, lenth do
    local ch = sub(str,i,i)
    if ch == typeStr then 
    strList[count]= i
    begin=i+1 
    count=count+1
    end
    end 
    local time2 = socket:gettime()
    print_t({"222222222222",str,strList,time2-time1})]]


    if #strList == 0 then 
        strList[1] = 1
    end 

    --print_t({"UIRichTextNew:findFieldList(str,typeStr)",strList})
    return strList
end 

return UIRichTextNew



你可能感兴趣的:(cocos2d-lua 3.x版本 公司项目 创建可滑动的富文本)