1
0
Files
OAiP-Presnyakov_Ilya-Labora…/Main/MainWindow.xaml.cs
2026-02-26 00:59:10 +03:00

420 lines
13 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
using DrawFigureLibrary;
using DrawFigureLibrary.Figures;
using System.Windows;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
namespace Main
{
public partial class MainWindow : Window
{
private RenderTargetBitmap? _renderTarget ;
private int _polyExpected ;
private List<Point> _polyPoints = new List<Point>() ;
private DrawFigureLibrary.Figure? _mouseSelected ;
private bool _isDragging ;
private Point _lastMouse ;
private void ClickAddRectangle(object sender, RoutedEventArgs e)
{
try
{
string name = RectName.Text.Trim();
if (!NameIsValid(name)) throw new Exception("Имя пустое или уже занято.");
int x = int.Parse(RectX.Text);
int y = int.Parse(RectY.Text);
int w = int.Parse(RectW.Text);
int h = int.Parse(RectH.Text);
ShapeContainer.AddFigure(new RectangleFigure(name, x, y, w, h));
Upd();
}
catch (FormatException)
{
MessageBox.Show("Некорректный формат числа");
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
private void ClickAddSquare(object sender, RoutedEventArgs e)
{
try
{
string name = SquareName.Text.Trim();
if (!NameIsValid(name)) throw new Exception("Имя пустое или уже занято.");
int x = int.Parse(SquareX.Text) ;
int y = int.Parse(SquareY.Text) ;
int side = int.Parse(SquareSide.Text) ;
ShapeContainer.AddFigure(new SquareFigure(name, x, y, side));
Upd();
}
catch (FormatException)
{
MessageBox.Show("Некорректный формат числа");
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
private void ClickAddEllipse(object sender, RoutedEventArgs e)
{
try
{
string name = EllipseName.Text.Trim();
if (!NameIsValid(name)) throw new Exception("Имя пустое или уже занято.");
int x = int.Parse(EllipseX.Text);
int y = int.Parse(EllipseY.Text);
int w = int.Parse(EllipseW.Text);
int h = int.Parse(EllipseH.Text);
ShapeContainer.AddFigure(new EllipseFigure(name, x, y, w, h));
Upd();
}
catch (FormatException)
{
MessageBox.Show("Некорректный формат числа");
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
private void ClickAddCircle(object sender, RoutedEventArgs e)
{
try
{
string name = CircleName.Text.Trim();
if (!NameIsValid(name)) throw new Exception("Имя пустое или уже занято.");
int x = int.Parse(CircleX.Text);
int y = int.Parse(CircleY.Text);
int d = int.Parse(CircleD.Text);
ShapeContainer.AddFigure(new CircleFigure(name, x, y, d));
Upd();
}
catch (FormatException)
{
MessageBox.Show("Некорректный формат числа");
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
private void ClickPolyStart(object sender, RoutedEventArgs e)
{
try
{
string name = PolyName.Text.Trim();
if (!NameIsValid(name)) throw new Exception("Имя пустое или уже занято.");
_polyExpected = int.Parse(PolyCount.Text);
if (_polyExpected < 3) throw new Exception("Минимум 3 вершины.");
_polyPoints = new List<Point>();
PolyCount.IsEnabled = false;
PolyX.IsEnabled = true;
PolyY.IsEnabled = true;
PolyAddPointBtn.IsEnabled = true;
PolyFinishBtn.IsEnabled = false;
PolyStatus.Text = $"Точек: 0 / {_polyExpected}";
}
catch (FormatException)
{
MessageBox.Show("Некорректный формат числа");
}
catch (Exception ex) {
MessageBox.Show(ex.Message);
}
}
private void ClickPolyAddPoint(object sender, RoutedEventArgs e)
{
try
{
int x = int.Parse(PolyX.Text);
int y = int.Parse(PolyY.Text);
if (_polyPoints.Count >= _polyExpected) throw new Exception("Все точки уже введены.");
_polyPoints.Add(new Point(x, y));
PolyStatus.Text = $"Точек: {_polyPoints.Count} / {_polyExpected}";
if (_polyPoints.Count == _polyExpected)
{
PolyAddPointBtn.IsEnabled = false;
PolyFinishBtn.IsEnabled = true;
}
}
catch (FormatException)
{
MessageBox.Show("Некорректный формат числа");
}
catch (Exception ex) {
MessageBox.Show(ex.Message);
}
}
private void ClickPolyFinish(object sender, RoutedEventArgs e)
{
try
{
string name = PolyName.Text.Trim();
if (!NameIsValid(name)) throw new Exception("Имя пустое или уже занято.");
if (_polyPoints.Count != _polyExpected) throw new Exception("Не все точки введены.");
ShapeContainer.AddFigure(new PolygonFigure(name, _polyPoints.ToArray()));
Upd();
PolyCount.IsEnabled = true;
PolyX.IsEnabled = false;
PolyY.IsEnabled = false;
PolyAddPointBtn.IsEnabled = false;
PolyFinishBtn.IsEnabled = false;
PolyStatus.Text = "";
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
private void ClickAddTriangle(object sender, RoutedEventArgs e)
{
try
{
string name = TriName.Text.Trim();
if (!NameIsValid(name)) throw new Exception("Имя пустое или уже занято.");
var a = new Point(int.Parse(Ax.Text), int.Parse(Ay.Text));
var b = new Point(int.Parse(Bx.Text), int.Parse(By.Text));
var c = new Point(int.Parse(Cx.Text), int.Parse(Cy.Text));
ShapeContainer.AddFigure(new Triangle(name, a, b, c));
Upd();
}
catch (FormatException)
{
MessageBox.Show("Некорректный формат числа");
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
private void ClickAddTerrainPointSunPointHumanPointText(object sender, RoutedEventArgs e)
{
try
{
string name = SceneName.Text.Trim();
if (!NameIsValid(name)) throw new Exception("Имя пустое или уже занято.");
int x = int.Parse(SceneX.Text);
int y = int.Parse(SceneY.Text);
int sceneW = int.Parse(SceneW.Text);
int sceneH = int.Parse(SceneH.Text);
ShapeContainer.AddFigure(new TerrainPointSunPointHumanPointText(name, x, y, sceneW, sceneH));
Upd();
}
catch (FormatException)
{
MessageBox.Show("Некорректный формат числа");
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
private void ClickMoveSelected(object sender, RoutedEventArgs e)
{
try
{
var fig = GetSelectedFigureOrThrow();
int dx = int.Parse(MoveDx.Text);
int dy = int.Parse(MoveDy.Text);
fig.MoveBy(dx, dy);
Redraw();
}
catch (FormatException)
{
MessageBox.Show("Некорректный формат числа");
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
private void ClickDeleteSelected(object sender, RoutedEventArgs e)
{
try
{
var fig = GetSelectedFigureOrThrow();
bool ok = ShapeContainer.RemoveFigure(fig);
if (!ok) throw new Exception("Фигура для удаления не найдена.");
Upd();
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
public MainWindow()
{
InitializeComponent();
}
private void Window_Loaded(object sender, RoutedEventArgs e)
{
Init.DrawingImage = DrawingImage;
int width = (int)DrawingImage.Width;
int height = (int)DrawingImage.Height;
if (width <= 0) width = 800;
if (height <= 0) height = 400;
_renderTarget = new RenderTargetBitmap(width, height, 96, 96, PixelFormats.Pbgra32);
DrawingImage.Source = _renderTarget;
ImgBorder.Width = width;
ImgBorder.Height = height;
Upd();
}
private void Redraw()
{
if (_renderTarget == null) return;
DrawingVisual drawVis = new DrawingVisual();
using (var ctx = drawVis.RenderOpen())
{
foreach (var fig in ShapeContainer.FigureList)
{
fig.Draw(ctx);
}
}
_renderTarget.Clear();
_renderTarget.Render(drawVis);
DrawingImage.Source = _renderTarget;
}
private void RefreshCombo()
{
FigureCombo.ItemsSource = null;
FigureCombo.ItemsSource = ShapeContainer.FigureList.Select(f => f.Name);
if (FigureCombo.Items.Count > 0 && FigureCombo.SelectedIndex < 0)
{
FigureCombo.SelectedIndex = 0;
}
}
private void Upd()
{
Redraw();
RefreshCombo();
}
private bool NameIsValid(string? name)
{
if (string.IsNullOrWhiteSpace(name)) return false;
if (ShapeContainer.FigureList.Any(f => f.Name == name)) return false;
return true;
}
private Figure GetSelectedFigureOrThrow()
{
if (FigureCombo.SelectedItem == null) throw new Exception("Фигура не выбрана.");
string name = FigureCombo.SelectedItem.ToString()!;
var fig = ShapeContainer.FindByName(name);
if (fig == null) throw new Exception("Фигура для операции не найдена.");
return fig;
}
private void MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
var p = e.GetPosition(DrawingImage);
_mouseSelected =
ShapeContainer.FigureList
.AsEnumerable()
.Reverse()
.FirstOrDefault(f => f.HitTest(p));
if (_mouseSelected != null)
{
FigureCombo.SelectedItem = _mouseSelected.Name;
_isDragging = true;
_lastMouse = p;
DrawingImage.CaptureMouse();
e.Handled = true;
}
}
private void MouseMove(object sender, MouseEventArgs e)
{
if (!_isDragging || _mouseSelected == null) return;
if (e.LeftButton != MouseButtonState.Pressed) return;
var p = e.GetPosition(DrawingImage);
int dx = (int)Math.Round(p.X - _lastMouse.X);
int dy = (int)Math.Round(p.Y - _lastMouse.Y);
if (dx == 0 && dy == 0) return;
if (_mouseSelected.MoveByChecked(dx, dy))
{
_lastMouse = p;
Redraw();
}
e.Handled = true;
}
private void MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
{
if (!_isDragging) return;
_isDragging = false;
_mouseSelected = null;
DrawingImage.ReleaseMouseCapture();
e.Handled = true;
}
}
}