@tool
extends DialogicEditor

## Editor for editing character resources.

signal character_loaded(resource_path:String)
signal portrait_selected()


# Current state
var loading := false
var current_previewed_scene: Variant = null
var current_scene_path: String = ""

# References
var selected_item: TreeItem
var def_portrait_path: String = DialogicUtil.get_module_path('Character').path_join('default_portrait.tscn')


######### EDITOR STUFF and LOADING/SAVING ######################################

#region Resource Logic
## Method is called once editors manager is ready to accept registers.
func _register() -> void:
	## Makes the editor open this when a .dch file is selected.
	## Then _open_resource() is called.
	editors_manager.register_resource_editor("dch", self)

	## Add an "add character" button
	var add_character_button: Button = editors_manager.add_icon_button(
			load("res://addons/dialogic/Editor/Images/Toolbar/add-character.svg"),
			'Add Character',
			self)
	add_character_button.pressed.connect(_on_create_character_button_pressed)
	add_character_button.shortcut = Shortcut.new()
	add_character_button.shortcut.events.append(InputEventKey.new())
	add_character_button.shortcut.events[0].keycode = KEY_2
	add_character_button.shortcut.events[0].ctrl_pressed = true

	## By default show the no character screen
	$NoCharacterScreen.show()


func _get_title() -> String:
	return "Character"


func _get_icon() -> Texture:
	return load("res://addons/dialogic/Editor/Images/Resources/character.svg")


## Called when a character is opened somehow
func _open_resource(resource:Resource) -> void:
	if resource == null:
		$NoCharacterScreen.show()
		return

	## Update resource
	current_resource = (resource as DialogicCharacter)

	## Make sure changes in the ui won't trigger saving
	loading = true

	## Load other main tabs
	for child in %MainSettingsSections.get_children():
		if child is DialogicCharacterEditorMainSection:
			child._load_character(current_resource)

	## Clear and then load Portrait section
	%PortraitSearch.text = ""
	load_portrait_tree()

	loading = false
	character_loaded.emit(resource.resource_path)

	%CharacterName.text = DialogicResourceUtil.get_unique_identifier(resource.resource_path)

	$NoCharacterScreen.hide()
	%PortraitChangeInfo.hide()


## Called when the character is opened.
func _open(extra_info:Variant="") -> void:
	if !ProjectSettings.get_setting('dialogic/portraits/default_portrait', '').is_empty():
		def_portrait_path = ProjectSettings.get_setting('dialogic/portraits/default_portrait', '')
	else:
		def_portrait_path = DialogicUtil.get_module_path('Character').path_join('default_portrait.tscn')

	if current_resource == null:
		$NoCharacterScreen.show()
		return

	update_preview(true)
	%PortraitChangeInfo.hide()


func _clear() -> void:
	current_resource = null
	current_resource_state = ResourceStates.SAVED
	$NoCharacterScreen.show()


func _save() -> void:
	if ! visible or not current_resource:
		return

	## Portrait list
	current_resource.portraits = get_updated_portrait_dict()

	## Main tabs
	for child in %MainSettingsSections.get_children():
		if child is DialogicCharacterEditorMainSection:
			current_resource = child._save_changes(current_resource)

	ResourceSaver.save(current_resource, current_resource.resource_path)
	current_resource_state = ResourceStates.SAVED
	DialogicResourceUtil.update_directory('dch')


## Saves a new empty character to the given path
func new_character(path: String) -> void:
	var resource := DialogicCharacter.new()
	resource.resource_path = path
	resource.display_name = path.get_file().trim_suffix("."+path.get_extension())
	resource.color = Color(1,1,1,1)
	resource.default_portrait = ""
	resource.custom_info = {}
	ResourceSaver.save(resource, path)
	EditorInterface.get_resource_filesystem().update_file(path)
	DialogicResourceUtil.update_directory('dch')
	editors_manager.edit_resource(resource)

#endregion


######### INTERFACE ############################################################

