diff --git a/Assets/Scripts/MeshPainter.Persistence.cs b/Assets/Scripts/MeshPainter.Persistence.cs index 0701d45..a771516 100644 --- a/Assets/Scripts/MeshPainter.Persistence.cs +++ b/Assets/Scripts/MeshPainter.Persistence.cs @@ -71,14 +71,15 @@ public partial class MeshPainter } /// - /// Writes the current painted maps to a new named slot. Returns false without writing if the painter - /// is not ready or a slot with this name already exists (no silent overwrite). + /// Writes the current painted maps to a named slot. Returns false without writing if the painter is + /// not ready. An existing slot of the same name is overwritten only when + /// is true; otherwise the call fails rather than clobbering it. /// - public bool SavePaintAs(string name) + public bool SavePaintAs(string name, bool overwrite = false) { if (!_setupValid || string.IsNullOrWhiteSpace(name)) return false; name = name.Trim(); - if (PaintExists(name)) return false; + if (!overwrite && PaintExists(name)) return false; try { diff --git a/Assets/Scripts/PaintHud.Library.cs b/Assets/Scripts/PaintHud.Library.cs index fb52090..dd40f06 100644 --- a/Assets/Scripts/PaintHud.Library.cs +++ b/Assets/Scripts/PaintHud.Library.cs @@ -9,9 +9,10 @@ using UnityEngine.UI; /// list, an entry template, and the Save / Confirm dialogs) is authored inside the PaintHudPanel layout /// prefab - this code only finds those objects by their stable names and wires the behaviour, exactly like /// does for the brush widgets. The list is populated by cloning the authored -/// Lib_EntryTemplate per saved slot. Save opens a name dialog (blocked if the name already exists, no -/// overwrite); Load and Delete go through a confirmation dialog. Loading replaces the current painting and, -/// when networked, re-broadcasts the loaded state to every other peer. +/// Lib_EntryTemplate per saved slot. Save opens a name dialog (an existing name is overwritten, with a +/// warning shown while typing); Load applies the selected slot immediately; Delete goes through a +/// confirmation dialog. Loading replaces the current painting and, when networked, re-broadcasts the +/// loaded state to every other peer. /// public partial class PaintHud { @@ -55,7 +56,6 @@ public partial class PaintHud private static readonly Color EntryNormal = new Color(0.18f, 0.18f, 0.22f, 1f); private static readonly Color EntrySelected = new Color(0.20f, 0.45f, 0.80f, 1f); - private static readonly Color OkAccent = new Color(0.20f, 0.45f, 0.80f, 1f); private static readonly Color OkDanger = new Color(0.62f, 0.26f, 0.26f, 1f); // --- Bind (find authored objects, hook listeners) --- @@ -200,17 +200,19 @@ public partial class PaintHud string name = _nameInput ? _nameInput.text.Trim() : ""; bool empty = string.IsNullOrEmpty(name); bool exists = !empty && MeshPainter.PaintExists(name); - if (_saveOkButton) _saveOkButton.interactable = !empty && !exists && painter; - if (_saveInfo) _saveInfo.text = exists ? "A painting with this name already exists." : ""; + // Overwrite is allowed -> the OK button stays enabled even when the name exists; the warning is + // purely informational so you know you are about to replace an existing slot. + if (_saveOkButton) _saveOkButton.interactable = !empty && painter; + if (_saveInfo) _saveInfo.text = exists ? "A painting with this name already exists and will be overwritten." : ""; } private void ConfirmSave() { if (!painter || !_nameInput) return; string name = _nameInput.text.Trim(); - if (string.IsNullOrEmpty(name) || MeshPainter.PaintExists(name)) { ValidateSaveName(); return; } + if (string.IsNullOrEmpty(name)) { ValidateSaveName(); return; } - if (painter.SavePaintAs(name)) + if (painter.SavePaintAs(name, overwrite: true)) { _selectedPainting = name; if (_saveDialog) _saveDialog.SetActive(false); @@ -225,8 +227,7 @@ public partial class PaintHud private void OnLoadClicked() { if (!painter || string.IsNullOrEmpty(_selectedPainting)) return; - string name = _selectedPainting; - ShowConfirm($"Load \"{name}\"?\nThe current painting will be lost.", OkAccent, () => DoLoad(name)); + DoLoad(_selectedPainting); // load immediately, no confirmation } private void OnDeleteClicked()