mirror of
https://github.com/leozide/leocad.git
synced 2026-10-27 06:20:55 +00:00
Large models can extend beyond the default far plane after fitting, leaving the view blank or clipped. Pass an explicit adjustment flag through view, model, and camera fitting, and reuse the fitted bounds to expand clipping with a margin, rounded up to multiples of 10,000. Adjust restored ordinary cameras after applying their saved state. Preserve named cameras and explicit command-line clipping planes, and avoid recalculating clipping during redraws or navigation. Route output fitting through the view and move the bounds policy definition out of the precompiled header.
372 lines
7.8 KiB
C++
372 lines
7.8 KiB
C++
#include "lc_global.h"
|
|
#include "lc_viewwidget.h"
|
|
#include "lc_glextensions.h"
|
|
#include "project.h"
|
|
#include "lc_library.h"
|
|
#include "lc_application.h"
|
|
#include "lc_mainwindow.h"
|
|
#include "lc_context.h"
|
|
#include "lc_view.h"
|
|
#include "lc_texture.h"
|
|
#include "lc_mesh.h"
|
|
#include "lc_profile.h"
|
|
#include "lc_previewwidget.h"
|
|
|
|
lcViewWidget::lcViewWidget(QWidget* Parent, lcView* View)
|
|
: QOpenGLWidget(Parent), mView(View)
|
|
{
|
|
mView->SetWidget(this);
|
|
|
|
setMouseTracking(true);
|
|
|
|
if (View->GetViewType() == lcViewType::View)
|
|
{
|
|
setFocusPolicy(Qt::StrongFocus);
|
|
setAcceptDrops(true);
|
|
}
|
|
}
|
|
|
|
lcViewWidget::~lcViewWidget()
|
|
{
|
|
}
|
|
|
|
QSize lcViewWidget::sizeHint() const
|
|
{
|
|
return mPreferredSize.isEmpty() ? QOpenGLWidget::sizeHint() : mPreferredSize;
|
|
}
|
|
|
|
lcView* lcViewWidget::GetView() const
|
|
{
|
|
return mView.get();
|
|
}
|
|
|
|
void lcViewWidget::SetView(lcView* View)
|
|
{
|
|
if (View)
|
|
{
|
|
if (context())
|
|
{
|
|
makeCurrent();
|
|
View->mContext->SetGLContext(context(), this);
|
|
}
|
|
|
|
View->SetWidget(this);
|
|
const float Scale = GetDeviceScale();
|
|
View->SetSize(width() * Scale, height() * Scale);
|
|
|
|
if (hasFocus())
|
|
View->SetFocus(true);
|
|
}
|
|
|
|
mView = std::unique_ptr<lcView>(View);
|
|
}
|
|
|
|
void lcViewWidget::UpdateMousePosition()
|
|
{
|
|
QPoint MousePosition = mapFromGlobal(QCursor::pos());
|
|
float DeviceScale = GetDeviceScale();
|
|
|
|
mView->SetMousePosition(MousePosition.x() * DeviceScale, mView->GetHeight() - MousePosition.y() * DeviceScale - 1);
|
|
mView->SetMouseModifiers(QApplication::keyboardModifiers());
|
|
}
|
|
|
|
void lcViewWidget::initializeGL()
|
|
{
|
|
mView->mContext->SetGLContext(context(), this);
|
|
}
|
|
|
|
void lcViewWidget::resizeGL(int Width, int Height)
|
|
{
|
|
const float Scale = GetDeviceScale();
|
|
|
|
mView->SetSize(Width * Scale, Height * Scale);
|
|
}
|
|
|
|
void lcViewWidget::paintGL()
|
|
{
|
|
mView->OnDraw();
|
|
}
|
|
|
|
bool lcViewWidget::event(QEvent* Event)
|
|
{
|
|
if (Event->type() == QEvent::NativeGesture)
|
|
{
|
|
QNativeGestureEvent* GestureEvent = static_cast<QNativeGestureEvent*>(Event);
|
|
|
|
switch (GestureEvent->gestureType())
|
|
{
|
|
case Qt::ZoomNativeGesture:
|
|
mView->Zoom(GestureEvent->value() * 100.0f);
|
|
break;
|
|
|
|
case Qt::SmartZoomNativeGesture:
|
|
mView->ZoomExtents(lcGeometryBoundsMode::IncludeFallback, false);
|
|
break;
|
|
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
|
|
return QOpenGLWidget::event(Event);
|
|
}
|
|
|
|
void lcViewWidget::focusInEvent(QFocusEvent* FocusEvent)
|
|
{
|
|
if (mView)
|
|
mView->SetFocus(true);
|
|
|
|
QOpenGLWidget::focusInEvent(FocusEvent);
|
|
}
|
|
|
|
void lcViewWidget::focusOutEvent(QFocusEvent* FocusEvent)
|
|
{
|
|
if (mView)
|
|
mView->SetFocus(false);
|
|
|
|
QOpenGLWidget::focusOutEvent(FocusEvent);
|
|
}
|
|
|
|
void lcViewWidget::keyPressEvent(QKeyEvent* KeyEvent)
|
|
{
|
|
if (KeyEvent->key() == Qt::Key_Control || KeyEvent->key() == Qt::Key_Shift)
|
|
{
|
|
mView->SetMouseModifiers(KeyEvent->modifiers());
|
|
mView->UpdateCursor();
|
|
}
|
|
|
|
QOpenGLWidget::keyPressEvent(KeyEvent);
|
|
}
|
|
|
|
void lcViewWidget::keyReleaseEvent(QKeyEvent* KeyEvent)
|
|
{
|
|
if (KeyEvent->key() == Qt::Key_Control || KeyEvent->key() == Qt::Key_Shift)
|
|
{
|
|
mView->SetMouseModifiers(KeyEvent->modifiers());
|
|
mView->UpdateCursor();
|
|
}
|
|
|
|
QOpenGLWidget::keyReleaseEvent(KeyEvent);
|
|
}
|
|
|
|
void lcViewWidget::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::MiddleButton:
|
|
mView->OnMiddleButtonDown();
|
|
break;
|
|
|
|
case Qt::RightButton:
|
|
mView->OnRightButtonDown();
|
|
break;
|
|
|
|
case Qt::BackButton:
|
|
mView->OnBackButtonDown();
|
|
break;
|
|
|
|
case Qt::ForwardButton:
|
|
mView->OnForwardButtonDown();
|
|
break;
|
|
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
|
|
void lcViewWidget::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::MiddleButton:
|
|
mView->OnMiddleButtonUp();
|
|
break;
|
|
|
|
case Qt::RightButton:
|
|
mView->OnRightButtonUp();
|
|
break;
|
|
|
|
case Qt::BackButton:
|
|
mView->OnBackButtonUp();
|
|
break;
|
|
|
|
case Qt::ForwardButton:
|
|
mView->OnForwardButtonUp();
|
|
break;
|
|
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
|
|
void lcViewWidget::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 lcViewWidget::mouseMoveEvent(QMouseEvent* MouseEvent)
|
|
{
|
|
float DeviceScale = GetDeviceScale();
|
|
|
|
mView->SetMousePosition(MouseEvent->x() * DeviceScale, mView->GetHeight() - MouseEvent->y() * DeviceScale - 1);
|
|
mView->SetMouseModifiers(MouseEvent->modifiers());
|
|
|
|
mView->OnMouseMove();
|
|
}
|
|
|
|
void lcViewWidget::wheelEvent(QWheelEvent* WheelEvent)
|
|
{
|
|
if (WheelEvent->source() == Qt::MouseEventSynthesizedBySystem)
|
|
{
|
|
switch (WheelEvent->phase())
|
|
{
|
|
case Qt::NoScrollPhase:
|
|
break;
|
|
|
|
case Qt::ScrollBegin:
|
|
mView->StartPanGesture();
|
|
WheelEvent->accept();
|
|
return;
|
|
|
|
case Qt::ScrollUpdate:
|
|
#if (QT_VERSION >= QT_VERSION_CHECK(5, 12, 0))
|
|
case Qt::ScrollMomentum:
|
|
#endif
|
|
mView->UpdatePanGesture(WheelEvent->pixelDelta().x(), -WheelEvent->pixelDelta().y());
|
|
WheelEvent->accept();
|
|
return;
|
|
|
|
case Qt::ScrollEnd:
|
|
mView->EndPanGesture(true);
|
|
WheelEvent->accept();
|
|
return;
|
|
}
|
|
}
|
|
|
|
if (WheelEvent->angleDelta().y() == 0)
|
|
{
|
|
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());
|
|
|
|
mWheelAccumulator += WheelEvent->angleDelta().y();
|
|
int Steps = mWheelAccumulator / 8;
|
|
|
|
if (Steps)
|
|
{
|
|
mView->OnMouseWheel(Steps / 15);
|
|
mWheelAccumulator -= Steps * 8;
|
|
}
|
|
|
|
WheelEvent->accept();
|
|
}
|
|
|
|
void lcViewWidget::leaveEvent(QEvent* Event)
|
|
{
|
|
mView->OnMouseLeave();
|
|
|
|
QOpenGLWidget::leaveEvent(Event);
|
|
}
|
|
|
|
void lcViewWidget::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 lcViewWidget::dragLeaveEvent(QDragLeaveEvent* DragLeaveEvent)
|
|
{
|
|
mView->EndDrag(false);
|
|
DragLeaveEvent->accept();
|
|
}
|
|
|
|
void lcViewWidget::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;
|
|
}
|
|
|
|
QOpenGLWidget::dragMoveEvent(DragMoveEvent);
|
|
}
|
|
|
|
void lcViewWidget::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;
|
|
}
|
|
|
|
QOpenGLWidget::dropEvent(DropEvent);
|
|
}
|