[Fix] Rename Scripts Folder

This commit is contained in:
2026-06-07 00:30:10 +07:00
parent 79a928ae52
commit 6c9cdaf67d
140 changed files with 0 additions and 0 deletions
@@ -0,0 +1,297 @@
using System;
using System.Collections.Generic;
using Minesweeper.Config;
using Minesweeper.Core;
using Minesweeper.Presentation.Factories;
using UnityEngine;
using UnityEngine.UI;
namespace Minesweeper.Presentation.Views
{
public sealed class BoardView : MonoBehaviour, IBoardView
{
private const float ResizeRefreshDelaySeconds = 0.5f;
private const float ResizeSizeEpsilon = 0.5f;
private const float MaximumCellPixelsPerUnitMultiplier = 1f;
private const float ContentPaddingReferenceCellSize = 202f;
private const float ContentPaddingReferencePadding = 15f;
private const float MinimumContentPadding = 1f;
[SerializeField] private GameObject root;
[SerializeField] private RectTransform boardPanel;
[SerializeField] private GridLayoutGroup gridLayoutGroup;
[SerializeField] private MinesweeperUiConfig uiConfig;
private readonly Dictionary<int, CellView> cellsByCoordinate = new Dictionary<int, CellView>();
private IReadOnlyList<BoardCellData> currentCells;
private bool inputEnabled = true;
private bool currentRevealUnflaggedMines;
private bool resizeRefreshPending;
private int currentBoardWidth;
private int currentBoardHeight;
private float currentContentPadding = MinimumContentPadding;
private float currentPixelsPerUnitMultiplier = 1f;
private float resizeStableAt;
private Vector2 lastObservedLayoutSize;
private GameObject Root => root != null ? root : gameObject;
public event Action CellPressStarted;
public event Action CellPressEnded;
public event Action PauseRequested;
public event Action<int, int> CellOpenRequested;
public event Action<int, int> CellFlagRequested;
private void Awake()
{
if (root == null)
{
root = gameObject;
}
if (boardPanel == null)
{
boardPanel = transform as RectTransform;
}
}
private void Update()
{
TrackResize();
}
public void BindConfig(MinesweeperUiConfig config)
{
uiConfig = config;
}
public void Show()
{
Root.SetActive(true);
ResetResizeTracking();
}
public void Hide()
{
Root.SetActive(false);
}
public void Rebuild(IReadOnlyList<BoardCellData> cells, int width, int height, ICellViewFactory cellViewFactory, bool revealUnflaggedMines)
{
Clear();
currentBoardWidth = width;
currentBoardHeight = height;
currentCells = cells;
currentRevealUnflaggedMines = revealUnflaggedMines;
ConfigureGrid(width, height);
for (var i = 0; i < cells.Count; i++)
{
CreateCell(cells[i], cellViewFactory);
}
Refresh(cells, revealUnflaggedMines);
}
public void Refresh(IReadOnlyList<BoardCellData> cells, bool revealUnflaggedMines)
{
currentCells = cells;
currentRevealUnflaggedMines = revealUnflaggedMines;
for (var i = 0; i < cells.Count; i++)
{
var cell = cells[i];
if (cellsByCoordinate.TryGetValue(ToKey(cell.X, cell.Y), out var view))
{
view.Render(cell, uiConfig, currentPixelsPerUnitMultiplier, currentContentPadding, revealUnflaggedMines);
}
}
}
public void SetInputEnabled(bool enabled)
{
inputEnabled = enabled;
foreach (var cell in cellsByCoordinate.Values)
{
cell.SetInputEnabled(enabled);
}
}
private void TrackResize()
{
if (boardPanel == null || !boardPanel.gameObject.activeInHierarchy || currentCells == null || currentBoardWidth <= 0 || currentBoardHeight <= 0)
{
return;
}
var layoutSize = GetLayoutSourceSize();
if (layoutSize.x <= 0f || layoutSize.y <= 0f)
{
return;
}
if (HasSizeChanged(layoutSize, lastObservedLayoutSize))
{
lastObservedLayoutSize = layoutSize;
resizeStableAt = Time.unscaledTime + ResizeRefreshDelaySeconds;
resizeRefreshPending = true;
return;
}
if (resizeRefreshPending && Time.unscaledTime >= resizeStableAt)
{
resizeRefreshPending = false;
RefreshLayout();
}
}
private void RefreshLayout()
{
ConfigureGrid(currentBoardWidth, currentBoardHeight);
Refresh(currentCells, currentRevealUnflaggedMines);
}
private void ConfigureGrid(int width, int height)
{
if (gridLayoutGroup == null || boardPanel == null || uiConfig == null)
{
return;
}
Canvas.ForceUpdateCanvases();
var layoutSize = GetLayoutSourceSize();
var panelWidth = layoutSize.x > 0f ? layoutSize.x : uiConfig.ReferenceCellSize * width;
var panelHeight = layoutSize.y > 0f ? layoutSize.y : uiConfig.ReferenceCellSize * height;
var cellSize = CalculateCellSize(panelWidth, panelHeight, width, height);
var padding = cellSize * uiConfig.BoardPaddingRatio;
var spacing = cellSize * uiConfig.GridSpacingRatio;
boardPanel.anchorMin = Vector2.zero;
boardPanel.anchorMax = Vector2.one;
boardPanel.offsetMin = new Vector2(padding, padding);
boardPanel.offsetMax = new Vector2(-padding, -padding);
gridLayoutGroup.constraint = GridLayoutGroup.Constraint.FixedColumnCount;
gridLayoutGroup.constraintCount = width;
gridLayoutGroup.padding = new RectOffset();
gridLayoutGroup.spacing = new Vector2(spacing, spacing);
gridLayoutGroup.cellSize = new Vector2(cellSize, cellSize);
currentPixelsPerUnitMultiplier = Mathf.Min(MaximumCellPixelsPerUnitMultiplier, uiConfig.ReferenceCellSize / cellSize);
currentContentPadding = CalculateContentPadding(cellSize);
lastObservedLayoutSize = layoutSize;
}
private Vector2 GetLayoutSourceSize()
{
var parentRect = boardPanel.parent as RectTransform;
var rect = parentRect != null ? parentRect.rect : boardPanel.rect;
return rect.size;
}
private void ResetResizeTracking()
{
resizeRefreshPending = false;
if (boardPanel != null)
{
lastObservedLayoutSize = GetLayoutSourceSize();
}
}
private float CalculateCellSize(float panelWidth, float panelHeight, int width, int height)
{
var widthUnits = width + 2f * uiConfig.BoardPaddingRatio + Mathf.Max(0, width - 1) * uiConfig.GridSpacingRatio;
var heightUnits = height + 2f * uiConfig.BoardPaddingRatio + Mathf.Max(0, height - 1) * uiConfig.GridSpacingRatio;
var cellByWidth = panelWidth / widthUnits;
var cellByHeight = panelHeight / heightUnits;
return Mathf.Max(uiConfig.MinimumCellSize, Mathf.Floor(Mathf.Min(cellByWidth, cellByHeight)));
}
private void CreateCell(BoardCellData cell, ICellViewFactory cellViewFactory)
{
if (gridLayoutGroup == null)
{
return;
}
var view = cellViewFactory.CreateCell(cell, gridLayoutGroup.transform);
if (view == null)
{
return;
}
view.SetInputEnabled(inputEnabled);
view.OpenRequested += OnCellOpenRequested;
view.FlagRequested += OnCellFlagRequested;
view.PressStarted += OnCellPressStarted;
view.PressEnded += OnCellPressEnded;
cellsByCoordinate[ToKey(cell.X, cell.Y)] = view;
}
private void Clear()
{
foreach (var cell in cellsByCoordinate.Values)
{
if (cell != null)
{
cell.OpenRequested -= OnCellOpenRequested;
cell.FlagRequested -= OnCellFlagRequested;
cell.PressStarted -= OnCellPressStarted;
cell.PressEnded -= OnCellPressEnded;
}
}
cellsByCoordinate.Clear();
if (gridLayoutGroup == null)
{
return;
}
for (var i = gridLayoutGroup.transform.childCount - 1; i >= 0; i--)
{
Destroy(gridLayoutGroup.transform.GetChild(i).gameObject);
}
}
private void OnCellOpenRequested(int x, int y)
{
CellOpenRequested?.Invoke(x, y);
}
private void OnCellFlagRequested(int x, int y)
{
CellFlagRequested?.Invoke(x, y);
}
private void OnCellPressStarted()
{
CellPressStarted?.Invoke();
}
private void OnCellPressEnded()
{
CellPressEnded?.Invoke();
}
private void OnPauseClicked()
{
PauseRequested?.Invoke();
}
private static float CalculateContentPadding(float cellSize)
{
return Mathf.Max(MinimumContentPadding, cellSize * ContentPaddingReferencePadding / ContentPaddingReferenceCellSize);
}
private static bool HasSizeChanged(Vector2 current, Vector2 previous)
{
return Mathf.Abs(current.x - previous.x) > ResizeSizeEpsilon || Mathf.Abs(current.y - previous.y) > ResizeSizeEpsilon;
}
private static int ToKey(int x, int y)
{
return (y << 16) ^ x;
}
}
}
@@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: 8e5eb8dfe520e3b40af304e66728dcfb
@@ -0,0 +1,147 @@
using System;
using Minesweeper.Core;
using Minesweeper.Config;
using TMPro;
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.UI;
namespace Minesweeper.Presentation.Views
{
public sealed class CellView : MonoBehaviour, IPointerClickHandler, IPointerDownHandler, IPointerUpHandler
{
[SerializeField] private Button button;
[SerializeField] private Image backgroundImage;
[SerializeField] private RectTransform contentRoot;
[SerializeField] private Image contentImage;
[SerializeField] private TMP_Text label;
private int x;
private int y;
private bool inputEnabled = true;
private bool isOpened;
public event Action<int, int> OpenRequested;
public event Action<int, int> FlagRequested;
public event Action PressStarted;
public event Action PressEnded;
public void Bind(Button button, Image backgroundImage, RectTransform contentRoot, Image contentImage, TMP_Text label)
{
this.button = button;
this.backgroundImage = backgroundImage;
this.contentRoot = contentRoot;
this.contentImage = contentImage;
this.label = label;
}
public void Initialize(int x, int y)
{
this.x = x;
this.y = y;
}
public void SetInputEnabled(bool enabled)
{
inputEnabled = enabled;
if (button != null)
{
button.interactable = enabled && !isOpened;
}
}
public void Render(BoardCellData cell, MinesweeperUiConfig config, float pixelsPerUnitMultiplier, float contentPadding, bool revealUnflaggedMines)
{
gameObject.name = $"bt_{cell.X}_{cell.Y}_{cell.DisplayValue}";
isOpened = cell.IsOpened;
var revealMine = revealUnflaggedMines && cell.IsMine && !cell.IsFlagged;
if (contentRoot != null)
{
contentRoot.offsetMin = new Vector2(contentPadding, contentPadding);
contentRoot.offsetMax = new Vector2(-contentPadding, -contentPadding);
}
if (backgroundImage != null)
{
backgroundImage.pixelsPerUnitMultiplier = pixelsPerUnitMultiplier;
backgroundImage.color = cell.IsOpened || revealMine ? config.OpenedCellColor : config.ClosedCellColor;
}
if (contentImage != null)
{
contentImage.pixelsPerUnitMultiplier = pixelsPerUnitMultiplier;
}
RenderContent(cell, config, revealMine);
if (button != null)
{
button.interactable = inputEnabled && !cell.IsOpened;
}
}
private void RenderContent(BoardCellData cell, MinesweeperUiConfig config, bool revealMine)
{
var showFlag = cell.IsFlagged && !cell.IsOpened;
var showMine = (cell.IsOpened && cell.IsMine) || revealMine;
var showMineAsText = showMine && config.MineSprite == null;
var showNumber = cell.IsOpened && !cell.IsMine && cell.NeighborMines > 0;
if (contentImage != null)
{
contentImage.gameObject.SetActive(showFlag || (showMine && !showMineAsText));
if (showFlag)
{
contentImage.sprite = config.FlagSprite;
}
else if (showMine)
{
contentImage.sprite = config.MineSprite;
}
contentImage.color = Color.white;
}
if (label != null)
{
label.gameObject.SetActive(showNumber || showMineAsText);
label.text = showMineAsText ? "M" : showNumber ? cell.NeighborMines.ToString() : string.Empty;
label.color = config.GetNumberTextColor(cell.NeighborMines);
}
}
public void OnPointerClick(PointerEventData eventData)
{
if (!inputEnabled)
{
return;
}
if (eventData.button == PointerEventData.InputButton.Left)
{
OpenRequested?.Invoke(x, y);
}
else if (eventData.button == PointerEventData.InputButton.Right)
{
FlagRequested?.Invoke(x, y);
}
}
public void OnPointerDown(PointerEventData eventData)
{
if (inputEnabled && eventData.button == PointerEventData.InputButton.Left)
{
PressStarted?.Invoke();
}
}
public void OnPointerUp(PointerEventData eventData)
{
if (eventData.button == PointerEventData.InputButton.Left)
{
PressEnded?.Invoke();
}
}
}
}
@@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: 2904d462d22809c499afe1842f6e6239
@@ -0,0 +1,22 @@
using System;
using System.Collections.Generic;
using Minesweeper.Core;
using Minesweeper.Presentation.Factories;
namespace Minesweeper.Presentation.Views
{
public interface IBoardView : IView
{
event Action CellPressStarted;
event Action CellPressEnded;
event Action PauseRequested;
event Action<int, int> CellOpenRequested;
event Action<int, int> CellFlagRequested;
void Show();
void Hide();
void Rebuild(IReadOnlyList<BoardCellData> cells, int width, int height, ICellViewFactory cellViewFactory, bool revealUnflaggedMines);
void Refresh(IReadOnlyList<BoardCellData> cells, bool revealUnflaggedMines);
void SetInputEnabled(bool enabled);
}
}
@@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: cfdc53be4df29994fa56373d71a3b43a
@@ -0,0 +1,19 @@
using System;
using Minesweeper.Core;
namespace Minesweeper.Presentation.Views
{
public interface IMainMenuView : IView
{
event Action StartClicked;
event Action SizeChanged;
GameSettingsValue SelectedSettings { get; }
void Show();
void Hide();
void ConfigureSizeX(int min, int max, int value);
void ConfigureSizeY(int min, int max, int value);
void ConfigureMines(int min, int max, int value);
}
}
@@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: 66cad179080f23a479c3418932137653
@@ -0,0 +1,14 @@
using System;
namespace Minesweeper.Presentation.Views
{
public interface IPauseView : IView
{
event Action RestartRequested;
event Action ResumeRequested;
event Action GoToMenuRequested;
void Show();
void Hide();
}
}
@@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: 68d5d80ca9e50564b8616608563e8d73
@@ -0,0 +1,14 @@
using System;
using Minesweeper.Core;
namespace Minesweeper.Presentation.Views
{
public interface IResultView : IView
{
event Action RestartRequested;
event Action GoToMenuRequested;
void Show(GameState state);
void Hide();
}
}
@@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: ab5a37a62d4a8284ea45b6d2c835a4d1
@@ -0,0 +1,15 @@
using System;
using Minesweeper.Config;
namespace Minesweeper.Presentation.Views
{
public interface ITopPanelView : IView
{
event Action SmileClicked;
void SetActive(bool active);
void SetRemainingMines(int remainingMines);
void SetTimer(float seconds);
void SetSmile(SmileFaceState state);
}
}
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: e0c8cae3d1ad4d7a9ca3e2f8f435cd7b
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,6 @@
namespace Minesweeper.Presentation.Views
{
public interface IView
{
}
}
@@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: 66a8b79ae5812744680f9e386b007144
@@ -0,0 +1,97 @@
using System;
using Minesweeper.Core;
using UnityEngine;
using UnityEngine.UI;
namespace Minesweeper.Presentation.Views
{
public sealed class MainMenuView : MonoBehaviour, IMainMenuView
{
[SerializeField] private GameObject root;
[SerializeField] private Button startButton;
[SerializeField] private MenuSliderView sizeXSlider = new MenuSliderView();
[SerializeField] private MenuSliderView sizeYSlider = new MenuSliderView();
[SerializeField] private MenuSliderView minesSlider = new MenuSliderView();
public event Action StartClicked;
public event Action SizeChanged;
public GameSettingsValue SelectedSettings => new GameSettingsValue(sizeXSlider.Value, sizeYSlider.Value, minesSlider.Value);
private void Awake()
{
if (root == null)
{
root = gameObject;
}
}
private void OnEnable()
{
if (startButton != null)
{
startButton.onClick.AddListener(OnStartClicked);
}
sizeXSlider.ValueChanged += OnSizeSliderChanged;
sizeYSlider.ValueChanged += OnSizeSliderChanged;
sizeXSlider.AddListeners();
sizeYSlider.AddListeners();
minesSlider.AddListeners();
}
private void OnDisable()
{
if (startButton != null)
{
startButton.onClick.RemoveListener(OnStartClicked);
}
sizeXSlider.RemoveListeners();
sizeYSlider.RemoveListeners();
minesSlider.RemoveListeners();
sizeXSlider.ValueChanged -= OnSizeSliderChanged;
sizeYSlider.ValueChanged -= OnSizeSliderChanged;
}
public void Show()
{
root.SetActive(true);
}
public void Hide()
{
root.SetActive(false);
}
public void ConfigureSizeX(int min, int max, int value)
{
sizeXSlider.Configure(min, max, value, "Size X");
}
public void ConfigureSizeY(int min, int max, int value)
{
sizeYSlider.Configure(min, max, value, "Size Y");
}
public void ConfigureMines(int min, int max, int value)
{
minesSlider.Configure(min, max, value, "Mines Count");
}
private void OnStartClicked()
{
StartClicked?.Invoke();
}
public void BindRoot(GameObject root)
{
this.root = root != null ? root : gameObject;
}
private void OnSizeSliderChanged(int value)
{
SizeChanged?.Invoke();
}
}
}
@@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: bb899c7e47cd4e341b0258dac3f7a238
@@ -0,0 +1,89 @@
using System;
using TMPro;
using UnityEngine;
using UnityEngine.UI;
namespace Minesweeper.Presentation.Views
{
[Serializable]
public sealed class MenuSliderView
{
[SerializeField] private Slider slider;
[SerializeField] private TMP_Text minText;
[SerializeField] private TMP_Text maxText;
[SerializeField] private TMP_Text valueText;
[SerializeField] private string valueLabel;
public event Action<int> ValueChanged;
public int Value => slider != null ? Mathf.RoundToInt(slider.value) : 0;
public void Bind(Slider slider, TMP_Text minText, TMP_Text maxText, TMP_Text valueText)
{
RemoveListeners();
this.slider = slider;
this.minText = minText;
this.maxText = maxText;
this.valueText = valueText;
AddListeners();
}
public void AddListeners()
{
if (slider != null)
{
slider.onValueChanged.AddListener(OnValueChanged);
}
}
public void RemoveListeners()
{
if (slider != null)
{
slider.onValueChanged.RemoveListener(OnValueChanged);
}
}
public void Configure(int min, int max, int value, string label)
{
if (slider == null)
{
return;
}
valueLabel = label;
var clampedMax = Mathf.Max(min, max);
var clampedValue = Mathf.Clamp(value, min, clampedMax);
slider.wholeNumbers = true;
slider.minValue = min;
slider.maxValue = clampedMax;
slider.SetValueWithoutNotify(clampedValue);
SetText(minText, min);
SetText(maxText, clampedMax);
SetValueText(clampedValue);
}
private void OnValueChanged(float value)
{
var intValue = Mathf.RoundToInt(value);
SetValueText(intValue);
ValueChanged?.Invoke(intValue);
}
private void SetValueText(int value)
{
if (valueText != null)
{
valueText.text = string.IsNullOrEmpty(valueLabel) ? value.ToString() : $"{valueLabel}: {value}";
}
}
private static void SetText(TMP_Text text, int value)
{
if (text != null)
{
text.text = value.ToString();
}
}
}
}
@@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: 15be53f58e067f944a33854111083046
@@ -0,0 +1,22 @@
namespace Minesweeper.Presentation.Views
{
public readonly struct MinesweeperScreenRefs
{
public MinesweeperScreenRefs(
MainMenuView mainMenuView,
BoardView boardView,
PauseView pauseView,
ResultView resultView)
{
MainMenuView = mainMenuView;
BoardView = boardView;
PauseView = pauseView;
ResultView = resultView;
}
public MainMenuView MainMenuView { get; }
public BoardView BoardView { get; }
public PauseView PauseView { get; }
public ResultView ResultView { get; }
}
}
@@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: 8a411cd19a61afa45851795dc2794651
@@ -0,0 +1,21 @@
using System;
using System.Collections.Generic;
using Minesweeper.Core;
using Minesweeper.Presentation.Factories;
namespace Minesweeper.Presentation.Views
{
public sealed class NullBoardView : IBoardView
{
public event Action CellPressStarted { add { } remove { } }
public event Action CellPressEnded { add { } remove { } }
public event Action PauseRequested { add { } remove { } }
public event Action<int, int> CellOpenRequested { add { } remove { } }
public event Action<int, int> CellFlagRequested { add { } remove { } }
public void Show() { }
public void Hide() { }
public void Rebuild(IReadOnlyList<BoardCellData> cells, int width, int height, ICellViewFactory cellViewFactory, bool revealUnflaggedMines) { }
public void Refresh(IReadOnlyList<BoardCellData> cells, bool revealUnflaggedMines) { }
public void SetInputEnabled(bool enabled) { }
}
}
@@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: 0e79bb89d6efdcb4a8c7462de1871790
@@ -0,0 +1,42 @@
using System;
using Minesweeper.Core;
namespace Minesweeper.Presentation.Views
{
public sealed class NullMainMenuView : IMainMenuView
{
public event Action StartClicked
{
add { }
remove { }
}
public event Action SizeChanged
{
add { }
remove { }
}
public GameSettingsValue SelectedSettings => default;
public void Show()
{
}
public void Hide()
{
}
public void ConfigureSizeX(int min, int max, int value)
{
}
public void ConfigureSizeY(int min, int max, int value)
{
}
public void ConfigureMines(int min, int max, int value)
{
}
}
}
@@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: 6b41dd95488a1db42adccef0225d2f89
@@ -0,0 +1,13 @@
using System;
namespace Minesweeper.Presentation.Views
{
public sealed class NullPauseView : IPauseView
{
public event Action RestartRequested { add { } remove { } }
public event Action ResumeRequested { add { } remove { } }
public event Action GoToMenuRequested { add { } remove { } }
public void Show() { }
public void Hide() { }
}
}
@@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: a2128d569219f1240ba7bb7c146fa1fd
@@ -0,0 +1,13 @@
using System;
using Minesweeper.Core;
namespace Minesweeper.Presentation.Views
{
public sealed class NullResultView : IResultView
{
public event Action RestartRequested { add { } remove { } }
public event Action GoToMenuRequested { add { } remove { } }
public void Show(GameState state) { }
public void Hide() { }
}
}
@@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: b1db865929a8fc24097435b51a80e818
@@ -0,0 +1,30 @@
using System;
using Minesweeper.Config;
namespace Minesweeper.Presentation.Views
{
public sealed class NullTopPanelView : ITopPanelView
{
public event Action SmileClicked
{
add { }
remove { }
}
public void SetActive(bool active)
{
}
public void SetRemainingMines(int remainingMines)
{
}
public void SetTimer(float seconds)
{
}
public void SetSmile(SmileFaceState state)
{
}
}
}
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: c8372ef8aa2747d7af12fce4f1324baf
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,99 @@
using System;
using UnityEngine;
using UnityEngine.UI;
namespace Minesweeper.Presentation.Views
{
public sealed class PauseView : MonoBehaviour, IPauseView
{
[SerializeField] private GameObject root;
[SerializeField] private Button restartButton;
[SerializeField] private Button resumeButton;
[SerializeField] private Button mainMenuButton;
public event Action RestartRequested;
public event Action ResumeRequested;
public event Action GoToMenuRequested;
private GameObject Root => root != null ? root : gameObject;
private void Awake()
{
if (root == null)
{
root = gameObject;
}
}
private void OnEnable()
{
AddListeners();
}
private void OnDisable()
{
RemoveListeners();
}
public void Show()
{
Root.SetActive(true);
}
public void Hide()
{
Root.SetActive(false);
}
private void AddListeners()
{
if (restartButton != null)
{
restartButton.onClick.AddListener(OnRestartClicked);
}
if (resumeButton != null)
{
resumeButton.onClick.AddListener(OnResumeClicked);
}
if (mainMenuButton != null)
{
mainMenuButton.onClick.AddListener(OnMainMenuClicked);
}
}
private void RemoveListeners()
{
if (restartButton != null)
{
restartButton.onClick.RemoveListener(OnRestartClicked);
}
if (resumeButton != null)
{
resumeButton.onClick.RemoveListener(OnResumeClicked);
}
if (mainMenuButton != null)
{
mainMenuButton.onClick.RemoveListener(OnMainMenuClicked);
}
}
private void OnRestartClicked()
{
RestartRequested?.Invoke();
}
private void OnResumeClicked()
{
ResumeRequested?.Invoke();
}
private void OnMainMenuClicked()
{
GoToMenuRequested?.Invoke();
}
}
}
@@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: 548c3a1ddca35cc4d823c260a88dcecf
@@ -0,0 +1,89 @@
using System;
using Minesweeper.Core;
using TMPro;
using UnityEngine;
using UnityEngine.UI;
namespace Minesweeper.Presentation.Views
{
public sealed class ResultView : MonoBehaviour, IResultView
{
[SerializeField] private GameObject root;
[SerializeField] private Button restartButton;
[SerializeField] private Button mainMenuButton;
[SerializeField] private TMP_Text resultText;
public event Action RestartRequested;
public event Action GoToMenuRequested;
private GameObject Root => root != null ? root : gameObject;
private void Awake()
{
if (root == null)
{
root = gameObject;
}
}
private void OnEnable()
{
AddListeners();
}
private void OnDisable()
{
RemoveListeners();
}
public void Show(GameState state)
{
Root.SetActive(true);
if (resultText != null)
{
resultText.text = state == GameState.Won ? "YOU WIN" : "GAME OVER";
}
}
public void Hide()
{
Root.SetActive(false);
}
private void AddListeners()
{
if (restartButton != null)
{
restartButton.onClick.AddListener(OnRestartClicked);
}
if (mainMenuButton != null)
{
mainMenuButton.onClick.AddListener(OnMainMenuClicked);
}
}
private void RemoveListeners()
{
if (restartButton != null)
{
restartButton.onClick.RemoveListener(OnRestartClicked);
}
if (mainMenuButton != null)
{
mainMenuButton.onClick.RemoveListener(OnMainMenuClicked);
}
}
private void OnRestartClicked()
{
RestartRequested?.Invoke();
}
private void OnMainMenuClicked()
{
GoToMenuRequested?.Invoke();
}
}
}
@@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: b0b04ab8a2ef00b4e8d36a96e4f034d8
@@ -0,0 +1,91 @@
using System;
using Minesweeper.Config;
using TMPro;
using UnityEngine;
using UnityEngine.UI;
namespace Minesweeper.Presentation.Views
{
public sealed class TopPanelView : MonoBehaviour, ITopPanelView
{
[SerializeField] private GameObject root;
[SerializeField] private TMP_Text mineText;
[SerializeField] private TMP_Text timerText;
[SerializeField] private Button smileButton;
[SerializeField] private Image smileImage;
[SerializeField] private MinesweeperUiConfig uiConfig;
public event Action SmileClicked;
private void Awake()
{
if (root == null)
{
root = gameObject;
}
}
private void OnEnable()
{
if (smileButton != null)
{
smileButton.onClick.AddListener(OnSmileClicked);
}
}
private void OnDisable()
{
if (smileButton != null)
{
smileButton.onClick.RemoveListener(OnSmileClicked);
}
}
public void SetActive(bool active)
{
root.SetActive(active);
}
public void SetRemainingMines(int remainingMines)
{
if (mineText != null)
{
mineText.text = Mathf.Max(0, remainingMines).ToString("00000");
}
}
public void SetTimer(float seconds)
{
if (timerText != null)
{
timerText.text = Mathf.FloorToInt(seconds).ToString("00000");
}
}
public void SetSmile(SmileFaceState state)
{
if (smileImage == null || uiConfig == null)
{
return;
}
var sprite = uiConfig.GetSmileSprite(state);
if (sprite != null)
{
smileImage.sprite = sprite;
}
smileImage.color = Color.white;
}
public void BindConfig(MinesweeperUiConfig config)
{
uiConfig = config;
}
private void OnSmileClicked()
{
SmileClicked?.Invoke();
}
}
}
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: cb4efc57f8404c98bff81ed5db093d81
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant: