/
ArtemNech
/
simpleOpenGL
Обзор
Документация
Войти
/
ArtemNech
/
simpleOpenGL
Код
Запросы
0
Задачи
Вики
Пакеты
0
Релизы
0
CI/CD
Аналитика
Безопасность
devOpt
backend/CGraphicPainter.cpp
343 строки
10 KB
Artem Nechitaylenko
updated readme and small fix
21 май 2026, 08:53
21 май 2026, 08:53
238288d
Код
Авторство
О чём код?
// // Created by artem on 1/1/25. // #include "CGraphicPainter.h" #include <QPainter> #include <QDragEnterEvent> #include <QOpenGLFunctions> #include <QMimeData> #include <QMenu> #include <QApplication> #include "diagram/CInteractionController.h" #include "CBacking.h" using namespace ngraph; CPainter::CPainter(QWidget* parent) : QOpenGLWidget(parent) { m_renderer = new QOpenGLRenderer(); m_interactionController = new CInteractionController(this); m_interactionController->setCallbackScrollBars([this](){this->updateScrollBars();}); m_interactionController->setCallbackRepaint([this](){ this->update(); }); m_renderer->takeController(m_interactionController); setContextMenuPolicy(Qt::CustomContextMenu); setMouseTracking(true); setFocusPolicy(Qt::StrongFocus); connect(this, &QWidget::customContextMenuRequested, this, &CPainter::onCustomContextMenuRequested); setAcceptDrops(true); updateScrollBars(); } CPainter::~CPainter() { makeCurrent(); delete m_renderer; doneCurrent(); delete m_interactionController; } void CPainter::initializeGL() { m_renderer->initialize(); } void CPainter::resizeGL(int w, int h) { m_interactionController->setViewport(ngraph::NSizeF(w, h)); m_renderer->resize(w, h); updateScrollBars(); } void CPainter::paintGL() { GLuint defaultFBO = defaultFramebufferObject(); m_renderer->renderDiagram(defaultFBO); if (m_postprocess_enabled) { update(); } } //====================================================================================================================== // Обработчики событий //====================================================================================================================== void CPainter::mousePressEvent(QMouseEvent* event) { if (event->button() == Qt::MiddleButton || (event->button() == Qt::LeftButton && event->modifiers() & Qt::ShiftModifier)) { NPointF screenPoint(event->position().x(), event->position().y()); m_interactionController->handleMousePressForPan(screenPoint); } else { NPointF screenPoint(event->position().x(), event->position().y()); uint32_t modif = event->modifiers(); auto modifier = static_cast<NKeyboardModifier>(modif); m_interactionController->handleMouseClick(screenPoint, event->button(), modifier); update(); } event->accept(); } void CPainter::mouseMoveEvent(QMouseEvent* event) { if (m_interactionController) { NPointF screenPoint(event->position().x(), event->position().y()); NKeyboardModifier modif = (NKeyboardModifier)((int)event->modifiers()); ngraph::NPointF mousePos (event->position().x(), event->position().y()); m_interactionController->handleMouseMove(mousePos, event->buttons(), modif); update(); } event->accept(); } void CPainter::mouseReleaseEvent(QMouseEvent* event) { NPointF screenPos(event->position().x(), event->position().y()); m_interactionController->handleMouseRelease(screenPos, event->button()); update(); event->accept(); } void CPainter::mouseDoubleClickEvent(QMouseEvent* event) { if (m_interactionController) { NPointF screenPoint(event->position().x(), event->position().y()); m_interactionController->handleMouseDoubleClick(screenPoint, event->button(), event->modifiers()); update(); } event->accept(); } void CPainter::wheelEvent(QWheelEvent* event) { m_interactionController->handleWheelEvent(event); update(); event->accept(); } void CPainter::leaveEvent(QEvent* event) { if (m_interactionController) { m_interactionController->clearHighlights(); update(); } QOpenGLWidget::leaveEvent(event); } void CPainter::keyPressEvent(QKeyEvent* event) { if (m_interactionController) { m_interactionController->handleKeyPress(event); update(); } event->accept(); } void CPainter::dragEnterEvent(QDragEnterEvent *event) { auto mime = event->mimeData(); auto source = mime->property("source").toString().toStdString(); if (source != "palette" && source != "canvas") { qDebug() << "CPainter::dragEnterEvent failed with source = '"+QString(source.c_str())+"'"; event->ignore(); return; } event->acceptProposedAction(); } void CPainter::dropEvent(QDropEvent *event) { auto mime = event->mimeData(); auto source = mime->property("source").toString().toStdString(); ngraph::NPointF pos(event->position().x(), event->position().y()); if (source == "palette") { int c_type = mime->property("comp_type").toInt(); if (!m_interactionController->handleDropFromPalette(c_type, pos)) { event->ignore(); return; } } // не планируется, но посмотрим куда выведет if (source == "canvas") { if (!m_interactionController->handleDropFromCanvas(pos)) { event->ignore(); return; } } event->acceptProposedAction(); repaint(); } void CPainter::dragMoveEvent(QDragMoveEvent *event) { auto mime = event->mimeData(); auto source = mime->property("source").toString().toStdString(); ngraph::NPointF pos(event->position().x(), event->position().y()); int c_type = mime->property("comp_type").toInt(); if (source == "palette") { if (!m_interactionController->handleDragFromPalette(c_type, pos)) { event->ignore(); return; } } else if (source == "canvas") { if(!m_interactionController->handleDragCanvasObject(pos)) { event->ignore(); return; } } else { event->ignore(); return; } event->acceptProposedAction(); repaint(); } //====================================================================================================================== //====================================================================================================================== //====================================================================================================================== void CPainter::horizonScroll( int position) { m_interactionController->setHorizontalScroll(position); // 1000 - максимум update(); } void CPainter::verticalScroll(int position) { m_interactionController->setVerticalScroll(position); update(); } void CPainter::setScrollBars(QScrollBar *horizon, QScrollBar *vertical) { if (!horizon || !vertical) return; m_horizon = horizon; m_vertical = vertical; connect(m_horizon, &QScrollBar::sliderMoved, this, &CPainter::horizonScroll); connect(m_vertical, &QScrollBar::sliderMoved, this, &CPainter::verticalScroll); m_horizon->setMaximum(1000); m_vertical->setMaximum(1000); m_horizon->setPageStep(1000/this->width()); m_vertical->setPageStep(1000/this->height()); } void CPainter::onCustomContextMenuRequested(const QPoint &pos) { m_currentActions.clear(); ngraph::NPointF globPos(m_interactionController->panOffset().x() + pos.x(), m_interactionController->panOffset().y() + pos.y()); m_interactionController->getContextActions(m_currentActions, globPos); if (m_currentActions.empty()) { return; } QMenu menu(this); for (auto & action : m_currentActions) { auto* qtAction = new QAction(QIcon(action.icon.c_str()), QString::fromStdString(action.text), &menu); qtAction->setEnabled(action.enabled); qtAction->setCheckable(action.checked); connect(qtAction, &QAction::triggered, [callback = action.callback]() { callback(); }); menu.addAction(qtAction); } menu.exec(mapToGlobal(pos)); } QOpenGLFunctions_3_3_Core *CPainter::get_core() { return this; } void CPainter::updateScrollBars() { ngraph::NRectF m_boundingRect = m_interactionController->diagram()->documentBounds(); double worldWidth = m_boundingRect.width(); double worldHeight = m_boundingRect.height(); // 2. Размер диаграммы в экранных координатах (пикселях) double screenWidth = worldWidth * m_interactionController->zoom(); double screenHeight = worldHeight * m_interactionController->zoom(); // 3. Текущая видимая область (окно просмотра) double viewportWidth = this->width(); // ширина вашего OpenGL окна double viewportHeight = this->height(); // 4. Позиция скроллбаров (в пикселях, относительно диаграммы) double scrollX = -m_interactionController->panOffset().x(); double scrollY = -m_interactionController->panOffset().y(); // 5. Диапазон скроллбаров double scrollMaxX = std::max(0.0, screenWidth - viewportWidth); double scrollMaxY = std::max(0.0, screenHeight - viewportHeight); if (m_horizon) { m_horizon->setRange(0, (int)scrollMaxX); m_horizon->setValue((int)std::clamp(scrollX, 0.0, scrollMaxX)); m_horizon->setPageStep((int)viewportWidth); } if (m_vertical) { m_vertical->setRange(0, (int)scrollMaxY); m_vertical->setValue((int)std::clamp(scrollY, 0.0, scrollMaxY)); m_vertical->setPageStep((int)viewportHeight); } } void CPainter::enablePostProcess(bool enabled) { m_renderer->setPostprocessEnabled(enabled); m_postprocess_enabled = enabled; if (enabled) { update(); } } //} // namespace ngraph