This repository has been archived on 2026-05-28. You can view files and clone it. You cannot open issues or pull requests or push a commit.
Files
DRAwer_2_0/Canvas.h
ParkSuMin 2b04a4bf1c Рефакторинг (1)
Создание системного заголовочного файла с нужными переопределениями, структурами и макросами
2025-12-25 19:01:57 +03:00

247 lines
10 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.
#pragma once
#include "System.h"
// ===================================================================
// Основной класс холста
// ===================================================================
/**
* @brief Класс холста для рисования геометрических фигур с ограничениями
*
* Класс предоставляет функциональность для создания и редактирования
* геометрических объектов с применением ограничений через геометрический
* солвер FreeCAD GCS.
*/
class Canvas : public QWidget
{
Q_OBJECT
public:
/**
* @brief Конструктор класса Canvas
* @param parent Родительский виджет
*/
explicit Canvas(QWidget* parent = nullptr);
/**
* @brief Деструктор класса Canvas
*/
~Canvas() override;
/**
* @brief Изменить текущий режим работы
* @param newMode Новый режим работы
*/
void changeMode(Mode newMode);
/**
* @brief Увеличить масштаб
*
* Увеличивает масштаб отображения на 5%
*/
void zoomIn();
/**
* @brief Уменьшить масштаб
*
* Уменьшает масштаб отображения на 5%
*/
void zoomOut();
/**
* @brief Сбросить масштаб к 100%
*/
void zoomReset();
protected:
/**
* @brief Обработчик нажатия кнопки мыши
* @param event Событие мыши
*/
void mousePressEvent(QMouseEvent* event) override;
/**
* @brief Обработчик перемещения мыши
* @param event Событие мыши
*/
void mouseMoveEvent(QMouseEvent* event) override;
/**
* @brief Обработчик отпускания кнопки мыши
* @param event Событие мыши
*/
void mouseReleaseEvent(QMouseEvent* event) override;
/**
* @brief Обработчик вращения колесика мыши
* @param event Событие колесика мыши
*/
void wheelEvent(QWheelEvent* event) override;
/**
* @brief Обработчик события отрисовки
* @param event Событие отрисовки
*/
void paintEvent(QPaintEvent* event) override;
/**
* @brief Обработчик нажатия клавиши клавиатуры
* @param event Событие клавиатуры
*/
void keyPressEvent(QKeyEvent* event) override;
/**
* @brief Обработчик выхода курсора за пределы виджета
* @param event Событие
*/
void leaveEvent(QEvent* event) override;
private:
#ifdef _DEBUG
/**
* @brief Показать тег объекта под курсором (только в режиме отладки)
* @param pos Позиция курсора на экране
*/
void showObjectTag(QPointF pos);
#endif
/**
* @brief Преобразовать координаты экрана в логические координаты
* @param screenPos Координаты на экране
* @return Логические координаты
*/
QPointF screenToLogical(const QPointF& screenPos) const;
/**
* @brief Получить группу совпадающих точек
* @param p Базовая точка
*/
void getCoincidentGroup(Point* p);
// ====================== Методы поиска и выбора ======================
/**
* @brief Найти линию под указанной позицией
* @param pos Позиция для поиска
* @param tolerance Допуск поиска
* @return Найденная линия или nullptr
*/
Curve* findAt(QPointF& pos, qreal tolerance = 5.0);
/**
* @brief Найти точку в указанной позиции
* @param position Позиция для поиска
* @param tolerance Допуск поиска
* @return Найденная точка или nullptr
*/
Point* findPointAt(QPointF position, qreal tolerance = 5.0);
/**
* @brief Проверить, совпадают ли две точки (ограничение P2P)
* @param point1 Первая точка
* @param point2 Вторая точка
* @return true если точки совпадают, иначе false
*/
bool areCoincident(Point* point1, Point* point2);
/**
* @brief Проверить горизонтальность или вертикальность между двумя точками
* @param point1 Первая точка
* @param point2 Вторая точка
* @param mode false - проверка горизонтальности, true - проверка вертикальности
* @return true если точки имеют указанное ограничение, иначе false
*/
bool areHorizontalVertical(Point* point1, Point* point2, bool mode);
/**
* @brief Проверить, является ли линия горизонтальной
* @param line Линия для проверки
* @return true если линия горизонтальна, иначе false
*/
bool isLineHorizontal(Line* line);
/**
* @brief Проверить, является ли линия вертикальной
* @param line Линия для проверки
* @return true если линия вертикальна, иначе false
*/
bool isLineVertical(Line* line);
/**
* @brief Проверить, являются ли две линии уже параллельными
* @param line1 Первая линия
* @param line2 Вторая линия
* @return true если линии уже параллельны, иначе false
*/
bool areAlreadyParallel(Line* line1, Line* line2);
/**
* @brief Проверить, являются ли две линии уже перпендикулярными
* @param line1 Первая линия
* @param line2 Вторая линия
* @return true если линии уже перпендикулярны, иначе false
*/
bool areAlreadyPerpendicular(Line* line1, Line* line2);
bool areAlreadyTangent(Curve* curve1, Curve* curve2);
// ====================== Методы работы с ограничениями ======================
/**
* @brief Удалить ограничение по его тегу
* @param tag Тег ограничения
*/
void remove_constraint(int tag);
/**
* @brief Решить геометрическую систему
*
* Вызывает солвер для решения системы ограничений и обновляет отображение
*/
void solve_for_canvas();
/**
* @brief Очистить холст
*
* Удаляет все объекты и ограничения, сбрасывает состояние
*/
void clearCanvas();
// ====================== Данные для перемещения объектов ======================
Point* draggedPoint{ nullptr }; ///< Точка, которую перемещают
Line* draggedLine{ nullptr }; ///< Линия, которую перемещают
Curve* draggedCurve { nullptr };
QPointF dragOffset; ///< Смещение при начале перемещения
// ====================== Данные геометрической системы ======================
System sys; ///< Геометрический солвер
QVector<Curve*> curves; ///< Геометрические кривые
QVector<Point*> points; ///< Все точки сцены
std::vector<double*> params; ///< Все параметры, передаваемые в солвер
// ====================== Коллекции ограничений ======================
std::set<LinePair> parallelPairs; ///< Пары параллельных линий
std::set<LinePair> perpendicularPairs; ///< Пары перпендикулярных линий
std::set<CurvePair> tangentPairs;
std::set<PointPair> P2Ppairs; ///< Пары совпадающих точек
std::set<PointPair> HORIZ_pairs; ///< Пары точек горизонтальных линий
std::set<PointPair> VERT_pairs; ///< Пары точек вертикальных линий
// ====================== Временные данные для режимов ======================
Line* current_line{ nullptr }; ///< Текущая линия в режимах рисования/параллельности
Circle* current_circle{ nullptr };
Curve* current_curve { nullptr };
Point* firstPoint{ nullptr }; ///< Первая точка в режиме совпадения
Mode mode{ Mode::None }; ///< Текущий режим работы
// ====================== Флаги состояния ======================
bool after_constraint{ false }; ///< Флаг, что только что добавлено ограничение
double scaleFactor{ 1.0 }; ///< Текущий масштаб отображения (1.0 = 100%)
// ====================== Счётчики ======================
int obj_count{ 0 }; ///< Счётчик объектов (для тегов)
int constraints_count{ 0 }; ///< Счётчик ограничений (для тегов)
// ====================== Информация о последнем ограничении ======================
std::map<int, ConstraintInfo> C_Info; ///< Карта информации об ограничениях
};