#region Interface
func _ready() -> void:
	if get_parent() is SubViewport:
		return

	DialogicUtil.get_dialogic_plugin().resource_saved.connect(_on_some_resource_saved)
	# NOTE: This check is required because up to 4.2 this signal is not exposed.
	if DialogicUtil.get_dialogic_plugin().has_signal("scene_saved"):
		DialogicUtil.get_dialogic_plugin().scene_saved.connect(_on_some_resource_saved)

	$NoCharacterScreen.color = get_theme_color("dark_color_2", "Editor")
	$NoCharacterScreen.show()
	setup_portrait_list_tab()

	_on_fit_preview_toggle_toggled(DialogicUtil.get_editor_setting('character_preview_fit', true))
	%PreviewLabel.add_theme_color_override("font_color", get_theme_color("readonly_color", "Editor"))

	%PortraitChangeWarning.add_theme_color_override("font_color", get_theme_color("warning_color", "Editor"))

	%RealPreviewPivot.texture = get_theme_icon("EditorPivot", "EditorIcons")

	%MainSettingsCollapse.icon = get_theme_icon("GuiVisibilityVisible", "EditorIcons")

	set_portrait_settings_position(DialogicUtil.get_editor_setting('portrait_settings_position', true))

	await find_parent('EditorView').ready

	## Add general tabs
	add_settings_section(load("res://addons/dialogic/Editor/CharacterEditor/char_edit_section_general.tscn").instantiate(), %MainSettingsSections)
	add_settings_section(load("res://addons/dialogic/Editor/CharacterEditor/char_edit_section_portraits.tscn").instantiate(), %MainSettingsSections)


	add_settings_section(load("res://addons/dialogic/Editor/CharacterEditor/char_edit_p_section_main_exports.tscn").instantiate(), %PortraitSettingsSection)
	add_settings_section(load("res://addons/dialogic/Editor/CharacterEditor/char_edit_p_section_exports.tscn").instantiate(), %PortraitSettingsSection)
	add_settings_section(load("res://addons/dialogic/Editor/CharacterEditor/char_edit_p_section_main.tscn").instantiate(), %PortraitSettingsSection)
	add_settings_section(load("res://addons/dialogic/Editor/CharacterEditor/char_edit_p_section_layout.tscn").instantiate(), %PortraitSettingsSection)

	## Load custom sections from modules
	for indexer in DialogicUtil.get_indexers():
		for path in indexer._get_character_editor_sections():
			var scene: Control = load(path).instantiate()
			if scene is DialogicCharacterEditorMainSection:
				add_settings_section(scene, %MainSettingsSections)
			elif scene is DialogicCharacterEditorPortraitSection:
				add_settings_section(scene, %PortraitSettingsSection)


## Add a section (a control) either to the given settings section (Main or Portraits)
## - sets up the title of the section
## - connects to various signals
func add_settings_section(edit:Control, parent:Node) ->  void:
	edit.changed.connect(something_changed)
	edit.character_editor = self
	if edit.has_signal('update_preview'):
		edit.update_preview.connect(update_preview)

	var button: Button
	if edit._show_title():
		var hbox := HBoxContainer.new()
		hbox.name = edit._get_title()+"BOX"
		button = Button.new()
		button.flat = true
		button.theme_type_variation = "DialogicSection"
		button.alignment = HORIZONTAL_ALIGNMENT_LEFT
		button.size_flags_horizontal = Control.SIZE_SHRINK_BEGIN
		button.text = edit._get_title()
		button.icon_alignment = HORIZONTAL_ALIGNMENT_RIGHT
		button.pressed.connect(_on_section_button_pressed.bind(button))
		button.focus_mode = Control.FOCUS_NONE
		button.icon = get_theme_icon("CodeFoldDownArrow", "EditorIcons")
		button.add_theme_color_override('icon_normal_color', get_theme_color("font_color", "DialogicSection"))

		hbox.size_flags_horizontal = Control.SIZE_EXPAND_FILL
		hbox.add_child(button)

		if !edit.hint_text.is_empty():
			var hint: Node = load("res://addons/dialogic/Editor/Common/hint_tooltip_icon.tscn").instantiate()
			hint.hint_text = edit.hint_text
			hbox.add_child(hint)

		parent.add_child(hbox)
	parent.add_child(edit)
	parent.add_child(HSeparator.new())
	if button and !edit._start_opened():
		_on_section_button_pressed(button)


func get_settings_section_by_name(name:String, main:=true) -> Node:
	var parent := %MainSettingsSections
	if not main:
		parent = %PortraitSettingsSection

	if parent.has_node(name):
		return parent.get_node(name)
	elif parent.has_node(name+"BOX/"+name):
		return parent.get_node(name+"BOX/"+name)
	else:
		return null


