AutoAdaptionController.cs 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144
  1. using System;
  2. using Godot;
  3. namespace TBL.GodotSharp.Ui.AutoAdaption
  4. {
  5. /// <summary>
  6. /// 自动自适应控制器
  7. /// <para>控制所有的 <see cref="AutoAdaptionUiRoot"/></para>
  8. /// </summary>
  9. public class AutoAdaptionController : Node
  10. {
  11. /// <summary>
  12. /// 设计 Ui 尺寸
  13. /// </summary>
  14. [Export] public Vector2 DesignSize;
  15. /// <summary>
  16. /// 自动缩放 Ui 开关
  17. /// </summary>
  18. [Export] private bool _autoScaleUi;
  19. /// <summary>
  20. /// 世界视图缩放值
  21. /// </summary>
  22. private int _worldViewScale = 1;
  23. /// <summary>
  24. /// 自动 Ui 缩放值
  25. /// </summary>
  26. private float _autoScaleShrink = 1.0f;
  27. /// <summary>
  28. /// 是否启用自动 Ui 调节
  29. /// </summary>
  30. public bool AutoScaleUi
  31. {
  32. get => _autoScaleUi;
  33. set
  34. {
  35. _autoScaleUi = value;
  36. var winSize = OS.WindowSize;
  37. var minSize = DesignSize;
  38. if (winSize.x < winSize.y)
  39. {
  40. minSize.y = minSize.x;
  41. }
  42. else
  43. {
  44. minSize.x = minSize.y;
  45. }
  46. if (_autoScaleUi)
  47. {
  48. var d = 1;
  49. if (winSize.x < winSize.y) d = 0;
  50. _autoScaleShrink = Mathf.Max(1.0f, Mathf.Floor(winSize[d] / minSize[d]));
  51. }
  52. else
  53. {
  54. _autoScaleShrink = 1.0f;
  55. }
  56. GetTree().SetScreenStretch(SceneTree.StretchMode.Disabled, SceneTree.StretchAspect.Expand, minSize);
  57. AutoAdaptionUiRoot.AdaptionShrink = _autoScaleShrink;
  58. if (_autoScaleUi)
  59. {
  60. WorldViewScale = Mathf.RoundToInt(_autoScaleShrink);
  61. }
  62. else
  63. {
  64. WorldViewScale = 1;
  65. }
  66. }
  67. }
  68. /// <summary>
  69. /// 世界视图缩放率
  70. /// </summary>
  71. public int WorldViewScale
  72. {
  73. get => Mathf.Max(1, _worldViewScale);
  74. set
  75. {
  76. _worldViewScale = value;
  77. // TODO: 世界视图
  78. // WorldViewContainer.WorldViewShrink = WorldViewScale;
  79. }
  80. }
  81. /// <summary>
  82. /// 自动 Ui 缩放率
  83. /// </summary>
  84. public float AutoScaleShrink => _autoScaleShrink;
  85. /// <summary>
  86. /// 屏幕尺寸变化事件
  87. /// </summary>
  88. protected void _OnScreenResized()
  89. {
  90. AutoScaleUi = _autoScaleUi;
  91. WorldViewScale = _worldViewScale;
  92. }
  93. #region Node
  94. public override async void _EnterTree()
  95. {
  96. var tree = GetTree();
  97. if (DesignSize == Vector2.Zero)
  98. DesignSize = new Vector2(
  99. Convert.ToSingle(ProjectSettings.GetSetting("display/window/size/width")),
  100. Convert.ToSingle(ProjectSettings.GetSetting("display/window/size/height"))
  101. );
  102. AutoScaleUi = _autoScaleUi;
  103. WorldViewScale = _worldViewScale;
  104. Name = nameof(AutoAdaptionController);
  105. tree.Connect("screen_resized", this, nameof(_OnScreenResized));
  106. await ToSignal(tree, "idle_frame");
  107. tree.EmitSignal("screen_resized");
  108. }
  109. public override void _ExitTree()
  110. {
  111. AutoScaleUi = _autoScaleUi;
  112. WorldViewScale = _worldViewScale;
  113. }
  114. #endregion
  115. /// <summary>
  116. /// 设置控件为填满设计尺寸
  117. /// </summary>
  118. public void SetFullParentDesignSize(Control target)
  119. {
  120. target.AnchorLeft = target.AnchorTop = 0.5f;
  121. target.AnchorRight = target.AnchorBottom = 0.5f;
  122. target.MarginLeft = DesignSize.x * -0.5f;
  123. target.MarginRight = DesignSize.x * 0.5f;
  124. target.MarginTop = DesignSize.x * -0.5f;
  125. target.MarginBottom = DesignSize.x * 0.5f;
  126. }
  127. }
  128. }