fix ChristmaTree: Select Number Action
This commit is contained in:
parent
383db346eb
commit
56f3e63046
|
|
@ -453,7 +453,21 @@ public class ChristmasTreeGameLogicService : IGameLogicService
|
||||||
Icon = "TouchApp",
|
Icon = "TouchApp",
|
||||||
Color = "Primary",
|
Color = "Primary",
|
||||||
Tooltip = $"Wähle eine Zahl zum Streichen: {string.Join(", ", availableNumbers)}",
|
Tooltip = $"Wähle eine Zahl zum Streichen: {string.Join(", ", availableNumbers)}",
|
||||||
Order = 1
|
Order = 1,
|
||||||
|
Parameters =
|
||||||
|
[
|
||||||
|
new ActionParameterDefinition
|
||||||
|
{
|
||||||
|
Key = "number",
|
||||||
|
Label = "Wähle eine Zahl",
|
||||||
|
Type = "select",
|
||||||
|
Options = availableNumbers.Select(n => new ActionParameterOption
|
||||||
|
{
|
||||||
|
Value = n,
|
||||||
|
Label = n.ToString()
|
||||||
|
}).ToList()
|
||||||
|
}
|
||||||
|
]
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -39,6 +39,53 @@ public record GameActionDescriptor
|
||||||
/// Display order for sorting (lower = first).
|
/// Display order for sorting (lower = first).
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public int Order { get; init; } = 100;
|
public int Order { get; init; } = 100;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Parameter definitions if action requires user input.
|
||||||
|
/// </summary>
|
||||||
|
public IReadOnlyList<ActionParameterDefinition>? Parameters { get; init; }
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Defines a parameter that must be collected from the user before executing an action.
|
||||||
|
/// </summary>
|
||||||
|
public record ActionParameterDefinition
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Parameter key (used in the parameters dictionary).
|
||||||
|
/// </summary>
|
||||||
|
public required string Key { get; init; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Display label for the parameter.
|
||||||
|
/// </summary>
|
||||||
|
public required string Label { get; init; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Parameter type: "select" for dropdown, "number" for numeric input.
|
||||||
|
/// </summary>
|
||||||
|
public string Type { get; init; } = "select";
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Available options for "select" type.
|
||||||
|
/// </summary>
|
||||||
|
public IReadOnlyList<ActionParameterOption>? Options { get; init; }
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// An option for a select-type parameter.
|
||||||
|
/// </summary>
|
||||||
|
public record ActionParameterOption
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// The value to use when this option is selected.
|
||||||
|
/// </summary>
|
||||||
|
public required object Value { get; init; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Display label for the option.
|
||||||
|
/// </summary>
|
||||||
|
public required string Label { get; init; }
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|
|
||||||
|
|
@ -17,7 +17,7 @@
|
||||||
Color="@GetColor(action.Color)"
|
Color="@GetColor(action.Color)"
|
||||||
StartIcon="@GetIcon(action.Icon)"
|
StartIcon="@GetIcon(action.Icon)"
|
||||||
Disabled="@(!action.IsEnabled || GameState.Value.IsSaving || GameState.Value.IsLoading)"
|
Disabled="@(!action.IsEnabled || GameState.Value.IsSaving || GameState.Value.IsLoading)"
|
||||||
OnClick="@(() => ExecuteAction(action.ActionId))"
|
OnClick="@(() => OnActionClick(action))"
|
||||||
Title="@action.Tooltip"
|
Title="@action.Tooltip"
|
||||||
Class="game-action-button">
|
Class="game-action-button">
|
||||||
@action.Label
|
@action.Label
|
||||||
|
|
@ -26,6 +26,40 @@
|
||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
|
|
||||||
|
<MudDialog @bind-Visible="_dialogVisible" Options="_dialogOptions">
|
||||||
|
<TitleContent>
|
||||||
|
<MudText Typo="Typo.h6">@_currentAction?.Label</MudText>
|
||||||
|
</TitleContent>
|
||||||
|
<DialogContent>
|
||||||
|
@if (_currentAction?.Parameters != null)
|
||||||
|
{
|
||||||
|
@foreach (var param in _currentAction.Parameters)
|
||||||
|
{
|
||||||
|
@if (param.Type == "select" && param.Options != null)
|
||||||
|
{
|
||||||
|
<div class="parameter-select">
|
||||||
|
<MudText Typo="Typo.subtitle2" Class="mb-2">@param.Label</MudText>
|
||||||
|
<div class="d-flex flex-wrap gap-2">
|
||||||
|
@foreach (var option in param.Options)
|
||||||
|
{
|
||||||
|
<MudButton Variant="Variant.Outlined"
|
||||||
|
Color="Color.Primary"
|
||||||
|
OnClick="@(() => SelectOption(param.Key, option.Value))"
|
||||||
|
Class="parameter-option-button">
|
||||||
|
@option.Label
|
||||||
|
</MudButton>
|
||||||
|
}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</DialogContent>
|
||||||
|
<DialogActions>
|
||||||
|
<MudButton OnClick="CloseDialog">Abbrechen</MudButton>
|
||||||
|
</DialogActions>
|
||||||
|
</MudDialog>
|
||||||
|
|
||||||
<style>
|
<style>
|
||||||
.game-action-panel {
|
.game-action-panel {
|
||||||
display: flex;
|
display: flex;
|
||||||
|
|
@ -40,10 +74,21 @@
|
||||||
.game-action-button {
|
.game-action-button {
|
||||||
min-width: 120px;
|
min-width: 120px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.parameter-select {
|
||||||
|
margin-bottom: 16px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.parameter-option-button {
|
||||||
|
min-width: 60px;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
@code {
|
@code {
|
||||||
private IReadOnlyList<GameActionDescriptor> _availableActions = [];
|
private IReadOnlyList<GameActionDescriptor> _availableActions = [];
|
||||||
|
private bool _dialogVisible;
|
||||||
|
private GameActionDescriptor? _currentAction;
|
||||||
|
private readonly DialogOptions _dialogOptions = new() { CloseOnEscapeKey = true, MaxWidth = MaxWidth.Small };
|
||||||
|
|
||||||
protected override void OnInitialized()
|
protected override void OnInitialized()
|
||||||
{
|
{
|
||||||
|
|
@ -81,9 +126,32 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void ExecuteAction(string actionId)
|
private void OnActionClick(GameActionDescriptor action)
|
||||||
{
|
{
|
||||||
Dispatcher.Dispatch(new ExecuteGameActionAction(actionId));
|
if (action.Parameters is { Count: > 0 })
|
||||||
|
{
|
||||||
|
_currentAction = action;
|
||||||
|
_dialogVisible = true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Dispatcher.Dispatch(new ExecuteGameActionAction(action.ActionId));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void SelectOption(string paramKey, object value)
|
||||||
|
{
|
||||||
|
if (_currentAction == null) return;
|
||||||
|
|
||||||
|
var parameters = new Dictionary<string, object> { [paramKey] = value };
|
||||||
|
Dispatcher.Dispatch(new ExecuteGameActionAction(_currentAction.ActionId, parameters));
|
||||||
|
CloseDialog();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void CloseDialog()
|
||||||
|
{
|
||||||
|
_dialogVisible = false;
|
||||||
|
_currentAction = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static Color GetColor(string colorName) => colorName switch
|
private static Color GetColor(string colorName) => colorName switch
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue