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.

117 lines
4.0 KiB

  1. -- 自动布局的方向
  2. ScreenLayoutDir =
  3. {
  4. -- 左边
  5. SL_Left = 1,
  6. -- 下面
  7. SL_Bottom = 2,
  8. -- 右边
  9. SL_Right = 3,
  10. -- 上面
  11. SL_Top = 4,
  12. }
  13. -- 全屏自动把一个控件绕着一个控件水平布局
  14. -- rect 控件的矩形(x,y,width,height)都是屏幕坐标系,锚点在0,0,即xy是这个控件的左下角
  15. -- pos 参考点,被控制的控件始终以这个参考点的轴向为主要参照(屏幕坐标)
  16. -- size 被控制的控件的大小(屏幕坐标)
  17. -- @return 返回被控制的控件的屏幕坐标,假设控件的锚点在0,0,即计算出来是被控制的控件的左下角位置
  18. function screenLayout(rect , pos , size , screenSize, dir)
  19. screenSize = screenSize or cc.Director:getInstance():getWinSize();
  20. local targetPos = nil
  21. if dir then
  22. -- 左边
  23. if dir == ScreenLayoutDir.SL_Left then
  24. targetPos = cc.p(rect.x - size.width, pos.y - size.height / 2);
  25. elseif dir == ScreenLayoutDir.SL_Bottom then
  26. targetPos = cc.p(pos.x, rect.y - size.height);
  27. elseif dir == ScreenLayoutDir.SL_Right then
  28. targetPos = cc.p(rect.x + rect.width, pos.y - size.height / 2);
  29. elseif dir == ScreenLayoutDir.SL_Top then
  30. targetPos = cc.p(pos.x, rect.y + rect.height);
  31. end
  32. -- 必须都要限制在定义的区域里面
  33. targetPos.x = cc.clampf(targetPos.x , 0 , screenSize.width - size.width);
  34. targetPos.y = cc.clampf(targetPos.y , 0 , screenSize.height - size.height);
  35. return targetPos
  36. else
  37. -- 计算左边位置(历史遗留问题)
  38. targetPos = cc.p(rect.x - size.width , pos.y - size.height / 2);
  39. -- 左边没越界,说明放得下
  40. if targetPos.x >= 0 then
  41. targetPos.y = cc.clampf(targetPos.y , 0 , screenSize.height - size.height);
  42. return targetPos;
  43. -- 左边放不下,放右边吧
  44. else
  45. targetPos.x = rect.x + rect.width;
  46. targetPos.y = cc.clampf(targetPos.y , 0 , screenSize.height - size.height);
  47. return targetPos;
  48. end
  49. end
  50. end
  51. -- 全屏布局函数
  52. -- nodeContainer 布局容器节点
  53. -- nodePoint 布局参考点的节点
  54. -- nodeTarget 被布局的节点
  55. function screenLayoutNode(nodeContainer , nodePoint , nodeTarget , screenSize, dir)
  56. local rect = nodeContainer:getWorldRect();
  57. local pos = nodePoint:getParent():convertToWorldSpace2D(cc.p(nodePoint:getLeftInParent() , nodePoint:getBottomInParent()));
  58. local size = nodeTarget:getContentSize();
  59. local targetPos = screenLayout(rect , pos , size , screenSize, dir);
  60. local targetToParentPos = nodeTarget:getParent():convertToNodeSpace2D(targetPos);
  61. local targetAp = nodeTarget:getAnchorPoint();
  62. targetToParentPos.x = targetToParentPos.x + targetAp.x * size.width
  63. targetToParentPos.y = targetToParentPos.y + targetAp.y * size.height
  64. nodeTarget:setPosition(targetToParentPos);
  65. end
  66. -- 自动执行的全屏布局
  67. -- nodeContainer 布局容器节点
  68. -- nodePoint 布局参考点的节点
  69. -- nodeTarget 被布局的节点
  70. -- dir表示强制放到那个方向(如果放不下就往里面挤挤)
  71. function autoScreenLayoutNode(nodeContainer , nodePoint , nodeTarget, screenSize, dir)
  72. local function onUpdate()
  73. screenLayoutNode(nodeContainer , nodePoint , nodeTarget, screenSize, dir);
  74. end
  75. -- 每帧更新一次
  76. schedule(nodeTarget , onUpdate , 0);
  77. onUpdate();
  78. return onUpdate;
  79. end
  80. -- 自动执行的全屏布局(当nodeContainer或者nodePoint不存在了则停止布局)
  81. -- nodeContainer 布局容器节点
  82. -- nodePoint 布局参考点的节点
  83. -- nodeTarget 被布局的节点
  84. function autoScreenLayoutNodeEx(nodeContainer , nodePoint , nodeTarget , screenSize)
  85. local layoutAction = nil
  86. local function onUpdate()
  87. if tolua.isnull(nodeContainer) or tolua.isnull(nodePoint) then
  88. local function stopLayoutAction()
  89. if not tolua.isnull(nodeTarget) and not tolua.isnull(layoutAction) then
  90. nodeTarget:stopAction(layoutAction)
  91. layoutAction = nil
  92. end
  93. end
  94. runInNextFrame(stopLayoutAction)
  95. else
  96. -- 更新
  97. screenLayoutNode(nodeContainer , nodePoint , nodeTarget , screenSize);
  98. end
  99. end
  100. -- 每帧更新一次
  101. layoutAction = schedule(nodeTarget , onUpdate , 0);
  102. onUpdate();
  103. return onUpdate;
  104. end