141 lines
5.6 KiB
C#
141 lines
5.6 KiB
C#
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,
|
|
Padding = 0, // Óáèðàåì âíóòðåííèå îòñòóïû
|
|
Content = new Grid() // Èñïîëüçóåì Grid äëÿ äîáàâëåíèÿ ñîäåðæèìîãî è ðó÷êè
|
|
};
|
|
|
|
// Ñîçäàåì ñîäåðæèìîå âíóòðè ôðåéìà
|
|
var content = new StackLayout
|
|
{
|
|
BackgroundColor = Colors.LightBlue,
|
|
Children =
|
|
{
|
|
new Label { Text = "Resizable Object", HorizontalOptions = LayoutOptions.Center, VerticalOptions = LayoutOptions.Center }
|
|
}
|
|
};
|
|
|
|
var resizeHandle = new BoxView
|
|
{
|
|
BackgroundColor = Colors.Gray,
|
|
WidthRequest = 20,
|
|
HeightRequest = 20
|
|
};
|
|
|
|
// Ñîçäàåì Grid âíóòðè Frame
|
|
var grid = (Grid)resizableFrame.Content;
|
|
|
|
// Íàñòðîèì ñåòêó: äîáàâèì äâà ñòîëáöà è äâå ñòðîêè
|
|
grid.ColumnDefinitions.Add(new ColumnDefinition { Width = GridLength.Star });
|
|
grid.ColumnDefinitions.Add(new ColumnDefinition { Width = GridLength.Auto }); // äëÿ ðó÷êè
|
|
grid.RowDefinitions.Add(new RowDefinition { Height = GridLength.Star });
|
|
grid.RowDefinitions.Add(new RowDefinition { Height = GridLength.Auto }); // äëÿ ðó÷êè
|
|
|
|
// Äîáàâëÿåì ñîäåðæèìîå â ïåðâóþ ÿ÷åéêó (ñòîëáåö 0, ñòðîêà 0)
|
|
grid.Children.Add(content); // Áåç óêàçàíèÿ êîëîíîê/ñòðîê
|
|
|
|
// Äîáàâëÿåì ðó÷êó â ïðàâûé íèæíèé óãîë (ñòîëáåö 1, ñòðîêà 1)
|
|
grid.Children.Add(resizeHandle); // Áåç óêàçàíèÿ êîëîíîê/ñòðîê
|
|
|
|
// Óñòàíàâëèâàåì ñòðîêó è êîëîíêó äëÿ ðó÷êè
|
|
Grid.SetRow(resizeHandle, 1);
|
|
Grid.SetColumn(resizeHandle, 1);
|
|
|
|
// Äîáàâëÿåì ïàíîðàìó äëÿ ïåðåìåùåíèÿ îáúåêòà
|
|
var panGesture = new PanGestureRecognizer();
|
|
panGesture.PanUpdated += (s, e) => OnDragPanUpdated(s, e, resizableFrame);
|
|
resizableFrame.GestureRecognizers.Add(panGesture);
|
|
|
|
// Äîáàâëÿåì ïàíîðàìó äëÿ èçìåíåíèÿ ðàçìåðà
|
|
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);
|
|
}
|
|
|
|
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)
|
|
{
|
|
double x = startX + e.TotalX;
|
|
double y = startY + e.TotalY;
|
|
AbsoluteLayout.SetLayoutBounds(frame, new Rect(x, y, frame.WidthRequest, frame.HeightRequest));
|
|
|
|
// Îáíîâëÿåì ïîçèöèþ ðó÷êè
|
|
var resizeHandle = (BoxView)((Grid)frame.Content).Children[1];
|
|
UpdateResizeHandlePosition(frame, resizeHandle);
|
|
}
|
|
}
|
|
|
|
private void OnResizePanUpdated(object sender, PanUpdatedEventArgs e, Frame frame, BoxView resizeHandle)
|
|
{
|
|
if (e.StatusType == GestureStatus.Started)
|
|
{
|
|
startX = frame.WidthRequest;
|
|
startY = frame.HeightRequest;
|
|
}
|
|
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)
|
|
{
|
|
var frameBounds = AbsoluteLayout.GetLayoutBounds(frame);
|
|
double x = frameBounds.X + frame.WidthRequest - resizeHandle.WidthRequest;
|
|
double y = frameBounds.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);
|
|
}
|
|
}
|
|
}
|