mirror of
https://github.com/leozide/leocad
synced 2024-12-26 21:58:44 +01:00
397 lines
8.9 KiB
C++
397 lines
8.9 KiB
C++
#include "lc_global.h"
|
|
#include "lc_qglwidget.h"
|
|
#include "lc_glwidget.h"
|
|
#include "lc_glextensions.h"
|
|
#include "project.h"
|
|
#include "lc_library.h"
|
|
#include "lc_application.h"
|
|
#include "lc_mainwindow.h"
|
|
#include "lc_partselectionwidget.h"
|
|
#include "lc_context.h"
|
|
#include "view.h"
|
|
#include "texfont.h"
|
|
#include "lc_viewsphere.h"
|
|
#include "lc_stringcache.h"
|
|
#include "lc_texture.h"
|
|
#include "lc_mesh.h"
|
|
#include "lc_profile.h"
|
|
#include "lc_previewwidget.h"
|
|
|
|
static QList<QGLWidget*> gWidgetList;
|
|
|
|
lcQGLWidget::lcQGLWidget(QWidget* Parent, lcGLWidget* Owner)
|
|
: QGLWidget(Parent, gWidgetList.isEmpty() ? nullptr : gWidgetList.first())
|
|
{
|
|
mWheelAccumulator = 0;
|
|
mView = Owner;
|
|
mView->SetWidget(this);
|
|
|
|
makeCurrent();
|
|
|
|
if (gWidgetList.isEmpty())
|
|
{
|
|
// TODO: Find a better place for the grid texture and font
|
|
gStringCache.Initialize(mView->mContext);
|
|
gTexFont.Initialize(mView->mContext);
|
|
|
|
lcInitializeGLExtensions(context());
|
|
lcContext::CreateResources();
|
|
View::CreateResources(mView->mContext);
|
|
lcViewSphere::CreateResources(mView->mContext);
|
|
|
|
if (!gSupportsShaderObjects && lcGetPreferences().mShadingMode == lcShadingMode::DefaultLights)
|
|
lcGetPreferences().mShadingMode = lcShadingMode::Flat;
|
|
|
|
if (!gSupportsFramebufferObjectARB && !gSupportsFramebufferObjectEXT)
|
|
gMainWindow->GetPartSelectionWidget()->DisableIconMode();
|
|
|
|
gPlaceholderMesh = new lcMesh;
|
|
gPlaceholderMesh->CreateBox();
|
|
}
|
|
|
|
gWidgetList.append(this);
|
|
|
|
mView->OnInitialUpdate();
|
|
|
|
setMouseTracking(true);
|
|
|
|
if (dynamic_cast<View*>(Owner))
|
|
{
|
|
setFocusPolicy(Qt::StrongFocus);
|
|
setAcceptDrops(true);
|
|
}
|
|
}
|
|
|
|
lcQGLWidget::~lcQGLWidget()
|
|
{
|
|
gWidgetList.removeOne(this);
|
|
|
|
if (gWidgetList.isEmpty())
|
|
{
|
|
gStringCache.Reset();
|
|
gTexFont.Reset();
|
|
|
|
lcGetPiecesLibrary()->ReleaseBuffers(mView->mContext);
|
|
View::DestroyResources(mView->mContext);
|
|
lcContext::DestroyResources();
|
|
lcViewSphere::DestroyResources(mView->mContext);
|
|
|
|
delete gPlaceholderMesh;
|
|
gPlaceholderMesh = nullptr;
|
|
}
|
|
|
|
delete mView;
|
|
}
|
|
|
|
QSize lcQGLWidget::sizeHint() const
|
|
{
|
|
return mPreferredSize.isNull() ? QGLWidget::sizeHint() : mPreferredSize;
|
|
}
|
|
|
|
void lcQGLWidget::SetView(lcGLWidget* View)
|
|
{
|
|
mView = View;
|
|
|
|
if (View)
|
|
{
|
|
View->SetWidget(this);
|
|
const float Scale = GetDeviceScale();
|
|
View->SetSize(width() * Scale, height() * Scale);
|
|
|
|
if (hasFocus())
|
|
View->SetFocus(true);
|
|
}
|
|
}
|
|
|
|
void lcQGLWidget::SetPreviewPosition(const QRect& ParentRect)
|
|
{
|
|
lcPreferences& Preferences = lcGetPreferences();
|
|
lcPreviewWidget* Preview = reinterpret_cast<lcPreviewWidget*>(mView);
|
|
|
|
setWindowTitle(tr("%1 Preview").arg(Preview->IsModel() ? "Submodel" : "Part"));
|
|
|
|
int Size[2] = { 300,200 };
|
|
if (Preferences.mPreviewSize == 400)
|
|
{
|
|
Size[0] = 400; Size[1] = 300;
|
|
}
|
|
mPreferredSize = QSize(Size[0], Size[1]);
|
|
|
|
const QRect desktop = QApplication::desktop()->geometry();
|
|
|
|
QPoint pos;
|
|
switch (Preferences.mPreviewLocation)
|
|
{
|
|
case lcPreviewLocation::TopRight:
|
|
pos = mapToGlobal(ParentRect.topRight());
|
|
break;
|
|
case lcPreviewLocation::TopLeft:
|
|
pos = mapToGlobal(ParentRect.topLeft());
|
|
break;
|
|
case lcPreviewLocation::BottomRight:
|
|
pos = mapToGlobal(ParentRect.bottomRight());
|
|
break;
|
|
default:
|
|
pos = mapToGlobal(ParentRect.bottomLeft());
|
|
break;
|
|
}
|
|
if (pos.x() < desktop.left())
|
|
pos.setX(desktop.left());
|
|
if (pos.y() < desktop.top())
|
|
pos.setY(desktop.top());
|
|
|
|
if ((pos.x() + width()) > desktop.width())
|
|
pos.setX(desktop.width() - width());
|
|
if ((pos.y() + height()) > desktop.bottom())
|
|
pos.setY(desktop.bottom() - height());
|
|
move(pos);
|
|
|
|
setMinimumSize(100,100);
|
|
show();
|
|
}
|
|
|
|
void lcQGLWidget::resizeGL(int Width, int Height)
|
|
{
|
|
mView->SetSize(Width, Height);
|
|
}
|
|
|
|
void lcQGLWidget::paintGL()
|
|
{
|
|
mView->OnDraw();
|
|
}
|
|
|
|
void lcQGLWidget::focusInEvent(QFocusEvent* FocusEvent)
|
|
{
|
|
if (mView)
|
|
mView->SetFocus(true);
|
|
|
|
QGLWidget::focusInEvent(FocusEvent);
|
|
}
|
|
|
|
void lcQGLWidget::focusOutEvent(QFocusEvent* FocusEvent)
|
|
{
|
|
if (mView)
|
|
mView->SetFocus(false);
|
|
|
|
QGLWidget::focusOutEvent(FocusEvent);
|
|
}
|
|
|
|
void lcQGLWidget::keyPressEvent(QKeyEvent* KeyEvent)
|
|
{
|
|
if (KeyEvent->key() == Qt::Key_Control || KeyEvent->key() == Qt::Key_Shift)
|
|
{
|
|
mView->SetMouseModifiers(KeyEvent->modifiers());
|
|
mView->UpdateCursor();
|
|
}
|
|
|
|
QGLWidget::keyPressEvent(KeyEvent);
|
|
}
|
|
|
|
void lcQGLWidget::keyReleaseEvent(QKeyEvent* KeyEvent)
|
|
{
|
|
if (KeyEvent->key() == Qt::Key_Control || KeyEvent->key() == Qt::Key_Shift)
|
|
{
|
|
mView->SetMouseModifiers(KeyEvent->modifiers());
|
|
mView->UpdateCursor();
|
|
}
|
|
|
|
QGLWidget::keyReleaseEvent(KeyEvent);
|
|
}
|
|
|
|
void lcQGLWidget::mousePressEvent(QMouseEvent* MouseEvent)
|
|
{
|
|
float DeviceScale = GetDeviceScale();
|
|
|
|
mView->SetMousePosition(MouseEvent->x() * DeviceScale, mView->GetHeight() - MouseEvent->y() * DeviceScale - 1);
|
|
mView->SetMouseModifiers(MouseEvent->modifiers());
|
|
|
|
switch (MouseEvent->button())
|
|
{
|
|
case Qt::LeftButton:
|
|
mView->OnLeftButtonDown();
|
|
break;
|
|
|
|
case Qt::MidButton:
|
|
mView->OnMiddleButtonDown();
|
|
break;
|
|
|
|
case Qt::RightButton:
|
|
mView->OnRightButtonDown();
|
|
break;
|
|
|
|
#if (QT_VERSION >= QT_VERSION_CHECK(5, 0, 0))
|
|
case Qt::BackButton:
|
|
mView->OnBackButtonDown();
|
|
break;
|
|
|
|
case Qt::ForwardButton:
|
|
mView->OnForwardButtonDown();
|
|
break;
|
|
#endif
|
|
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
|
|
void lcQGLWidget::mouseReleaseEvent(QMouseEvent* MouseEvent)
|
|
{
|
|
float DeviceScale = GetDeviceScale();
|
|
|
|
mView->SetMousePosition(MouseEvent->x() * DeviceScale, mView->GetHeight() - MouseEvent->y() * DeviceScale - 1);
|
|
mView->SetMouseModifiers(MouseEvent->modifiers());
|
|
|
|
switch (MouseEvent->button())
|
|
{
|
|
case Qt::LeftButton:
|
|
mView->OnLeftButtonUp();
|
|
break;
|
|
|
|
case Qt::MidButton:
|
|
mView->OnMiddleButtonUp();
|
|
break;
|
|
|
|
case Qt::RightButton:
|
|
mView->OnRightButtonUp();
|
|
break;
|
|
|
|
#if (QT_VERSION >= QT_VERSION_CHECK(5, 0, 0))
|
|
case Qt::BackButton:
|
|
mView->OnBackButtonUp();
|
|
break;
|
|
|
|
case Qt::ForwardButton:
|
|
mView->OnForwardButtonUp();
|
|
break;
|
|
#endif
|
|
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
|
|
void lcQGLWidget::mouseDoubleClickEvent(QMouseEvent* MouseEvent)
|
|
{
|
|
float DeviceScale = GetDeviceScale();
|
|
|
|
mView->SetMousePosition(MouseEvent->x() * DeviceScale, mView->GetHeight() - MouseEvent->y() * DeviceScale - 1);
|
|
mView->SetMouseModifiers(MouseEvent->modifiers());
|
|
|
|
switch (MouseEvent->button())
|
|
{
|
|
case Qt::LeftButton:
|
|
mView->OnLeftButtonDoubleClick();
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
|
|
void lcQGLWidget::mouseMoveEvent(QMouseEvent* MouseEvent)
|
|
{
|
|
float DeviceScale = GetDeviceScale();
|
|
|
|
mView->SetMousePosition(MouseEvent->x() * DeviceScale, mView->GetHeight() - MouseEvent->y() * DeviceScale - 1);
|
|
mView->SetMouseModifiers(MouseEvent->modifiers());
|
|
|
|
mView->OnMouseMove();
|
|
}
|
|
|
|
void lcQGLWidget::wheelEvent(QWheelEvent* WheelEvent)
|
|
{
|
|
#if (QT_VERSION >= QT_VERSION_CHECK(5, 2, 0))
|
|
if (WheelEvent->angleDelta().y() == 0)
|
|
#else
|
|
if ((WheelEvent->orientation() & Qt::Vertical) == 0)
|
|
#endif
|
|
{
|
|
WheelEvent->ignore();
|
|
return;
|
|
}
|
|
|
|
float DeviceScale = GetDeviceScale();
|
|
|
|
#if (QT_VERSION >= QT_VERSION_CHECK(5, 14, 0))
|
|
mView->SetMousePosition(WheelEvent->position().x() * DeviceScale, mView->GetHeight() - WheelEvent->position().y() * DeviceScale - 1);
|
|
#else
|
|
mView->SetMousePosition(WheelEvent->x() * DeviceScale, mView->GetHeight() - WheelEvent->y() * DeviceScale - 1);
|
|
#endif
|
|
mView->SetMouseModifiers(WheelEvent->modifiers());
|
|
|
|
#if (QT_VERSION >= QT_VERSION_CHECK(5, 2, 0))
|
|
mWheelAccumulator += WheelEvent->angleDelta().y() / 8;
|
|
#else
|
|
mWheelAccumulator += WheelEvent->delta() / 8;
|
|
#endif
|
|
int numSteps = mWheelAccumulator / 15;
|
|
|
|
if (numSteps)
|
|
{
|
|
mView->OnMouseWheel(numSteps);
|
|
mWheelAccumulator -= numSteps * 15;
|
|
}
|
|
|
|
WheelEvent->accept();
|
|
}
|
|
|
|
void lcQGLWidget::dragEnterEvent(QDragEnterEvent* DragEnterEvent)
|
|
{
|
|
const QMimeData* MimeData = DragEnterEvent->mimeData();
|
|
|
|
if (MimeData->hasFormat("application/vnd.leocad-part"))
|
|
{
|
|
DragEnterEvent->acceptProposedAction();
|
|
mView->BeginDrag(lcDragState::Piece);
|
|
return;
|
|
}
|
|
else if (MimeData->hasFormat("application/vnd.leocad-color"))
|
|
{
|
|
DragEnterEvent->acceptProposedAction();
|
|
mView->BeginDrag(lcDragState::Color);
|
|
return;
|
|
}
|
|
|
|
DragEnterEvent->ignore();
|
|
}
|
|
|
|
void lcQGLWidget::dragLeaveEvent(QDragLeaveEvent* DragLeaveEvent)
|
|
{
|
|
mView->EndDrag(false);
|
|
DragLeaveEvent->accept();
|
|
}
|
|
|
|
void lcQGLWidget::dragMoveEvent(QDragMoveEvent* DragMoveEvent)
|
|
{
|
|
const QMimeData* MimeData = DragMoveEvent->mimeData();
|
|
|
|
if (MimeData->hasFormat("application/vnd.leocad-part") || MimeData->hasFormat("application/vnd.leocad-color"))
|
|
{
|
|
float DeviceScale = GetDeviceScale();
|
|
|
|
mView->SetMousePosition(DragMoveEvent->pos().x() * DeviceScale, mView->GetHeight() - DragMoveEvent->pos().y() * DeviceScale - 1);
|
|
mView->SetMouseModifiers(DragMoveEvent->keyboardModifiers());
|
|
|
|
mView->OnMouseMove();
|
|
|
|
DragMoveEvent->accept();
|
|
return;
|
|
}
|
|
|
|
QGLWidget::dragMoveEvent(DragMoveEvent);
|
|
}
|
|
|
|
void lcQGLWidget::dropEvent(QDropEvent* DropEvent)
|
|
{
|
|
const QMimeData* MimeData = DropEvent->mimeData();
|
|
|
|
if (MimeData->hasFormat("application/vnd.leocad-part") || MimeData->hasFormat("application/vnd.leocad-color"))
|
|
{
|
|
mView->EndDrag(true);
|
|
setFocus(Qt::MouseFocusReason);
|
|
|
|
DropEvent->accept();
|
|
return;
|
|
}
|
|
|
|
QGLWidget::dropEvent(DropEvent);
|
|
}
|