require("luaScript.Tools.Nodes.CCNode2D"); cc.Widget.ClassName = "Widget" function cc.Widget:extend(node) cc.Node2D:extend(node); -- 名字 node:setName("Widget"); end function cc.Widget:loadFromXmlNode(xmlNode) cc.Node2D.loadFromXmlNode(self , xmlNode); self.SpriteFrameFiles = xmlNode.SpriteFrameFiles; if self.SpriteFrameFiles then for i , v in ipairs(self.SpriteFrameFiles) do cc.SpriteFrameCache:getInstance():addSpriteFramesWithFile(v); end end self:ignoreContentAdaptWithSize(xmlNode.ignoreSize); local sizeType = xmlNode.sizeType; self:setSizeType(sizeType); if sizeType == cc.SizeType.percent then self:setSizePercent(xmlNode.sizePercent); else self:setSize(xmlNode.size); end local positionType = xmlNode.positionType; self:setPositionType(positionType); if positionType == cc.PositionType.percent then self:setPositionPercent(xmlNode.positionPercent); end self:setActionTag(xmlNode.actionTag); self:setTouchEnabled(xmlNode.touchAble); self:setFlippedX(xmlNode.flipX); self:setFlippedY(xmlNode.flipY); if xmlNode.ClickSoundFile then self:setClickSoundFile(xmlNode.ClickSoundFile); end local layoutParameter = xmlNode.layoutParameter; if layoutParameter then local parameter; local paramterType = layoutParameter.type; if paramterType == cc.LayoutParameterType.linear then parameter = cc.LinearLayoutParameter:create(); parameter:setGravity(layoutParameter.gravity); if layoutParameter.fillWidth ~= nil then parameter:setFillWidth(layoutParameter.fillWidth); parameter:setFillHeight(layoutParameter.fillHeight); end elseif paramterType == cc.LayoutParameterType.relative then parameter = cc.RelativeLayoutParameter:create(); parameter:setAlign(layoutParameter.align); elseif paramterType == cc.LayoutParameterType.none then parameter = cc.LayoutParameter:create(); end if parameter then parameter:setMargin(layoutParameter.margin); self:setLayoutParameter(parameter); end end end function cc.Widget:createNode() local layer = cc.Widget:create(); cc.Widget:extend(layer); return layer; end -- 获得世界坐标系的矩形,左下角和宽高 function cc.Widget:getWorldRect() local containerPos = self:getParent():convertToWorldSpace2D(cc.p(self:getLeftInParent() , self:getBottomInParent())); local containerSize = self:getContentSize(); local rect = cc.rect(containerPos.x , containerPos.y , containerSize.width , containerSize.height); return rect; end function cc.Widget:collectAllImage() local spriteFiles = {}; local function visit(child) if child.collectPListFiles then local files = child:collectPListFiles(); for i , v in pairs(files) do spriteFiles[v] = 1; end end end self:visitNode(visit); return spriteFiles; end -- 从新计算这个Widget以及下面所有子Widget引用到了什么PList文件,并记录到SpriteFrameFiles中 function cc.Widget:recalcAllPList() local spriteFiles = self:collectAllImage(); local spriteFrameFiles = {}; for i , v in pairs(spriteFiles) do if string.endsWith(string.lower(i) , ".plist") then table.insert(spriteFrameFiles , i); end end table.sort(spriteFrameFiles , function(a,b)return a < b;end); self:setSpriteFrameFiles(spriteFrameFiles); end cc.Widget.setAutoSize = cc.Widget.ignoreContentAdaptWithSize; cc.Widget.isAutoSize = cc.Widget.isIgnoreContentAdaptWithSize; function getUITexture(name , t) return {name , t}; end function collectPListFile(files , name , t) if t == cc.TextureResType.plistType then local spriteFrame = cc.SpriteFrameCache:getInstance():getSpriteFrameByName(name); if spriteFrame then table.insert(files , spriteFrame:getPListFile()); end else table.insert(files , name); end return nil; end -- 编辑器模式,可以plist代替文件 if EditorMode then function setUITexture(func , self, names) -- 本地文件,就找下有没有这个文件,如果没有,就用plist里的 if names[2] == cc.TextureResType.localType then -- 定义了文件,并且文件不存在 if names[1] ~= "" and names[1] ~= nil and not cc.FileSystem:fileExists(names[1]) then local pathName , baseName , ext = string.splitFilename(names[1]); print("拆开了不存在的png:" , pathName , baseName , ext); -- 找这个文件所在文件夹的所有的plist local files = cc.FileSystem:listFiles(pathName); for i , pkg in ipairs(files) do print("遍历文件" , i , pkg); local plistFile = pathName .. "/" .. pkg; local pkgPath , pkgBase , pkgExt = string.splitFilename(plistFile); if string.lower(pkgExt) == "plist" then print("加载plist" , plistFile); cc.SpriteFrameCache:getInstance():addSpriteFramesWithFile(plistFile); local spriteFrame = cc.SpriteFrameCache:getInstance():getSpriteFrameByName(baseName); if spriteFrame then print("使用PLIST中的代替:" , plistFile , baseName); func(self , baseName , cc.TextureResType.plistType); return; end end end end end func(self , names[1] , names[2]); end else function setUITexture(func , self, names) func(self , names[1] , names[2]); end end -- 把Size以动画形式设置到size值 function cc.Widget:animSize(targetSize , duration) if not tolua.isnull(self.AnimSizeAction) then self:stopAction(self.AnimSizeAction); end self.AnimSizeAction = nil; local currentSize = self:getSize(); if targetSize.x ~= currentSize.x or targetSize.y ~= currentSize.y then local action = cc.EaseSineOut:create(cc.UISizeTo:create(duration , targetSize)); self.AnimSizeAction = action; self:runAction(action); end end -- 把Position以动画形式设置到translation值(xyz) function cc.Widget:animTranslation(targetPosition , duration) if not tolua.isnull(self.AnimPositionAction) then self:stopAction(self.AnimPositionAction); end self.AnimPositionAction = nil; local currentSize = self:getTranslation(); if targetPosition.x ~= currentSize.x or targetPosition.y ~= currentSize.y or targetPosition.z ~= currentSize.z then local action = cc.EaseSineOut:create(cc.MoveTo:create(duration , targetPosition)); self.AnimPositionAction = action; self:runAction(action); end end -- 把SizePercent以动画形式设置到size值 function cc.Widget:animSizePercent(targetSizePercent , duration, callbackFunc) if not tolua.isnull(self.AnimSizePercentAction) then self:stopAction(self.AnimSizePercentAction); end self.AnimSizePercentAction = nil; local currentPercent = self:getSizePercent(); if targetSizePercent.x ~= currentPercent.x or targetSizePercent.y ~= currentPercent.y then local action = cc.EaseSineOut:create(cc.UISizePercentTo:create(duration , targetSizePercent)); self.AnimSizePercentAction = action; self:runActions(action, callbackFunc); end end -- 把PositionPercent以动画形式设置到size值 function cc.Widget:animPositionPercent(targetSizePercent , duration, callbackFunc) if not tolua.isnull(self.AnimPositionPercentAction) then self:stopAction(self.AnimPositionPercentAction); end self.AnimPositionPercentAction = nil; local currentPercent = self:getPositionPercent(); if targetSizePercent.x ~= currentPercent.x or targetSizePercent.y ~= currentPercent.y then local action = cc.EaseSineOut:create(cc.UIPositionPercentTo:create(duration , targetSizePercent)); self.AnimPositionPercentAction = action; self:runActions(action, callbackFunc); end end -- 把子元素一起设置Enable function cc.Widget:setEnableds(enable) local function visit(node) if node.setEnabled then node:setEnabled(enable); end end self:visitNode(visit); end -- 把子元素一起设置GreyEnabled function cc.Widget:setAllGreyEnabled(enable) local function visit(node) if node.setGreyEnabled then node:setGreyEnabled(enable); end end self:visitNode(visit); end -- 注册按钮被点击的事件 function cc.Widget:registerClick(callbackFunc, clickBeginFunc, clickCancelFunc,showGlobalEffect) local function onTouchEvent(sender, eventType, touch) -- 点击开始的回调 if eventType == cc.TouchEventType.began then if(clickBeginFunc)then clickBeginFunc(self) end if(not showGlobalEffect)then ignoreCurTouchEffect(); end --和美术约定,按下会播narrow的动画剪切,松开会播upspring; self:playClip("anxia") -- 点击结束的回调 elseif eventType == cc.TouchEventType.ended then local currentView = app.currentView local buttonName = self:getName() local currentViewName = ""; if(currentView)then currentViewName = currentView.__cname end if(callbackFunc)then callbackFunc(self, eventType, touch); end self:playClip("huanyuan") -- 点击取消的回调 elseif eventType == cc.TouchEventType.canceled then if(clickCancelFunc)then clickCancelFunc(self); end self:playClip("huanyuan") end return true; end self:setTouchEnabled(true) self:addTouchEventListener(onTouchEvent) end --\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ function cc.Widget:initDragValue() -- widget数据 self.dragItemData = nil; -- 是否允许拖曳 self.EnableDrag = true; -- 表示按下的时候的鼠标位置 self.TouchBeginPos = nil; -- 表示按下时控件所在的位置 self.StartItemPos = nil; -- 开始时的ZOrder self.StartItemZOrder = nil; -- 当前正在拖动的控件 self.onDragItem = nil; --/////////////////////// -- 拖拽开始的回调 -- 回调格式onDragStart(),如果返回false,则拖拽无效 self.onDragStart = nil; -- 拖拽结束的回调,会在拖拽到的目标上产生这个回调 -- 回调格式onDragEnd(源控件数据,目标控件数据) self.onDragEndFunc = nil; -- 拖拽取消的回调 -- 回调格式onDragCancel() self.onDragCancel = nil; -- 移动时的回调 self.onMoveFunc = nil; --//////////////////////////// -- 查找函数 self.findNodeFunc = nil; end -- 注册点击事件(用于控件拖动) function cc.Widget:registerDragClick(showGlobalEffect) local function onTouchEvent(sender, eventType, touch) -- 点击开始的回调 if eventType == cc.TouchEventType.began then self:dragBeginFunc(touch) if(not showGlobalEffect)then ignoreCurTouchEffect(); end -- 点击结束的回调 elseif eventType == cc.TouchEventType.ended then self:dragBackFunc(touch) -- 点击取消的回调 elseif eventType == cc.TouchEventType.canceled then self:dragCancelFunc(touch) elseif eventType == cc.TouchEventType.moved then self:dragMoveFunc(touch) end return true; end self:initDragValue(); self:addTouchEventListener(onTouchEvent) end function cc.Widget:registerTouchEvent(toucheBegin, touchMove, touchEnd, touchCancel) local function onTouchEvent(sender, eventType, touch) -- 点击开始的回调 if eventType == cc.TouchEventType.began then if toucheBegin then toucheBegin(touch) end -- 点击结束的回调 elseif eventType == cc.TouchEventType.ended then if touchEnd then touchEnd(touch) --toucheBegin(touch) end -- 点击取消的回调 elseif eventType == cc.TouchEventType.canceled then if touchCancel then touchCancel(touch) --toucheBegin(touch) end elseif eventType == cc.TouchEventType.moved then if touchMove then touchMove(touch) end end return true; end self:addTouchEventListener(onTouchEvent) end -- 点击结束 function cc.Widget:dragBackFunc(touch) -- 没有装备就不能拖动,返回 if not self.EnableDrag then return false end -- 看鼠标落点在哪个控件上 local touchPos = touch:getLocation(); local targetId = self:findDragedCtrl(touchPos) if targetId then local startPosition = self.StartItemPos -- 取消移动 self:cancelMove(true, touch); -- 产生结束拖拽事件 if self.onDragEndFunc then self.onDragEndFunc(self.dragItemData, targetId, touch) end return false else -- 取消移动 self:cancelMove(nil, touch); end end function cc.Widget:dragBeginFunc(touch) -- 产生开始拖拽事件 if self.onDragStart then self.onDragStart(touch) end if not self.EnableDrag then return false; end local touchPos = touch:getLocation(); if self:hitTest(touchPos) then self.TouchBeginPos = touchPos; self.StartItemPos = self:getPosition(); self.StartItemZOrder = self:getLocalZOrder(); self.onDragItem = self.dragItemData; -- 开始移动,就弹到最前面 self:setLocalZOrder(100); end return true; end function cc.Widget:dragMoveFunc(touch) if not self.EnableDrag then return false; end if self.onMoveFunc then self.onMoveFunc(touch); end local touchPos = touch:getLocation(); -- 计算开始点的世界坐标 local worldStartPos = self:getParent():convertToWorldSpace(self.StartItemPos) -- 计算鼠标从点下到现在移动了多远 local offsetWithTouch = cc.p(touchPos.x - self.TouchBeginPos.x , touchPos.y - self.TouchBeginPos.y) -- 计算节点位移(世界坐标) local offsetWithItem = cc.p(worldStartPos.x + offsetWithTouch.x , worldStartPos.y + offsetWithTouch.y) -- 节点位移(节点坐标) local movePos = self:getParent():convertToNodeSpace2D(offsetWithItem); self:setPosition(movePos); end function cc.Widget:dragCancelFunc(touch) if not self.EnableDrag then return false; end self:cancelMove(nil, touch); end -- 查找与鼠标经过的DragCtrl控件 function cc.Widget:findDragedCtrl(ptInWorld) local dragedCtrl = nil if self.findNodeFunc then local dragItem = self.dragItemData dragedCtrl = self.findNodeFunc(ptInWorld, dragItem) else local rootNode = self:getParent(); local function doVisit(node) if node:hitTest(ptInWorld) then dragedCtrl = node; return false; end return true; end rootNode:visitNode(doVisit); end return dragedCtrl; end function cc.Widget:cancelMove(isReset, touch) -- 产生取消拖拽事件 if self.onDragCancel then self.onDragCancel(isReset, touch); end self:setPosition(self.StartItemPos) self:setLocalZOrder(self.StartItemZOrder) -- 表示按下的时候的鼠标位置 self.TouchBeginPos = nil; -- 表示按下时控件所在的位置 self.StartItemPos = nil; -- 开始时的ZOrder self.StartItemZOrder = nil; -- 当前正在拖动的控件 self.onDragItem = nil; end --\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ function cc.Widget:removeAllChildrenTouchEvent() local function visit(node) if node.removeAllTouchEventListeners then node:removeAllTouchEventListeners(); end return true end self:visitNode(visit); end require("luaScript.Tools.Widgets.Label"); require("luaScript.Tools.Widgets.UILayout"); require("luaScript.Tools.Widgets.UIButton"); require("luaScript.Tools.Widgets.UIText"); require("luaScript.Tools.Widgets.UICheckBox"); require("luaScript.Tools.Widgets.UIImageView"); require("luaScript.Tools.Widgets.UILoadingBar"); require("luaScript.Tools.Widgets.UIPageView"); require("luaScript.Tools.Widgets.UIScrollView"); require("luaScript.Tools.Widgets.UISlider"); require("luaScript.Tools.Widgets.UITextBMFont"); require("luaScript.Tools.Widgets.UITextField"); require("luaScript.Tools.Widgets.UIListView"); require("luaScript.Tools.Widgets.UIHtmlCtrl"); require("luaScript.Tools.Widgets.UIEffectButton"); require("luaScript.Tools.Widgets.UIGridLine"); require("luaScript.Tools.Widgets.UIWidgetFile"); require("luaScript.Tools.Widgets.UIVideoView"); require("luaScript.Tools.Widgets.UIScaler"); require("luaScript.Tools.Widgets.UICache");