func _on_section_button_pressed(button:Button) -> void:
	var section_header := button.get_parent()
	var section := section_header.get_parent().get_child(section_header.get_index()+1)
	if section.visible:
		button.icon = get_theme_icon("CodeFoldedRightArrow", "EditorIcons")
		section.visible = false
	else:
		button.icon = get_theme_icon("CodeFoldDownArrow", "EditorIcons")
		section.visible = true

	if section_header.get_parent().get_child_count() > section_header.get_index()+2 and section_header.get_parent().get_child(section_header.get_index()+2) is Separator:
		section_header.get_parent().get_child(section_header.get_index()+2).visible = section_header.get_parent().get_child(section_header.get_index()+1).visible


func something_changed(fake_argument = "", fake_arg2 = null) -> void:
	if not loading:
		current_resource_state = ResourceStates.UNSAVED


func _on_main_settings_collapse_toggled(button_pressed:bool) -> void:
	%MainSettingsTitle.visible = !button_pressed
	%MainSettingsScroll.visible = !button_pressed
	if button_pressed:
		%MainSettings.hide()
		%MainSettingsCollapse.icon = get_theme_icon("GuiVisibilityHidden", "EditorIcons")
	else:
		%MainSettings.show()
		%MainSettingsCollapse.icon = get_theme_icon("GuiVisibilityVisible", "EditorIcons")


func _on_switch_portrait_settings_position_pressed() -> void:
	set_portrait_settings_position(!%RightSection.vertical)


func set_portrait_settings_position(is_below:bool) -> void:
	%RightSection.vertical = is_below
	DialogicUtil.set_editor_setting('portrait_settings_position', is_below)
	if is_below:
		%SwitchPortraitSettingsPosition.icon = get_theme_icon("ControlAlignRightWide", "EditorIcons")
	else:
		%SwitchPortraitSettingsPosition.icon = get_theme_icon("ControlAlignBottomWide", "EditorIcons")

#endregion


########## PORTRAIT SECTION ####################################################

#region Portrait Section
func setup_portrait_list_tab() -> void:
	%PortraitTree.editor = self

	## Portrait section styling/connections
	%AddPortraitButton.icon = get_theme_icon("Add", "EditorIcons")
	%AddPortraitButton.pressed.connect(add_portrait)
	%AddPortraitGroupButton.icon = load("res://addons/dialogic/Editor/Images/Pieces/add-folder.svg")
	%AddPortraitGroupButton.pressed.connect(add_portrait_group)
	%ImportPortraitsButton.icon = get_theme_icon("Load", "EditorIcons")
	%ImportPortraitsButton.pressed.connect(open_portrait_folder_select)
	%PortraitSearch.right_icon = get_theme_icon("Search", "EditorIcons")
	%PortraitSearch.text_changed.connect(filter_portrait_list)

	%PortraitTree.item_selected.connect(load_selected_portrait)
	%PortraitTree.item_edited.connect(_on_item_edited)
	%PortraitTree.item_activated.connect(_on_item_activated)


func open_portrait_folder_select() -> void:
	find_parent("EditorView").godot_file_dialog(
		import_portraits_from_folder, "*.svg, *.png",
		EditorFileDialog.FILE_MODE_OPEN_DIR)


func import_portraits_from_folder(path:String) -> void:
	var parent: TreeItem = %PortraitTree.get_root()

	if %PortraitTree.get_selected() and %PortraitTree.get_selected() != parent and %PortraitTree.get_selected().get_metadata(0).has('group'):
		parent = %PortraitTree.get_selected()

	var dir := DirAccess.open(path)
	dir.list_dir_begin()
	var file_name: String = dir.get_next()
	var files := []
	while file_name != "":
		if not dir.current_is_dir():
			var file_lower := file_name.to_lower()
			if '.svg' in file_lower or '.png' in file_lower:
				if not '.import' in file_lower:
					files.append(file_name)
		file_name = dir.get_next()

	var prefix: String = files[0]
	for file in files:
		while true:
			if file.begins_with(prefix):
				break
			if prefix.is_empty():
				break
			prefix = prefix.substr(0, len(prefix)-1)

	for file in files:
		%PortraitTree.add_portrait_item(file.trim_prefix(prefix).trim_suffix('.'+file.get_extension()),
			{'scene':"",'export_overrides':{'image':var_to_str(path.path_join(file))}, 'scale':1, 'offset':Vector2(), 'mirror':false}, parent)

	## Handle selection
	if parent.get_child_count():
		parent.get_first_child().select(0)
	else:
		# Call anyways to clear preview and hide portrait settings section
		load_selected_portrait()

	something_changed()


