You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

540 lines
15 KiB

  1. require("luaScript.Tools.Nodes.CCNode2D");
  2. cc.Widget.ClassName = "Widget"
  3. function cc.Widget:extend(node)
  4. cc.Node2D:extend(node);
  5. -- 名字
  6. node:setName("Widget");
  7. end
  8. function cc.Widget:loadFromXmlNode(xmlNode)
  9. cc.Node2D.loadFromXmlNode(self , xmlNode);
  10. self.SpriteFrameFiles = xmlNode.SpriteFrameFiles;
  11. if self.SpriteFrameFiles then
  12. for i , v in ipairs(self.SpriteFrameFiles) do
  13. cc.SpriteFrameCache:getInstance():addSpriteFramesWithFile(v);
  14. end
  15. end
  16. self:ignoreContentAdaptWithSize(xmlNode.ignoreSize);
  17. local sizeType = xmlNode.sizeType;
  18. self:setSizeType(sizeType);
  19. if sizeType == cc.SizeType.percent then
  20. self:setSizePercent(xmlNode.sizePercent);
  21. else
  22. self:setSize(xmlNode.size);
  23. end
  24. local positionType = xmlNode.positionType;
  25. self:setPositionType(positionType);
  26. if positionType == cc.PositionType.percent then
  27. self:setPositionPercent(xmlNode.positionPercent);
  28. end
  29. self:setActionTag(xmlNode.actionTag);
  30. self:setTouchEnabled(xmlNode.touchAble);
  31. self:setFlippedX(xmlNode.flipX);
  32. self:setFlippedY(xmlNode.flipY);
  33. if xmlNode.ClickSoundFile then
  34. self:setClickSoundFile(xmlNode.ClickSoundFile);
  35. end
  36. local layoutParameter = xmlNode.layoutParameter;
  37. if layoutParameter then
  38. local parameter;
  39. local paramterType = layoutParameter.type;
  40. if paramterType == cc.LayoutParameterType.linear then
  41. parameter = cc.LinearLayoutParameter:create();
  42. parameter:setGravity(layoutParameter.gravity);
  43. if layoutParameter.fillWidth ~= nil then
  44. parameter:setFillWidth(layoutParameter.fillWidth);
  45. parameter:setFillHeight(layoutParameter.fillHeight);
  46. end
  47. elseif paramterType == cc.LayoutParameterType.relative then
  48. parameter = cc.RelativeLayoutParameter:create();
  49. parameter:setAlign(layoutParameter.align);
  50. elseif paramterType == cc.LayoutParameterType.none then
  51. parameter = cc.LayoutParameter:create();
  52. end
  53. if parameter then
  54. parameter:setMargin(layoutParameter.margin);
  55. self:setLayoutParameter(parameter);
  56. end
  57. end
  58. end
  59. function cc.Widget:createNode()
  60. local layer = cc.Widget:create();
  61. cc.Widget:extend(layer);
  62. return layer;
  63. end
  64. -- 获得世界坐标系的矩形,左下角和宽高
  65. function cc.Widget:getWorldRect()
  66. local containerPos = self:getParent():convertToWorldSpace2D(cc.p(self:getLeftInParent() , self:getBottomInParent()));
  67. local containerSize = self:getContentSize();
  68. local rect = cc.rect(containerPos.x , containerPos.y , containerSize.width , containerSize.height);
  69. return rect;
  70. end
  71. function cc.Widget:collectAllImage()
  72. local spriteFiles = {};
  73. local function visit(child)
  74. if child.collectPListFiles then
  75. local files = child:collectPListFiles();
  76. for i , v in pairs(files) do
  77. spriteFiles[v] = 1;
  78. end
  79. end
  80. end
  81. self:visitNode(visit);
  82. return spriteFiles;
  83. end
  84. -- 从新计算这个Widget以及下面所有子Widget引用到了什么PList文件,并记录到SpriteFrameFiles中
  85. function cc.Widget:recalcAllPList()
  86. local spriteFiles = self:collectAllImage();
  87. local spriteFrameFiles = {};
  88. for i , v in pairs(spriteFiles) do
  89. if string.endsWith(string.lower(i) , ".plist") then
  90. table.insert(spriteFrameFiles , i);
  91. end
  92. end
  93. table.sort(spriteFrameFiles , function(a,b)return a < b;end);
  94. self:setSpriteFrameFiles(spriteFrameFiles);
  95. end
  96. cc.Widget.setAutoSize = cc.Widget.ignoreContentAdaptWithSize;
  97. cc.Widget.isAutoSize = cc.Widget.isIgnoreContentAdaptWithSize;
  98. function getUITexture(name , t)
  99. return {name , t};
  100. end
  101. function collectPListFile(files , name , t)
  102. if t == cc.TextureResType.plistType then
  103. local spriteFrame = cc.SpriteFrameCache:getInstance():getSpriteFrameByName(name);
  104. if spriteFrame then
  105. table.insert(files , spriteFrame:getPListFile());
  106. end
  107. else
  108. table.insert(files , name);
  109. end
  110. return nil;
  111. end
  112. -- 编辑器模式,可以plist代替文件
  113. if EditorMode then
  114. function setUITexture(func , self, names)
  115. -- 本地文件,就找下有没有这个文件,如果没有,就用plist里的
  116. if names[2] == cc.TextureResType.localType then
  117. -- 定义了文件,并且文件不存在
  118. if names[1] ~= "" and names[1] ~= nil and not cc.FileSystem:fileExists(names[1]) then
  119. local pathName , baseName , ext = string.splitFilename(names[1]);
  120. print("拆开了不存在的png:" , pathName , baseName , ext);
  121. -- 找这个文件所在文件夹的所有的plist
  122. local files = cc.FileSystem:listFiles(pathName);
  123. for i , pkg in ipairs(files) do
  124. print("遍历文件" , i , pkg);
  125. local plistFile = pathName .. "/" .. pkg;
  126. local pkgPath , pkgBase , pkgExt = string.splitFilename(plistFile);
  127. if string.lower(pkgExt) == "plist" then
  128. print("加载plist" , plistFile);
  129. cc.SpriteFrameCache:getInstance():addSpriteFramesWithFile(plistFile);
  130. local spriteFrame = cc.SpriteFrameCache:getInstance():getSpriteFrameByName(baseName);
  131. if spriteFrame then
  132. print("使用PLIST中的代替:" , plistFile , baseName);
  133. func(self , baseName , cc.TextureResType.plistType);
  134. return;
  135. end
  136. end
  137. end
  138. end
  139. end
  140. func(self , names[1] , names[2]);
  141. end
  142. else
  143. function setUITexture(func , self, names)
  144. func(self , names[1] , names[2]);
  145. end
  146. end
  147. -- 把Size以动画形式设置到size值
  148. function cc.Widget:animSize(targetSize , duration)
  149. if not tolua.isnull(self.AnimSizeAction) then
  150. self:stopAction(self.AnimSizeAction);
  151. end
  152. self.AnimSizeAction = nil;
  153. local currentSize = self:getSize();
  154. if targetSize.x ~= currentSize.x or targetSize.y ~= currentSize.y then
  155. local action = cc.EaseSineOut:create(cc.UISizeTo:create(duration , targetSize));
  156. self.AnimSizeAction = action;
  157. self:runAction(action);
  158. end
  159. end
  160. -- 把Position以动画形式设置到translation值(xyz)
  161. function cc.Widget:animTranslation(targetPosition , duration)
  162. if not tolua.isnull(self.AnimPositionAction) then
  163. self:stopAction(self.AnimPositionAction);
  164. end
  165. self.AnimPositionAction = nil;
  166. local currentSize = self:getTranslation();
  167. if targetPosition.x ~= currentSize.x or targetPosition.y ~= currentSize.y or targetPosition.z ~= currentSize.z then
  168. local action = cc.EaseSineOut:create(cc.MoveTo:create(duration , targetPosition));
  169. self.AnimPositionAction = action;
  170. self:runAction(action);
  171. end
  172. end
  173. -- 把SizePercent以动画形式设置到size值
  174. function cc.Widget:animSizePercent(targetSizePercent , duration, callbackFunc)
  175. if not tolua.isnull(self.AnimSizePercentAction) then
  176. self:stopAction(self.AnimSizePercentAction);
  177. end
  178. self.AnimSizePercentAction = nil;
  179. local currentPercent = self:getSizePercent();
  180. if targetSizePercent.x ~= currentPercent.x or targetSizePercent.y ~= currentPercent.y then
  181. local action = cc.EaseSineOut:create(cc.UISizePercentTo:create(duration , targetSizePercent));
  182. self.AnimSizePercentAction = action;
  183. self:runActions(action, callbackFunc);
  184. end
  185. end
  186. -- 把PositionPercent以动画形式设置到size值
  187. function cc.Widget:animPositionPercent(targetSizePercent , duration, callbackFunc)
  188. if not tolua.isnull(self.AnimPositionPercentAction) then
  189. self:stopAction(self.AnimPositionPercentAction);
  190. end
  191. self.AnimPositionPercentAction = nil;
  192. local currentPercent = self:getPositionPercent();
  193. if targetSizePercent.x ~= currentPercent.x or targetSizePercent.y ~= currentPercent.y then
  194. local action = cc.EaseSineOut:create(cc.UIPositionPercentTo:create(duration , targetSizePercent));
  195. self.AnimPositionPercentAction = action;
  196. self:runActions(action, callbackFunc);
  197. end
  198. end
  199. -- 把子元素一起设置Enable
  200. function cc.Widget:setEnableds(enable)
  201. local function visit(node)
  202. if node.setEnabled then
  203. node:setEnabled(enable);
  204. end
  205. end
  206. self:visitNode(visit);
  207. end
  208. -- 把子元素一起设置GreyEnabled
  209. function cc.Widget:setAllGreyEnabled(enable)
  210. local function visit(node)
  211. if node.setGreyEnabled then
  212. node:setGreyEnabled(enable);
  213. end
  214. end
  215. self:visitNode(visit);
  216. end
  217. -- 注册按钮被点击的事件
  218. function cc.Widget:registerClick(callbackFunc, clickBeginFunc, clickCancelFunc,showGlobalEffect)
  219. local function onTouchEvent(sender, eventType, touch)
  220. -- 点击开始的回调
  221. if eventType == cc.TouchEventType.began then
  222. if(clickBeginFunc)then
  223. clickBeginFunc(self)
  224. end
  225. if(not showGlobalEffect)then
  226. ignoreCurTouchEffect();
  227. end
  228. --和美术约定,按下会播narrow的动画剪切,松开会播upspring;
  229. self:playClip("anxia")
  230. -- 点击结束的回调
  231. elseif eventType == cc.TouchEventType.ended then
  232. local currentView = app.currentView
  233. local buttonName = self:getName()
  234. local currentViewName = "";
  235. if(currentView)then
  236. currentViewName = currentView.__cname
  237. end
  238. if(callbackFunc)then
  239. callbackFunc(self, eventType, touch);
  240. end
  241. self:playClip("huanyuan")
  242. -- 点击取消的回调
  243. elseif eventType == cc.TouchEventType.canceled then
  244. if(clickCancelFunc)then
  245. clickCancelFunc(self);
  246. end
  247. self:playClip("huanyuan")
  248. end
  249. return true;
  250. end
  251. self:setTouchEnabled(true)
  252. self:addTouchEventListener(onTouchEvent)
  253. end
  254. --\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  255. function cc.Widget:initDragValue()
  256. -- widget数据
  257. self.dragItemData = nil;
  258. -- 是否允许拖曳
  259. self.EnableDrag = true;
  260. -- 表示按下的时候的鼠标位置
  261. self.TouchBeginPos = nil;
  262. -- 表示按下时控件所在的位置
  263. self.StartItemPos = nil;
  264. -- 开始时的ZOrder
  265. self.StartItemZOrder = nil;
  266. -- 当前正在拖动的控件
  267. self.onDragItem = nil;
  268. --///////////////////////
  269. -- 拖拽开始的回调
  270. -- 回调格式onDragStart(),如果返回false,则拖拽无效
  271. self.onDragStart = nil;
  272. -- 拖拽结束的回调,会在拖拽到的目标上产生这个回调
  273. -- 回调格式onDragEnd(源控件数据,目标控件数据)
  274. self.onDragEndFunc = nil;
  275. -- 拖拽取消的回调
  276. -- 回调格式onDragCancel()
  277. self.onDragCancel = nil;
  278. -- 移动时的回调
  279. self.onMoveFunc = nil;
  280. --////////////////////////////
  281. -- 查找函数
  282. self.findNodeFunc = nil;
  283. end
  284. -- 注册点击事件(用于控件拖动)
  285. function cc.Widget:registerDragClick(showGlobalEffect)
  286. local function onTouchEvent(sender, eventType, touch)
  287. -- 点击开始的回调
  288. if eventType == cc.TouchEventType.began then
  289. self:dragBeginFunc(touch)
  290. if(not showGlobalEffect)then
  291. ignoreCurTouchEffect();
  292. end
  293. -- 点击结束的回调
  294. elseif eventType == cc.TouchEventType.ended then
  295. self:dragBackFunc(touch)
  296. -- 点击取消的回调
  297. elseif eventType == cc.TouchEventType.canceled then
  298. self:dragCancelFunc(touch)
  299. elseif eventType == cc.TouchEventType.moved then
  300. self:dragMoveFunc(touch)
  301. end
  302. return true;
  303. end
  304. self:initDragValue();
  305. self:addTouchEventListener(onTouchEvent)
  306. end
  307. function cc.Widget:registerTouchEvent(toucheBegin, touchMove, touchEnd, touchCancel)
  308. local function onTouchEvent(sender, eventType, touch)
  309. -- 点击开始的回调
  310. if eventType == cc.TouchEventType.began then
  311. if toucheBegin then
  312. toucheBegin(touch)
  313. end
  314. -- 点击结束的回调
  315. elseif eventType == cc.TouchEventType.ended then
  316. if touchEnd then
  317. touchEnd(touch)
  318. --toucheBegin(touch)
  319. end
  320. -- 点击取消的回调
  321. elseif eventType == cc.TouchEventType.canceled then
  322. if touchCancel then
  323. touchCancel(touch)
  324. --toucheBegin(touch)
  325. end
  326. elseif eventType == cc.TouchEventType.moved then
  327. if touchMove then
  328. touchMove(touch)
  329. end
  330. end
  331. return true;
  332. end
  333. self:addTouchEventListener(onTouchEvent)
  334. end
  335. -- 点击结束
  336. function cc.Widget:dragBackFunc(touch)
  337. -- 没有装备就不能拖动,返回
  338. if not self.EnableDrag then
  339. return false
  340. end
  341. -- 看鼠标落点在哪个控件上
  342. local touchPos = touch:getLocation();
  343. local targetId = self:findDragedCtrl(touchPos)
  344. if targetId then
  345. local startPosition = self.StartItemPos
  346. -- 取消移动
  347. self:cancelMove(true, touch);
  348. -- 产生结束拖拽事件
  349. if self.onDragEndFunc then
  350. self.onDragEndFunc(self.dragItemData, targetId, touch)
  351. end
  352. return false
  353. else
  354. -- 取消移动
  355. self:cancelMove(nil, touch);
  356. end
  357. end
  358. function cc.Widget:dragBeginFunc(touch)
  359. -- 产生开始拖拽事件
  360. if self.onDragStart then
  361. self.onDragStart(touch)
  362. end
  363. if not self.EnableDrag then
  364. return false;
  365. end
  366. local touchPos = touch:getLocation();
  367. if self:hitTest(touchPos) then
  368. self.TouchBeginPos = touchPos;
  369. self.StartItemPos = self:getPosition();
  370. self.StartItemZOrder = self:getLocalZOrder();
  371. self.onDragItem = self.dragItemData;
  372. -- 开始移动,就弹到最前面
  373. self:setLocalZOrder(100);
  374. end
  375. return true;
  376. end
  377. function cc.Widget:dragMoveFunc(touch)
  378. if not self.EnableDrag then
  379. return false;
  380. end
  381. if self.onMoveFunc then
  382. self.onMoveFunc(touch);
  383. end
  384. local touchPos = touch:getLocation();
  385. -- 计算开始点的世界坐标
  386. local worldStartPos = self:getParent():convertToWorldSpace(self.StartItemPos)
  387. -- 计算鼠标从点下到现在移动了多远
  388. local offsetWithTouch = cc.p(touchPos.x - self.TouchBeginPos.x , touchPos.y - self.TouchBeginPos.y)
  389. -- 计算节点位移(世界坐标)
  390. local offsetWithItem = cc.p(worldStartPos.x + offsetWithTouch.x , worldStartPos.y + offsetWithTouch.y)
  391. -- 节点位移(节点坐标)
  392. local movePos = self:getParent():convertToNodeSpace2D(offsetWithItem);
  393. self:setPosition(movePos);
  394. end
  395. function cc.Widget:dragCancelFunc(touch)
  396. if not self.EnableDrag then
  397. return false;
  398. end
  399. self:cancelMove(nil, touch);
  400. end
  401. -- 查找与鼠标经过的DragCtrl控件
  402. function cc.Widget:findDragedCtrl(ptInWorld)
  403. local dragedCtrl = nil
  404. if self.findNodeFunc then
  405. local dragItem = self.dragItemData
  406. dragedCtrl = self.findNodeFunc(ptInWorld, dragItem)
  407. else
  408. local rootNode = self:getParent();
  409. local function doVisit(node)
  410. if node:hitTest(ptInWorld) then
  411. dragedCtrl = node;
  412. return false;
  413. end
  414. return true;
  415. end
  416. rootNode:visitNode(doVisit);
  417. end
  418. return dragedCtrl;
  419. end
  420. function cc.Widget:cancelMove(isReset, touch)
  421. -- 产生取消拖拽事件
  422. if self.onDragCancel then
  423. self.onDragCancel(isReset, touch);
  424. end
  425. self:setPosition(self.StartItemPos)
  426. self:setLocalZOrder(self.StartItemZOrder)
  427. -- 表示按下的时候的鼠标位置
  428. self.TouchBeginPos = nil;
  429. -- 表示按下时控件所在的位置
  430. self.StartItemPos = nil;
  431. -- 开始时的ZOrder
  432. self.StartItemZOrder = nil;
  433. -- 当前正在拖动的控件
  434. self.onDragItem = nil;
  435. end
  436. --\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  437. function cc.Widget:removeAllChildrenTouchEvent()
  438. local function visit(node)
  439. if node.removeAllTouchEventListeners then
  440. node:removeAllTouchEventListeners();
  441. end
  442. return true
  443. end
  444. self:visitNode(visit);
  445. end
  446. require("luaScript.Tools.Widgets.Label");
  447. require("luaScript.Tools.Widgets.UILayout");
  448. require("luaScript.Tools.Widgets.UIButton");
  449. require("luaScript.Tools.Widgets.UIText");
  450. require("luaScript.Tools.Widgets.UICheckBox");
  451. require("luaScript.Tools.Widgets.UIImageView");
  452. require("luaScript.Tools.Widgets.UILoadingBar");
  453. require("luaScript.Tools.Widgets.UIPageView");
  454. require("luaScript.Tools.Widgets.UIScrollView");
  455. require("luaScript.Tools.Widgets.UISlider");
  456. require("luaScript.Tools.Widgets.UITextBMFont");
  457. require("luaScript.Tools.Widgets.UITextField");
  458. require("luaScript.Tools.Widgets.UIListView");
  459. require("luaScript.Tools.Widgets.UIHtmlCtrl");
  460. require("luaScript.Tools.Widgets.UIEffectButton");
  461. require("luaScript.Tools.Widgets.UIGridLine");
  462. require("luaScript.Tools.Widgets.UIWidgetFile");
  463. require("luaScript.Tools.Widgets.UIVideoView");
  464. require("luaScript.Tools.Widgets.UIScaler");
  465. require("luaScript.Tools.Widgets.UICache");