tool class_name NewGamePanel extends PopupPanel signal start_triggered(config, texture) const pref_path := "user://preferences.cfg" const cached_artwork_path := "user://artwork.dat" const easy_columns := 3 const easy_rows := 3 const easy_iterations := 4 const normal_columns := 4 const normal_rows := 4 const normal_iterations := 10 const hard_columns := 5 const hard_rows := 5 const hard_iterations := 30 const Utils = preload("res://src/Utils.gd") export var window_scale_factor = 0.9 # how big the popup will be compared to screen export var default_artwork_texture: Texture var preferences = ConfigFile.new() var fade_duration = 0.2 var fade_scale_factor = 0.9 var flip_duration = 0.4 onready var popup = $"." onready var panel = $Panel onready var edit_panel = $EditPanel onready var tween = $Tween onready var difficulty_container = $Panel/VBoxContainer/Difficulty onready var easy_button = $Panel/VBoxContainer/Difficulty/Easy onready var normal_button = $Panel/VBoxContainer/Difficulty/Normal onready var hard_button = $Panel/VBoxContainer/Difficulty/Hard onready var custom_button = $Panel/VBoxContainer/HBoxContainer/Custom onready var preview = $Panel/VBoxContainer/ArtworkSource/Preview onready var columns_spinbox = $EditPanel/VBoxContainer/Columns/SpinBox onready var rows_spinbox = $EditPanel/VBoxContainer/Rows/SpinBox onready var iterations_spinbox = $EditPanel/VBoxContainer/Iterations/SpinBox func _init(): var err = preferences.load(pref_path) func _ready(): rect_pivot_offset = rect_size / 2 assert(popup.theme != null) var popup_style : = popup.get_stylebox("panel", "PopupPanel") as StyleBoxFlat assert(popup_style != null) var panel_style := panel.get_stylebox("panel", "Panel") as StyleBoxFlat assert(panel_style != null) var modified_panel_style = panel_style.duplicate() modified_panel_style.corner_radius_bottom_left = popup_style.corner_radius_bottom_left modified_panel_style.corner_radius_bottom_right = popup_style.corner_radius_bottom_right modified_panel_style.corner_radius_top_left = popup_style.corner_radius_top_left modified_panel_style.corner_radius_top_right = popup_style.corner_radius_top_right panel.set("custom_styles/panel", modified_panel_style) edit_panel.set("custom_styles/panel", modified_panel_style) panel.show() edit_panel.hide() edit_panel.hide() var button_max_width: int = $EditPanel/VBoxContainer.rect_size.x / 3.5 var button_width := min(200, button_max_width) print_debug("button max width = ", button_max_width) easy_button.rect_min_size.x = button_width normal_button.rect_min_size.x = button_width hard_button.rect_min_size.x = button_width custom_button.rect_min_size.x = button_width func fade_in(): tween.remove_all() tween.interpolate_property(self, "rect_scale", Vector2(fade_scale_factor, fade_scale_factor), Vector2.ONE, fade_duration, Tween.TRANS_LINEAR, Tween.EASE_IN) tween.interpolate_property(self, "modulate:a", 0.0, 1.0, fade_duration, Tween.TRANS_LINEAR, Tween.EASE_IN) tween.start() func fade_out(): tween.remove_all() tween.interpolate_property(self, "rect_scale", Vector2.ONE, Vector2(fade_scale_factor, fade_scale_factor), fade_duration, Tween.TRANS_LINEAR, Tween.EASE_IN) tween.interpolate_property(self, "modulate:a", 1.0, 0.0, fade_duration, Tween.TRANS_LINEAR, Tween.EASE_IN) tween.interpolate_callback(self, fade_duration, "hide") tween.start() func flip_over(new_panel: Panel) -> void: tween.remove_all() var mid_duration = flip_duration / 2.0 tween.interpolate_property(self, "rect_scale:x", 1.0, 0.0, mid_duration) tween.interpolate_callback($Panel, mid_duration, "hide") tween.interpolate_callback(new_panel, mid_duration, "show") tween.interpolate_property(self, "rect_scale:x", 0.0, 1.0, mid_duration, Tween.TRANS_LINEAR, Tween.EASE_IN, mid_duration) tween.start() func flip_back(previous_panel: Panel) -> void: _update_description() tween.remove_all() var mid_duration = flip_duration / 2.0 tween.interpolate_property(self, "rect_scale:x", 1.0, 0.0, mid_duration) tween.interpolate_callback($Panel, mid_duration, "show") tween.interpolate_callback(previous_panel, mid_duration, "hide") tween.interpolate_property(self, "rect_scale:x", 0.0, 1.0, mid_duration, Tween.TRANS_LINEAR, Tween.EASE_IN, mid_duration) tween.start() func _update_description(): var columns := 0 var rows := 0 var iterations := 0 if easy_button.pressed: columns = easy_columns rows = easy_rows iterations = easy_iterations if normal_button.pressed: columns = normal_columns rows = normal_rows iterations = normal_iterations if hard_button.pressed: columns = hard_columns rows = hard_rows iterations = hard_iterations if custom_button.pressed: columns = columns_spinbox.value as int rows = rows_spinbox.value as int iterations = iterations_spinbox.value as int var desc: RichTextLabel = $Panel/VBoxContainer/HBoxContainer/Description # $Panel/Description.text = "Dimension: %d x %d\nIterations: %d" % [columns, rows, iterations] desc.clear() desc.push_align(RichTextLabel.ALIGN_CENTER) desc.add_text("Board: ") desc.push_bold() desc.add_text("%d" % [columns]) desc.pop() desc.add_text(" x ") desc.push_bold() desc.add_text("%d" % [rows]) desc.pop() desc.newline() desc.add_text("Shuffle: ") desc.push_bold() desc.add_text("%d" % [iterations]) desc.pop() func _set_artwork(tex: Texture) -> void: preview.texture = tex var file = File.new() if file.open(cached_artwork_path, File.WRITE) != OK: assert(false) file.store_var(tex.get_data(), true) file.close() # # Signals # func _on_Cancel_pressed(): fade_out() func _on_Start_pressed(): if easy_button.pressed: preferences.set_value("game", "difficulty", "easy") preferences.set_value("game", "columns", easy_columns) preferences.set_value("game", "rows", easy_rows) preferences.set_value("game", "shuffle_iterations", easy_iterations) if normal_button.pressed: preferences.set_value("game", "difficulty", "normal") preferences.set_value("game", "columns", normal_columns) preferences.set_value("game", "rows", normal_rows) preferences.set_value("game", "shuffle_iterations", normal_iterations) if hard_button.pressed: preferences.set_value("game", "difficulty", "hard") preferences.set_value("game", "columns", hard_columns) preferences.set_value("game", "rows", hard_rows) preferences.set_value("game", "shuffle_iterations", hard_iterations) if custom_button.pressed: preferences.set_value("game", "difficulty", "custom") preferences.set_value("game", "columns", columns_spinbox.value) preferences.set_value("game", "rows", rows_spinbox.value) preferences.set_value("game", "shuffle_iterations", iterations_spinbox.value) preferences.save(pref_path) emit_signal("start_triggered", preferences, preview.texture) fade_out() func _on_NewGamePanel_about_to_show(): var difficulty = preferences.get_value("game", "difficulty", "normal") easy_button.pressed = difficulty == "easy" normal_button.pressed = difficulty == "normal" hard_button.pressed = difficulty == "hard" custom_button.pressed = difficulty == "custom" columns_spinbox.value = preferences.get_value("game", "custom_columns", normal_columns) rows_spinbox.value = preferences.get_value("game", "custom_rows", normal_rows) iterations_spinbox.value = preferences.get_value("game", "custom_shuffle_iterations", normal_iterations) _update_description() preview.texture = Utils.deserialize_texture(cached_artwork_path) if preview.texture == null: preview.texture = default_artwork_texture # $Panel/Start.grab_focus() fade_in() func _on_Edit_Cancel_pressed(): columns_spinbox.value = preferences.get_value("game", "custom_columns", normal_columns) rows_spinbox.value = preferences.get_value("game", "custom_rows", normal_rows) iterations_spinbox.value = preferences.get_value("game", "custom_shuffle_iterations", normal_iterations) flip_back($EditPanel) func _on_Edit_Save_pressed(): print_debug(columns_spinbox.value) preferences.set_value("game", "custom_columns", columns_spinbox.value as int) preferences.set_value("game", "custom_rows", rows_spinbox.value as int) preferences.set_value("game", "custom_shuffle_iterations", iterations_spinbox.value as int) flip_back($EditPanel) func _on_Easy_pressed(): _update_description() func _on_Normal_pressed(): _update_description() func _on_Hard_pressed(): _update_description() func _on_Custom_pressed(): _update_description() flip_over($EditPanel) func _on_LoadImage_pressed(): flip_over($ImagePicker) #func _on_ImagePicker_file_selected(path): # print_debug(path) # var texture := load(path) # if texture == null: # print_debug("Cannot load image from path: ", path) # return # preview.texture = texture # # var file = File.new() # file.store_var(texture) # # var directory = Directory.new() # # TODO: remove previous artwork.png, artwork.jpg files # var cached_artwork_path := "user://artwork.%s" % [path.get_extension()] # var error = directory.copy(path, cached_artwork_path) # if error != OK: # print_debug("Cannot cache image") # _artwork_path = path # else: # _artwork_path = cached_artwork_path # flip_back($ImagePicker) func _on_ImagePicker_canceled(): flip_back($ImagePicker) func _on_ImagePicker_texture_selected(texture): _set_artwork(texture) flip_back($ImagePicker)