diff --git a/Assets/Darkmatter/Code/Core/Contracts/Features/Coloring/IColoringController.cs b/Assets/Darkmatter/Code/Core/Contracts/Features/Coloring/IColoringController.cs new file mode 100644 index 0000000..95d990a --- /dev/null +++ b/Assets/Darkmatter/Code/Core/Contracts/Features/Coloring/IColoringController.cs @@ -0,0 +1,17 @@ +using System.Collections.Generic; +using System.Threading; +using Cysharp.Threading.Tasks; +using Darkmatter.Core.Contracts.Features.DrawingCatalog; +using UnityEngine; + +namespace Darkmatter.Core.Contracts.Features.Coloring; + +public interface IColoringController +{ + UniTask InitializeRegionsAsync(IDrawingTemplate template, IReadOnlyDictionary savedColors, + CancellationToken ct); + + void PaintRegion(string regionId, Color color); + IReadOnlyDictionary GetCurrentColors(); + void Clear(); +} \ No newline at end of file diff --git a/Assets/Darkmatter/Code/Core/Contracts/Features/Coloring/IColoringController.cs.meta b/Assets/Darkmatter/Code/Core/Contracts/Features/Coloring/IColoringController.cs.meta new file mode 100644 index 0000000..336851a --- /dev/null +++ b/Assets/Darkmatter/Code/Core/Contracts/Features/Coloring/IColoringController.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: b5ba5a7108234751ac286a57795fac06 +timeCreated: 1779971202 \ No newline at end of file diff --git a/Assets/Darkmatter/Code/Core/Contracts/Features/DrawingCatalog/IDrawingTemplate.cs b/Assets/Darkmatter/Code/Core/Contracts/Features/DrawingCatalog/IDrawingTemplate.cs index 9e997a5..176dd47 100644 --- a/Assets/Darkmatter/Code/Core/Contracts/Features/DrawingCatalog/IDrawingTemplate.cs +++ b/Assets/Darkmatter/Code/Core/Contracts/Features/DrawingCatalog/IDrawingTemplate.cs @@ -10,8 +10,10 @@ namespace Darkmatter.Core.Contracts.Features.DrawingCatalog string Id { get; } string DisplayName { get; } Sprite DefaultThumbnail { get; } - GameObject Prefab { get; } + GameObject DrawingPrefab { get; } + GameObject ColoringPrefab { get; } IReadOnlyList Pieces { get; } IReadOnlyList Regions { get; } + string ColorPaletteId { get; } } } \ No newline at end of file diff --git a/Assets/Darkmatter/Code/Core/Contracts/Features/GameplayFlow/IGameplayFlowController.cs b/Assets/Darkmatter/Code/Core/Contracts/Features/GameplayFlow/IGameplayFlowController.cs new file mode 100644 index 0000000..ef900f0 --- /dev/null +++ b/Assets/Darkmatter/Code/Core/Contracts/Features/GameplayFlow/IGameplayFlowController.cs @@ -0,0 +1,12 @@ +using Cysharp.Threading.Tasks; + +namespace Darkmatter.Core.Contracts.Features.GameplayFlow +{ + public interface IGameplayFlowController + { + UniTask BackAsync(); + UniTask SaveAsync(); + UniTask NextAsync(); + void OnApplicationPaused(); + } +} diff --git a/Assets/Darkmatter/Code/Core/Contracts/Features/GameplayFlow/IGameplayFlowController.cs.meta b/Assets/Darkmatter/Code/Core/Contracts/Features/GameplayFlow/IGameplayFlowController.cs.meta new file mode 100644 index 0000000..2b93b46 --- /dev/null +++ b/Assets/Darkmatter/Code/Core/Contracts/Features/GameplayFlow/IGameplayFlowController.cs.meta @@ -0,0 +1,2 @@ +fileFormatVersion: 2 +guid: fee5907f5643d492ab8ba177f84c30f6 \ No newline at end of file diff --git a/Assets/Darkmatter/Code/Core/Contracts/Features/History/IUndoStack.cs b/Assets/Darkmatter/Code/Core/Contracts/Features/History/IUndoStack.cs index 196ea7c..1891c27 100644 --- a/Assets/Darkmatter/Code/Core/Contracts/Features/History/IUndoStack.cs +++ b/Assets/Darkmatter/Code/Core/Contracts/Features/History/IUndoStack.cs @@ -7,9 +7,11 @@ namespace Darkmatter.Core.Contracts.Features.History event Action OnStackChanged; bool CanUndo { get; } bool CanRedo { get; } - void Push(ICommand cmd); // executes + appends + void Push(ICommand cmd); + void Append(ICommand cmd); void Undo(); void Redo(); - void Clear(); + void Clear(); // reverts every command via Undo, then drops (user-facing "wipe" semantics) + void Drop(); // drops the list without reverting (controller cleanup — avoids touching destroyed views) } } \ No newline at end of file diff --git a/Assets/Darkmatter/Code/Core/Contracts/Features/Progression/IProgressionSystem.cs b/Assets/Darkmatter/Code/Core/Contracts/Features/Progression/IProgressionSystem.cs index 9ba76a5..e22f21e 100644 --- a/Assets/Darkmatter/Code/Core/Contracts/Features/Progression/IProgressionSystem.cs +++ b/Assets/Darkmatter/Code/Core/Contracts/Features/Progression/IProgressionSystem.cs @@ -12,6 +12,9 @@ namespace Darkmatter.Core.Contracts.Features.Progression IReadOnlyCollection CompletedTemplateIds { get; } void MarkCompleted(string templateId); + string LastOpenedTemplateId { get; } + UniTask SetLastOpenedAsync(string templateId); + DrawingProgress? GetProgress(string templateId); UniTask SaveProgressAsync(DrawingProgress progress); UniTask SaveProgressAsync(DrawingProgress progress, byte[] thumbnailPng); diff --git a/Assets/Darkmatter/Code/Core/Data/Dynamic/Features/Coloring/ColorRegionDTO.cs b/Assets/Darkmatter/Code/Core/Data/Dynamic/Features/Coloring/ColorRegionDTO.cs index 94a4d91..ee882bf 100644 --- a/Assets/Darkmatter/Code/Core/Data/Dynamic/Features/Coloring/ColorRegionDTO.cs +++ b/Assets/Darkmatter/Code/Core/Data/Dynamic/Features/Coloring/ColorRegionDTO.cs @@ -1,18 +1,19 @@ using UnityEngine; +using UnityEngine.UI; namespace Darkmatter.Core.Data.Dynamic.Features.Coloring { public readonly struct ColorRegionDTO { - public string RegionId { get; } - public Sprite Sprite { get; } + public string Id { get; } + public Image Image { get; } public Vector2 AnchoredPosition { get; } public Color InitialColor { get; } - public ColorRegionDTO(string regionId, Sprite sprite, Vector2 anchoredPosition, Color initialColor) + public ColorRegionDTO(string id, Image image, Vector2 anchoredPosition, Color initialColor) { - RegionId = regionId; - Sprite = sprite; + Id = id; + Image = image; AnchoredPosition = anchoredPosition; InitialColor = initialColor; } diff --git a/Assets/Darkmatter/Code/Core/Data/Dynamic/Features/Progression/ProgressionRootDto.cs b/Assets/Darkmatter/Code/Core/Data/Dynamic/Features/Progression/ProgressionRootDto.cs index d01aad4..18fb3f2 100644 --- a/Assets/Darkmatter/Code/Core/Data/Dynamic/Features/Progression/ProgressionRootDto.cs +++ b/Assets/Darkmatter/Code/Core/Data/Dynamic/Features/Progression/ProgressionRootDto.cs @@ -7,5 +7,6 @@ namespace Darkmatter.Core.Data.Dynamic.Features.Progression public struct ProgressionRootDto { public List records; + public string lastOpenedTemplateId; } -} \ No newline at end of file +} diff --git a/Assets/Darkmatter/Code/Core/Data/Static/Features/DrawingTemplate/DrawingTemplateSO.cs b/Assets/Darkmatter/Code/Core/Data/Static/Features/DrawingTemplate/DrawingTemplateSO.cs index 9e10add..0ea022b 100644 --- a/Assets/Darkmatter/Code/Core/Data/Static/Features/DrawingTemplate/DrawingTemplateSO.cs +++ b/Assets/Darkmatter/Code/Core/Data/Static/Features/DrawingTemplate/DrawingTemplateSO.cs @@ -12,8 +12,10 @@ namespace Darkmatter.Core.Data.Static.Features.DrawingTemplate [field: SerializeField] public string Id { get; private set; } [field: SerializeField] public string DisplayName { get; private set; } [field: SerializeField] public Sprite DefaultThumbnail { get; private set; } - [field: SerializeField] public GameObject Prefab { get; private set; } + [field: SerializeField] public GameObject DrawingPrefab { get; private set; } + [field: SerializeField] public GameObject ColoringPrefab { get; private set; } [field: SerializeField] public IReadOnlyList Pieces { get; private set; } [field: SerializeField] public IReadOnlyList Regions { get; private set; } + [field: SerializeField] public string ColorPaletteId { get; private set; } = "defaultPalette"; } } \ No newline at end of file diff --git a/Assets/Darkmatter/Code/Core/Data/Static/Features/ShapeBuilder/ShapeBuilderConfig.cs b/Assets/Darkmatter/Code/Core/Data/Static/Features/ShapeBuilder/ShapeBuilderConfig.cs index 37948e8..5bc1267 100644 --- a/Assets/Darkmatter/Code/Core/Data/Static/Features/ShapeBuilder/ShapeBuilderConfig.cs +++ b/Assets/Darkmatter/Code/Core/Data/Static/Features/ShapeBuilder/ShapeBuilderConfig.cs @@ -8,7 +8,6 @@ namespace Darkmatter.Core.Data.Static.Features.ShapeBuilder { [Header("Radii (canvas units; reference resolution 2048x2048)")] [SerializeField] private float snapRadius = 100f; - [SerializeField] private float snapGraceMultiplier = 1.5f; [SerializeField] private float previewRadius = 200f; [Header("Tween durations (seconds)")] diff --git a/Assets/Darkmatter/Code/Core/Enums/Services/Audio/SfxId.cs b/Assets/Darkmatter/Code/Core/Enums/Services/Audio/SfxId.cs index 9863533..e0de386 100644 --- a/Assets/Darkmatter/Code/Core/Enums/Services/Audio/SfxId.cs +++ b/Assets/Darkmatter/Code/Core/Enums/Services/Audio/SfxId.cs @@ -6,5 +6,6 @@ namespace Darkmatter.Core.Enums.Services.Audio ShapeHover = 100, ShapeSnap = 101, ShapeReturn = 102, + UiTap = 200, } } diff --git a/Assets/Darkmatter/Code/Features/ColorbookFlow/Features.Colorbook.asmdef b/Assets/Darkmatter/Code/Features/ColorbookFlow/Features.Colorbook.asmdef index 31f53e4..1c1165d 100644 --- a/Assets/Darkmatter/Code/Features/ColorbookFlow/Features.Colorbook.asmdef +++ b/Assets/Darkmatter/Code/Features/ColorbookFlow/Features.Colorbook.asmdef @@ -4,8 +4,11 @@ "references": [ "GUID:6a0a834eb41764f12ba55c3fb04a40cb", "GUID:c1c03c0e5b2f4412b9f2be1c20d6a9b1", + "GUID:c176ee863a5e74e88a6517f9f102cf92", + "GUID:b4c9f7fbf1e144933a1797dc208ece5f", "GUID:b0214a6008ed146ff8f122a6a9c2f6cc", - "GUID:f51ebe6a0ceec4240a699833d6309b23" + "GUID:f51ebe6a0ceec4240a699833d6309b23", + "GUID:80ecb87cae9c44d19824e70ea7229748" ], "includePlatforms": [], "excludePlatforms": [], @@ -16,4 +19,4 @@ "defineConstraints": [], "versionDefines": [], "noEngineReferences": false -} \ No newline at end of file +} diff --git a/Assets/Darkmatter/Code/Features/ColorbookFlow/System/ColorbookFlowController.cs b/Assets/Darkmatter/Code/Features/ColorbookFlow/System/ColorbookFlowController.cs index 0055772..abc58c8 100644 --- a/Assets/Darkmatter/Code/Features/ColorbookFlow/System/ColorbookFlowController.cs +++ b/Assets/Darkmatter/Code/Features/ColorbookFlow/System/ColorbookFlowController.cs @@ -1,26 +1,62 @@ +using System; using System.Threading; using Cysharp.Threading.Tasks; using Darkmatter.Core.Contracts.Features.DrawingCatalog; using Darkmatter.Core.Contracts.Features.Loading; +using Darkmatter.Core.Contracts.Features.Progression; +using Darkmatter.Core.Contracts.Services.Scenes; +using Darkmatter.Core.Data.Signals.Features.Drawing; +using Darkmatter.Core.Enums.Services.Scenes; +using Darkmatter.Libs.Observer; using VContainer.Unity; namespace Darkmatter.Features.Colorbook.System; -public class ColorbookFlowController : IAsyncStartable +public class ColorbookFlowController : IAsyncStartable, IDisposable { private readonly IDrawingCatalogController _drawingCatalog; private readonly ILoadingScreen _loadingScreen; + private readonly IProgressionSystem _progression; + private readonly ISceneService _scenes; + private readonly IEventBus _bus; - public ColorbookFlowController(IDrawingCatalogController drawingCatalog, ILoadingScreen loadingScreen) + private IDisposable _selectedSub; + + public ColorbookFlowController( + IDrawingCatalogController drawingCatalog, + ILoadingScreen loadingScreen, + IProgressionSystem progression, + ISceneService scenes, + IEventBus bus) { _drawingCatalog = drawingCatalog; _loadingScreen = loadingScreen; + _progression = progression; + _scenes = scenes; + _bus = bus; } - + public async UniTask StartAsync(CancellationToken cancellation = new CancellationToken()) { _loadingScreen.SetProgress(1f); await _drawingCatalog.InitializeAsync(cancellation); + _selectedSub = _bus.Subscribe(OnDrawingSelected); _loadingScreen.Hide(); } -} \ No newline at end of file + + private void OnDrawingSelected(DrawingSelectedSignal signal) + { + HandleSelectionAsync(signal.TemplateId).Forget(); + } + + private async UniTaskVoid HandleSelectionAsync(string templateId) + { + await _progression.SetLastOpenedAsync(templateId); + await _scenes.LoadSceneAsync(GameScene.Gameplay, progress: null, cancellationToken: default); + } + + public void Dispose() + { + _selectedSub?.Dispose(); + } +} diff --git a/Assets/Darkmatter/Code/Features/Coloring/Commands/ColorRegionCommand.cs b/Assets/Darkmatter/Code/Features/Coloring/Commands/ColorRegionCommand.cs new file mode 100644 index 0000000..f6370ec --- /dev/null +++ b/Assets/Darkmatter/Code/Features/Coloring/Commands/ColorRegionCommand.cs @@ -0,0 +1,22 @@ +using Darkmatter.Core.Contracts.Features.History; +using Darkmatter.Features.Coloring.UI; +using UnityEngine; + +namespace Darkmatter.Features.Coloring.Commands; + +public class ColorRegionCommand : ICommand +{ + private readonly ColorRegionView _view; + private readonly Color _from; + private readonly Color _to; + + public ColorRegionCommand(ColorRegionView view, Color from, Color to) + { + _view = view; + _from = from; + _to = to; + } + + public void Execute() => _view.SetColor(_to); + public void Undo() => _view.SetColor(_from); +} diff --git a/Assets/Darkmatter/Code/Features/Coloring/Commands/ColorRegionCommand.cs.meta b/Assets/Darkmatter/Code/Features/Coloring/Commands/ColorRegionCommand.cs.meta new file mode 100644 index 0000000..4585a38 --- /dev/null +++ b/Assets/Darkmatter/Code/Features/Coloring/Commands/ColorRegionCommand.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: c212dc9aaa7e4445968fee229a715b3b +timeCreated: 1779972906 \ No newline at end of file diff --git a/Assets/Darkmatter/Code/Features/Coloring/Installers/ColoringFeatureModule.cs b/Assets/Darkmatter/Code/Features/Coloring/Installers/ColoringFeatureModule.cs index 748ad2f..4730c18 100644 --- a/Assets/Darkmatter/Code/Features/Coloring/Installers/ColoringFeatureModule.cs +++ b/Assets/Darkmatter/Code/Features/Coloring/Installers/ColoringFeatureModule.cs @@ -1,3 +1,5 @@ +using Darkmatter.Core.Contracts.Features.Coloring; +using Darkmatter.Features.Coloring.Systems; using Darkmatter.Features.Coloring.UI; using Darkmatter.Libs.Installers; using UnityEngine; @@ -17,6 +19,10 @@ namespace Darkmatter.Features.Coloring builder.RegisterComponent(paletteHolderView); builder.RegisterEntryPoint().WithParameter(paletteHolderView); } + + builder.Register(Lifetime.Singleton); + builder.Register(Lifetime.Singleton); + builder.Register(Lifetime.Singleton); } } -} +} \ No newline at end of file diff --git a/Assets/Darkmatter/Code/Features/Coloring/Systems/ColorButtonFactory.cs b/Assets/Darkmatter/Code/Features/Coloring/Systems/ColorButtonFactory.cs new file mode 100644 index 0000000..54f202f --- /dev/null +++ b/Assets/Darkmatter/Code/Features/Coloring/Systems/ColorButtonFactory.cs @@ -0,0 +1,30 @@ +using Darkmatter.Core.Contracts.Services.Audio; +using Darkmatter.Features.Coloring.UI; +using UnityEngine; + +namespace Darkmatter.Features.Coloring.Systems; + +public class ColorButtonFactory : IColorButtonFactory +{ + private readonly ColorPaletteHolderView _holder; + private readonly ColoringStateRepository _repository; + private readonly ISfxPlayer _sfx; + + public ColorButtonFactory( + ColorPaletteHolderView holder, + ColoringStateRepository repository, + ISfxPlayer sfx) + { + _holder = holder; + _repository = repository; + _sfx = sfx; + } + + public ColorButton Create(GameObject prefab, Color color) + { + var go = Object.Instantiate(prefab, _holder.SpawnRoot); + var btn = go.GetComponent(); + btn.Setup(color, _repository, _sfx); + return btn; + } +} \ No newline at end of file diff --git a/Assets/Darkmatter/Code/Features/Coloring/Systems/ColorButtonFactory.cs.meta b/Assets/Darkmatter/Code/Features/Coloring/Systems/ColorButtonFactory.cs.meta new file mode 100644 index 0000000..265df0e --- /dev/null +++ b/Assets/Darkmatter/Code/Features/Coloring/Systems/ColorButtonFactory.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 1bba9a928a76471391068acd46c4f684 +timeCreated: 1779970637 \ No newline at end of file diff --git a/Assets/Darkmatter/Code/Features/Coloring/Systems/ColoringController.cs b/Assets/Darkmatter/Code/Features/Coloring/Systems/ColoringController.cs new file mode 100644 index 0000000..a98b6f1 --- /dev/null +++ b/Assets/Darkmatter/Code/Features/Coloring/Systems/ColoringController.cs @@ -0,0 +1,146 @@ +using System; +using System.Collections.Generic; +using System.Threading; +using Cysharp.Threading.Tasks; +using Darkmatter.Core.Contracts.Features.Coloring; +using Darkmatter.Core.Contracts.Features.DrawingCatalog; +using Darkmatter.Core.Contracts.Features.GameplayFlow; +using Darkmatter.Core.Contracts.Features.History; +using Darkmatter.Core.Contracts.Services.Assets; +using Darkmatter.Core.Data.Signals.Features.Coloring; +using Darkmatter.Core.Data.Static.Features.Coloring; +using Darkmatter.Features.Coloring.Commands; +using Darkmatter.Features.Coloring.UI; +using Darkmatter.Libs.Observer; +using UnityEngine; +using ZLinq; + +namespace Darkmatter.Features.Coloring.Systems; + +public class ColoringController : IColoringController, IDisposable +{ + private const string ColorButtonPrefabKey = "colorButton"; + + private readonly ColoringStateRepository _repository; + private readonly IColorButtonFactory _buttonFactory; + private readonly IEventBus _bus; + private readonly IAssetProviderService _assetProviderService; + private readonly IUndoStack _history; + private readonly IGameplaySceneRefs _refs; + + private GameObject _colorInstance; + private GameObject _colorButtonPrefab; + private readonly List _regions = new(); + private readonly List _buttons = new(); + + public ColoringController( + ColoringStateRepository repository, + IColorButtonFactory buttonFactory, + IEventBus bus, + IAssetProviderService assetProviderService, + IUndoStack history, + IGameplaySceneRefs refs) + { + _repository = repository; + _buttonFactory = buttonFactory; + _bus = bus; + _assetProviderService = assetProviderService; + _history = history; + _refs = refs; + } + + public async UniTask InitializeRegionsAsync(IDrawingTemplate template, + IReadOnlyDictionary savedColors, CancellationToken ct) + { + Clear(); + await TryLoadColorButtonPrefabAsync(ct); + ct.ThrowIfCancellationRequested(); + await TryLoadColorPaletteAsync(template, ct); + ct.ThrowIfCancellationRequested(); + CreateColorButtonInstances(); + InitializeColorRegions(template, savedColors); + } + + public void PaintRegion(string regionId, Color color) + { + var region = _regions.AsValueEnumerable().FirstOrDefault(r => r.RegionId == regionId); + if (region == null) return; + + var from = region.Color; + _history.Push(new ColorRegionCommand(region, from, color)); + _bus.Publish(new ColorAppliedSignal(regionId, color)); + } + + public IReadOnlyDictionary GetCurrentColors() + { + var snapshot = new Dictionary(_regions.Count); + foreach (var region in _regions) + snapshot[region.RegionId] = region.Color; + return snapshot; + } + + public void Clear() + { + _history.Drop(); + + foreach (var button in _buttons) + if (button != null) UnityEngine.Object.Destroy(button.gameObject); + _buttons.Clear(); + + _regions.Clear(); + + if (_colorInstance != null) + { + UnityEngine.Object.Destroy(_colorInstance); + _colorInstance = null; + } + } + + public void Dispose() => Clear(); + + private void InitializeColorRegions(IDrawingTemplate template, IReadOnlyDictionary savedColors) + { + _colorInstance = UnityEngine.Object.Instantiate(template.ColoringPrefab, _refs.PaperRoot); + var views = _colorInstance.GetComponentsInChildren(includeInactive: true); + + foreach (var region in views) + { + var id = region.RegionId; + var authoredColor = region.Color; + var resumeColor = savedColors != null && savedColors.TryGetValue(id, out var saved) + ? saved + : authoredColor; + + if (resumeColor != authoredColor) + _history.Append(new ColorRegionCommand(region, authoredColor, resumeColor)); + + _regions.Add(region); + region.Initialize(resumeColor, () => PaintRegion(id, _repository.SelectedColor)); + } + } + + private async UniTask TryLoadColorButtonPrefabAsync(CancellationToken ct) + { + if (_colorButtonPrefab != null) return; + + _colorButtonPrefab = await _assetProviderService.LoadAssetAsync( + ColorButtonPrefabKey, progress: null, cancellationToken: ct); + if (_colorButtonPrefab == null) + throw new Exception($"No color button prefab at '{ColorButtonPrefabKey}'"); + } + + private async UniTask TryLoadColorPaletteAsync(IDrawingTemplate template, CancellationToken ct) + { + var palette = await _assetProviderService.LoadAssetAsync( + template.ColorPaletteId, progress: null, cancellationToken: ct); + if (palette == null) + throw new Exception($"No color palette at '{template.ColorPaletteId}'"); + _repository.SetPalette(palette); + } + + private void CreateColorButtonInstances() + { + foreach (var color in _repository.SelectedPalette.Colors) + _buttons.Add(_buttonFactory.Create(_colorButtonPrefab, color)); + } +} diff --git a/Assets/Darkmatter/Code/Features/Coloring/Systems/ColoringController.cs.meta b/Assets/Darkmatter/Code/Features/Coloring/Systems/ColoringController.cs.meta new file mode 100644 index 0000000..5993764 --- /dev/null +++ b/Assets/Darkmatter/Code/Features/Coloring/Systems/ColoringController.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 0849f8cc757842278c38ee6f4d61b985 +timeCreated: 1779971175 \ No newline at end of file diff --git a/Assets/Darkmatter/Code/Features/Coloring/Systems/ColoringStateRepository.cs b/Assets/Darkmatter/Code/Features/Coloring/Systems/ColoringStateRepository.cs new file mode 100644 index 0000000..e42d3ce --- /dev/null +++ b/Assets/Darkmatter/Code/Features/Coloring/Systems/ColoringStateRepository.cs @@ -0,0 +1,33 @@ +using System; +using Darkmatter.Core.Contracts.Features.Coloring; +using UnityEngine; + +namespace Darkmatter.Features.Coloring.Systems; + +public class ColoringStateRepository +{ + public IColorPalette SelectedPalette { get; private set; } + public int SelectedIndex { get; private set; } + public Color SelectedColor => + SelectedPalette != null && SelectedIndex >= 0 && SelectedIndex < SelectedPalette.Colors.Count + ? SelectedPalette.Colors[SelectedIndex] + : Color.white; + + public event Action SelectedIndexChanged; + + public void SetPalette(IColorPalette palette) + { + SelectedPalette = palette; + SelectedIndex = 0; + SelectedIndexChanged?.Invoke(); + } + + public void SelectColor(Color color) + { + if (SelectedPalette == null) return; + var idx = SelectedPalette.Colors.IndexOf(color); + if (idx < 0) return; + SelectedIndex = idx; + SelectedIndexChanged?.Invoke(); + } +} diff --git a/Assets/Darkmatter/Code/Features/Coloring/Systems/ColoringStateRepository.cs.meta b/Assets/Darkmatter/Code/Features/Coloring/Systems/ColoringStateRepository.cs.meta new file mode 100644 index 0000000..d78264e --- /dev/null +++ b/Assets/Darkmatter/Code/Features/Coloring/Systems/ColoringStateRepository.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: a288824e4f554000994bec451c09957c +timeCreated: 1779970861 \ No newline at end of file diff --git a/Assets/Darkmatter/Code/Features/Coloring/Systems/IColorButtonFactory.cs b/Assets/Darkmatter/Code/Features/Coloring/Systems/IColorButtonFactory.cs new file mode 100644 index 0000000..2e67f9d --- /dev/null +++ b/Assets/Darkmatter/Code/Features/Coloring/Systems/IColorButtonFactory.cs @@ -0,0 +1,9 @@ +using Darkmatter.Features.Coloring.UI; +using UnityEngine; + +namespace Darkmatter.Features.Coloring.Systems; + +public interface IColorButtonFactory +{ + ColorButton Create(GameObject prefab,Color color); +} \ No newline at end of file diff --git a/Assets/Darkmatter/Code/Features/Coloring/Systems/IColorButtonFactory.cs.meta b/Assets/Darkmatter/Code/Features/Coloring/Systems/IColorButtonFactory.cs.meta new file mode 100644 index 0000000..5256ee4 --- /dev/null +++ b/Assets/Darkmatter/Code/Features/Coloring/Systems/IColorButtonFactory.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 91b71be7f45a41cbb17492f82a3f0967 +timeCreated: 1779970564 \ No newline at end of file diff --git a/Assets/Darkmatter/Code/Features/Coloring/UI/ColorButton.cs b/Assets/Darkmatter/Code/Features/Coloring/UI/ColorButton.cs new file mode 100644 index 0000000..c64d29c --- /dev/null +++ b/Assets/Darkmatter/Code/Features/Coloring/UI/ColorButton.cs @@ -0,0 +1,54 @@ +using Darkmatter.Core.Contracts.Services.Audio; +using Darkmatter.Core.Enums.Services.Audio; +using Darkmatter.Features.Coloring.Systems; +using UnityEngine; +using UnityEngine.UI; + +namespace Darkmatter.Features.Coloring.UI +{ + [RequireComponent(typeof(Button))] + public class ColorButton : MonoBehaviour + { + [SerializeField] private Image swatch; + [SerializeField] private GameObject selectedUI; + private Button _button; + private Color _color; + private ColoringStateRepository _repository; + private ISfxPlayer _sfx; + + private void Awake() + { + _button = GetComponent