func add_portrait(portrait_name:String='New portrait', portrait_data:Dictionary={'scene':"", 'export_overrides':{'image':''}, 'scale':1, 'offset':Vector2(), 'mirror':false}) -> void:
	var parent: TreeItem = %PortraitTree.get_root()
	if %PortraitTree.get_selected():
		if %PortraitTree.get_selected().get_metadata(0) and %PortraitTree.get_selected().get_metadata(0).has('group'):
			parent = %PortraitTree.get_selected()
		else:
			parent = %PortraitTree.get_selected().get_parent()
	var item: TreeItem = %PortraitTree.add_portrait_item(portrait_name, portrait_data, parent)
	item.set_meta('new', true)
	item.set_editable(0, true)
	item.select(0)
	%PortraitTree.call_deferred('edit_selected')
	something_changed()


func add_portrait_group() -> void:
	var parent_item: TreeItem = %PortraitTree.get_root()
	if %PortraitTree.get_selected() and %PortraitTree.get_selected().get_metadata(0).has('group'):
		parent_item = %PortraitTree.get_selected()
	var item: TreeItem = %PortraitTree.add_portrait_group("Group", parent_item)
	item.set_meta('new', true)
	item.set_editable(0, true)
	item.select(0)
	%PortraitTree.call_deferred('edit_selected')


func load_portrait_tree() -> void:
	%PortraitTree.clear_tree()
	var root: TreeItem = %PortraitTree.create_item()

	for portrait in current_resource.portraits.keys():
		var portrait_label: String = portrait
		var parent: TreeItem = %PortraitTree.get_root()
		if '/' in portrait:
			parent = %PortraitTree.create_necessary_group_items(portrait)
			portrait_label = portrait.split('/')[-1]

		%PortraitTree.add_portrait_item(portrait_label, current_resource.portraits[portrait], parent)

	update_default_portrait_star(current_resource.default_portrait)

	if root.get_child_count():
		root.get_first_child().select(0)
		while %PortraitTree.get_selected().get_child_count():
			%PortraitTree.get_selected().get_child(0).select(0)
	else:
		# Call anyways to clear preview and hide portrait settings section
		load_selected_portrait()


func filter_portrait_list(filter_term := "") -> void:
	filter_branch(%PortraitTree.get_root(), filter_term)


func filter_branch(parent: TreeItem, filter_term: String) -> bool:
	var anything_visible := false
	for item in parent.get_children():
		if item.get_metadata(0).has('group'):
			item.visible = filter_branch(item, filter_term)
			anything_visible = item.visible
		elif filter_term.is_empty() or filter_term.to_lower() in item.get_text(0).to_lower():
			item.visible = true
			anything_visible = true
		else:
			item.visible = false
	return anything_visible


## This is used to save the portrait data
func get_updated_portrait_dict() -> Dictionary:
	return list_portraits(%PortraitTree.get_root().get_children())


func list_portraits(tree_items: Array[TreeItem], dict := {}, path_prefix := "") -> Dictionary:
	for item in tree_items:
		if item.get_metadata(0).has('group'):
			dict = list_portraits(item.get_children(), dict, path_prefix+item.get_text(0)+"/")
		else:
			dict[path_prefix +item.get_text(0)] = item.get_metadata(0)
	return dict


func load_selected_portrait() -> void:
	if selected_item and is_instance_valid(selected_item):
		selected_item.set_editable(0, false)

	selected_item = %PortraitTree.get_selected()

	if selected_item and selected_item.get_metadata(0) != null and !selected_item.get_metadata(0).has('group'):
		%PortraitSettingsSection.show()
		var current_portrait_data: Dictionary = selected_item.get_metadata(0)
		portrait_selected.emit(%PortraitTree.get_full_item_name(selected_item), current_portrait_data)

		update_preview()

		for child in %PortraitSettingsSection.get_children():
			if child is DialogicCharacterEditorPortraitSection:
				child.selected_item = selected_item
				child._load_portrait_data(current_portrait_data)

	else:
		%PortraitSettingsSection.hide()
		update_preview()


func delete_portrait_item(item: TreeItem) -> void:
	if item.get_next_visible(true) and item.get_next_visible(true) != item:
		item.get_next_visible(true).select(0)
	else:
		selected_item = null
		load_selected_portrait()
	item.free()
	something_changed()


func duplicate_item(item: TreeItem) -> void:
	var new_item: TreeItem = %PortraitTree.add_portrait_item(item.get_text(0)+'_duplicated', item.get_metadata(0).duplicate(true), item.get_parent())
	new_item.set_meta('new', true)
	new_item.select(0)


func _input(event: InputEvent) -> void:
	if !is_visible_in_tree() or (get_viewport().gui_get_focus_owner()!= null and !name+'/' in str(get_viewport().gui_get_focus_owner().get_path())):
		return
	if event is InputEventKey and event.pressed:
		if event.keycode == KEY_F2 and %PortraitTree.get_selected():
			%PortraitTree.get_selected().set_editable(0, true)
			%PortraitTree.edit_selected()
			get_viewport().set_input_as_handled()
		elif event.keycode == KEY_DELETE and get_viewport().gui_get_focus_owner() is Tree and %PortraitTree.get_selected():
			delete_portrait_item(%PortraitTree.get_selected())
			get_viewport().set_input_as_handled()


func _on_portrait_right_click_menu_index_pressed(id: int) -> void:
	# RENAME BUTTON
	if id == 0:
		_on_item_activated()
	# DELETE BUTTON
	if id == 2:
		delete_portrait_item(%PortraitTree.get_selected())
	# DUPLICATE ITEM
	elif id == 1:
		duplicate_item(%PortraitTree.get_selected())
	elif id == 4:
		get_settings_section_by_name("Portraits").set_default_portrait(%PortraitTree.get_full_item_name(%PortraitTree.get_selected()))


## This removes/and adds the DEFAULT star on the portrait list
func update_default_portrait_star(default_portrait_name: String) -> void:
	var item_list: Array = %PortraitTree.get_root().get_children()
	if item_list.is_empty() == false:
		while true:
			var item: TreeItem = item_list.pop_back()
			if item.get_button_by_id(0, 2) != -1:
				item.erase_button(0, item.get_button_by_id(0, 2))
			if %PortraitTree.get_full_item_name(item) == default_portrait_name:
				item.add_button(0, get_theme_icon("Favorites", "EditorIcons"), 2, true, "Default")
			item_list.append_array(item.get_children())
			if item_list.is_empty():
				break


func _on_item_edited() -> void:
	selected_item = %PortraitTree.get_selected()
	something_changed()
	if selected_item:
		if %PreviewLabel.text.trim_prefix('Preview of "').trim_suffix('"') == current_resource.default_portrait:
			current_resource.default_portrait = %PortraitTree.get_full_item_name(selected_item)
		selected_item.set_editable(0, false)

		if !selected_item.has_meta('new') and %PortraitTree.get_full_item_name(selected_item) != selected_item.get_meta('previous_name'):
			report_name_change(selected_item)
			%PortraitChangeInfo.show()
	update_preview()


func _on_item_activated() -> void:
	if %PortraitTree.get_selected() == null:
		return
	%PortraitTree.get_selected().set_editable(0, true)
	%PortraitTree.edit_selected()


func report_name_change(item: TreeItem) -> void:
	if item.get_metadata(0).has('group'):
		for s_item in item.get_children():
			if s_item.get_metadata(0).has('group') or !s_item.has_meta('new'):
				report_name_change(s_item)
	else:
		if item.get_meta('previous_name') == %PortraitTree.get_full_item_name(item):
			return
		editors_manager.reference_manager.add_portrait_ref_change(
			item.get_meta('previous_name'),
			%PortraitTree.get_full_item_name(item),
			[DialogicResourceUtil.get_unique_identifier(current_resource.resource_path)])
	item.set_meta('previous_name', %PortraitTree.get_full_item_name(item))
	%PortraitChangeInfo.show()

#endregion

########### PREVIEW ############################################################

