[Add] Screen Init & Base new menu
This commit is contained in:
@@ -0,0 +1,16 @@
|
||||
using System;
|
||||
using UnityEngine;
|
||||
|
||||
namespace Minesweeper.Config
|
||||
{
|
||||
[Serializable]
|
||||
public sealed class MinesweeperScreenCatalog
|
||||
{
|
||||
[field: SerializeField] public GameObject MainMenuPanelPrefab { get; private set; }
|
||||
[field: SerializeField] public GameObject BoardGridPrefab { get; private set; }
|
||||
[field: SerializeField] public GameObject PausePanelPrefab { get; private set; }
|
||||
[field: SerializeField] public GameObject ResultPanelPrefab { get; private set; }
|
||||
|
||||
public bool IsValid => MainMenuPanelPrefab != null && BoardGridPrefab != null && PausePanelPrefab != null && ResultPanelPrefab != null;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 6d0009ea7e70ee548a09cd95d482ec83
|
||||
@@ -17,6 +17,8 @@ namespace Minesweeper.Infrastructure
|
||||
{
|
||||
[SerializeField] private MinesweeperGameConfig gameConfig;
|
||||
[SerializeField] private MinesweeperUiConfig uiConfig;
|
||||
[SerializeField] private MinesweeperScreenCatalog screenCatalog = new MinesweeperScreenCatalog();
|
||||
[SerializeField] private Transform contentRoot;
|
||||
[SerializeField] private TopPanelView topPanelView;
|
||||
[SerializeField] private MainMenuView mainMenuView;
|
||||
[SerializeField] private GameView gameView;
|
||||
@@ -35,6 +37,17 @@ namespace Minesweeper.Infrastructure
|
||||
builder.Register<GameStateViewAdapter>(Lifetime.Singleton).As<IGameStateViewAdapter>();
|
||||
builder.Register<CellViewFactory>(Lifetime.Singleton).As<ICellViewFactory>();
|
||||
|
||||
var screenRefs = SpawnScreens();
|
||||
if (screenRefs.MainMenuView != null)
|
||||
{
|
||||
mainMenuView = screenRefs.MainMenuView;
|
||||
}
|
||||
|
||||
if (gameView != null && screenRefs.BoardPanel != null)
|
||||
{
|
||||
gameView.BindScreens(screenRefs);
|
||||
}
|
||||
|
||||
if (topPanelView != null)
|
||||
{
|
||||
topPanelView.BindConfig(resolvedUiConfig);
|
||||
@@ -100,5 +113,15 @@ namespace Minesweeper.Infrastructure
|
||||
|
||||
return ScriptableObject.CreateInstance<MinesweeperUiConfig>();
|
||||
}
|
||||
|
||||
private MinesweeperScreenRefs SpawnScreens()
|
||||
{
|
||||
if (contentRoot == null || screenCatalog == null || !screenCatalog.IsValid)
|
||||
{
|
||||
return default;
|
||||
}
|
||||
|
||||
return new MinesweeperScreenBootstrapper().Spawn(contentRoot, screenCatalog);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,127 @@
|
||||
using Minesweeper.Config;
|
||||
using Minesweeper.Presentation.Views;
|
||||
using TMPro;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
|
||||
namespace Minesweeper.Presentation.Factories
|
||||
{
|
||||
public sealed class MinesweeperScreenBootstrapper
|
||||
{
|
||||
private const string MainMenuPanelName = "MainMenuPanel";
|
||||
private const string BoardGridName = "BoardGrid";
|
||||
private const string PausePanelName = "PausePanel";
|
||||
private const string ResultPanelName = "ResultPanel";
|
||||
private const string StartButtonPath = "StartButton";
|
||||
private const string RestartButtonPath = "RestartButton";
|
||||
private const string ContinueButtonPath = "ContinueButton";
|
||||
private const string MainMenuButtonPath = "MainMenuButton";
|
||||
private const string ResultTextPath = "ResultText";
|
||||
|
||||
public MinesweeperScreenRefs Spawn(Transform contentRoot, MinesweeperScreenCatalog catalog)
|
||||
{
|
||||
if (contentRoot == null)
|
||||
{
|
||||
Debug.LogError("Minesweeper screen bootstrap failed: Content root is not assigned.");
|
||||
return default;
|
||||
}
|
||||
|
||||
if (catalog == null || !catalog.IsValid)
|
||||
{
|
||||
Debug.LogError("Minesweeper screen bootstrap failed: screen catalog prefab references are incomplete.");
|
||||
return default;
|
||||
}
|
||||
|
||||
ClearContent(contentRoot);
|
||||
|
||||
var mainMenu = SpawnScreen(catalog.MainMenuPanelPrefab, contentRoot, MainMenuPanelName, 0);
|
||||
var board = SpawnScreen(catalog.BoardGridPrefab, contentRoot, BoardGridName, 1);
|
||||
var pause = SpawnScreen(catalog.PausePanelPrefab, contentRoot, PausePanelName, 2);
|
||||
var result = SpawnScreen(catalog.ResultPanelPrefab, contentRoot, ResultPanelName, 3);
|
||||
|
||||
var mainMenuView = RequireComponent<MainMenuView>(mainMenu.transform, MainMenuPanelName);
|
||||
mainMenuView.Bind(mainMenu, RequireChildComponent<Button>(mainMenu.transform, StartButtonPath));
|
||||
|
||||
var refs = new MinesweeperScreenRefs(
|
||||
mainMenuView,
|
||||
RequireComponent<RectTransform>(board.transform, BoardGridName),
|
||||
RequireComponent<GridLayoutGroup>(board.transform, BoardGridName),
|
||||
pause,
|
||||
RequireChildComponent<Button>(pause.transform, RestartButtonPath),
|
||||
RequireChildComponent<Button>(pause.transform, ContinueButtonPath),
|
||||
RequireChildComponent<Button>(pause.transform, MainMenuButtonPath),
|
||||
result,
|
||||
RequireChildComponent<Button>(result.transform, RestartButtonPath),
|
||||
RequireChildComponent<Button>(result.transform, MainMenuButtonPath),
|
||||
RequireChildComponent<TMP_Text>(result.transform, ResultTextPath));
|
||||
|
||||
mainMenu.SetActive(false);
|
||||
board.SetActive(false);
|
||||
pause.SetActive(false);
|
||||
result.SetActive(false);
|
||||
|
||||
return refs;
|
||||
}
|
||||
|
||||
private static GameObject SpawnScreen(GameObject prefab, Transform parent, string expectedName, int siblingIndex)
|
||||
{
|
||||
var instance = Object.Instantiate(prefab, parent, false);
|
||||
instance.name = expectedName;
|
||||
instance.transform.SetSiblingIndex(siblingIndex);
|
||||
Stretch(instance.GetComponent<RectTransform>());
|
||||
return instance;
|
||||
}
|
||||
|
||||
private static void ClearContent(Transform contentRoot)
|
||||
{
|
||||
for (var i = contentRoot.childCount - 1; i >= 0; i--)
|
||||
{
|
||||
var child = contentRoot.GetChild(i);
|
||||
child.SetParent(null, false);
|
||||
Object.Destroy(child.gameObject);
|
||||
}
|
||||
}
|
||||
|
||||
private static T RequireComponent<T>(Transform root, string ownerName) where T : Component
|
||||
{
|
||||
var component = root.GetComponent<T>();
|
||||
if (component == null)
|
||||
{
|
||||
Debug.LogError($"Minesweeper screen bootstrap failed: '{ownerName}' is missing {typeof(T).Name}.");
|
||||
}
|
||||
|
||||
return component;
|
||||
}
|
||||
|
||||
private static T RequireChildComponent<T>(Transform root, string path) where T : Component
|
||||
{
|
||||
var child = root.Find(path);
|
||||
if (child == null)
|
||||
{
|
||||
Debug.LogError($"Minesweeper screen bootstrap failed: '{root.name}/{path}' was not found.");
|
||||
return null;
|
||||
}
|
||||
|
||||
var component = child.GetComponent<T>();
|
||||
if (component == null)
|
||||
{
|
||||
Debug.LogError($"Minesweeper screen bootstrap failed: '{root.name}/{path}' is missing {typeof(T).Name}.");
|
||||
}
|
||||
|
||||
return component;
|
||||
}
|
||||
|
||||
private static void Stretch(RectTransform rectTransform)
|
||||
{
|
||||
if (rectTransform == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
rectTransform.anchorMin = Vector2.zero;
|
||||
rectTransform.anchorMax = Vector2.one;
|
||||
rectTransform.offsetMin = Vector2.zero;
|
||||
rectTransform.offsetMax = Vector2.zero;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 38a228c86699cdb499351cf807842dfb
|
||||
@@ -143,6 +143,31 @@ namespace Minesweeper.Presentation.Views
|
||||
uiConfig = config;
|
||||
}
|
||||
|
||||
public void BindScreens(MinesweeperScreenRefs refs)
|
||||
{
|
||||
if (isActiveAndEnabled)
|
||||
{
|
||||
RemoveButtonListeners();
|
||||
}
|
||||
|
||||
boardPanel = refs.BoardPanel;
|
||||
gridLayoutGroup = refs.BoardGrid;
|
||||
pauseRoot = refs.PauseRoot;
|
||||
restartButton = refs.PauseRestartButton;
|
||||
resumeButton = refs.PauseResumeButton;
|
||||
mainMenuButton = refs.PauseMainMenuButton;
|
||||
resultRoot = refs.ResultRoot;
|
||||
resultRestartButton = refs.ResultRestartButton;
|
||||
resultMainMenuButton = refs.ResultMainMenuButton;
|
||||
resultText = refs.ResultText;
|
||||
ResetResizeTracking();
|
||||
|
||||
if (isActiveAndEnabled)
|
||||
{
|
||||
AddButtonListeners();
|
||||
}
|
||||
}
|
||||
|
||||
public void RebuildBoard(IReadOnlyList<BoardCellData> cells, int width, int height, ICellViewFactory cellViewFactory, bool revealUnflaggedMines)
|
||||
{
|
||||
ClearBoard();
|
||||
|
||||
@@ -17,6 +17,8 @@ namespace Minesweeper.Presentation.Views
|
||||
{
|
||||
root = gameObject;
|
||||
}
|
||||
|
||||
AutoBind();
|
||||
}
|
||||
|
||||
private void OnEnable()
|
||||
@@ -49,5 +51,23 @@ namespace Minesweeper.Presentation.Views
|
||||
{
|
||||
StartClicked?.Invoke();
|
||||
}
|
||||
|
||||
public void Bind(GameObject root, Button startButton)
|
||||
{
|
||||
this.root = root != null ? root : gameObject;
|
||||
this.startButton = startButton;
|
||||
}
|
||||
|
||||
private void AutoBind()
|
||||
{
|
||||
if (startButton == null)
|
||||
{
|
||||
var startButtonTransform = transform.Find("StartButton");
|
||||
if (startButtonTransform != null)
|
||||
{
|
||||
startButton = startButtonTransform.GetComponent<Button>();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,47 @@
|
||||
using TMPro;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
|
||||
namespace Minesweeper.Presentation.Views
|
||||
{
|
||||
public readonly struct MinesweeperScreenRefs
|
||||
{
|
||||
public MinesweeperScreenRefs(
|
||||
MainMenuView mainMenuView,
|
||||
RectTransform boardPanel,
|
||||
GridLayoutGroup boardGrid,
|
||||
GameObject pauseRoot,
|
||||
Button pauseRestartButton,
|
||||
Button pauseResumeButton,
|
||||
Button pauseMainMenuButton,
|
||||
GameObject resultRoot,
|
||||
Button resultRestartButton,
|
||||
Button resultMainMenuButton,
|
||||
TMP_Text resultText)
|
||||
{
|
||||
MainMenuView = mainMenuView;
|
||||
BoardPanel = boardPanel;
|
||||
BoardGrid = boardGrid;
|
||||
PauseRoot = pauseRoot;
|
||||
PauseRestartButton = pauseRestartButton;
|
||||
PauseResumeButton = pauseResumeButton;
|
||||
PauseMainMenuButton = pauseMainMenuButton;
|
||||
ResultRoot = resultRoot;
|
||||
ResultRestartButton = resultRestartButton;
|
||||
ResultMainMenuButton = resultMainMenuButton;
|
||||
ResultText = resultText;
|
||||
}
|
||||
|
||||
public MainMenuView MainMenuView { get; }
|
||||
public RectTransform BoardPanel { get; }
|
||||
public GridLayoutGroup BoardGrid { get; }
|
||||
public GameObject PauseRoot { get; }
|
||||
public Button PauseRestartButton { get; }
|
||||
public Button PauseResumeButton { get; }
|
||||
public Button PauseMainMenuButton { get; }
|
||||
public GameObject ResultRoot { get; }
|
||||
public Button ResultRestartButton { get; }
|
||||
public Button ResultMainMenuButton { get; }
|
||||
public TMP_Text ResultText { get; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 8a411cd19a61afa45851795dc2794651
|
||||
Reference in New Issue
Block a user