Новая страница с нодами

This commit is contained in:
ARCHI86 2024-11-10 16:10:13 +03:00
parent befc30e196
commit db62966c32
6 changed files with 143 additions and 13 deletions

View file

@ -10,7 +10,7 @@
<!-- Главная страница приложения -->
<FlyoutItem Title="Главная" Icon="add.png">
<ShellContent ContentTemplate="{DataTemplate local:GraphPage}" />
<ShellContent ContentTemplate="{DataTemplate local:ResizableCanvasPage}" />
</FlyoutItem>
<!-- Выпадающий список категорий -->

View file

@ -58,7 +58,7 @@ namespace NotesDataAnalyst
// Отрисовка текста
canvas.FontColor = Colors.Black;
canvas.DrawString(node.Text, (float)node.Position.X + 5, (float)node.Position.Y + 5, HorizontalAlignment.Left);
canvas.DrawString(node.Text, (float)node.Position.X + 50, (float)node.Position.Y + 10, HorizontalAlignment.Center);
// Если нода выбрана, рисуем пунктирную обводку и "ручку" для изменения размера
if (node.IsActive)
@ -70,8 +70,8 @@ namespace NotesDataAnalyst
// Ручка для изменения размера
canvas.FillColor = Colors.Gray;
canvas.FillRectangle(
(float)(node.Position.X + node.Size.Width - 10),
(float)(node.Position.Y + node.Size.Height - 10),
(float)(node.Position.X + node.Size.Width - 0),
(float)(node.Position.Y + node.Size.Height - 1),
10, 10);
}
}

View file