#region Preview
func update_preview(force := false, ignore_settings_reload := false) -> void:
	%ScenePreviewWarning.hide()

	if selected_item and is_instance_valid(selected_item) and selected_item.get_metadata(0) != null and !selected_item.get_metadata(0).has('group'):
		%PreviewLabel.text = 'Preview of "'+%PortraitTree.get_full_item_name(selected_item)+'"'

		var current_portrait_data: Dictionary = selected_item.get_metadata(0)

		if not force and current_previewed_scene != null \
			and scene_file_path == current_portrait_data.get('scene') \
			and current_previewed_scene.has_method('_should_do_portrait_update') \
			and is_instance_valid(current_previewed_scene.get_script()) \
			and current_previewed_scene._should_do_portrait_update(current_resource, selected_item.get_text(0)):
			# We keep the same scene.
			pass
		else:

			for node in %RealPreviewPivot.get_children():
				node.queue_free()

			current_previewed_scene = null
			current_scene_path = ""

			var scene_path := def_portrait_path
			if not current_portrait_data.get('scene', '').is_empty():
				scene_path = current_portrait_data.get('scene')

			if ResourceLoader.exists(scene_path):
				current_previewed_scene = load(scene_path).instantiate()
				current_scene_path = scene_path

			if not current_previewed_scene == null:
				%RealPreviewPivot.add_child(current_previewed_scene)

		if not current_previewed_scene == null:
			var scene: Node = current_previewed_scene

			scene.show_behind_parent = true
			DialogicUtil.apply_scene_export_overrides(scene, current_portrait_data.get('export_overrides', {}))

			var mirror: bool = current_portrait_data.get('mirror', false) != current_resource.mirror
			var scale: float = current_portrait_data.get('scale', 1) * current_resource.scale

			if current_portrait_data.get('ignore_char_scale', false):
				scale = current_portrait_data.get('scale', 1)

			var offset: Vector2 = current_portrait_data.get('offset', Vector2()) + current_resource.offset

			if is_instance_valid(scene.get_script()) and scene.script.is_tool():

				if scene.has_method('_update_portrait'):
					## Create a fake duplicate resource that has all the portrait changes applied already
					var preview_character := current_resource.duplicate()
					preview_character.portraits = get_updated_portrait_dict()
					scene._update_portrait(preview_character, %PortraitTree.get_full_item_name(selected_item))

				if scene.has_method('_set_mirror'):
					scene._set_mirror(mirror)

			if !%FitPreview_Toggle.button_pressed:
				scene.position = Vector2() + offset
				scene.scale = Vector2(1,1)*scale
			else:

				if not scene.get_script() == null and scene.script.is_tool() and scene.has_method('_get_covered_rect'):
					var rect: Rect2 = scene._get_covered_rect()
					var available_rect: Rect2 = %FullPreviewAvailableRect.get_rect()
					scene.scale = Vector2(1,1) * min(available_rect.size.x/rect.size.x, available_rect.size.y/rect.size.y)
					%RealPreviewPivot.position = (rect.position)*-1*scene.scale
					%RealPreviewPivot.position.x = %FullPreviewAvailableRect.size.x/2
					scene.position = Vector2()

				else:
					%ScenePreviewWarning.show()
		else:
			%PreviewLabel.text = 'Nothing to preview'

		if not ignore_settings_reload:
			for child in %PortraitSettingsSection.get_children():
				if child is DialogicCharacterEditorPortraitSection:
					child._recheck(current_portrait_data)

	else:
		%PreviewLabel.text = 'No portrait to preview.'

		for node in %RealPreviewPivot.get_children():
			node.queue_free()

		current_previewed_scene = null
		current_scene_path = ""


func _on_some_resource_saved(file:Variant) -> void:
	if current_previewed_scene == null:
		return

	if file is Resource and file == current_previewed_scene.script:
		update_preview(true)

	if typeof(file) == TYPE_STRING and file == current_previewed_scene.get_meta("path", ""):
		update_preview(true)


func _on_full_preview_available_rect_resized() -> void:
	if %FitPreview_Toggle.button_pressed:
		update_preview(false, true)


func _on_create_character_button_pressed() -> void:
	editors_manager.show_add_resource_dialog(
			new_character,
			'*.dch; DialogicCharacter',
			'Create new character',
			'character',
			)


func _on_fit_preview_toggle_toggled(button_pressed):
	%FitPreview_Toggle.set_pressed_no_signal(button_pressed)
	if button_pressed:
		%FitPreview_Toggle.icon = get_theme_icon("ScrollContainer", "EditorIcons")
		%FitPreview_Toggle.tooltip_text = "Real scale"
	else:
		%FitPreview_Toggle.tooltip_text = "Fit into preview"
		%FitPreview_Toggle.icon = get_theme_icon("CenterContainer", "EditorIcons")
	DialogicUtil.set_editor_setting('character_preview_fit', button_pressed)
	update_preview(false, true)

#endregion

## Open the reference manager
func _on_reference_manger_button_pressed() -> void:
	editors_manager.reference_manager.open()
	%PortraitChangeInfo.hide()
