Add UI Engine and welcome screen
This commit is contained in:
parent
147aab7784
commit
8a512b0e12
7 changed files with 349 additions and 5 deletions
|
@ -25,6 +25,7 @@ logger="*res://src/logger.gd"
|
|||
misc="*res://src/misc.gd"
|
||||
preader="*res://src/preader.gd"
|
||||
pmana="*res://src/pmana.gd"
|
||||
ui_engine="*res://src/ui_engine.gd"
|
||||
|
||||
[display]
|
||||
|
||||
|
@ -33,7 +34,7 @@ window/size/viewport_height=540
|
|||
|
||||
[editor]
|
||||
|
||||
run/main_run_args="%command% ++ example"
|
||||
run/main_run_args="%command% ++ "
|
||||
export/convert_text_resources_to_binary=false
|
||||
|
||||
[editor_plugins]
|
||||
|
@ -76,6 +77,12 @@ console={
|
|||
, Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":96,"physical_keycode":0,"key_label":0,"unicode":0,"echo":false,"script":null)
|
||||
]
|
||||
}
|
||||
editor_switchres={
|
||||
"deadzone": 0.5,
|
||||
"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":0,"key_label":4194335,"unicode":0,"echo":false,"script":null)
|
||||
, Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":4194335,"physical_keycode":0,"key_label":0,"unicode":0,"echo":false,"script":null)
|
||||
]
|
||||
}
|
||||
|
||||
[rendering]
|
||||
|
||||
|
|
|
@ -63,6 +63,7 @@ func _ready() -> void:
|
|||
expressionscript.misc = get_node("/root/misc")
|
||||
expressionscript.preader = get_node("/root/preader")
|
||||
expressionscript.pmana = get_node("/root/pmana")
|
||||
expressionscript.ui_engine = get_node("/root/ui_engine")
|
||||
expressionscript.console = self
|
||||
expressionscript.loader = get_node("/root/Presencode")
|
||||
add_child(expressionscript)
|
||||
|
@ -88,12 +89,12 @@ func _process(_delta: float) -> void:
|
|||
# Change console position
|
||||
position.x = position.x-cursor_offset.x
|
||||
position.y = position.y-cursor_offset.y
|
||||
# Set new cursor_origin
|
||||
cursor_origin = cursor_position
|
||||
# Prevent console from going out of scope
|
||||
var position_new: Vector2 = check_violation()
|
||||
if position != position_new:
|
||||
position = position_new
|
||||
# Set new cursor_origin
|
||||
cursor_origin = cursor_position
|
||||
|
||||
# Helper function, prevents console from going out of scope
|
||||
func check_violation() -> Vector2:
|
||||
|
|
|
@ -28,6 +28,7 @@ var logger: Node = null
|
|||
var misc: Node = null
|
||||
var preader: Node = null
|
||||
var pmana: Node = null
|
||||
var ui_engine: Node = null
|
||||
# SceneTree
|
||||
var console: Node = null
|
||||
var loader: Node = null
|
||||
|
|
15
src/misc.gd
15
src/misc.gd
|
@ -134,6 +134,21 @@ func check_platform() -> void:
|
|||
_: # Platform not supported
|
||||
logger.error("The \"" + OS.get_name() + "\" operating system is not supported by Presencode. You can add support for that platform to Presencode yourself, if you want.")
|
||||
|
||||
# Returns the best common resolution
|
||||
func get_best_resolution() -> Vector2i:
|
||||
logger.info("Determining best resolution")
|
||||
var screen_size: Vector2 = Vector2(DisplayServer.screen_get_size())
|
||||
var resolutions: Array[Vector2] = [Vector2(960, 540), Vector2(1920, 1080), Vector2(2560, 1440), Vector2(3840, 2160)]
|
||||
var closest_resolution: Vector2 = Vector2(NAN, NAN)
|
||||
var closest_distance: float = INF
|
||||
for resolution in resolutions:
|
||||
var distance = screen_size.distance_to(resolution)
|
||||
if distance < closest_distance:
|
||||
closest_distance = distance
|
||||
closest_resolution = resolution
|
||||
if closest_resolution == Vector2(NAN, NAN): return Vector2i(960, 540)
|
||||
else: return closest_resolution
|
||||
|
||||
# Check for manifest consistency
|
||||
func check_manifest_consistency(manifest: Dictionary) -> misc.Error:
|
||||
logger.diag("Checking manifest for consistency")
|
||||
|
|
113
src/ui/welcome.gd
Normal file
113
src/ui/welcome.gd
Normal file
|
@ -0,0 +1,113 @@
|
|||
extends Node
|
||||
|
||||
func switch_mode() -> void:
|
||||
DisplayServer.window_set_title("Presencode » Welcome")
|
||||
update_splash()
|
||||
|
||||
@warning_ignore("integer_division")
|
||||
func update_resolution(new_resolution: Vector2i) -> void:
|
||||
var base: Button = get_node("Wallpaper/Welcome")
|
||||
var wallpaper_size: Vector2 = Vector2(7440, 4822)
|
||||
base.get_parent().size = Vector2(wallpaper_size.x*(new_resolution.x/wallpaper_size.x), wallpaper_size.y*(new_resolution.y/wallpaper_size.y))
|
||||
base.size = Vector2(new_resolution.x*0.9, new_resolution.y*0.9)
|
||||
base.position = Vector2(new_resolution.x*0.05, new_resolution.y*0.05)
|
||||
base.add_theme_stylebox_override("normal", get_stylebox_blur(new_resolution))
|
||||
base.add_theme_stylebox_override("hover", get_stylebox_blur(new_resolution))
|
||||
base.add_theme_stylebox_override("pressed", get_stylebox_blur(new_resolution))
|
||||
base.add_theme_stylebox_override("disabled", get_stylebox_blur(new_resolution))
|
||||
for child in base.get_children(true):
|
||||
for group in child.get_groups():
|
||||
match(group):
|
||||
"font":
|
||||
child.add_theme_font_override("normal_font", ResourceLoader.load("res://assets/fonts/Inter/Regular.ttf"))
|
||||
child.add_theme_font_override("bold_font", ResourceLoader.load("res://assets/fonts/Inter/Bold.ttf"))
|
||||
child.add_theme_font_override("italics_font", ResourceLoader.load("res://assets/fonts/Inter/Italic.ttf"))
|
||||
child.add_theme_font_override("bold_italics_font", ResourceLoader.load("res://assets/fonts/Inter/BoldItalic.ttf"))
|
||||
child.add_theme_font_override("mono_font", ResourceLoader.load("res://assets/fonts/FiraCode/Regular.ttf"))
|
||||
"font_normal":
|
||||
child.add_theme_font_size_override("normal_font_size", new_resolution.x/40)
|
||||
child.add_theme_font_size_override("bold_font_size", new_resolution.x/40)
|
||||
child.add_theme_font_size_override("italics_font_size", new_resolution.x/40)
|
||||
child.add_theme_font_size_override("bold_italics_font_size", new_resolution.x/40)
|
||||
child.add_theme_font_size_override("mono_font_size", new_resolution.x/41.73913043478261)
|
||||
"font_small":
|
||||
child.add_theme_font_size_override("normal_font_size", new_resolution.x/53.33333333333333)
|
||||
child.add_theme_font_size_override("bold_font_size", new_resolution.x/53.33333333333333)
|
||||
child.add_theme_font_size_override("italics_font_size", new_resolution.x/53.33333333333333)
|
||||
child.add_theme_font_size_override("bold_italics_font_size", new_resolution.x/53.33333333333333)
|
||||
child.add_theme_font_size_override("mono_font_size", new_resolution.x/53.33333333333333)
|
||||
"font_one": child.add_theme_font_override("font", ResourceLoader.load("res://assets/fonts/Inter/Regular.ttf"))
|
||||
"font_one_normal": child.add_theme_font_size_override("font_size", new_resolution.x/40)
|
||||
"font_one_small": child.add_theme_font_size_override("font_size", new_resolution.x/53.33333333333333)
|
||||
base.get_node("Icon").size = Vector2(new_resolution.x/1.5, new_resolution.y/4.5)
|
||||
base.get_node("Icon").position = Vector2(base.size.x/2-base.get_node("Icon").size.x/2, base.size.y*0.05)
|
||||
base.get_node("Splash").size = Vector2(new_resolution.x/1.5, new_resolution.y/15.88235294117647)
|
||||
base.get_node("Splash").position = Vector2(base.size.x/2-base.get_node("Splash").size.x/2, base.get_node("Icon").position.y+11*(new_resolution.y/49.09090909090909))
|
||||
base.get_node("OpenButton").size = Vector2(new_resolution.x/4.403669724770642, new_resolution.y/14.21052631578947)
|
||||
base.get_node("OpenButton").position = Vector2(base.size.x/16, base.size.y/2.410714285714286)
|
||||
base.get_node("EditorButton").size = Vector2(new_resolution.x/4.403669724770642, new_resolution.y/14.21052631578947)
|
||||
base.get_node("EditorButton").position = Vector2(base.size.x-base.get_node("OpenButton").position.x-base.get_node("EditorButton").size.x, base.size.y/2.410714285714286)
|
||||
base.get_node("AboutText").size = Vector2(new_resolution.x/1.5, new_resolution.y/7.5)
|
||||
base.get_node("AboutText").position = Vector2(base.size.x/2-base.get_node("AboutText").size.x/2, base.size.y-base.size.y/54-base.size.y/7.5)
|
||||
|
||||
@warning_ignore("integer_division")
|
||||
func get_stylebox_blur(resolution_: Vector2i) -> StyleBoxFlat:
|
||||
var stylebox: StyleBoxFlat = StyleBoxFlat.new()
|
||||
stylebox.bg_color = Color8(0, 0, 0, 180)
|
||||
stylebox.corner_radius_top_left = resolution_.x/30
|
||||
stylebox.corner_radius_top_right = resolution_.x/30
|
||||
stylebox.corner_radius_bottom_left = resolution_.x/30
|
||||
stylebox.corner_radius_bottom_right = resolution_.x/30
|
||||
return stylebox
|
||||
|
||||
func update_splash() -> void:
|
||||
logger.diag("Updating splash text")
|
||||
get_node("Wallpaper/Welcome/Splash").text = "[center]" + ["The first native code-based presentation viewer.", "Presenting your presentations since 2023", "Made using Godot", "nice", "[b]your mom[/b]", "Also try LibreOffice!", "... exists.", "making unprofessional presentations"].pick_random() + "[/center]"
|
||||
|
||||
func open_presentation_picker() -> void:
|
||||
logger.info("Opening presentation")
|
||||
var fd: FileDialog = FileDialog.new()
|
||||
fd.access = FileDialog.ACCESS_FILESYSTEM
|
||||
fd.current_path = "user://"
|
||||
fd.file_mode = FileDialog.FILE_MODE_OPEN_FILE
|
||||
fd.add_filter("*.pcpa", "")
|
||||
fd.add_filter("*.zip", "")
|
||||
fd.mode_overrides_title = false
|
||||
fd.show_hidden_files = true
|
||||
fd.title = "Open a Presencode presentation file"
|
||||
fd.use_native_dialog = true
|
||||
fd.cancel_button_text = "Cancel"
|
||||
fd.ok_button_text = "Present"
|
||||
fd.visible = true
|
||||
fd.connect("file_selected", func(path: String): open_presentation(path))
|
||||
add_child(fd)
|
||||
|
||||
func open_presentation(path: String) -> void:
|
||||
if FileAccess.file_exists(path) and path.ends_with(".zip") or path.ends_with(".pcpa"): # .pcpa = presencode presentation archive
|
||||
logger.info("Opening presentation archive")
|
||||
preader.open_presentation(path, true)
|
||||
elif DirAccess.dir_exists_absolute(path):
|
||||
logger.info("Opening presentation directory")
|
||||
preader.open_presentation(path, false)
|
||||
else:
|
||||
await logger.error("Presentation file/directory \"" + path + "\" not found")
|
||||
# Read manifest & entrypoint files
|
||||
preader.read_manifest()
|
||||
preader.read_entrypoint()
|
||||
# Update window properties
|
||||
get_node("/root/Console").calculate_drag_area(preader.get_ratio_resolution())
|
||||
DisplayServer.window_set_title("Presencode » Presenting \"" + preader.get_topic() + "\" by \"" + preader.get_authors() + "\"")
|
||||
DisplayServer.window_set_mode(DisplayServer.WINDOW_MODE_WINDOWED)
|
||||
DisplayServer.window_set_size(preader.get_ratio_resolution())
|
||||
DisplayServer.window_set_min_size(preader.get_ratio_resolution())
|
||||
if get_node("/root/Presencode").config_window_size_support: get_node("/root/Presencode/WindowSizeSupport/EndPixel").position = Vector2(preader.get_ratio_resolution().x-1, preader.get_ratio_resolution().y-1)
|
||||
get_tree().root.content_scale_size = preader.get_ratio_resolution()
|
||||
get_tree().root.content_scale_mode = Window.CONTENT_SCALE_MODE_VIEWPORT
|
||||
get_tree().root.content_scale_aspect = Window.CONTENT_SCALE_ASPECT_KEEP
|
||||
get_tree().root.content_scale_factor = 1.0
|
||||
await get_tree().process_frame
|
||||
DisplayServer.window_set_position(misc.get_center(DisplayServer.screen_get_size(), DisplayServer.window_get_size()))
|
||||
# Add entrypoint to SceneTree
|
||||
get_tree().root.add_child(preader.get_entrypoint())
|
||||
# Uninitialize UI Engine
|
||||
ui_engine.uninitialize()
|
82
src/ui_engine.gd
Normal file
82
src/ui_engine.gd
Normal file
|
@ -0,0 +1,82 @@
|
|||
extends Node
|
||||
|
||||
# Enums
|
||||
enum UIMode {
|
||||
UNKNOWN,
|
||||
WELCOME
|
||||
}
|
||||
|
||||
# Nodes
|
||||
var loader: Control = null
|
||||
var ui_mode_node: Control = null
|
||||
|
||||
# States
|
||||
var initialized: bool = false
|
||||
var ui_mode: UIMode = UIMode.UNKNOWN
|
||||
var resolution: String = "960x540"
|
||||
|
||||
func initialize(loader_: Control) -> void:
|
||||
if initialized:
|
||||
logger.error("The UI Engine been initialized already")
|
||||
return
|
||||
logger.info("Initializing UI Engine")
|
||||
loader = loader_
|
||||
initialized = true
|
||||
logger.diag("Switching to welcome mode")
|
||||
switch_mode(UIMode.WELCOME)
|
||||
update_resolution(misc.get_best_resolution())
|
||||
logger.diag("Updating window properties")
|
||||
DisplayServer.window_set_mode(DisplayServer.WINDOW_MODE_FULLSCREEN)
|
||||
DisplayServer.window_set_min_size(Vector2i(960, 540))
|
||||
get_tree().root.content_scale_mode = Window.CONTENT_SCALE_MODE_VIEWPORT
|
||||
get_tree().root.content_scale_aspect = Window.CONTENT_SCALE_ASPECT_KEEP
|
||||
get_tree().root.content_scale_factor = 1.0
|
||||
|
||||
func uninitialize() -> void:
|
||||
if !initialized:
|
||||
logger.error("The UI Engine is not initialized.")
|
||||
return
|
||||
logger.info("Uninitializing UI Engine")
|
||||
loader = null
|
||||
initialized = false
|
||||
resolution = "960x540"
|
||||
ui_mode = UIMode.UNKNOWN
|
||||
logger.info("Unloading UI mode")
|
||||
ui_mode_node.queue_free()
|
||||
ui_mode_node = null
|
||||
|
||||
func _process(_delta: float) -> void:
|
||||
if !initialized: return
|
||||
if Input.is_action_just_pressed("editor_switchres"):
|
||||
match(resolution):
|
||||
"960x540": update_resolution(Vector2i(1920, 1080))
|
||||
"1920x1080": update_resolution(Vector2i(2560, 1440))
|
||||
"2560x1440": update_resolution(Vector2i(3840, 2160))
|
||||
"3840x2160": update_resolution(Vector2i(960, 540))
|
||||
|
||||
func switch_mode(mode: UIMode) -> void:
|
||||
if !initialized:
|
||||
logger.error("The UI Engine hasn't been initialized yet")
|
||||
return
|
||||
if mode == UIMode.UNKNOWN: return
|
||||
logger.info("Switching to mode " + str(mode))
|
||||
if ui_mode_node != null: loader.remove_child(ui_mode_node)
|
||||
match(mode):
|
||||
UIMode.WELCOME:
|
||||
ui_mode_node = ResourceLoader.load("res://ui/Welcome.tscn").instantiate()
|
||||
ui_mode = UIMode.WELCOME
|
||||
loader.add_child(ui_mode_node)
|
||||
ui_mode_node.switch_mode()
|
||||
|
||||
func update_resolution(new_resolution: Vector2i) -> void:
|
||||
if !initialized:
|
||||
logger.error("The UI Engine hasn't been initialized yet")
|
||||
return
|
||||
DisplayServer.window_set_size(new_resolution)
|
||||
get_tree().root.content_scale_size = new_resolution
|
||||
if get_node_or_null("/root/Console") != null: get_node("/root/Console").calculate_drag_area(new_resolution)
|
||||
resolution = str(new_resolution.x) + "x" + str(new_resolution.y)
|
||||
match(ui_mode):
|
||||
UIMode.UNKNOWN: return
|
||||
UIMode.WELCOME: ui_mode_node.update_resolution(new_resolution)
|
||||
logger.diag("Set resolution to " + str(new_resolution.x) + "x" + str(new_resolution.y))
|
125
ui/Welcome.tscn
Normal file
125
ui/Welcome.tscn
Normal file
|
@ -0,0 +1,125 @@
|
|||
[gd_scene load_steps=6 format=3 uid="uid://b8byh8tp1kc6b"]
|
||||
|
||||
[ext_resource type="Texture2D" uid="uid://s10lveujhhqs" path="res://assets/images/Wallpaper.png" id="1_3cfcw"]
|
||||
[ext_resource type="Script" path="res://src/ui/welcome.gd" id="1_rowat"]
|
||||
[ext_resource type="Texture2D" uid="uid://41uwq5qahj23" path="res://assets/images/IconTextInverted.png" id="2_2w5c0"]
|
||||
|
||||
[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_0l23a"]
|
||||
bg_color = Color(0, 0, 0, 0.705882)
|
||||
corner_radius_top_left = 32
|
||||
corner_radius_top_right = 32
|
||||
corner_radius_bottom_right = 32
|
||||
corner_radius_bottom_left = 32
|
||||
|
||||
[sub_resource type="StyleBoxEmpty" id="StyleBoxEmpty_sor5s"]
|
||||
|
||||
[node name="GUIWelcome" type="Control"]
|
||||
layout_mode = 3
|
||||
anchors_preset = 15
|
||||
anchor_right = 1.0
|
||||
anchor_bottom = 1.0
|
||||
grow_horizontal = 2
|
||||
grow_vertical = 2
|
||||
script = ExtResource("1_rowat")
|
||||
|
||||
[node name="Wallpaper" type="NinePatchRect" parent="."]
|
||||
layout_mode = 0
|
||||
offset_right = 960.0
|
||||
offset_bottom = 540.0
|
||||
texture = ExtResource("1_3cfcw")
|
||||
|
||||
[node name="Welcome" type="Button" parent="Wallpaper"]
|
||||
layout_mode = 1
|
||||
anchors_preset = 8
|
||||
anchor_left = 0.5
|
||||
anchor_top = 0.5
|
||||
anchor_right = 0.5
|
||||
anchor_bottom = 0.5
|
||||
offset_left = -432.0
|
||||
offset_top = -243.0
|
||||
offset_right = 432.0
|
||||
offset_bottom = 243.0
|
||||
grow_horizontal = 2
|
||||
grow_vertical = 2
|
||||
theme_override_styles/normal = SubResource("StyleBoxFlat_0l23a")
|
||||
theme_override_styles/hover = SubResource("StyleBoxFlat_0l23a")
|
||||
theme_override_styles/pressed = SubResource("StyleBoxFlat_0l23a")
|
||||
theme_override_styles/disabled = SubResource("StyleBoxFlat_0l23a")
|
||||
theme_override_styles/focus = SubResource("StyleBoxEmpty_sor5s")
|
||||
|
||||
[node name="Icon" type="NinePatchRect" parent="Wallpaper/Welcome"]
|
||||
layout_mode = 1
|
||||
anchors_preset = 5
|
||||
anchor_left = 0.5
|
||||
anchor_right = 0.5
|
||||
offset_left = -320.0
|
||||
offset_top = 24.3
|
||||
offset_right = 320.0
|
||||
offset_bottom = 144.3
|
||||
grow_horizontal = 2
|
||||
texture = ExtResource("2_2w5c0")
|
||||
|
||||
[node name="Splash" type="RichTextLabel" parent="Wallpaper/Welcome" groups=["font", "font_normal"]]
|
||||
layout_mode = 1
|
||||
anchors_preset = 5
|
||||
anchor_left = 0.5
|
||||
anchor_right = 0.5
|
||||
offset_left = -320.0
|
||||
offset_top = 152.975
|
||||
offset_right = 320.0
|
||||
offset_bottom = 186.975
|
||||
grow_horizontal = 2
|
||||
mouse_filter = 2
|
||||
bbcode_enabled = true
|
||||
text = "[center]splash text[/center]"
|
||||
scroll_active = false
|
||||
|
||||
[node name="AboutText" type="RichTextLabel" parent="Wallpaper/Welcome" groups=["font", "font_small"]]
|
||||
layout_mode = 1
|
||||
anchors_preset = 7
|
||||
anchor_left = 0.5
|
||||
anchor_top = 1.0
|
||||
anchor_right = 0.5
|
||||
anchor_bottom = 1.0
|
||||
offset_left = -320.0
|
||||
offset_top = -92.0
|
||||
offset_right = 320.0
|
||||
offset_bottom = -20.0
|
||||
grow_horizontal = 2
|
||||
grow_vertical = 0
|
||||
mouse_filter = 2
|
||||
bbcode_enabled = true
|
||||
text = "[center][i]Copyright (c) 2024[/i] [b]JeremyStar™ & Contributors[/b]
|
||||
Licensed under the [b]GNU General Public License version 3[/b].
|
||||
Thank you for using Presencode <3[/center]"
|
||||
scroll_active = false
|
||||
|
||||
[node name="OpenButton" type="Button" parent="Wallpaper/Welcome" groups=["font_one", "font_one_normal"]]
|
||||
layout_mode = 1
|
||||
anchors_preset = 4
|
||||
anchor_top = 0.5
|
||||
anchor_bottom = 0.5
|
||||
offset_left = 60.0
|
||||
offset_top = -19.0
|
||||
offset_right = 278.0
|
||||
offset_bottom = 19.0
|
||||
grow_vertical = 2
|
||||
text = "Open presentation"
|
||||
|
||||
[node name="EditorButton" type="Button" parent="Wallpaper/Welcome" groups=["font_one", "font_one_normal"]]
|
||||
layout_mode = 1
|
||||
anchors_preset = 6
|
||||
anchor_left = 1.0
|
||||
anchor_top = 0.5
|
||||
anchor_right = 1.0
|
||||
anchor_bottom = 0.5
|
||||
offset_left = -278.0
|
||||
offset_top = -19.0
|
||||
offset_right = -60.0
|
||||
offset_bottom = 19.0
|
||||
grow_horizontal = 0
|
||||
grow_vertical = 2
|
||||
text = "Edit presentation"
|
||||
|
||||
[connection signal="pressed" from="Wallpaper/Welcome" to="." method="update_splash"]
|
||||
[connection signal="pressed" from="Wallpaper/Welcome/OpenButton" to="." method="open_presentation_picker"]
|
Loading…
Reference in a new issue