diff --git a/Main/MainWindow.xaml.cs b/Main/MainWindow.xaml.cs new file mode 100644 index 0000000..97194ee --- /dev/null +++ b/Main/MainWindow.xaml.cs @@ -0,0 +1,420 @@ +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 _polyPoints = new List() ; + + 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(); + 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; + } + } +} \ No newline at end of file