main.gd 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130
  1. # The root Control node ("Main") and AspectRatioContainer nodes are the most important
  2. # pieces of this demo.
  3. # Both nodes have their Layout set to Full Rect
  4. # (with their rect spread across the whole viewport, and Anchor set to Full Rect).
  5. extends Control
  6. var base_window_size = Vector2(ProjectSettings.get_setting("display/window/size/width"), ProjectSettings.get_setting("display/window/size/height"))
  7. # These defaults match this demo's project settings. Adjust as needed if adapting this
  8. # in your own project.
  9. var stretch_mode = SceneTree.STRETCH_MODE_2D
  10. var stretch_aspect = SceneTree.STRETCH_ASPECT_EXPAND
  11. var scale_factor = 1.0
  12. var gui_aspect_ratio = -1.0
  13. var gui_margin = 0.0
  14. onready var panel = $Panel
  15. onready var arc = $Panel/AspectRatioContainer
  16. func _ready():
  17. # The `resized` signal will be emitted when the window size changes, as the root Control node
  18. # is resized whenever the window size changes. This is because the root Control node
  19. # uses a Full Rect anchor, so its size will always be equal to the window size.
  20. # warning-ignore:return_value_discarded
  21. connect("resized", self, "_on_resized")
  22. update_container()
  23. func update_container():
  24. # The code within this function needs to be run twice to work around an issue with containers
  25. # having a 1-frame delay with updates.
  26. # Otherwise, `panel.rect_size` returns a value of the previous frame, which results in incorrect
  27. # sizing of the inner AspectRatioContainer when using the Fit to Window setting.
  28. for _i in 2:
  29. if is_equal_approx(gui_aspect_ratio, -1.0):
  30. # Fit to Window. Tell the AspectRatioContainer to use the same aspect ratio as the window,
  31. # making the AspectRatioContainer not have any visible effect.
  32. arc.ratio = panel.rect_size.aspect()
  33. # Apply GUI margin on the AspectRatioContainer's parent (Panel).
  34. # This also makes the GUI margin apply on controls located outside the AspectRatioContainer
  35. # (such as the inner side label in this demo).
  36. panel.margin_top = gui_margin
  37. panel.margin_bottom = -gui_margin
  38. else:
  39. # Constrained aspect ratio.
  40. arc.ratio = min(panel.rect_size.aspect(), gui_aspect_ratio)
  41. # Adjust top and bottom margins relative to the aspect ratio when it's constrained.
  42. # This ensures that GUI margin settings behave exactly as if the window had the
  43. # original aspect ratio size.
  44. panel.margin_top = gui_margin / gui_aspect_ratio
  45. panel.margin_bottom = -gui_margin / gui_aspect_ratio
  46. panel.margin_left = gui_margin
  47. panel.margin_right = -gui_margin
  48. func _on_gui_aspect_ratio_item_selected(index):
  49. match index:
  50. 0: # Fit to Window
  51. gui_aspect_ratio = -1.0
  52. 1: # 5:4
  53. gui_aspect_ratio = 5.0 / 4.0
  54. 2: # 4:3
  55. gui_aspect_ratio = 4.0 / 3.0
  56. 3: # 3:2
  57. gui_aspect_ratio = 3.0 / 2.0
  58. 4: # 16:10
  59. gui_aspect_ratio = 16.0 / 10.0
  60. 5: # 16:9
  61. gui_aspect_ratio = 16.0 / 9.0
  62. 6: # 21:9
  63. gui_aspect_ratio = 21.0 / 9.0
  64. update_container()
  65. func _on_resized():
  66. update_container()
  67. func _on_gui_margin_drag_ended(_value_changed):
  68. gui_margin = $"Panel/AspectRatioContainer/ColorRect/CenterContainer/Options/GUIMargin/HSlider".value
  69. $"Panel/AspectRatioContainer/ColorRect/CenterContainer/Options/GUIMargin/Value".text = str(gui_margin)
  70. update_container()
  71. func _on_window_base_size_item_selected(index):
  72. match index:
  73. 0: # 648×648 (1:1)
  74. base_window_size = Vector2(648, 648)
  75. 1: # 640×480 (4:3)
  76. base_window_size = Vector2(640, 480)
  77. 2: # 720×480 (3:2)
  78. base_window_size = Vector2(720, 480)
  79. 3: # 800×600 (4:3)
  80. base_window_size = Vector2(800, 600)
  81. 4: # 1152×648 (16:9)
  82. base_window_size = Vector2(1152, 648)
  83. 5: # 1280×720 (16:9)
  84. base_window_size = Vector2(1280, 720)
  85. 6: # 1280×800 (16:10)
  86. base_window_size = Vector2(1280, 800)
  87. 7: # 1680×720 (21:9)
  88. base_window_size = Vector2(1680, 720)
  89. get_tree().set_screen_stretch(stretch_mode, stretch_aspect, base_window_size, scale_factor)
  90. update_container()
  91. func _on_window_stretch_mode_item_selected(index):
  92. stretch_mode = index
  93. get_tree().set_screen_stretch(stretch_mode, stretch_aspect, base_window_size, scale_factor)
  94. # Disable irrelevant options when the stretch mode is Disabled.
  95. $"Panel/AspectRatioContainer/ColorRect/CenterContainer/Options/WindowBaseSize/OptionButton".disabled = stretch_mode == SceneTree.STRETCH_MODE_DISABLED
  96. $"Panel/AspectRatioContainer/ColorRect/CenterContainer/Options/WindowStretchAspect/OptionButton".disabled = stretch_mode == SceneTree.STRETCH_MODE_DISABLED
  97. func _on_window_stretch_aspect_item_selected(index):
  98. stretch_aspect = index
  99. get_tree().set_screen_stretch(stretch_mode, stretch_aspect, base_window_size, scale_factor)
  100. func _on_window_scale_factor_drag_ended(_value_changed):
  101. scale_factor = $"Panel/AspectRatioContainer/ColorRect/CenterContainer/Options/WindowScaleFactor/HSlider".value
  102. $"Panel/AspectRatioContainer/ColorRect/CenterContainer/Options/WindowScaleFactor/Value".text = "%d%%" % (scale_factor * 100)
  103. get_tree().set_screen_stretch(stretch_mode, stretch_aspect, base_window_size, scale_factor)