Some checks failed
Gitea Actions Demo / Explore-Gitea-Actions (push) Has been cancelled
- завершен спринт 24 марта - 2 апреля с опережением плана и закрытием задач раньше срока - расширена и стабилизирована система призов: добавлены и доработаны QR-tier конфиги, новые типы и модели данных, сохранение `qrCodes` в `prizes.json`, fallback-логика и синхронизация через `PrizeSystemManager`, `PrizeDatabase` и `LevelPrizeConfig` - переработан flow настройки QR-призов: добавлены `QRCodeSettingsModal` и связанный UI-код, разнесены короткий текст приза и полный текст сообщения, добавлены шаблоны форматирования, корректная подстановка текста в QR и в UI-модалках, а также сохранение конфигурации между запусками - доработан flow суперприза и текстовых настроек: добавлены fallback-правила показа, корректная обработка пустых строк и строк из одних пробелов, обновлены binders и показ текста в меню - реализована и обновлена отдельная настройка витрины: добавлена `PrizeStandSettingsModal`, обновлена навигация строк, логика выбора ячейки и порогов очков, циклический выбор ячеек, ускорение изменения значений и исправления для keyboard/gamepad UX - доработана игровая модалка витрины `PrizeStandModal`: добавлен вывод очков игрока, форматируемый текст счета, улучшено отображение ячеек и связанная логика выбора приза - исправлен подсчет очков и интеграция с prize flow: `ScoreSystem` переведен на событийное обновление текущего счета, добавлены `CurrentScore`, `CurrentScoreChanged` и корректный display score, витрина и связанные UI-элементы теперь получают актуальные очки, а не нулевые или несвоевременные preview-значения - переработаны модальные окна и навигация UI: улучшены `Modal`, `ModalManager`, `UIRowPointer`, `RulesModal`, `QRCodeModal`, `PrizeStandModal`, `LevelPrizeSettingsModal` и др., чтобы фокус, указатель и submit работали консистентно без мыши - обновлен win/prize UI: доработаны `WinBannerController`, `GameEndUIController`, `MainMenu`, `QRCodeUIController`, `TopPanelTextController` и настройки UI, улучшены тексты баннеров, отображение призов и итогового счета - обновлены сцены и ассеты под новый flow: `MainMenu`, `Level UI`, prefab'ы строк настроек и кнопок, глобальные префабы, шрифты TMP, иконки, recovery-данные и ресурсы UI - добавлены вспомогательные UI-компоненты и служебные скрипты: `ButtonTextFocusColor`, `SelectableDescriptionTarget`, `QRTier` и другие изменения, поддерживающие новый конфигурируемый prize UI
90 lines
3.0 KiB
C#
90 lines
3.0 KiB
C#
using System;
|
||
using TMPro;
|
||
using UnityEngine;
|
||
using UnityEngine.UI;
|
||
|
||
namespace RR.Common.UI
|
||
{
|
||
public class SettingsGroupPanel : MonoBehaviour
|
||
{
|
||
[Header("Wiring")]
|
||
[SerializeField] private TMP_Text titleText;
|
||
[SerializeField] private Button headerButton;
|
||
[SerializeField] private GameObject contentRoot; // сюда будут инстанситься строки настроек
|
||
|
||
[Header("Optional icons")]
|
||
[SerializeField] private GameObject iconExpanded;
|
||
[SerializeField] private GameObject iconCollapsed;
|
||
|
||
public Transform ContentRoot => contentRoot ? contentRoot.transform : transform;
|
||
|
||
/// <summary>
|
||
/// Событие вызывается при сворачивании/разворачивании группы
|
||
/// </summary>
|
||
public event Action<SettingsGroupPanel, bool> OnExpandedChanged;
|
||
|
||
private bool expanded = true;
|
||
private string prefsKey;
|
||
private bool rememberState;
|
||
private string groupTitle = string.Empty;
|
||
|
||
public void Init(string title, string prefsKey, bool defaultExpanded, bool rememberState)
|
||
{
|
||
this.prefsKey = prefsKey;
|
||
this.rememberState = rememberState;
|
||
groupTitle = title ?? string.Empty;
|
||
|
||
if (titleText) titleText.text = title;
|
||
|
||
bool startExpanded = defaultExpanded;
|
||
if (this.rememberState && !string.IsNullOrEmpty(this.prefsKey))
|
||
startExpanded = PlayerPrefs.GetInt(this.prefsKey, defaultExpanded ? 1 : 0) == 1;
|
||
|
||
SetExpanded(startExpanded, save: false);
|
||
|
||
if (headerButton)
|
||
{
|
||
headerButton.onClick.RemoveAllListeners();
|
||
headerButton.onClick.AddListener(Toggle);
|
||
}
|
||
}
|
||
|
||
public void BindExternalDescriptionTarget(TMP_Text targetText)
|
||
{
|
||
if (headerButton == null) return;
|
||
|
||
SelectableDescriptionTarget descriptionTarget =
|
||
headerButton.GetComponent<SelectableDescriptionTarget>();
|
||
|
||
if (descriptionTarget == null)
|
||
descriptionTarget = headerButton.gameObject.AddComponent<SelectableDescriptionTarget>();
|
||
|
||
descriptionTarget.Configure(targetText, $"Группа {groupTitle}");
|
||
}
|
||
|
||
public void Toggle() => SetExpanded(!expanded, save: true);
|
||
|
||
public void SetExpanded(bool value, bool save)
|
||
{
|
||
expanded = value;
|
||
|
||
if (contentRoot) contentRoot.SetActive(expanded);
|
||
if (iconExpanded) iconExpanded.SetActive(expanded);
|
||
if (iconCollapsed) iconCollapsed.SetActive(!expanded);
|
||
|
||
if (save && rememberState && !string.IsNullOrEmpty(prefsKey))
|
||
{
|
||
PlayerPrefs.SetInt(prefsKey, expanded ? 1 : 0);
|
||
PlayerPrefs.Save();
|
||
}
|
||
|
||
// Чтобы лэйаут сразу пересчитался
|
||
var rt = transform as RectTransform;
|
||
if (rt) LayoutRebuilder.ForceRebuildLayoutImmediate(rt);
|
||
|
||
// Уведомляем подписчиков об изменении состояния
|
||
OnExpandedChanged?.Invoke(this, expanded);
|
||
}
|
||
}
|
||
}
|