@ -52,12 +52,12 @@ namespace NotesDataAnalyst
if ((DateTime.Now - tapStartTime).TotalMilliseconds >= longPressDuration)
{
// Çäåñü âûïîëíÿåòñÿ äåéñòâèå ïðè äëèòåëüíîì íàæàòèè
OnNodeLongPressed();
// OnNodeLongPressed();
}
return false; // Îñòàíàâëèâàåì òàéìåð
});
}
/*
private void OnNodeLongPressed()
{
if (_selectedNode != null)
@ -78,7 +78,7 @@ namespace NotesDataAnalyst
// Çäåñü ðåàëèçóéòå äåéñòâèå ïðè äëèòåëüíîì íàæàòèè
// DisplayAlert("Äëèòåëüíîå íàæàòèå", "Âû íàæàëè è óäåðæèâàëè ýëåìåíò", "ÎÊ");
}
}*/
private void OnNodeTapped(object sender, TappedEventArgs e)
{
@ -243,25 +243,25 @@ namespace NotesDataAnalyst
private bool IsOnRightResizeHandle(GraphNode node, PointF point)
{
const float handleSize = 400;
return Math.Abs(point.X - (node.Position.X + node.Size.Width)) <= handleSize;
const float handleSize = 10;
return Math.Abs(point.X - (node.Position.X + node.Size.Width - 1)) <= handleSize;
}
private bool IsOnLeftResizeHandle(GraphNode node, PointF point)
{
const float handleSize = 400;
const float handleSize = 10;
return Math.Abs(point.X - node.Position.X) <= handleSize;
}
private bool IsOnTopResizeHandle(GraphNode node, PointF point)
{
const float handleSize = 400;
const float handleSize = 10;
return Math.Abs(point.Y - node.Position.Y) <= handleSize;
}
private bool IsOnBottomResizeHandle(GraphNode node, PointF point)
{
const float handleSize = 400;
const float handleSize = 10;
return Math.Abs(point.Y - (node.Position.Y + node.Size.Height)) <= handleSize;
}
@ -279,7 +279,7 @@ namespace NotesDataAnalyst
// Ïðîâåðêà, íàõîäèòñÿ ëè òî÷êà íà "ðó÷êå" èçìåíåíèÿ ðàçìåðà
private bool IsOnResizeHandle(GraphNode node, PointF point)
{
const float handleSize = 200f; // Ðàçìåð ðó÷êè èçìåíåíèÿ ðàçìåðà
const float handleSize = 20f; // Ðàçìåð ðó÷êè èçìåíåíèÿ ðàçìåðà
// Îïðåäåëÿåì ïðÿìîóãîëüíèêè äëÿ êàæäîé ðó÷êè
var rightHandleRect = new RectF(

View file

@ -84,6 +84,9 @@
<MauiXaml Update="NoteContent\NoteSelectionPopup.xaml">
<Generator>MSBuild:Compile</Generator>
</MauiXaml>
<MauiXaml Update="ResizableCanvasPage.xaml">
<Generator>MSBuild:Compile</Generator>
</MauiXaml>
</ItemGroup>
</Project>

12
ResizableCanvasPage.xaml Normal file
View file

@ -0,0 +1,12 @@
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="NotesDataAnalyst.ResizableCanvasPage"
Title="ResizableCanvasPage">
<ScrollView>
<AbsoluteLayout x:Name="CanvasLayout"
WidthRequest="2000" HeightRequest="2000">
<!-- Элементы будут добавляться программно -->
</AbsoluteLayout>
</ScrollView>
</ContentPage>

115
ResizableCanvasPage.xaml.cs Normal file
View file

@ -0,0 +1,115 @@
using Microsoft.Maui.Controls;
using Microsoft.Maui.Graphics;
using System;
namespace NotesDataAnalyst
{
public partial class ResizableCanvasPage : ContentPage
{
private const double InitialWidth = 150;
private const double InitialHeight = 100;
private double startX, startY;
public ResizableCanvasPage()
{
InitializeComponent();
}
// Ìåòîä äëÿ äîáàâëåíèÿ íîâîãî îáúåêòà
private void AddResizableObject(double x, double y)
{
// Ñîçäàåì Frame êàê íîâûé îáúåêò
var resizableFrame = new Frame
{
BackgroundColor = Colors.LightBlue,
BorderColor = Colors.DarkBlue,
CornerRadius = 8,
WidthRequest = InitialWidth,
HeightRequest = InitialHeight
};
// Äîáàâëÿåì îáðàáîò÷èê ïåðåòàñêèâàíèÿ
var panGesture = new PanGestureRecognizer();
panGesture.PanUpdated += (s, e) => OnDragPanUpdated(s, e, resizableFrame);
resizableFrame.GestureRecognizers.Add(panGesture);
// Äîáàâëÿåì ìàðêåð äëÿ èçìåíåíèÿ ðàçìåðà
var resizeHandle = new BoxView
{
BackgroundColor = Colors.Gray,
WidthRequest = 20,
HeightRequest = 20
};
// Äîáàâëÿåì îáðàáîò÷èê èçìåíåíèÿ ðàçìåðà
var resizePanGesture = new PanGestureRecognizer();
resizePanGesture.PanUpdated += (s, e) => OnResizePanUpdated(s, e, resizableFrame, resizeHandle);
resizeHandle.GestureRecognizers.Add(resizePanGesture);
// Äîáàâëÿåì ýëåìåíòû íà õîëñò
AbsoluteLayout.SetLayoutBounds(resizableFrame, new Rect(x, y, InitialWidth, InitialHeight));
CanvasLayout.Children.Add(resizableFrame);
UpdateResizeHandlePosition(resizableFrame, resizeHandle);
CanvasLayout.Children.Add(resizeHandle);
}
// Îáðàáîò÷èê äëÿ ïåðåòàñêèâàíèÿ îáúåêòà
private void OnDragPanUpdated(object sender, PanUpdatedEventArgs e, Frame frame)
{
if (e.StatusType == GestureStatus.Started)
{
// Çàïîìèíàåì íà÷àëüíóþ ïîçèöèþ îáúåêòà
startX = AbsoluteLayout.GetLayoutBounds(frame).X;
startY = AbsoluteLayout.GetLayoutBounds(frame).Y;
}
else if (e.StatusType == GestureStatus.Running)
{
// Óñòàíàâëèâàåì íîâóþ ïîçèöèþ, ïðèáàâëÿÿ èçìåíåíèå ïî îñè X è Y
double x = startX + e.TotalX;
double y = startY + e.TotalY;
AbsoluteLayout.SetLayoutBounds(frame, new Rect(x, y, frame.Width, frame.Height));
}
}
// Îáðàáîò÷èê äëÿ èçìåíåíèÿ ðàçìåðà îáúåêòà
private void OnResizePanUpdated(object sender, PanUpdatedEventArgs e, Frame frame, BoxView resizeHandle)
{
if (e.StatusType == GestureStatus.Started)
{
// Çàïîìèíàåì íà÷àëüíûå ðàçìåðû îáúåêòà
startX = frame.Width;
startY = frame.Height;
}
else if (e.StatusType == GestureStatus.Running)
{
// Èçìåíÿåì ðàçìåðû îáúåêòà â çàâèñèìîñòè îò æåñòà
double newWidth = Math.Max(50, startX + e.TotalX);
double newHeight = Math.Max(50, startY + e.TotalY);
frame.WidthRequest = newWidth;
frame.HeightRequest = newHeight;
// Îáíîâëÿåì ïîçèöèþ ðó÷êè èçìåíåíèÿ ðàçìåðà
UpdateResizeHandlePosition(frame, resizeHandle);
}
}
// Ìåòîä äëÿ îáíîâëåíèÿ ïîçèöèè ðó÷êè èçìåíåíèÿ ðàçìåðà
private void UpdateResizeHandlePosition(Frame frame, BoxView resizeHandle)
{
double x = AbsoluteLayout.GetLayoutBounds(frame).X + frame.WidthRequest - resizeHandle.WidthRequest;
double y = AbsoluteLayout.GetLayoutBounds(frame).Y + frame.HeightRequest - resizeHandle.HeightRequest;
AbsoluteLayout.SetLayoutBounds(resizeHandle, new Rect(x, y, resizeHandle.WidthRequest, resizeHandle.HeightRequest));
}
// Ïðèìåð âûçîâà ìåòîäà äîáàâëåíèÿ îáúåêòîâ
protected override void OnAppearing()
{
base.OnAppearing();
// Ïðèìåð äîáàâëåíèÿ íåñêîëüêèõ îáúåêòîâ íà õîëñò
AddResizableObject(100, 100);
AddResizableObject(400, 200);
AddResizableObject(700, 400);
}
}
}