Add phantom camera
This commit is contained in:
@@ -0,0 +1,162 @@
|
||||
#######################################################################
|
||||
# Credit goes to the Dialogue Manager plugin for this script
|
||||
# Check it out at: https://github.com/nathanhoad/godot_dialogue_manager
|
||||
#######################################################################
|
||||
|
||||
@tool
|
||||
extends Control
|
||||
|
||||
#region Constants
|
||||
|
||||
const TEMP_FILE_NAME = "user://temp.zip"
|
||||
|
||||
#endregion
|
||||
|
||||
|
||||
#region Signals
|
||||
|
||||
signal failed()
|
||||
signal updated(updated_to_version: String)
|
||||
|
||||
#endregion
|
||||
|
||||
|
||||
#region @onready
|
||||
|
||||
#@onready var logo: TextureRect = %Logo
|
||||
@onready var _download_verion: Label = %DownloadVersionLabel
|
||||
@onready var _download_http_request: HTTPRequest = %DownloadHTTPRequest
|
||||
@onready var _download_button: Button = %DownloadButton
|
||||
@onready var _download_button_bg: NinePatchRect = %DownloadButtonBG
|
||||
@onready var _download_label: Label = %UpdateLabel
|
||||
|
||||
@onready var _breaking_label: Label = %BreakingLabel
|
||||
@onready var _breaking_margin_container: MarginContainer = %BreakingMarginContainer
|
||||
@onready var _breaking_options_button: OptionButton = %BreakingOptionButton
|
||||
#@onready var current_version_label: Label = %CurrentVersionLabel
|
||||
|
||||
#endregion
|
||||
|
||||
|
||||
#region Variables
|
||||
|
||||
# Todo - For 4.2 upgrade - Shows current version
|
||||
var _download_dialogue: AcceptDialog
|
||||
var _button_texture_default: Texture2D = load("res://addons/phantom_camera/assets/PhantomCameraBtnPrimaryDefault.png")
|
||||
var _button_texture_hover: Texture2D = load("res://addons/phantom_camera/assets/PhantomCameraBtnPrimaryHover.png")
|
||||
|
||||
var next_version_release: Dictionary:
|
||||
set(value):
|
||||
next_version_release = value
|
||||
_download_verion.text = "%s update is available for download" % value.tag_name.substr(1)
|
||||
# Todo - For 4.2 upgrade
|
||||
#current_version_label.text = "Current version is " + editor_plugin.get_version()
|
||||
get:
|
||||
return next_version_release
|
||||
|
||||
var _breaking_window_height: float = 520
|
||||
var _breaking_window_height_update: float = 600
|
||||
|
||||
#endregion
|
||||
|
||||
|
||||
#region Private Functions
|
||||
|
||||
func _ready() -> void:
|
||||
_download_http_request.request_completed.connect(_on_http_request_request_completed)
|
||||
_download_button.pressed.connect(_on_download_button_pressed)
|
||||
_download_button.mouse_entered.connect(_on_mouse_entered)
|
||||
_download_button.mouse_exited.connect(_on_mouse_exited)
|
||||
|
||||
_breaking_label.hide()
|
||||
_breaking_margin_container.hide()
|
||||
_breaking_options_button.hide()
|
||||
|
||||
_breaking_options_button.item_selected.connect(_on_item_selected)
|
||||
|
||||
|
||||
func _on_item_selected(index: int) -> void:
|
||||
if index == 1:
|
||||
_download_button.show()
|
||||
_download_dialogue.size = Vector2(_download_dialogue.size.x, _breaking_window_height_update)
|
||||
else:
|
||||
_download_button.hide()
|
||||
_download_dialogue.size = Vector2(_download_dialogue.size.x, _breaking_window_height)
|
||||
|
||||
|
||||
func _on_download_button_pressed() -> void:
|
||||
_download_http_request.request(next_version_release.zipball_url)
|
||||
_download_button.disabled = true
|
||||
_download_label.text = "Downloading..."
|
||||
_download_button_bg.hide()
|
||||
|
||||
|
||||
func _on_mouse_entered() -> void:
|
||||
_download_button_bg.set_texture(_button_texture_hover)
|
||||
|
||||
|
||||
func _on_mouse_exited() -> void:
|
||||
_download_button_bg.set_texture(_button_texture_default)
|
||||
|
||||
|
||||
func _on_http_request_request_completed(result: int, response_code: int, headers: PackedStringArray, body: PackedByteArray) -> void:
|
||||
if result != HTTPRequest.RESULT_SUCCESS:
|
||||
failed.emit()
|
||||
return
|
||||
|
||||
# Save the downloaded zip
|
||||
var zip_file: FileAccess = FileAccess.open(TEMP_FILE_NAME, FileAccess.WRITE)
|
||||
zip_file.store_buffer(body)
|
||||
zip_file.close()
|
||||
|
||||
OS.move_to_trash(ProjectSettings.globalize_path("res://addons/phantom_camera"))
|
||||
|
||||
var zip_reader: ZIPReader = ZIPReader.new()
|
||||
zip_reader.open(TEMP_FILE_NAME)
|
||||
var files: PackedStringArray = zip_reader.get_files()
|
||||
|
||||
var base_path = files[1]
|
||||
# Remove archive folder
|
||||
files.remove_at(0)
|
||||
# Remove assets folder
|
||||
files.remove_at(0)
|
||||
|
||||
for path in files:
|
||||
var new_file_path: String = path.replace(base_path, "")
|
||||
if path.ends_with("/"):
|
||||
DirAccess.make_dir_recursive_absolute("res://addons/%s" % new_file_path)
|
||||
else:
|
||||
var file: FileAccess = FileAccess.open("res://addons/%s" % new_file_path, FileAccess.WRITE)
|
||||
file.store_buffer(zip_reader.read_file(path))
|
||||
|
||||
zip_reader.close()
|
||||
DirAccess.remove_absolute(TEMP_FILE_NAME)
|
||||
|
||||
updated.emit(next_version_release.tag_name.substr(1))
|
||||
|
||||
|
||||
func _on_notes_button_pressed() -> void:
|
||||
OS.shell_open(next_version_release.html_url)
|
||||
|
||||
#endregion
|
||||
|
||||
#region Public Functions
|
||||
|
||||
func show_updater_warning(next_version_number: Array, current_version_number: Array) -> void:
|
||||
var current_version_number_0: int = current_version_number[0] as int
|
||||
var current_version_number_1: int = current_version_number[1] as int
|
||||
|
||||
var next_version_number_0: int = next_version_number[0] as int # Major release number in the new release
|
||||
var next_version_number_1: int = next_version_number[1] as int # Minor release number in the new release
|
||||
|
||||
if next_version_number_0 > current_version_number_0 or \
|
||||
next_version_number_1 > current_version_number_1:
|
||||
_breaking_label.show()
|
||||
_breaking_margin_container.show()
|
||||
_breaking_options_button.show()
|
||||
_download_button.hide()
|
||||
|
||||
_download_dialogue = get_parent()
|
||||
_download_dialogue.size = Vector2(_download_dialogue.size.x, _breaking_window_height)
|
||||
|
||||
#endregion
|
179
addons/phantom_camera/scripts/panel/updater/update_button.gd
Normal file
179
addons/phantom_camera/scripts/panel/updater/update_button.gd
Normal file
@@ -0,0 +1,179 @@
|
||||
#######################################################################
|
||||
# Credit goes to the Dialogue Manager plugin for this script
|
||||
# Check it out at: https://github.com/nathanhoad/godot_dialogue_manager
|
||||
#######################################################################
|
||||
|
||||
@tool
|
||||
extends Button
|
||||
|
||||
#region Constants
|
||||
|
||||
const REMOTE_RELEASE_URL: StringName = "https://api.github.com/repos/ramokz/phantom-camera/releases"
|
||||
const UPDATER_CONSTANTS := preload("res://addons/phantom_camera/scripts/panel/updater/updater_constants.gd")
|
||||
|
||||
#endregion
|
||||
|
||||
|
||||
#region @onready
|
||||
|
||||
@onready var http_request: HTTPRequest = %HTTPRequest
|
||||
@onready var download_dialog: AcceptDialog = %DownloadDialog
|
||||
@onready var download_update_panel: Control = %DownloadUpdatePanel
|
||||
@onready var needs_reload_dialog: AcceptDialog = %NeedsReloadDialog
|
||||
@onready var update_failed_dialog: AcceptDialog = %UpdateFailedDialog
|
||||
|
||||
#endregion
|
||||
|
||||
|
||||
#region Variables
|
||||
|
||||
# The main editor plugin
|
||||
var editor_plugin: EditorPlugin
|
||||
|
||||
var needs_reload: bool = false
|
||||
|
||||
# A lambda that gets called just before refreshing the plugin. Return false to stop the reload.
|
||||
var on_before_refresh: Callable = func(): return true
|
||||
|
||||
#endregion
|
||||
|
||||
|
||||
#region Private Functions
|
||||
|
||||
func _ready() -> void:
|
||||
hide()
|
||||
|
||||
# Check for updates on GitHub Releases
|
||||
check_for_update()
|
||||
|
||||
pressed.connect(_on_update_button_pressed)
|
||||
http_request.request_completed.connect(_request_request_completed)
|
||||
download_update_panel.updated.connect(_on_download_update_panel_updated)
|
||||
needs_reload_dialog.confirmed.connect(_on_needs_reload_dialog_confirmed)
|
||||
|
||||
|
||||
func _request_request_completed(result: int, response_code: int, headers: PackedStringArray, body: PackedByteArray) -> void:
|
||||
if result != HTTPRequest.RESULT_SUCCESS: return
|
||||
|
||||
if not editor_plugin: return
|
||||
var current_version: String = editor_plugin.get_version()
|
||||
|
||||
# Work out the next version from the releases information on GitHub
|
||||
var response: Array = JSON.parse_string(body.get_string_from_utf8())
|
||||
if typeof(response) != TYPE_ARRAY: return
|
||||
|
||||
# GitHub releases are in order of creation, not order of version
|
||||
var versions: Array = response.filter(func(release):
|
||||
var version: String = release.tag_name.substr(1)
|
||||
return version_to_number(version) > version_to_number(current_version)
|
||||
)
|
||||
|
||||
if versions.size() > 0:
|
||||
# Safeguard forks from being updated itself
|
||||
if FileAccess.file_exists("res://dev_scenes/3d/dev_scene_3d.tscn") or \
|
||||
not ProjectSettings.get_setting(UPDATER_CONSTANTS.setting_updater_enabled):
|
||||
|
||||
if not ProjectSettings.get_setting(UPDATER_CONSTANTS.setting_updater_notify_release): return
|
||||
|
||||
print_rich("
|
||||
[color=#3AB99A] ********[/color]
|
||||
[color=#3AB99A] ************[/color]
|
||||
[color=#3AB99A]**************[/color]
|
||||
[color=#3AB99A]****** *** *[/color]
|
||||
[color=#3AB99A]****** ***[/color]
|
||||
[color=#3AB99A]********** *****[/color]
|
||||
[color=#3AB99A]******** ***********[/color]
|
||||
[color=#3AB99A]******** *********** **[/color]
|
||||
[color=#3AB99A]********* **************[/color]
|
||||
[color=#3AB99A]********** *************[/color]
|
||||
[color=#3AB99A]** ** ** ******* **[/color]
|
||||
[font_size=18][b]New Phantom Camera version is available[/b][/font_size]")
|
||||
|
||||
if FileAccess.file_exists("res://dev_scenes/3d/dev_scene_3d.tscn"):
|
||||
print_rich("[font_size=14][color=#EAA15E][b]As you're using a fork of the project, you will need to update it manually[/b][/color][/font_size]")
|
||||
|
||||
print_rich("[font_size=12]If you don't want to see this message, then it can be disabled inside:\n[code]Project Settings/Phantom Camera/Updater/Show New Release Info on Editor Launch in Output[/code]")
|
||||
|
||||
return
|
||||
|
||||
download_update_panel.next_version_release = versions[0]
|
||||
download_update_panel.show_updater_warning(
|
||||
versions[0].tag_name.substr(1).split("."),
|
||||
current_version.split(".")
|
||||
)
|
||||
_set_scale()
|
||||
editor_plugin.panel_button.add_theme_color_override("font_color", Color("#3AB99A"))
|
||||
editor_plugin.panel_button.icon = load("res://addons/phantom_camera/icons/phantom_camera_updater_panel_icon.svg")
|
||||
editor_plugin.panel_button.add_theme_color_override("icon_normal_color", Color("#3AB99A"))
|
||||
show()
|
||||
|
||||
|
||||
func _on_update_button_pressed() -> void:
|
||||
if needs_reload:
|
||||
var will_refresh = on_before_refresh.call()
|
||||
if will_refresh:
|
||||
EditorInterface.restart_editor(true)
|
||||
else:
|
||||
_set_scale()
|
||||
download_dialog.popup_centered()
|
||||
|
||||
|
||||
func _set_scale() -> void:
|
||||
var scale: float = EditorInterface.get_editor_scale()
|
||||
download_dialog.min_size = Vector2(300, 250) * scale
|
||||
|
||||
|
||||
func _on_download_dialog_close_requested() -> void:
|
||||
download_dialog.hide()
|
||||
|
||||
|
||||
func _on_download_update_panel_updated(updated_to_version: String) -> void:
|
||||
download_dialog.hide()
|
||||
|
||||
needs_reload_dialog.dialog_text = "Reload to finish update"
|
||||
needs_reload_dialog.ok_button_text = "Reload"
|
||||
needs_reload_dialog.cancel_button_text = "Cancel"
|
||||
needs_reload_dialog.popup_centered()
|
||||
|
||||
needs_reload = true
|
||||
text = "Reload Project"
|
||||
|
||||
|
||||
func _on_download_update_panel_failed() -> void:
|
||||
download_dialog.hide()
|
||||
update_failed_dialog.dialog_text = "Updated Failed"
|
||||
update_failed_dialog.popup_centered()
|
||||
|
||||
|
||||
func _on_needs_reload_dialog_confirmed() -> void:
|
||||
EditorInterface.restart_editor(true)
|
||||
|
||||
|
||||
func _on_timer_timeout() -> void:
|
||||
if not needs_reload:
|
||||
check_for_update()
|
||||
|
||||
#endregion
|
||||
|
||||
|
||||
#region Public Functions
|
||||
|
||||
# Convert a version number to an actually comparable number
|
||||
func version_to_number(version: String) -> int:
|
||||
var regex = RegEx.new()
|
||||
regex.compile("[a-zA-Z]+")
|
||||
if regex.search(str(version)): return 0
|
||||
|
||||
var bits = version.split(".")
|
||||
var version_bit: int
|
||||
var multiplier: int = 10000
|
||||
for i in bits.size():
|
||||
version_bit += bits[i].to_int() * multiplier / (10 ** (i))
|
||||
|
||||
return version_bit
|
||||
|
||||
|
||||
func check_for_update() -> void:
|
||||
http_request.request(REMOTE_RELEASE_URL)
|
||||
|
||||
#endregion
|
@@ -0,0 +1,9 @@
|
||||
extends RefCounted
|
||||
|
||||
# Plugin Project Settings Sections
|
||||
const setting_phantom_camera: StringName = "phantom_camera/"
|
||||
const setting_updater_name: StringName = setting_phantom_camera + "updater/"
|
||||
|
||||
# Updater Settings
|
||||
const setting_updater_enabled: StringName = setting_updater_name + "enable_updater"
|
||||
const setting_updater_notify_release: StringName = setting_updater_name + "show_new_release_info_on_editor_launch_in_output"
|
Reference in New Issue
Block a user