From db62966c3212e47f093fe745eaabba05e84b6096 Mon Sep 17 00:00:00 2001 From: ARCHI86 Date: Sun, 10 Nov 2024 16:10:13 +0300 Subject: [PATCH] =?UTF-8?q?=D0=9D=D0=BE=D0=B2=D0=B0=D1=8F=20=D1=81=D1=82?= =?UTF-8?q?=D1=80=D0=B0=D0=BD=D0=B8=D1=86=D0=B0=20=D1=81=20=D0=BD=D0=BE?= =?UTF-8?q?=D0=B4=D0=B0=D0=BC=D0=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- AppShell.xaml | 2 +- GraphDrawable.cs | 6 +- GraphPage.xaml.cs | 18 +++--- NotesDataAnalyst.csproj | 3 + ResizableCanvasPage.xaml | 12 ++++ ResizableCanvasPage.xaml.cs | 115 ++++++++++++++++++++++++++++++++++++ 6 files changed, 143 insertions(+), 13 deletions(-) create mode 100644 ResizableCanvasPage.xaml create mode 100644 ResizableCanvasPage.xaml.cs diff --git a/AppShell.xaml b/AppShell.xaml index 96d0e53..ec82c4e 100644 --- a/AppShell.xaml +++ b/AppShell.xaml @@ -10,7 +10,7 @@ - + diff --git a/GraphDrawable.cs b/GraphDrawable.cs index e715d49..5ae069b 100644 --- a/GraphDrawable.cs +++ b/GraphDrawable.cs @@ -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); } } diff --git a/GraphPage.xaml.cs b/GraphPage.xaml.cs index 19bf12e..e6c5873 100644 --- a/GraphPage.xaml.cs +++ b/GraphPage.xaml.cs @@ -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( diff --git a/NotesDataAnalyst.csproj b/NotesDataAnalyst.csproj index c37b54a..d6d392a 100644 --- a/NotesDataAnalyst.csproj +++ b/NotesDataAnalyst.csproj @@ -84,6 +84,9 @@ MSBuild:Compile + + MSBuild:Compile + diff --git a/ResizableCanvasPage.xaml b/ResizableCanvasPage.xaml new file mode 100644 index 0000000..7e77c14 --- /dev/null +++ b/ResizableCanvasPage.xaml @@ -0,0 +1,12 @@ + + + + + + + + \ No newline at end of file diff --git a/ResizableCanvasPage.xaml.cs b/ResizableCanvasPage.xaml.cs new file mode 100644 index 0000000..3873c19 --- /dev/null +++ b/ResizableCanvasPage.xaml.cs @@ -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); + } + } +} \ No newline at end of file