559 lines
23 KiB
Plaintext
559 lines
23 KiB
Plaintext
@using RobotNet.MapShares.Models
|
|
@using RobotNet.WebApp.Maps.Components.Editor.Edge
|
|
@using RobotNet.WebApp.Maps.Components.Editor.Node
|
|
@using RobotNet.WebApp.Maps.Components.Editor.Zone
|
|
|
|
@inject IJSRuntime JSRuntime
|
|
@inject IHttpClientFactory HttpClientFactory
|
|
@inject IDialogService Dialog
|
|
@inject ISnackbar Snackbar
|
|
|
|
<div class="map-viewer-container" @ref="ViewContainerRef" tabindex="1">
|
|
<div @ref=ViewMovementRef>
|
|
<svg @ref=MapContainerRef class="map-editor" letter-spacing="normal">
|
|
<MapSvgDefs />
|
|
<image @ref="MapImageRef" class="map-image" visibility="@(ShowMapSlam ? "visible" : "hidden")" />
|
|
<OriginVector />
|
|
|
|
<CascadingValue Value="MapIsActive">
|
|
<MapGrid @ref="@MapGridRef" Show="@ShowGrid" />
|
|
<MapZone Models="@Zones" IsShow="@(EditorState != EditorState.CreateZone && EditorState != EditorState.SettingZone)" />
|
|
<MapEdge @ref="MapEdgesRef" Models="@Edges" EdgeSelectedChanged="OnSelectedEdgeChanged" EditorState="@EditorState" />
|
|
<MapNode Models="@Nodes" Elements="Elements" ShowName="@ShowName" EditorState="@EditorState" />
|
|
<EdgeControlPoint @ref="EdgeControlPointRef" />
|
|
<EdgeStraightCreating @ref="EdgeStraightCreatingRef" />
|
|
<EdgeCurveCreating @ref="EdgeCurveCreatingRef" />
|
|
<MapZone @ref=@MapZoneRef Models="@Zones" IsShow="@(EditorState == EditorState.CreateZone || EditorState == EditorState.SettingZone)" IsSetting="@(EditorState == EditorState.SettingZone)" ActivedZoneChanged="OnActivedZoneChanged" EditorState="@EditorState" />
|
|
<MapScaner @ref=MapScanerRef />
|
|
<ZoneCreating @ref=ZoneCreatingRef />
|
|
<ZoneControlPoint @ref="ZoneControlPointRef"/>
|
|
<MapCopy @ref=MapCopyRef />
|
|
</CascadingValue>
|
|
</svg>
|
|
</div>
|
|
<MapMousePosition @ref="MapInfoRef" />
|
|
|
|
<MudOverlay @bind-Visible="OverlayIsVisible" DarkBackground="true" Absolute="true">
|
|
<MudText Typo="Typo.h1" Color="@Color.Error" Style="font-weight: bold;">@OverlayIsStr</MudText>
|
|
</MudOverlay>
|
|
</div>
|
|
|
|
@code {
|
|
[Parameter]
|
|
public bool ShowGrid { get; set; }
|
|
|
|
[Parameter]
|
|
public bool ShowName { get; set; }
|
|
|
|
[Parameter]
|
|
public bool ShowMapSlam { get; set; }
|
|
|
|
[Parameter]
|
|
public bool MapIsActive { get; set; }
|
|
|
|
[Parameter]
|
|
public ZoneType ZoneType { get; set; }
|
|
|
|
[Parameter]
|
|
public EditorState EditorState { get; set; }
|
|
|
|
[Parameter]
|
|
public EventCallback<bool> MultiselectedEdgeChanged { get; set; }
|
|
|
|
[Parameter]
|
|
public EventCallback<bool> MultiselectedNodeChanged { get; set; }
|
|
|
|
[Parameter]
|
|
public EventCallback<bool> ZoneselectedChanged { get; set; }
|
|
|
|
[Parameter]
|
|
public EventCallback<bool> NodesUndoableChanged { get; set; }
|
|
|
|
[Parameter]
|
|
public EventCallback<EditorState> KeyPress { get; set; }
|
|
|
|
[Parameter]
|
|
public EventCallback<bool> MapIsChecking { get; set; }
|
|
|
|
private MapMousePosition MapInfoRef = null!;
|
|
private EdgeStraightCreating EdgeStraightCreatingRef = null!;
|
|
private EdgeCurveCreating EdgeCurveCreatingRef = null!;
|
|
private MapEdge MapEdgesRef = null!;
|
|
private MapGrid MapGridRef = null!;
|
|
private EdgeControlPoint EdgeControlPointRef = null!;
|
|
private MapScaner MapScanerRef = null!;
|
|
private ZoneCreating ZoneCreatingRef = null!;
|
|
private MapZone MapZoneRef = null!;
|
|
private ZoneControlPoint ZoneControlPointRef = null!;
|
|
private MapCopy MapCopyRef = null!;
|
|
|
|
private DotNetObjectReference<MapContainer> DotNetObj = null!;
|
|
private ElementReference ViewContainerRef;
|
|
private ElementReference ViewMovementRef;
|
|
private ElementReference MapContainerRef;
|
|
private ElementReference MapImageRef;
|
|
|
|
private double ViewContainerRectX;
|
|
private double ViewContainerRectY;
|
|
private double ViewContainerRectWidth;
|
|
private double ViewContainerRectHeight;
|
|
private double ViewContainerRectTop;
|
|
private double ViewContainerRectRight;
|
|
private double ViewContainerRectBottom;
|
|
private double ViewContainerRectLeft;
|
|
|
|
private double CursorX;
|
|
private double CursorY;
|
|
private double ClientOriginX;
|
|
private double ClientOriginY;
|
|
private double Scale = 1;
|
|
private double Left;
|
|
private double Top;
|
|
private double FitScale = 1;
|
|
|
|
private double Resolution = 1;
|
|
private double OriginX;
|
|
private double OriginY;
|
|
private double ImageWidth;
|
|
private double ImageHeight;
|
|
|
|
private MapDataDto MapData = new();
|
|
public MapEdgeModel Edges { get; set; } = [];
|
|
public MapNodeModel Nodes { get; set; } = [];
|
|
public MapZoneModel Zones { get; set; } = [];
|
|
public MapElementModel Elements { get; set; } = [];
|
|
private HttpClient Http = default!;
|
|
|
|
private bool OverlayIsVisible = false;
|
|
private string OverlayIsStr = "Loading...";
|
|
|
|
protected override async Task OnAfterRenderAsync(bool firstRender)
|
|
{
|
|
await base.OnAfterRenderAsync(firstRender);
|
|
if (!firstRender) return;
|
|
|
|
Http = HttpClientFactory.CreateClient("MapManagerAPI");
|
|
DotNetObj = DotNetObjectReference.Create(this);
|
|
|
|
await JSRuntime.InvokeVoidAsync("DOMCssLoaded");
|
|
|
|
await JSRuntime.InvokeVoidAsync("UpdateViewContainerRect", DotNetObj, ViewContainerRef, nameof(ViewContainerResize));
|
|
await JSRuntime.InvokeVoidAsync("ResizeObserverRegister", DotNetObj, ViewContainerRef, nameof(ViewContainerResize));
|
|
await JSRuntime.InvokeVoidAsync("AddMouseMoveEventListener", DotNetObj, ViewContainerRef, nameof(MouseMoveOnMapContainer));
|
|
await JSRuntime.InvokeVoidAsync("AddEventListener", DotNetObj, ViewContainerRef, "click", nameof(ViewContainerClick));
|
|
await JSRuntime.InvokeVoidAsync("AddKeyUpEventListener", DotNetObj, ViewContainerRef, nameof(ViewContainerKeyUp));
|
|
|
|
await JSRuntime.InvokeVoidAsync("AddMouseWheelEventListener", DotNetObj, MapContainerRef, nameof(MouseWheelOnMapContainer));
|
|
await JSRuntime.InvokeVoidAsync("AddMouseUpEventListener", DotNetObj, MapContainerRef, nameof(MouseUpOnMapContainer));
|
|
await JSRuntime.InvokeVoidAsync("AddMouseDownEventListener", DotNetObj, MapContainerRef, nameof(MouseDownOnMapContainer));
|
|
await JSRuntime.InvokeVoidAsync("AddTouchMoveEventListener", DotNetObj, ViewContainerRef, nameof(TouchMoveOnMapContainer));
|
|
}
|
|
|
|
private async Task LoadMap()
|
|
{
|
|
try
|
|
{
|
|
OverlayIsVisible = true;
|
|
StateHasChanged();
|
|
|
|
var mapDataResult = await Http.GetFromJsonAsync<MessageResult<MapDataDto>>($"api/MapsData/{MapData.Id}");
|
|
if (mapDataResult is not null && mapDataResult.Data is not null)
|
|
{
|
|
MapIsActive = mapDataResult.Data.Active;
|
|
await LoadMap(mapDataResult.Data);
|
|
OverlayIsVisible = false;
|
|
}
|
|
else OverlayIsStr = "Map Not Existed";
|
|
StateHasChanged();
|
|
}
|
|
catch
|
|
{
|
|
OverlayIsStr = "Map Not Existed";
|
|
StateHasChanged();
|
|
return;
|
|
}
|
|
}
|
|
|
|
public async Task LoadMap(MapDataDto? mapData)
|
|
{
|
|
if (mapData == null)
|
|
{
|
|
MapData = new();
|
|
Nodes.ReplaceAll([]);
|
|
Edges.ReplaceAll([]);
|
|
Zones.ReplaceAll([]);
|
|
Elements.ReplaceAll([]);
|
|
Resolution = 1.0;
|
|
OriginY = 0;
|
|
OriginX = 0;
|
|
ImageHeight = 0;
|
|
ImageWidth = 0;
|
|
MapGridRef.Resize(OriginX, OriginY, ImageHeight, ImageWidth);
|
|
await JSRuntime.InvokeVoidAsync("SetMapSvgConfig", MapContainerRef, ImageWidth, ImageHeight, OriginX, 1.0);
|
|
await JSRuntime.InvokeVoidAsync("SetImageAttribute", MapImageRef, ImageWidth, ImageHeight, OriginX, OriginY, "");
|
|
}
|
|
else
|
|
{
|
|
MapData = mapData;
|
|
Nodes.ReplaceAll(MapData.Nodes);
|
|
Edges.ReplaceAll(MapData.Edges.Select(edge => new EdgeModel(edge, Nodes[edge.StartNodeId], Nodes[edge.EndNodeId])));
|
|
Zones.ReplaceAll(MapData.Zones);
|
|
Elements.ReplaceAll(MapData.Elements.Select(element => new ElementModel(element, Nodes[element.NodeId])));
|
|
Resolution = mapData.Resolution;
|
|
OriginY = -mapData.ImageHeight * Resolution - mapData.OriginY;
|
|
OriginX = mapData.OriginX;
|
|
ImageHeight = mapData.ImageHeight * Resolution;
|
|
ImageWidth = mapData.ImageWidth * Resolution;
|
|
MapGridRef.Resize(OriginX, OriginY, ImageHeight, ImageWidth);
|
|
|
|
await JSRuntime.InvokeVoidAsync("SetMapSvgConfig", MapContainerRef, ImageWidth, ImageHeight, OriginX, mapData.OriginY);
|
|
await JSRuntime.InvokeVoidAsync("SetImageAttribute", MapImageRef, ImageWidth, ImageHeight, OriginX, OriginY, $"{Http.BaseAddress}api/images/map/{mapData.Id}");
|
|
await JSRuntime.InvokeVoidAsync("UpdateViewContainerRect", DotNetObj, ViewContainerRef, nameof(ViewContainerResize));
|
|
await ScaleFitContentAsync();
|
|
}
|
|
}
|
|
|
|
public async Task ScaleFitContentAsync()
|
|
{
|
|
Scale = FitScale;
|
|
await SetViewMovement((ViewContainerRectWidth - ImageWidth * Scale) / 2, (ViewContainerRectHeight - ImageHeight * Scale) / 2);
|
|
await JSRuntime.InvokeVoidAsync("SetMapSvgRect", MapContainerRef, ImageWidth * Scale, ImageHeight * Scale);
|
|
}
|
|
|
|
private async Task SetViewMovement(double left, double top)
|
|
{
|
|
Top = top;
|
|
Left = left;
|
|
|
|
ClientOriginX = ViewContainerRectLeft + Left - OriginX * Scale;
|
|
ClientOriginY = ViewContainerRectTop + Top - OriginY * Scale;
|
|
await JSRuntime.InvokeVoidAsync("SetMapMovement", ViewMovementRef, Top, Left);
|
|
}
|
|
|
|
public async Task ScaleZoom(double deltaY)
|
|
{
|
|
if (deltaY > 0)
|
|
{
|
|
if (Scale >= FitScale * 20) return;
|
|
}
|
|
else
|
|
{
|
|
if (Scale <= FitScale / 2) return;
|
|
}
|
|
double oldScale = Scale;
|
|
Scale += deltaY;
|
|
|
|
double centerXBefore = ((ViewContainerRectLeft + ViewContainerRectWidth / 2) - ClientOriginX) / oldScale - OriginX;
|
|
double centerYBefore = (ClientOriginY - (ViewContainerRectHeight / 2 + ViewContainerRectTop)) / oldScale - (MapData is null ? 0 : MapData.OriginY);
|
|
|
|
await SetViewMovement(Left - centerXBefore * deltaY, Top - (ImageHeight - centerYBefore) * deltaY);
|
|
await JSRuntime.InvokeVoidAsync("SetMapSvgRect", MapContainerRef, ImageWidth * Scale, ImageHeight * Scale);
|
|
}
|
|
|
|
[JSInvokable]
|
|
public async Task ViewContainerClick() => await ViewContainerRef.FocusAsync();
|
|
|
|
[JSInvokable]
|
|
public void ViewContainerResize(double x, double y, double width, double height, double top, double right, double bottom, double left)
|
|
{
|
|
ViewContainerRectX = x;
|
|
ViewContainerRectY = y;
|
|
ViewContainerRectWidth = width;
|
|
ViewContainerRectHeight = height;
|
|
ViewContainerRectTop = top;
|
|
ViewContainerRectRight = right;
|
|
ViewContainerRectBottom = bottom;
|
|
ViewContainerRectLeft = left;
|
|
|
|
ClientOriginX = ViewContainerRectLeft + Left - OriginX * Scale;
|
|
ClientOriginY = ViewContainerRectTop + Top - OriginY * Scale;
|
|
|
|
FitScale = Math.Min(ViewContainerRectWidth / ImageWidth, ViewContainerRectHeight / ImageHeight);
|
|
}
|
|
|
|
[JSInvokable]
|
|
public async Task TouchMoveOnMapContainer(double clientX, double clientY, int touchCount, double movementX, double movementY)
|
|
{
|
|
CursorX = (clientX - ClientOriginX) / Scale;
|
|
CursorY = (ClientOriginY - clientY) / Scale;
|
|
MapInfoRef.Update(CursorX, CursorY);
|
|
|
|
if (touchCount == 1) await SetViewMovement(Left + movementX, Top + movementY);
|
|
}
|
|
|
|
[JSInvokable]
|
|
public async Task MouseWheelOnMapContainer(double deltaY, double offsetX, double offsetY)
|
|
{
|
|
double scaleChange;
|
|
if (deltaY > 0)
|
|
{
|
|
if (Scale <= FitScale / 2) return;
|
|
scaleChange = Scale > FitScale ? -(Scale / FitScale) : -0.1;
|
|
}
|
|
else
|
|
{
|
|
if (Scale >= FitScale * 100) return;
|
|
scaleChange = Scale < FitScale ? 0.5 : (Scale / FitScale);
|
|
}
|
|
|
|
double oldScale = Scale;
|
|
|
|
Scale += scaleChange;
|
|
await JSRuntime.InvokeVoidAsync("SetMapSvgRect", MapContainerRef, ImageWidth * Scale, ImageHeight * Scale);
|
|
|
|
double mouseX = CursorX - OriginX;
|
|
double mouseY = CursorY - (MapData is null ? 0 : MapData.OriginY);
|
|
await SetViewMovement(Left - mouseX * scaleChange, Top - (ImageHeight - mouseY) * scaleChange);
|
|
}
|
|
|
|
[JSInvokable]
|
|
public async Task MouseMoveOnMapContainer(double clientX, double clientY, long buttons, bool ctrlKey, double movementX, double movementY)
|
|
{
|
|
CursorX = (clientX - ClientOriginX) / Scale;
|
|
CursorY = (ClientOriginY - clientY) / Scale;
|
|
MapInfoRef.Update(CursorX, CursorY);
|
|
if (EditorState == EditorState.CreateCurveEdge || EditorState == EditorState.CreateDoubleCurveEdge) await EdgeCurveCreatingRef.Update(CursorX, CursorY);
|
|
else if (EditorState == EditorState.CreateZone) await ZoneCreatingRef.Update(CursorX, CursorY);
|
|
|
|
switch (buttons)
|
|
{
|
|
case 1:
|
|
if (MapIsActive) break;
|
|
switch (EditorState)
|
|
{
|
|
case EditorState.CreateStraighEdge:
|
|
await EdgeStraightCreatingRef.Update(CursorX, CursorY);
|
|
break;
|
|
case EditorState.CreateCurveEdge:
|
|
case EditorState.CreateDoubleCurveEdge:
|
|
await EdgeCurveCreatingRef.Update(CursorX, CursorY);
|
|
break;
|
|
case EditorState.Scaner:
|
|
await MapScanerRef.Update(CursorX, CursorY);
|
|
break;
|
|
case EditorState.NavigationEdit:
|
|
if (ctrlKey) NodePositionMove(CursorX, CursorY);
|
|
break;
|
|
case EditorState.SettingZone:
|
|
if (ctrlKey) ZoneUpdateShape(CursorX, CursorY);
|
|
break;
|
|
case EditorState.Move:
|
|
if (ctrlKey)
|
|
{
|
|
if (Edges.ActivedEdges.Count > 0) EdgesPositionMove(CursorX, CursorY);
|
|
else NodesPositionMove(CursorX, CursorY);
|
|
}
|
|
break;
|
|
case EditorState.Copy:
|
|
if (ctrlKey) MapCopyRef.UpdateMove(CursorX, CursorY);
|
|
break;
|
|
}
|
|
break;
|
|
case 4:
|
|
await SetViewMovement(Left + movementX, Top + movementY);
|
|
break;
|
|
}
|
|
}
|
|
|
|
[JSInvokable]
|
|
public async Task ViewContainerKeyUp(string code, string key, bool altKey, bool ctrlKey, bool shiftKey)
|
|
{
|
|
if (MapIsActive) return;
|
|
switch (code)
|
|
{
|
|
case "Escape":
|
|
await EditStateChange();
|
|
break;
|
|
case "Delete":
|
|
_ = InvokeAsync(async Task () =>
|
|
{
|
|
if (EditorState == EditorState.NavigationEdit || EditorState == EditorState.Scaner) await DeleteEdge();
|
|
else if (EditorState == EditorState.SettingZone) await DeleteZone();
|
|
});
|
|
break;
|
|
case "KeyZ":
|
|
if (ctrlKey) UndoEditorBackup();
|
|
break;
|
|
case "KeyS":
|
|
if (ctrlKey) await SaveChanged();
|
|
break;
|
|
case "KeyM":
|
|
if (EditorState != EditorState.Scaner) return;
|
|
if (ctrlKey)
|
|
{
|
|
if (EditorBackup.Count > 0)
|
|
{
|
|
var save = await SaveChanged();
|
|
if (!save) break;
|
|
}
|
|
await SetCursor("grab");
|
|
await KeyPress.InvokeAsync(EditorState.Move);
|
|
}
|
|
break;
|
|
case "KeyC":
|
|
if (EditorState != EditorState.Scaner) return;
|
|
if (ctrlKey) await KeyPress.InvokeAsync(EditorState.Copy);
|
|
break;
|
|
}
|
|
StateHasChanged();
|
|
}
|
|
|
|
[JSInvokable]
|
|
public async Task MouseUpOnMapContainer(int button, bool altKey, bool ctrlKey, bool shiftKey)
|
|
{
|
|
if (button == 0 && !MapIsActive)
|
|
{
|
|
switch (EditorState)
|
|
{
|
|
case EditorState.CreateStraighEdge:
|
|
await CreateEdge(EdgeStraightCreatingRef.X1, EdgeStraightCreatingRef.Y1, EdgeStraightCreatingRef.X2, EdgeStraightCreatingRef.Y2);
|
|
await EdgeStraightCreatingRef.Hidden();
|
|
break;
|
|
case EditorState.CreateCurveEdge:
|
|
case EditorState.CreateDoubleCurveEdge:
|
|
await EdgeCurveCreatingRef.FinishSubEdgeAsync(CursorX, CursorY);
|
|
if (EdgeCurveCreatingRef.CreateStep == EdgeCurveCreating.CreateCurveEdgeStep.Finish)
|
|
{
|
|
var edgeCreateModel = EdgeCurveCreatingRef.GetEdgeCreateModel();
|
|
await CreateEdge(edgeCreateModel.X1, edgeCreateModel.Y1, edgeCreateModel.X2, edgeCreateModel.Y2, edgeCreateModel.TrajectoryDegree, edgeCreateModel.ControlPoint1X, edgeCreateModel.ControlPoint1Y, edgeCreateModel.ControlPoint2X, edgeCreateModel.ControlPoint2Y);
|
|
await EdgeCurveCreatingRef.Hidden();
|
|
}
|
|
break;
|
|
case EditorState.Scaner:
|
|
await ScanerActive(MapScanerRef.X1, MapScanerRef.Y1, MapScanerRef.X2, MapScanerRef.Y2);
|
|
await MapScanerRef.Hidden();
|
|
break;
|
|
case EditorState.CreateZone:
|
|
if (ZoneCreatingRef.Step == 4)
|
|
{
|
|
await CreateZone(ZoneCreatingRef.X1, ZoneCreatingRef.Y1, ZoneCreatingRef.X2, ZoneCreatingRef.Y2, ZoneCreatingRef.X3, ZoneCreatingRef.Y3, ZoneCreatingRef.X4, ZoneCreatingRef.Y4, ZoneType);
|
|
await ZoneCreatingRef.Hidden();
|
|
}
|
|
break;
|
|
case EditorState.SettingZone:
|
|
if (Zones.ZoneActived is not null && Zones.ZoneActived.ActiveNode != 5) Zones.ZoneActived.ActiveNode = 5;
|
|
break;
|
|
case EditorState.NavigationEdit:
|
|
if (Edges.ActivedEdges.Count == 1)
|
|
{
|
|
Edges.ActivedEdges[0].ActivedControlPoint1 = false;
|
|
Edges.ActivedEdges[0].ActivedControlPoint2 = false;
|
|
}
|
|
Nodes.SelectedNode = null;
|
|
break;
|
|
case EditorState.Move:
|
|
await SetCursor("grab");
|
|
break;
|
|
}
|
|
StateHasChanged();
|
|
}
|
|
}
|
|
|
|
[JSInvokable]
|
|
public async Task MouseDownOnMapContainer(int button, bool altKey, bool ctrlKey, bool shiftKey)
|
|
{
|
|
if (button == 0 && !MapIsActive)
|
|
{
|
|
var startNode = MapEditorHelper.GetClosesNode(CursorX, CursorY, Nodes.Select(node => new NodeDto() { X = node.X, Y = node.Y }).ToList());
|
|
switch (EditorState)
|
|
{
|
|
case EditorState.CreateStraighEdge:
|
|
await EdgeStraightCreatingRef.StartCreateAsync(startNode?.X ?? CursorX, startNode?.Y ?? CursorY);
|
|
break;
|
|
case EditorState.CreateCurveEdge:
|
|
await EdgeCurveCreatingRef.CreateSubEdgeAsync(startNode?.X ?? CursorX, startNode?.Y ?? CursorY);
|
|
break;
|
|
case EditorState.CreateDoubleCurveEdge:
|
|
await EdgeCurveCreatingRef.CreateSubEdgeAsync(startNode?.X ?? CursorX, startNode?.Y ?? CursorY, TrajectoryDegree.Three);
|
|
break;
|
|
case EditorState.Scaner:
|
|
await MapScanerRef.CreateAsync(CursorX, CursorY);
|
|
break;
|
|
case EditorState.CreateZone:
|
|
await ZoneCreatingRef.CreateAsync(CursorX, CursorY);
|
|
break;
|
|
case EditorState.SettingZone:
|
|
if (Zones.ZoneActived is not null) Zones.ZoneActived.SetStartMovePosition(CursorX, CursorY);
|
|
break;
|
|
case EditorState.Move:
|
|
await SetCursor("grabbing");
|
|
Edges.SetStartMovePosition(CursorX, CursorY);
|
|
Nodes.SetStartMovePosition(CursorX, CursorY);
|
|
break;
|
|
case EditorState.Copy:
|
|
MapCopyRef.SetStartMovePosition(CursorX, CursorY);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
private async Task OnSelectedEdgeChanged(EdgeModel? model)
|
|
{
|
|
if (model is not null && EditorState == EditorState.NavigationEdit)
|
|
{
|
|
if (model.TrajectoryDegree == TrajectoryDegree.One) EdgeControlPointRef.SetControl(null);
|
|
else EdgeControlPointRef.SetControl(model);
|
|
Edges.ActivedEdge([model]);
|
|
await MultiselectedEdgeChanged.InvokeAsync(Edges.ActivedEdges.Count > 0);
|
|
}
|
|
else EdgeControlPointRef.SetControl(null);
|
|
}
|
|
|
|
private void OnActivedZoneChanged((ZoneModel model, bool state) data)
|
|
{
|
|
if (EditorState == EditorState.SettingZone)
|
|
{
|
|
if (data.state)
|
|
{
|
|
ZoneControlPointRef.SetControl(data.model);
|
|
_ = ZoneselectedChanged.InvokeAsync(true);
|
|
return;
|
|
}
|
|
}
|
|
ZoneControlPointRef.SetControl(null);
|
|
}
|
|
|
|
public async Task EditStateChange()
|
|
{
|
|
await EdgeCurveCreatingRef.Hidden();
|
|
await EdgeStraightCreatingRef.Hidden();
|
|
await ZoneCreatingRef.Hidden();
|
|
MapCopyRef.OnShow(false, []);
|
|
Zones.UnActivedZone();
|
|
EdgeControlPointRef.SetControl(null);
|
|
if (EditorState == EditorState.Copy) await CreateMapCopy();
|
|
if (EditorState != EditorState.Move)
|
|
{
|
|
Edges.UnActivedEdge();
|
|
Nodes.UnActivedNode();
|
|
}
|
|
if (EditorState != EditorState.Copy) await SaveChanged();
|
|
if (EditorState != EditorState.Copy && EditorState != EditorState.Move) await SetCursor("initial");
|
|
await MultiselectedEdgeChanged.InvokeAsync(Edges.ActivedEdges.Count() > 0);
|
|
await MultiselectedNodeChanged.InvokeAsync(Nodes.ActivedNodes.Count() > 0);
|
|
await ZoneselectedChanged.InvokeAsync(false);
|
|
StateHasChanged();
|
|
}
|
|
|
|
public async Task CreateMapCopy()
|
|
{
|
|
if (Edges.ActivedEdges.Count > 0)
|
|
{
|
|
if (EditorBackup.Count > 0)
|
|
{
|
|
var save = await SaveChanged();
|
|
if (!save) return;
|
|
}
|
|
MapCopyRef.OnShow(true, Edges.ActivedEdges);
|
|
EditorBackup.Add(new()
|
|
{
|
|
Type = MapEditorBackupType.Copy,
|
|
});
|
|
await NodesUndoableChanged.InvokeAsync(true);
|
|
await SetCursor("copy");
|
|
}
|
|
}
|
|
|
|
public async Task SetCursor(string data) => await JSRuntime.InvokeVoidAsync("ElementSetAttribute", MapContainerRef, "cursor", data);
|
|
}
|