= =唔
--[[ local labelEx = require("ui.ui_label_ex"):create(300) -- width l:addChild(labelEx, 100) labelEx:setPosition(100, self.visibleSize.height) labelEx:setString("普通文字$C<3>颜色$C<1>普通颜色$S<36>大小$S<0>普通大小$I<101>←图片$B<button>按钮$E<99>表情\n换\n行") ]]-- local UILabelEx = class("UILabelEx", require("ui.ui_common")) -- 控制字符 UILabelEx.C_CHR = "$" -- 单字显示时间间隔 UILabelEx.WAIT_FOR_MESSAGE = 5 / 60 -- 默认字号 UILabelEx.DEFAULT_FONT_SIZE = 24 -- 行间距 UILabelEx.DEFAULT_LINE_HEIGHT = 12 function UILabelEx:ctor(width, show_fast) UILabelEx.super.ctor(self, "") self._defaultFontSize = UILabelEx.DEFAULT_FONT_SIZE self._lineHeight = UILabelEx.DEFAULT_LINE_HEIGHT self._width = width self._show_fast = not not show_fast self._height = self._defaultFontSize self._rootWgt = ccui.Layout:create() self:addChild(self._rootWgt, 100) self:clear() end function UILabelEx:clear() self._contentStr = "" self._texts = self._texts or {} -- 文字 self._images = self._images or {} -- 图片 self._widgets = self._widgets or {} -- 按钮等 self._armatures = self._armatures or {} -- 动画 self._contents = self._contents or {} -- 包含文字图片等实际顺序的数组 self._currentLine = self._currentLine or {} -- 渲染中的本行元素 self._strIndex = 1 -- 遍历的当前字符 self._currentColor = 1 -- 当前文字颜色 self._currentFontSize = self._defaultFontSize -- 当前文字大小 for k, v in pairs(self._texts) do v:removeFromParent() self._texts[k] = nil end for k, v in pairs(self._images) do v:removeFromParent() self._images[k] = nil end for k, v in pairs(self._widgets) do v:removeFromParent() self._widgets[k] = nil end for k, v in pairs(self._armatures) do v:removeFromParent() self._armatures[k] = nil end self._texts = {} self._images = {} self._widgets = {} self._armatures = {} self._contents = {} self._renderPos = { x = 0, y = 0, maxHeight = self._defaultFontSize -- 记录本行最大高度 } self._currentLine = {} if self._scheduleShow ~= nil then cc.Director:getInstance():getScheduler():unscheduleScriptEntry(self._scheduleShow) end self._scheduleShow = nil self._showSeq = 0 end -- 判断utf8字符byte长度 -- 0xxxxxxx - 1 byte -- 110yxxxx - 192, 2 byte -- 1110yyyy - 225, 3 byte -- 11110zzz - 240, 4 byte local function chsize(char) if not char then print("not char") return 0 elseif char > 240 then return 4 elseif char > 225 then return 3 elseif char > 192 then return 2 else return 1 end end -- 计算utf8字符串字符数, 各种字符都按一个字符计算 -- 例如utf8len("1你好") => 3 local function utf8len(str) local len = 0 local currentIndex = 1 while currentIndex <= #str do local char = string.byte(str, currentIndex) currentIndex = currentIndex + chsize(char) len = len +1 end return len end -- 截取utf8 字符串 -- str: 要截取的字符串 -- startChar: 开始字符下标,从1开始 -- numChars: 要截取的字符长度 local function utf8sub(str, startChar, numChars) local startIndex = 1 while startChar > 1 do local char = string.byte(str, startIndex) startIndex = startIndex + chsize(char) startChar = startChar - 1 end local currentIndex = startIndex while numChars > 0 and currentIndex <= #str do local char = string.byte(str, currentIndex) currentIndex = currentIndex + chsize(char) numChars = numChars -1 end return str:sub(startIndex, currentIndex - 1) end function UILabelEx:onEnter() self:ignoreAnchorPointForPosition(false) self:setAnchorPoint(0, 1) end function UILabelEx:onExit() self:clear() end -- 根据代码取文字颜色 function UILabelEx:getColor(code) code = code or 1 local colors = { cc.c3b(255, 255, 255), -- 白色 cc.c3b(0, 0, 0), -- 黑色 cc.c3b(255, 0, 0), -- 红色 cc.c3b(0, 255, 0), -- 绿色 cc.c3b(0, 0, 255), -- 蓝色 cc.c3b(0, 255, 255) -- 黄色 } return colors[code] or colors[1] end function UILabelEx:setDefaultFontSize(size) size = size or self._defaultFontSize if size <= 0 then size = self._defaultFontSize end self._defaultFontSize = size end function UILabelEx:setString(str) self:clear() self._contentStr = str self:refresh() self._scheduleShow = cc.Director:getInstance() :getScheduler() :scheduleScriptFunc(handler(self, self.scheduleShow), UILabelEx.WAIT_FOR_MESSAGE, false) end --[[ "普通文字\eC[color]颜色\eC[1]普通\n颜色\eS[size]大小\eS[24]普通大小\eI[img]←图片\eB[button]按钮\eE[emj]表情" ]]-- function UILabelEx:refresh() print(utf8len(self._contentStr)) while self._strIndex <= utf8len(self._contentStr) do self:progressContentString() end if self._show_fast then self._seq = #self._contents end self:nextLine() self._height = self._renderPos.y self._rootWgt:ignoreAnchorPointForPosition(false) self._rootWgt:setAnchorPoint(cc.p(0, 1)) self._rootWgt:setBackGroundColorType(ccui.LayoutBackGroundColorType.solid) self._rootWgt:setBackGroundColor(cc.c3b(128, 128, 128)) self._rootWgt:setContentSize(self._width, self._height) end -- 处理特殊字符 function UILabelEx:progressContentString() local str = utf8sub(self._contentStr, self._strIndex, 1) self._strIndex = self._strIndex + 1 -- print("str:"..str) if str == "\r" then -- 回车 return elseif str == "\n" then -- 换行 self:progressNewLine() elseif str == UILabelEx.C_CHR then -- 控制符 -- 处理中会影响self._strIndex self:progressControlChar() else -- 普通文字 self:progressNormalText(str) end end -- 换行 function UILabelEx:progressNewLine() self:nextLine() end -- 控制符 function UILabelEx:progressControlChar() local chr = utf8sub(self._contentStr, self._strIndex, 1) self._strIndex = self._strIndex + 1 chr = string.upper(chr) -- print("char:"..chr) local progressFlag = false -- 是否正常解析 local s, e, val = string.find(self._contentStr, "<(.-)>", string.len(utf8sub(self._contentStr, 1, self._strIndex))) if val and s == string.len(utf8sub(self._contentStr, 1, self._strIndex)) then progressFlag = true print("val:"..(val ~= nil and val or "nil")) if chr == "C" then progressFlag = self:changeFontColor(tonumber(val)) -- 修改颜色 elseif chr == "S" then progressFlag = self:changeFontSize(tonumber(val)) -- 修改字号 elseif chr == "I" then progressFlag = self:progressImage(tonumber(val)) -- 插入图片 elseif chr == "B" then progressFlag = self:progressBtn(val) -- 插入按钮 elseif chr == "E" then progressFlag = self:progressEmoji(tonumber(val)) -- 插入表情 end end if progressFlag then self._strIndex = self._strIndex + utf8len(val) + 2 else -- 处理失败,当做通常字符处理 self._strIndex = self._strIndex - 2 local str = utf8sub(self._contentStr, self._strIndex, 1) self._strIndex = self._strIndex + 1 self:progressNormalText(str) end end -- 普通文字 function UILabelEx:progressNormalText(chr) print("progress normal:"..chr) local uiText = ccui.Text:create() uiText:setString(chr) uiText:setVisible(self._show_fast) uiText:setFontSize(self._currentFontSize) uiText:setColor(self:getColor(self._currentColor)) self:addChild(uiText, 100) if uiText:getContentSize().width > self._width then print("too big width, scaled") uiText:setScale(self._width / uiText:getContentSize().width) end if self._renderPos.x + uiText:getContentSize().width > self._width then self:nextLine() end self:setElemPosition(uiText, self._renderPos.x, self._renderPos.y) self._renderPos.x = self._renderPos.x + uiText:getContentSize().width self._renderPos.maxHeight = (self._renderPos.maxHeight > uiText:getContentSize().height) and self._renderPos.maxHeight or uiText:getContentSize().height self._texts[#self._texts + 1] = uiText self._contents[#self._contents + 1] = uiText self._currentLine[#self._currentLine + 1] = uiText return true end function UILabelEx:changeFontColor(code) if not code then return false end self._currentColor = code return true end function UILabelEx:changeFontSize(code) if not code then return false end if code <= 0 then code = self._defaultFontSize end self._currentFontSize = code return true end function UILabelEx:progressImage(code) if not code then return end print("progress image:"..code) local image = t_image[code] if not image then return false end cc.SpriteFrameCache:getInstance():addSpriteFrames(image.plist) local uiImage = ccui.ImageView:create() uiImage:loadTexture(image.name, ccui.TextureResType.plistType) uiImage:setVisible(self._show_fast) self:addChild(uiImage, 100) if uiImage:getContentSize().width > self._width then print("too big width, scaled") uiImage:setScale(self._width / uiImage:getContentSize().width) end if self._renderPos.x + uiImage:getContentSize().width > self._width then self:nextLine() end self:setElemPosition(uiImage, self._renderPos.x, self._renderPos.y) self._renderPos.x = self._renderPos.x + uiImage:getContentSize().width self._renderPos.maxHeight = (self._renderPos.maxHeight > uiImage:getContentSize().height) and self._renderPos.maxHeight or uiImage:getContentSize().height self._images[#self._images + 1] = uiImage self._contents[#self._contents + 1] = uiImage self._currentLine[#self._currentLine + 1] = uiImage return true end function UILabelEx:progressBtn(str) return false end function UILabelEx:progressEmoji(code) if not code then return false end print("progress emoji:"..code) local animation = t_animation[code] if not animation then return false end ccs.ArmatureDataManager:getInstance():addArmatureFileInfo(animation.json) local armature = ccs.Armature:create(animation.name) armature:getAnimation():play("effect") armature:setVisible(self._show_fast) self:addChild(armature, 100) if armature:getContentSize().width > self._width then print("too big width, scaled") armature:setScale(self._width / armature:getContentSize().width) end if self._renderPos.x + armature:getContentSize().width > self._width then self:nextLine() end self:setElemPosition(armature, self._renderPos.x, self._renderPos.y) self._renderPos.x = self._renderPos.x + armature:getContentSize().width self._renderPos.maxHeight = (self._renderPos.maxHeight > armature:getContentSize().height) and self._renderPos.maxHeight or armature:getContentSize().height self._armatures[#self._armatures + 1] = armature self._contents[#self._contents + 1] = armature self._currentLine[#self._currentLine + 1] = armature return true end function UILabelEx:setElemPosition(elem, _x, _y) elem:ignoreAnchorPointForPosition(false) elem:setAnchorPoint(cc.p(0,0)) if _x then local x = _x + elem:getContentSize().width * elem:getAnchorPoint().x elem:setPositionX(x) end if _y then local y = _y + elem:getContentSize().height * elem:getAnchorPoint().y elem:setPositionY(-y) end end function UILabelEx:nextLine() -- 调整当前行元素高度,适应maxHeight for k, v in pairs(self._currentLine) do self:setElemPosition(v, nil, self._renderPos.y + self._renderPos.maxHeight) end self._renderPos.x = 0 self._renderPos.y = self._renderPos.y + self._renderPos.maxHeight + self._lineHeight / 2 self._renderPos.maxHeight = self._defaultFontSize self._currentLine = {} end function UILabelEx:scheduleShow(dt) if self._showSeq < #self._contents then self._showSeq = self._showSeq + 1 self._contents[self._showSeq]:setVisible(true) end end return UILabelEx
还没完成就是了。。。