RobotNet/RobotNet.WebApp/Pages/NavigationMapEditor.razor
2025-10-15 15:15:53 +07:00

197 lines
7.1 KiB
Plaintext

@page "/navigation-maps/editor/{Id:guid}"
@attribute [Authorize]
@using RobotNet.MapShares.Dtos
@using RobotNet.MapShares.Enums
@using RobotNet.Shares
@using RobotNet.WebApp.Maps.Components.Editor
@using RobotNet.WebApp.Maps.Components.Toolbar
@inject IHttpClientFactory HttpClientFactory
@inject IJSRuntime JSRuntime
<PageTitle>Map Designer</PageTitle>
<div class="d-flex flex-column w-100 h-100 position-relative" @onkeyup:preventDefault @onkeypress:preventDefault @onkeydown:preventDefault>
<EditorToolbar @ref="@EditorToolbarRef" MapIsActive="@MapIsActive" ShowName="@ShowName" ShowGrid="@ShowGrid" ShowMapSlam="@ShowMapSlam" EditorState="@EditorState"
MultiSelectedEdge="@MultiselectedEdge" MultiSelectedNode="@MultiselectedNode" NodesUndoable="@NodesUndoable" ZoneSelected="@ZoneSelected"
EditorZoneTypeChanged="((zonetype) => ZoneType = zonetype)"
ControlStateClick="ControlStateClick"
EditorStateChanged="EditorStateChanged"
EditorExtensionChanged="EditorExtensionChanged"
AlignStateClick="AlignStateClick" />
<div class="w-100 flex-grow-1">
<MapContainer @ref="MapContainerRef" ShowGrid="@ShowGrid" ShowName="@ShowName" ShowMapSlam="ShowMapSlam" EditorState="@EditorState" MapIsActive="@MapIsActive" ZoneType="@ZoneType"
MultiselectedEdgeChanged="((value) => MultiselectedEdge = value)"
MultiselectedNodeChanged="((value) => MultiselectedNode = value)"
ZoneselectedChanged="((value) => ZoneSelected = value)"
NodesUndoableChanged="((value) => NodesUndoable = value)" KeyPress="EditorStateChanged" MapIsChecking="MapIsChecking" />
</div>
<div class="d-flex w-100 h-100 position-absolute" style="visibility: @(OverlayIsShow ? "visiable" :"hidden")">
<div class="d-flex w-100 h-100 position-absolute" style="background-color: #f2f2f2; opacity: 0.5; z-index: 999" />
<div class="d-flex w-100 h-100 align-items-center justify-content-center position-absolute" style="z-index: 1000">
<div class="d-flex" style="width: fit-content; height: fit-content;">
<span style="font-size: 4rem; color: red; font-weight: bold">@OverlayIsStr</span>
</div>
</div>
</div>
</div>
@code {
[Parameter, EditorRequired]
public Guid Id { get; set; }
private EditorToolbar EditorToolbarRef = null!;
private MapContainer MapContainerRef = null!;
private bool ShowGrid = true;
private bool ShowName = true;
private bool ShowMapSlam = true;
private bool MapIsActive;
private bool MultiselectedEdge = false;
private bool MultiselectedNode = false;
private bool ZoneSelected = false;
private bool NodesUndoable = false;
private EditorState EditorState = EditorState.View;
private ZoneType ZoneType = ZoneType.Operating;
private bool OverlayIsShow = false;
private string OverlayIsStr = "Loading...";
private HttpClient Http = default!;
protected override async Task OnAfterRenderAsync(bool firstRender)
{
await base.OnAfterRenderAsync(firstRender);
if (!firstRender) return;
Http = HttpClientFactory.CreateClient("MapManagerAPI");
await LoadMap();
}
private async Task LoadMap()
{
try
{
OverlayIsShow = true;
StateHasChanged();
var mapDataResult = await Http.GetFromJsonAsync<MessageResult<MapDataDto>>($"api/MapsData/{Id}");
if (mapDataResult is not null && mapDataResult.Data is not null)
{
MapIsActive = mapDataResult.Data.Active;
await MapContainerRef.LoadMap(mapDataResult.Data);
OverlayIsShow = false;
}
else OverlayIsStr = "Map Not Existed";
StateHasChanged();
}
catch
{
OverlayIsStr = "Map Not Existed";
StateHasChanged();
return;
}
}
private void EditorExtensionChanged((ControlState state, bool value) extension)
{
switch (extension.state)
{
case ControlState.ShowName:
ShowName = extension.value;
break;
case ControlState.ShowGrid:
ShowGrid = extension.value;
break;
case ControlState.ShowMapSlam:
ShowMapSlam = extension.value;
break;
}
StateHasChanged();
}
private async Task ControlStateClick(ControlState state)
{
switch (state)
{
case ControlState.Undo:
MapContainerRef.UndoEditorBackup();
break;
case ControlState.FitScreen:
await MapContainerRef.ScaleFitContentAsync();
break;
case ControlState.Save:
await MapContainerRef.SaveChanged();
break;
case ControlState.ZoomIn:
await MapContainerRef.ScaleZoom(0.5);
break;
case ControlState.ZoomOut:
await MapContainerRef.ScaleZoom(-0.5);
break;
case ControlState.Delete:
if (EditorState == EditorState.NavigationEdit || EditorState == EditorState.Scaner) await MapContainerRef.DeleteEdge();
else if (EditorState == EditorState.SettingZone) await MapContainerRef.DeleteZone();
break;
case ControlState.CheckMap:
await MapContainerRef.CheckMap();
break;
}
}
private async Task EditorStateChanged(EditorState state)
{
if (EditorState != state)
{
EditorState = state;
await MapContainerRef.EditStateChange();
EditorToolbarRef.SetEditorState(state);
StateHasChanged();
}
}
private async Task AlignStateClick(AlignState state)
{
switch (state)
{
case AlignState.HorizontalLeft:
MapContainerRef.HorizontalLeft();
break;
case AlignState.HorizontalRight:
MapContainerRef.HorizontalRight();
break;
case AlignState.VerticalTop:
MapContainerRef.VerticalTop();
break;
case AlignState.VerticalBottom:
MapContainerRef.VerticalBottom();
break;
case AlignState.HorizontalCenter:
MapContainerRef.HorizontalCenter();
break;
case AlignState.VerticalCenter:
MapContainerRef.VerticalCenter();
break;
case AlignState.MergeNode:
await MapContainerRef.MergeNode();
break;
case AlignState.SplitNode:
await MapContainerRef.SplitNode();
break;
}
}
private void MapIsChecking(bool state)
{
if (state)
{
OverlayIsShow = true;
OverlayIsStr = "Map Checking ...";
}
else OverlayIsShow = false;
StateHasChanged();
}
}