itchio-opengamepadui-plugin/core/itch_settings.gd

169 lines
6.3 KiB
GDScript3
Raw Normal View History

2026-08-05 17:27:43 -03:00
extends Control
## itch.io plugin settings screen
##
## NOTE: this uses plain Godot Controls rather than OpenGamepadUI's themed
## widget set (the ones used by the built-in Steam plugin's settings scene,
## e.g. its custom StatusIndicator/TextInput components), since this plugin
## was written without editor access to those scene resources. Swap the
## nodes below for the themed equivalents if you want it to match the rest
## of the settings UI pixel-for-pixel.
const ItchClient := preload("res://plugins/itch/core/itch_client.gd")
var settings_manager := load("res://core/global/settings_manager.tres") as SettingsManager
var notification_manager := load("res://core/global/notification_manager.tres") as NotificationManager
const icon := preload("res://plugins/itch/assets/itch.svg")
@onready var status_label: Label = $%StatusLabel
@onready var api_key_box: LineEdit = $%ApiKeyInput
@onready var username_box: LineEdit = $%UsernameInput
@onready var password_box: LineEdit = $%PasswordInput
@onready var login_method: OptionButton = $%LoginMethod
2026-08-05 17:27:43 -03:00
@onready var save_button: Button = $%SaveButton
@onready var help_label: Label = $%HelpLabel
@onready var filter_check: CheckBox = $%FilterUnsupported
@onready var show_purchases_check: CheckBox = $%ShowPurchases
@onready var collections_container: VBoxContainer = $%CollectionsContainer
2026-08-05 17:27:43 -03:00
@onready var itch: ItchClient = get_tree().get_first_node_in_group("itch_client")
var _collection_checks: Dictionary = {}
2026-08-05 17:27:43 -03:00
func _ready() -> void:
var api_key := settings_manager.get_value("plugin.itch", "api_key", "") as String
api_key_box.text = api_key
api_key_box.secret = true
var saved_method: int = settings_manager.get_value("plugin.itch", "login_method", 0) as int
login_method.selected = saved_method
_on_login_method_changed(saved_method)
var username := settings_manager.get_value("plugin.itch", "username", "") as String
username_box.text = username
filter_check.button_pressed = settings_manager.get_value("plugin.itch", "filter_unsupported", true) as bool
show_purchases_check.button_pressed = settings_manager.get_value("plugin.itch", "show_purchases", true) as bool
2026-08-05 17:27:43 -03:00
_update_status()
itch.client_ready.connect(_update_status)
itch.logged_in.connect(_on_login)
save_button.pressed.connect(_on_save_button)
filter_check.toggled.connect(_on_filter_toggled)
login_method.item_selected.connect(_on_login_method_changed)
show_purchases_check.toggled.connect(_on_show_purchases_toggled)
# Build collection checkboxes once we're logged in.
itch.logged_in.connect(_populate_collections.bind(), CONNECT_ONE_SHOT)
2026-08-05 17:27:43 -03:00
func _update_status() -> void:
if not itch:
status_label.text = "Status: itch client not found"
return
if itch.state == itch.STATE.BOOT:
status_label.text = "Status: starting butlerd..."
return
if not itch.is_logged_in:
status_label.text = "Status: connected, not logged in"
return
var username: String = itch.profile.get("user", {}).get("username", "")
status_label.text = "Status: logged in as " + username
func _on_login(status: ItchClient.LOGIN_STATUS, _profile: Dictionary) -> void:
_update_status()
var notify := Notification.new("")
notify.icon = icon
if status == ItchClient.LOGIN_STATUS.OK:
notify.text = "Successfully logged in to itch.io"
else:
notify.text = "itch.io login failed. Double check your credentials."
2026-08-05 17:27:43 -03:00
notification_manager.show(notify)
func _on_login_method_changed(idx: int) -> void:
# API key mode: show API key input, hide user/pass.
# Password mode: show user/pass, hide API key.
var is_api := idx == 0
api_key_box.visible = is_api
username_box.visible = not is_api
password_box.visible = not is_api
help_label.visible = is_api
2026-08-05 17:27:43 -03:00
func _on_save_button() -> void:
var method: int = login_method.selected
settings_manager.set_value("plugin.itch", "login_method", method)
if method == 0:
# API key login
var api_key: String = api_key_box.text.strip_edges()
settings_manager.set_value("plugin.itch", "api_key", api_key)
if api_key == "":
return
itch.login_with_api_key(api_key)
else:
# Username/password login
var username: String = username_box.text.strip_edges()
var password: String = password_box.text
settings_manager.set_value("plugin.itch", "username", username)
if username == "" or password == "":
return
itch.login_with_password(username, password)
## Fetches the user's collections and builds a checkbox for each one.
func _populate_collections(_status: ItchClient.LOGIN_STATUS, _profile: Dictionary) -> void:
if not itch.is_logged_in:
return
var profile_id: int = itch.profile.get("user", {}).get("id", itch.profile.get("id", 0))
var res := await itch._rpc_call("Fetch.ProfileCollections", {"profileId": profile_id})
if "error" in res:
2026-08-05 17:27:43 -03:00
return
var collections: Array = res.get("items", [])
# Load saved visibility state.
var hidden: Dictionary = settings_manager.get_value("plugin.itch", "hidden_collections", {}) as Dictionary
# Clear old checkboxes.
for child in collections_container.get_children():
child.queue_free()
_collection_checks.clear()
for c in collections:
var collection: Dictionary = c
var col_name: String = collection.get("title", "Collection " + str(collection.get("id", "")))
var col_id: String = str(collection.get("id", 0))
var check := CheckBox.new()
check.text = col_name
check.button_pressed = not hidden.has(col_id)
check.toggled.connect(_on_collection_toggled.bind(col_id))
collections_container.add_child(check)
_collection_checks[col_id] = check
func _on_collection_toggled(pressed: bool, col_id: String) -> void:
var hidden: Dictionary = settings_manager.get_value("plugin.itch", "hidden_collections", {}) as Dictionary
if pressed:
hidden.erase(col_id)
else:
hidden[col_id] = true
settings_manager.set_value("plugin.itch", "hidden_collections", hidden)
func _on_show_purchases_toggled(pressed: bool) -> void:
settings_manager.set_value("plugin.itch", "show_purchases", pressed)
## Persists the platform filter and reloads the itch.io library so the
## change applies without restarting. The setting is read back by
## library_itch.gd on every library load, so toggling just re-filters.
func _on_filter_toggled(pressed: bool) -> void:
settings_manager.set_value("plugin.itch", "filter_unsupported", pressed)
var library_manager := load("res://core/global/library_manager.tres") as LibraryManager
if library_manager:
library_manager.load_library("itch")