diff --git a/common/lc_application.cpp b/common/lc_application.cpp index e6ee513e..3c85c41f 100644 --- a/common/lc_application.cpp +++ b/common/lc_application.cpp @@ -9,6 +9,7 @@ #include "lc_partselectionwidget.h" #include "lc_shortcuts.h" #include "view.h" +#include "lc_previewwidget.h" lcApplication* gApplication; @@ -43,6 +44,17 @@ void lcPreferences::LoadDefaults() mAutoLoadMostRecent = lcGetProfileInt(LC_PROFILE_AUTOLOAD_MOSTRECENT); mRestoreTabLayout = lcGetProfileInt(LC_PROFILE_RESTORE_TAB_LAYOUT); mColorTheme = static_cast(lcGetProfileInt(LC_PROFILE_COLOR_THEME)); + + mPreviewActiveColor = lcGetProfileInt(LC_PROFILE_PREVIEW_ACTIVE_COLOR); + mPreviewViewSphereEnabled = lcGetProfileInt(LC_PROFILE_PREVIEW_VIEW_SPHERE_ENABLED); + mPreviewViewSphereSize = lcGetProfileInt(LC_PROFILE_PREVIEW_VIEW_SPHERE_SIZE); + mPreviewViewSphereLocation = static_cast(lcGetProfileInt(LC_PROFILE_PREVIEW_VIEW_SPHERE_LOCATION)); + mPreviewEnabled = lcGetProfileInt(LC_PROFILE_PREVIEW_ENABLED); + mPreviewSize = lcGetProfileInt(LC_PROFILE_PREVIEW_SIZE); + mPreviewLocation = static_cast(lcGetProfileInt(LC_PROFILE_PREVIEW_LOCATION)); + mPreviewPosition = static_cast(lcGetProfileInt(LC_PROFILE_PREVIEW_POSITION)); + mDrawPreviewAxis = lcGetProfileInt(LC_PROFILE_PREVIEW_DRAW_AXES); + mDrawPreviewViewSphere = lcGetProfileInt(LC_PROFILE_PREVIEW_DRAW_VIEW_SPHERE); } void lcPreferences::SaveDefaults() @@ -76,6 +88,17 @@ void lcPreferences::SaveDefaults() lcSetProfileInt(LC_PROFILE_AUTOLOAD_MOSTRECENT, mAutoLoadMostRecent); lcSetProfileInt(LC_PROFILE_RESTORE_TAB_LAYOUT, mRestoreTabLayout); lcSetProfileInt(LC_PROFILE_COLOR_THEME, static_cast(mColorTheme)); + + lcSetProfileInt(LC_PROFILE_PREVIEW_ACTIVE_COLOR, mPreviewActiveColor); + lcSetProfileInt(LC_PROFILE_PREVIEW_ENABLED, mPreviewViewSphereEnabled); + lcSetProfileInt(LC_PROFILE_PREVIEW_VIEW_SPHERE_SIZE, mPreviewViewSphereSize); + lcSetProfileInt(LC_PROFILE_PREVIEW_VIEW_SPHERE_LOCATION, static_cast(mPreviewViewSphereLocation)); + lcSetProfileInt(LC_PROFILE_PREVIEW_ENABLED, mPreviewEnabled); + lcSetProfileInt(LC_PROFILE_PREVIEW_SIZE, mPreviewSize); + lcSetProfileInt(LC_PROFILE_PREVIEW_LOCATION, static_cast(mPreviewLocation)); + lcSetProfileInt(LC_PROFILE_PREVIEW_POSITION, static_cast(mPreviewPosition)); + lcSetProfileInt(LC_PROFILE_PREVIEW_DRAW_AXES, mDrawPreviewAxis); + lcSetProfileInt(LC_PROFILE_PREVIEW_DRAW_VIEW_SPHERE, mDrawPreviewViewSphere); } void lcPreferences::SetInterfaceColors(lcColorTheme ColorTheme) @@ -220,6 +243,9 @@ void lcApplication::SetProject(Project* Project) gMainWindow->RemoveAllModelTabs(); + if (gMainWindow->GetPreviewWidget()) + gMainWindow->GetPreviewWidget()->ClearPreview(); + delete mProject; mProject = Project; @@ -779,6 +805,8 @@ void lcApplication::ShowPreferencesDialog() Options.MouseShortcutsModified = false; Options.MouseShortcutsDefault = false; + lcPreviewPosition PreviewDockable = Options.Preferences.mPreviewPosition; + lcQPreferencesDialog Dialog(gMainWindow, &Options); if (Dialog.exec() != QDialog::Accepted) return; @@ -805,6 +833,11 @@ void lcApplication::ShowPreferencesDialog() lcSetProfileInt(LC_PROFILE_ANTIALIASING_SAMPLES, Options.AASamples); lcSetProfileInt(LC_PROFILE_STUD_LOGO, Options.StudLogo); + lcPreviewPosition Dockable = Options.Preferences.mPreviewPosition; + if (PreviewDockable != Dockable) + gMainWindow->TogglePreviewWidget( + Dockable == lcPreviewPosition::Dockable); + if (LanguageChanged || LibraryChanged || ColorsChanged || AAChanged) QMessageBox::information(gMainWindow, tr("LeoCAD"), tr("Some changes will only take effect the next time you start LeoCAD.")); diff --git a/common/lc_application.h b/common/lc_application.h index 73f8e947..a640a317 100644 --- a/common/lc_application.h +++ b/common/lc_application.h @@ -21,6 +21,21 @@ enum class lcViewSphereLocation BottomRight }; +enum class lcPreviewLocation +{ + TopLeft, + TopRight, + BottomLeft, + BottomRight +}; + +enum class lcPreviewPosition +{ + Dockable, + Floating, + Viewport // not implemented +}; + enum class lcColorTheme { Dark, @@ -63,6 +78,17 @@ public: bool mAutoLoadMostRecent; bool mRestoreTabLayout; lcColorTheme mColorTheme; + + int mPreviewEnabled; + quint32 mPreviewActiveColor; + int mPreviewViewSphereEnabled; + int mPreviewViewSphereSize; + lcViewSphereLocation mPreviewViewSphereLocation; + lcPreviewLocation mPreviewLocation; + lcPreviewPosition mPreviewPosition; + int mPreviewSize; + int mDrawPreviewAxis; + int mDrawPreviewViewSphere; }; class lcApplication : public QApplication @@ -112,4 +138,3 @@ inline lcPreferences& lcGetPreferences() { return gApplication->mPreferences; } - diff --git a/common/lc_mainwindow.cpp b/common/lc_mainwindow.cpp index 31c56a5d..a9b5860a 100644 --- a/common/lc_mainwindow.cpp +++ b/common/lc_mainwindow.cpp @@ -24,6 +24,8 @@ #include "lc_library.h" #include "lc_colors.h" +#include "lc_previewwidget.h" + #if LC_ENABLE_GAMEPAD #include #endif @@ -105,6 +107,7 @@ lcMainWindow::lcMainWindow() mCurrentPieceInfo = nullptr; mSelectionMode = lcSelectionMode::Single; mModelTabWidget = nullptr; + mPreviewToolBar = nullptr; memset(&mSearchOptions, 0, sizeof(mSearchOptions)); @@ -163,8 +166,8 @@ void lcMainWindow::CreateWidgets() connect(mModelTabWidget->tabBar(), SIGNAL(tabCloseRequested(int)), this, SLOT(ModelTabClosed(int))); connect(mModelTabWidget->tabBar(), SIGNAL(customContextMenuRequested(const QPoint&)), this, SLOT(ModelTabContextMenuRequested(const QPoint&))); #else - mModelTabWidget->setMovable(true); - mModelTabWidget->setTabsClosable(true); + mModelTabWidget->setMovable(true); + mModelTabWidget->setTabsClosable(true); connect(mModelTabWidget, SIGNAL(tabCloseRequested(int)), this, SLOT(ModelTabClosed(int))); #endif setCentralWidget(mModelTabWidget); @@ -746,11 +749,71 @@ void lcMainWindow::CreateToolBars() mTimelineToolBar->setWidget(mTimelineWidget); addDockWidget(Qt::RightDockWidgetArea, mTimelineToolBar); + // Preview + const lcPreferences& Preferences = lcGetPreferences(); + if (Preferences.mPreviewPosition == lcPreviewPosition::Dockable) + CreatePreviewWidget(); + tabifyDockWidget(mPartsToolBar, mPropertiesToolBar); tabifyDockWidget(mPropertiesToolBar, mTimelineToolBar); + + connect(mPropertiesToolBar, SIGNAL (topLevelChanged(bool)), this, SLOT (EnableWindowFlags(bool))); + connect(mTimelineToolBar, SIGNAL (topLevelChanged(bool)), this, SLOT (EnableWindowFlags(bool))); + connect(mPartsToolBar, SIGNAL (topLevelChanged(bool)), this, SLOT (EnableWindowFlags(bool))); + connect(mColorsToolBar, SIGNAL (topLevelChanged(bool)), this, SLOT (EnableWindowFlags(bool))); + mPartsToolBar->raise(); } +void lcMainWindow::PreviewPiece(const QString &PartType, int ColorCode) +{ + if (mPreviewWidget) { + if (!mPreviewWidget->SetCurrentPiece(PartType, ColorCode)) + QMessageBox::critical(gMainWindow, tr("Error"), tr("Part preview for % failed.").arg(PartType)); + } +} + +void lcMainWindow::CreatePreviewWidget() +{ + mPreviewWidget = new lcPreviewDockWidget(); + + mPreviewToolBar = new QDockWidget(tr("Preview"), this); + mPreviewToolBar->setWindowTitle(trUtf8("Preview")); + mPreviewToolBar->setObjectName("PreviewToolBarw"); + mPreviewToolBar->setAllowedAreas(Qt::LeftDockWidgetArea | Qt::RightDockWidgetArea); + mPreviewToolBar->setWidget(mPreviewWidget); + addDockWidget(Qt::RightDockWidgetArea, mPreviewToolBar); + + tabifyDockWidget(mTimelineToolBar, mPreviewToolBar); + + connect(mPreviewToolBar, SIGNAL (topLevelChanged(bool)), this, SLOT (EnableWindowFlags(bool))); +} + +void lcMainWindow::TogglePreviewWidget(bool visible) +{ + if (mPreviewToolBar) { + if (visible) + mPreviewToolBar->show(); + else + mPreviewToolBar->hide(); + } else if (visible) { + CreatePreviewWidget(); + } +} + +void lcMainWindow::EnableWindowFlags(bool Detached) +{ + if (Detached) { + QDockWidget *DockWidget = qobject_cast(sender()); + DockWidget->setWindowFlags(Qt::CustomizeWindowHint | + Qt::Window | + Qt::WindowMinimizeButtonHint | + Qt::WindowMaximizeButtonHint | + Qt::WindowCloseButtonHint); + DockWidget->show(); + } +} + class lcElidedLabel : public QFrame { public: diff --git a/common/lc_mainwindow.h b/common/lc_mainwindow.h index 34febd67..cf86d964 100644 --- a/common/lc_mainwindow.h +++ b/common/lc_mainwindow.h @@ -7,6 +7,7 @@ class View; class lcPartSelectionWidget; +class lcPreviewDockWidget; class PiecePreview; class lcQGLWidget; class lcQPartsTree; @@ -246,6 +247,11 @@ public: return mPartSelectionWidget; } + lcPreviewDockWidget* GetPreviewWidget() const + { + return mPreviewWidget; + } + QMenu* GetToolsMenu() const { return mToolsMenu; @@ -352,6 +358,8 @@ public: public slots: void ProjectFileChanged(const QString& Path); + void PreviewPiece(const QString &, int); + void TogglePreviewWidget(bool); protected slots: void UpdateDockWidgetActions(); @@ -364,6 +372,7 @@ protected slots: void ActionTriggered(); void ColorChanged(int ColorIndex); void Print(QPrinter* Printer); + void EnableWindowFlags(bool); protected: void closeEvent(QCloseEvent *event) override; @@ -384,6 +393,7 @@ protected: void ShowRenderDialog(); void ShowInstructionsDialog(); void ShowPrintDialog(); + void CreatePreviewWidget(); bool OpenProjectFile(const QString& FileName); @@ -423,6 +433,7 @@ protected: QToolBar* mStandardToolBar; QToolBar* mToolsToolBar; QToolBar* mTimeToolBar; + QDockWidget* mPreviewToolBar; QDockWidget* mPartsToolBar; QDockWidget* mColorsToolBar; QDockWidget* mPropertiesToolBar; @@ -435,6 +446,7 @@ protected: QLineEdit* mTransformXEdit; QLineEdit* mTransformYEdit; QLineEdit* mTransformZEdit; + lcPreviewDockWidget* mPreviewWidget; lcElidedLabel* mStatusBarLabel; QLabel* mStatusPositionLabel; diff --git a/common/lc_model.cpp b/common/lc_model.cpp index b3c1976f..b9120239 100644 --- a/common/lc_model.cpp +++ b/common/lc_model.cpp @@ -23,6 +23,7 @@ #include "lc_qpropertiesdialog.h" #include "lc_qutils.h" #include "lc_lxf.h" +#include "lc_previewwidget.h" #if (QT_VERSION >= QT_VERSION_CHECK(5, 0, 0)) #include #endif @@ -180,7 +181,8 @@ void lcModelProperties::ParseLDrawLine(QTextStream& Stream) } } -lcModel::lcModel(const QString& FileName) +lcModel::lcModel(const QString& FileName, bool Preview) + : mIsPreview(Preview) { mProperties.mModelName = FileName; mProperties.mFileName = FileName; @@ -196,7 +198,7 @@ lcModel::~lcModel() { if (mPieceInfo) { - if (gMainWindow && gMainWindow->GetCurrentPieceInfo() == mPieceInfo) + if (!mIsPreview && gMainWindow && gMainWindow->GetCurrentPieceInfo() == mPieceInfo) gMainWindow->SetCurrentPieceInfo(nullptr); if (mPieceInfo->GetModel() == this) @@ -264,7 +266,13 @@ void lcModel::DeleteModel() lcReleaseTexture(mBackgroundTexture); mBackgroundTexture = nullptr; - if (gMainWindow) + if (mIsPreview && gPreviewWidget) { + lcCamera* Camera = gPreviewWidget->GetCamera(); + + if (Camera && !Camera->IsSimple() && mCameras.FindIndex(Camera) != -1) + gPreviewWidget->SetCamera(Camera); + } + else if (gMainWindow) { const lcArray* Views = gMainWindow->GetViewsForModel(this); @@ -1819,6 +1827,10 @@ void lcModel::SubModelCompareBoundingBox(const lcMatrix44& WorldMatrix, lcVector void lcModel::SaveCheckpoint(const QString& Description) { + if (mIsPreview) { + return; + } + lcModelHistoryEntry* ModelHistoryEntry = new lcModelHistoryEntry(); ModelHistoryEntry->Description = Description; @@ -1840,6 +1852,10 @@ void lcModel::SaveCheckpoint(const QString& Description) void lcModel::LoadCheckPoint(lcModelHistoryEntry* CheckPoint) { + if (mIsPreview) { + return; + } + lcPiecesLibrary* Library = lcGetPiecesLibrary(); std::vector LoadedInfos; @@ -2424,10 +2440,12 @@ void lcModel::DeleteSelectedObjects() { if (RemoveSelectedObjects()) { - gMainWindow->UpdateTimeline(false, false); - gMainWindow->UpdateSelectedObjects(true); - gMainWindow->UpdateAllViews(); - SaveCheckpoint(tr("Deleting")); + if (!mIsPreview) { + gMainWindow->UpdateTimeline(false, false); + gMainWindow->UpdateSelectedObjects(true); + gMainWindow->UpdateAllViews(); + SaveCheckpoint(tr("Deleting")); + } } } @@ -3861,8 +3879,10 @@ void lcModel::SelectAllPieces() if (Piece->IsVisible(mCurrentStep)) Piece->SetSelected(true); - gMainWindow->UpdateSelectedObjects(true); - gMainWindow->UpdateAllViews(); + if (!mIsPreview) { + gMainWindow->UpdateSelectedObjects(true); + gMainWindow->UpdateAllViews(); + } } void lcModel::InvertSelection() @@ -4026,7 +4046,8 @@ void lcModel::FindPiece(bool FindFirst, bool SearchForward) void lcModel::UndoAction() { - if (mUndoHistory.size() < 2) + + if (mIsPreview || mUndoHistory.size() < 2) return; lcModelHistoryEntry* Undo = mUndoHistory.front(); @@ -4041,7 +4062,7 @@ void lcModel::UndoAction() void lcModel::RedoAction() { - if (mRedoHistory.empty()) + if (mIsPreview || mRedoHistory.empty()) return; lcModelHistoryEntry* Redo = mRedoHistory.front(); @@ -4061,7 +4082,7 @@ void lcModel::BeginMouseTool() void lcModel::EndMouseTool(lcTool Tool, bool Accept) { - if (!Accept) + if (!Accept && !mIsPreview) { LoadCheckPoint(mUndoHistory[0]); return; @@ -4078,7 +4099,8 @@ void lcModel::EndMouseTool(lcTool Tool, bool Accept) break; case LC_TOOL_CAMERA: - gMainWindow->UpdateCameraMenu(); + if (!mIsPreview) + gMainWindow->UpdateCameraMenu(); SaveCheckpoint(tr("New Camera")); break; @@ -4099,22 +4121,22 @@ void lcModel::EndMouseTool(lcTool Tool, bool Accept) break; case LC_TOOL_ZOOM: - if (!gMainWindow->GetActiveView()->mCamera->IsSimple()) + if (!mIsPreview && !gMainWindow->GetActiveView()->mCamera->IsSimple()) SaveCheckpoint(tr("Zoom")); break; case LC_TOOL_PAN: - if (!gMainWindow->GetActiveView()->mCamera->IsSimple()) + if (!mIsPreview && !gMainWindow->GetActiveView()->mCamera->IsSimple()) SaveCheckpoint(tr("Pan")); break; case LC_TOOL_ROTATE_VIEW: - if (!gMainWindow->GetActiveView()->mCamera->IsSimple()) + if (!mIsPreview && !gMainWindow->GetActiveView()->mCamera->IsSimple()) SaveCheckpoint(tr("Orbit")); break; case LC_TOOL_ROLL: - if (!gMainWindow->GetActiveView()->mCamera->IsSimple()) + if (!mIsPreview && !gMainWindow->GetActiveView()->mCamera->IsSimple()) SaveCheckpoint(tr("Roll")); break; @@ -4308,7 +4330,8 @@ void lcModel::UpdatePanTool(lcCamera* Camera, const lcVector3& Distance) { Camera->Pan(Distance - mMouseToolDistance, mCurrentStep, gMainWindow->GetAddKeys()); mMouseToolDistance = Distance; - gMainWindow->UpdateAllViews(); + if (!mIsPreview) + gMainWindow->UpdateAllViews(); } void lcModel::UpdateOrbitTool(lcCamera* Camera, float MouseX, float MouseY) @@ -4318,7 +4341,8 @@ void lcModel::UpdateOrbitTool(lcCamera* Camera, float MouseX, float MouseY) Camera->Orbit(MouseX - mMouseToolDistance.x, MouseY - mMouseToolDistance.y, Center, mCurrentStep, gMainWindow->GetAddKeys()); mMouseToolDistance.x = MouseX; mMouseToolDistance.y = MouseY; - gMainWindow->UpdateAllViews(); + if (!mIsPreview) + gMainWindow->UpdateAllViews(); } void lcModel::UpdateRollTool(lcCamera* Camera, float Mouse) @@ -4384,10 +4408,12 @@ void lcModel::ZoomExtents(lcCamera* Camera, float Aspect) lcVector3 Points[8]; lcGetBoxCorners(Min, Max, Points); - Camera->ZoomExtents(Aspect, Center, Points, 8, mCurrentStep, gMainWindow->GetAddKeys()); + Camera->ZoomExtents(Aspect, Center, Points, 8, mCurrentStep, mIsPreview ? false : gMainWindow->GetAddKeys()); - gMainWindow->UpdateSelectedObjects(false); - gMainWindow->UpdateAllViews(); + if (!mIsPreview) { + gMainWindow->UpdateSelectedObjects(false); + gMainWindow->UpdateAllViews(); + } if (!Camera->IsSimple()) SaveCheckpoint(tr("Zoom")); @@ -4395,10 +4421,11 @@ void lcModel::ZoomExtents(lcCamera* Camera, float Aspect) void lcModel::Zoom(lcCamera* Camera, float Amount) { - Camera->Zoom(Amount, mCurrentStep, gMainWindow->GetAddKeys()); - gMainWindow->UpdateSelectedObjects(false); - gMainWindow->UpdateAllViews(); - + Camera->Zoom(Amount, mCurrentStep, mIsPreview ? false : gMainWindow->GetAddKeys()); + if (!mIsPreview) { + gMainWindow->UpdateSelectedObjects(false); + gMainWindow->UpdateAllViews(); + } if (!Camera->IsSimple()) SaveCheckpoint(tr("Zoom")); } diff --git a/common/lc_model.h b/common/lc_model.h index 42902074..8d0c8a3f 100644 --- a/common/lc_model.h +++ b/common/lc_model.h @@ -103,7 +103,7 @@ struct lcModelHistoryEntry class lcModel { public: - lcModel(const QString& FileName); + lcModel(const QString& FileName, bool Preview = false); ~lcModel(); lcModel(const lcModel&) = delete; @@ -116,6 +116,11 @@ public: return mSavedHistory != mUndoHistory[0]; } + bool IsPreview() + { + return mIsPreview; + } + bool GetPieceWorldMatrix(lcPiece* Piece, lcMatrix44& ParentWorldMatrix) const; bool IncludesModel(const lcModel* Model) const; void CreatePieceInfo(Project* Project); @@ -234,7 +239,13 @@ public: if (mUndoHistory.empty()) SaveCheckpoint(QString()); - mSavedHistory = mUndoHistory[0]; + if (!mIsPreview) + mSavedHistory = mUndoHistory[0]; + } + + void SetPreviewPiece(lcPiece* Piece) + { + AddPiece(Piece); } void Cut(); @@ -379,6 +390,7 @@ protected: lcModelProperties mProperties; PieceInfo* mPieceInfo; + bool mIsPreview; bool mActive; lcStep mCurrentStep; lcVector3 mMouseToolDistance; diff --git a/common/lc_partselectionwidget.cpp b/common/lc_partselectionwidget.cpp index 85dc8430..ab830fdc 100644 --- a/common/lc_partselectionwidget.cpp +++ b/common/lc_partselectionwidget.cpp @@ -11,6 +11,9 @@ #include "view.h" #include "lc_glextensions.h" +#include "lc_qglwidget.h" +#include "lc_previewwidget.h" + Q_DECLARE_METATYPE(QList) void lcPartSelectionItemDelegate::paint(QPainter* Painter, const QStyleOptionViewItem& Option, const QModelIndex& Index) const @@ -412,7 +415,7 @@ void lcPartSelectionListModel::DrawPreview(int InfoIndex) glClearColor(1.0f, 1.0f, 1.0f, 0.0f); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); - + lcMatrix44 ProjectionMatrix, ViewMatrix; Info->ZoomExtents(20.0f, Aspect, ProjectionMatrix, ViewMatrix); @@ -572,9 +575,9 @@ void lcPartSelectionListView::SetCategory(lcPartCategoryType Type, int Index) case lcPartCategoryType::Category: mListModel->SetCategory(Index); break; - case lcPartCategoryType::Count: - break; - } + case lcPartCategoryType::Count: + break; + } setCurrentIndex(mListModel->index(0, 0)); } @@ -680,6 +683,91 @@ void lcPartSelectionListView::startDrag(Qt::DropActions SupportedActions) Drag->exec(Qt::CopyAction); } +void lcPartSelectionListView::mouseDoubleClickEvent(QMouseEvent *event) +{ + QAbstractItemView::mouseDoubleClickEvent(event); + if ( event->button() == Qt::LeftButton ) { + PreviewSelection(currentIndex().row()); + } +} + +void lcPartSelectionListView::PreviewSelection(int InfoIndex) +{ + PieceInfo* Info = mListModel->GetPieceInfo(InfoIndex); + if (!Info) + return; + + bool IsSubfile = Info->IsModel(); + QString PartType = Info->mFileName; + quint32 ColorCode = IsSubfile ? 16 : lcGetColorCode(mListModel->GetColorIndex()); + const lcPreferences& Preferences = lcGetPreferences(); + + if (Preferences.mPreviewPosition != lcPreviewPosition::Floating) { + emit gMainWindow->PreviewPiece(PartType, ColorCode); + return; + } + + if (!Preferences.mPreviewEnabled) + return; + + QString TypeLabel = IsSubfile ? "Submodel" : "Part"; + QString WindowTitle = QString("%1 Preview").arg(TypeLabel); + + lcPreviewWidget *Preview = new lcPreviewWidget(); + + lcQGLWidget *ViewWidget = new lcQGLWidget(nullptr, Preview, true/*isView*/, true/*isPreview*/); + + if (Preview && ViewWidget) { + if (!Preview->SetCurrentPiece(PartType, ColorCode)) + QMessageBox::critical(gMainWindow, tr("Error"), tr("Preview %1 failed.").arg(Info->mFileName)); + + ViewWidget->setWindowTitle(WindowTitle); + int Size[2] = { 300,200 }; + if (Preferences.mPreviewSize == 400) { + Size[0] = 400; Size[1] = 300; + } + ViewWidget->preferredSize = QSize(Size[0], Size[1]); + float Scale = ViewWidget->deviceScale(); + Preview->mWidth = ViewWidget->width() * Scale; + Preview->mHeight = ViewWidget->height() * Scale; + + const QRect desktop = QApplication::desktop()->geometry(); + + QPoint pos; + switch (Preferences.mPreviewLocation) + { + case lcPreviewLocation::TopRight: + pos = mapToGlobal(rect().topRight()); + break; + case lcPreviewLocation::TopLeft: + pos = mapToGlobal(rect().topLeft()); + break; + case lcPreviewLocation::BottomRight: + pos = mapToGlobal(rect().bottomRight()); + break; + default: + pos = mapToGlobal(rect().bottomLeft()); + break; + } + if (pos.x() < desktop.left()) + pos.setX(desktop.left()); + if (pos.y() < desktop.top()) + pos.setY(desktop.top()); + + if ((pos.x() + ViewWidget->width()) > desktop.width()) + pos.setX(desktop.width() - ViewWidget->width()); + if ((pos.y() + ViewWidget->height()) > desktop.bottom()) + pos.setY(desktop.bottom() - ViewWidget->height()); + ViewWidget->move(pos); + + ViewWidget->setMinimumSize(100,100); + ViewWidget->show(); + ViewWidget->setFocus(); + } else { + QMessageBox::critical(gMainWindow, tr("Error"), tr("Preview %1 failed.").arg(Info->mFileName)); + } +} + lcPartSelectionWidget::lcPartSelectionWidget(QWidget* Parent) : QWidget(Parent), mFilterAction(nullptr) { diff --git a/common/lc_partselectionwidget.h b/common/lc_partselectionwidget.h index 83eae960..9997bdd9 100644 --- a/common/lc_partselectionwidget.h +++ b/common/lc_partselectionwidget.h @@ -88,6 +88,11 @@ public: return mShowPartNames; } + int GetColorIndex() const + { + return mColorIndex; + } + bool IsColorLocked() const { return mColorLocked; @@ -182,6 +187,8 @@ public slots: protected: void SetIconSize(int Size); + void PreviewSelection(int InfoIndex); + void mouseDoubleClickEvent(QMouseEvent *event) override; lcPartSelectionListModel* mListModel; lcPartSelectionWidget* mPartSelectionWidget; diff --git a/common/lc_previewwidget.cpp b/common/lc_previewwidget.cpp new file mode 100644 index 00000000..a37ea77d --- /dev/null +++ b/common/lc_previewwidget.cpp @@ -0,0 +1,637 @@ +#include "QMessageBox" +#include "lc_global.h" +#include "lc_previewwidget.h" +#include "pieceinf.h" +#include "piece.h" +#include "project.h" +#include "lc_model.h" +#include "camera.h" +#include "texfont.h" +#include "lc_library.h" + +#include "lc_qglwidget.h" + +lcPreviewWidget* gPreviewWidget; + +lcPreviewDockWidget::lcPreviewDockWidget(QMainWindow *parent) + :QMainWindow(parent) +{ + Preview = new lcPreviewWidget(); + ViewWidget = new lcQGLWidget(nullptr, Preview, true/*IsView*/, true/*IsPreview*/); + setCentralWidget(ViewWidget); + setMinimumSize(200, 200); + ToolBar = addToolBar(tr("PreviewDescription")); + ToolBar->setObjectName("PreviewDescription"); + ToolBar->setMovable(false); + Label = new QLabel(""); + ToolBar->addWidget(Label); +} + +bool lcPreviewDockWidget::SetCurrentPiece(const QString &PartType, int ColorCode) +{ + Label->setText("Loading..."); + if (Preview->SetCurrentPiece(PartType, ColorCode)) { + Label->setText(Preview->GetDescription()); + return true; + } + return false; +} + +void lcPreviewDockWidget::ClearPreview() +{ + Preview->ClearPreview(); + Label->setText(""); +} + +lcPreviewWidget::lcPreviewWidget() +: mLoader(new Project(true/*IsPreview*/)), + mViewSphere(this/*Preview*/), + mIsPart(false) +{ + mTool = LC_TOOL_SELECT; + mTrackTool = LC_TRACKTOOL_NONE; + mTrackButton = lcTrackButton::None; + + mLoader->SetActiveModel(0); + mModel = mLoader->GetActiveModel(); + mCamera = nullptr; + + SetDefaultCamera(); +} + +lcPreviewWidget::~lcPreviewWidget() +{ + if (mCamera && mCamera->IsSimple()) + delete mCamera; + + if (mIsPart) { + lcPiecesLibrary* Library = lcGetPiecesLibrary(); + for (lcPiece* Piece : mModel->GetPieces()) + { + PieceInfo *Info = Piece->mPieceInfo; + Library->ReleasePieceInfo(Info); + } + } +} + +bool lcPreviewWidget::SetCurrentPiece(const QString &PartType, int ColorCode) +{ + lcPiecesLibrary *Library = lcGetPiecesLibrary(); + PieceInfo* Info = Library->FindPiece(PartType.toLatin1().constData(), nullptr, false, false); + if (Info) { + mIsPart = true; + mDescription = Info->m_strDescription; + lcModel* ActiveModel = GetActiveModel(); + + ActiveModel->SelectAllPieces(); + ActiveModel->DeleteSelectedObjects(); + + Library->LoadPieceInfo(Info, false, true); + Library->WaitForLoadQueue(); + + float* Matrix = lcMatrix44Identity();; + lcMatrix44 Transform(lcVector4( Matrix[0], Matrix[2], -Matrix[1], 0.0f), lcVector4(Matrix[8], Matrix[10], -Matrix[9], 0.0f), + lcVector4(-Matrix[4], -Matrix[6], Matrix[5], 0.0f), lcVector4(Matrix[12], Matrix[14], -Matrix[13], 1.0f)); + + int CurrentStep = 1; + lcPiece* Piece = new lcPiece(nullptr); + + Piece->SetPieceInfo(Info, PartType, false); + Piece->Initialize(Transform, CurrentStep); + Piece->SetColorCode(ColorCode); + + ActiveModel->SetPreviewPiece(Piece); + + Piece = nullptr; + } else { + QString ModelPath = QString("%1/%2") + .arg(QDir::currentPath()) + .arg(PartType); + + if (!mLoader->Load(ModelPath)) { + QMessageBox::critical(nullptr, QMessageBox::tr("Error"), QMessageBox::tr("Failed to load '%1'.").arg(ModelPath)); + return false; + } + + mLoader->SetActiveModel(0); + lcGetPiecesLibrary()->RemoveTemporaryPieces(); + mModel = mLoader->GetActiveModel(); + if (!mModel->GetProperties().mDescription.isEmpty()) + mDescription = mModel->GetProperties().mDescription; + else + mDescription = PartType; + } + ZoomExtents(); + + return true; +} + +void lcPreviewWidget::ClearPreview() +{ + mLoader = new Project(true/*IsPreview*/); + mLoader->SetActiveModel(0); + mModel = mLoader->GetActiveModel(); + lcGetPiecesLibrary()->UnloadUnusedParts(); + Redraw(); +} + +void lcPreviewWidget::SetDefaultCamera() +{ + if (!mCamera || !mCamera->IsSimple()) + mCamera = new lcCamera(true); + mCamera->SetViewpoint(LC_VIEWPOINT_HOME); +} + +void lcPreviewWidget::SetCamera(lcCamera* Camera) // called by lcModel::DeleteModel() +{ + if (!mCamera || !mCamera->IsSimple()) + mCamera = new lcCamera(true); + + mCamera->CopyPosition(Camera); +} + +lcModel* lcPreviewWidget::GetActiveModel() const +{ + return mModel; +} + +void lcPreviewWidget::ZoomExtents() +{ + lcModel* ActiveModel = GetActiveModel(); + if (ActiveModel) { + ActiveModel->ZoomExtents(mCamera, float(mWidth) / float(mHeight)); + Redraw(); + } +} + +lcMatrix44 lcPreviewWidget::GetProjectionMatrix() const +{ + float AspectRatio = (float)mWidth / (float)mHeight; + + if (mCamera->IsOrtho()) + { + float OrthoHeight = mCamera->GetOrthoHeight() / 2.0f; + float OrthoWidth = OrthoHeight * AspectRatio; + + return lcMatrix44Ortho(-OrthoWidth, OrthoWidth, -OrthoHeight, OrthoHeight, mCamera->m_zNear, mCamera->m_zFar * 4); + } + else + return lcMatrix44Perspective(mCamera->m_fovy, AspectRatio, mCamera->m_zNear, mCamera->m_zFar); +} + +void lcPreviewWidget::StartOrbitTracking() // called by viewSphere +{ + mTrackTool = LC_TRACKTOOL_ORBIT_XY; + + OnUpdateCursor(); + + OnButtonDown(lcTrackButton::Left); +} + +void lcPreviewWidget::SetViewpoint(const lcVector3& Position) +{ + if (!mCamera || !mCamera->IsSimple()) + { + lcCamera* OldCamera = mCamera; + + mCamera = new lcCamera(true); + + if (OldCamera) + mCamera->CopySettings(OldCamera); + } + + mCamera->SetViewpoint(Position); + + Redraw(); +} + +void lcPreviewWidget::DrawViewport() +{ + mContext->SetWorldMatrix(lcMatrix44Identity()); + mContext->SetViewMatrix(lcMatrix44Translation(lcVector3(0.375, 0.375, 0.0))); + mContext->SetProjectionMatrix(lcMatrix44Ortho(0.0f, mWidth, 0.0f, mHeight, -1.0f, 1.0f)); + + mContext->SetDepthWrite(false); + glDisable(GL_DEPTH_TEST); + + if (true/*we have an active view*/) + { + mContext->SetMaterial(lcMaterialType::UnlitColor); + mContext->SetColor(lcVector4FromColor(lcGetPreferences().mPreviewActiveColor)); + float Verts[8] = { 0.0f, 0.0f, mWidth - 1.0f, 0.0f, mWidth - 1.0f, mHeight - 1.0f, 0.0f, mHeight - 1.0f }; + + mContext->SetVertexBufferPointer(Verts); + mContext->SetVertexFormatPosition(2); + mContext->DrawPrimitives(GL_LINE_LOOP, 0, 4); + } + + mContext->SetDepthWrite(true); + glEnable(GL_DEPTH_TEST); +} + +void lcPreviewWidget::DrawAxes() +{ +// glClear(GL_DEPTH_BUFFER_BIT); + + const float Verts[28 * 3] = + { + 0.00f, 0.00f, 0.00f, 20.00f, 0.00f, 0.00f, 12.00f, 3.00f, 0.00f, 12.00f, 2.12f, 2.12f, + 12.00f, 0.00f, 3.00f, 12.00f, -2.12f, 2.12f, 12.00f, -3.00f, 0.00f, 12.00f, -2.12f, -2.12f, + 12.00f, 0.00f, -3.00f, 12.00f, 2.12f, -2.12f, 0.00f, 20.00f, 0.00f, 3.00f, 12.00f, 0.00f, + 2.12f, 12.00f, 2.12f, 0.00f, 12.00f, 3.00f, -2.12f, 12.00f, 2.12f, -3.00f, 12.00f, 0.00f, + -2.12f, 12.00f, -2.12f, 0.00f, 12.00f, -3.00f, 2.12f, 12.00f, -2.12f, 0.00f, 0.00f, 20.00f, + 0.00f, 3.00f, 12.00f, 2.12f, 2.12f, 12.00f, 3.00f, 0.00f, 12.00f, 2.12f, -2.12f, 12.00f, + 0.00f, -3.00f, 12.00f, -2.12f, -2.12f, 12.00f, -3.00f, 0.00f, 12.00f, -2.12f, 2.12f, 12.00f, + }; + + const GLushort Indices[78] = + { + 0, 1, 0, 10, 0, 19, + 1, 2, 3, 1, 3, 4, 1, 4, 5, 1, 5, 6, 1, 6, 7, 1, 7, 8, 1, 8, 9, 1, 9, 2, + 10, 11, 12, 10, 12, 13, 10, 13, 14, 10, 14, 15, 10, 15, 16, 10, 16, 17, 10, 17, 18, 10, 18, 11, + 19, 20, 21, 19, 21, 22, 19, 22, 23, 19, 23, 24, 19, 24, 25, 19, 25, 26, 19, 26, 27, 19, 27, 20 + }; + + lcMatrix44 TranslationMatrix = lcMatrix44Translation(lcVector3(30.375f, 30.375f, 0.0f)); + lcMatrix44 WorldViewMatrix = mCamera->mWorldView; + WorldViewMatrix.SetTranslation(lcVector3(0, 0, 0)); + + mContext->SetMaterial(lcMaterialType::UnlitColor); + mContext->SetWorldMatrix(lcMatrix44Identity()); + mContext->SetViewMatrix(lcMul(WorldViewMatrix, TranslationMatrix)); + mContext->SetProjectionMatrix(lcMatrix44Ortho(0, mWidth, 0, mHeight, -50, 50)); + + mContext->SetVertexBufferPointer(Verts); + mContext->SetVertexFormatPosition(3); + mContext->SetIndexBufferPointer(Indices); + + mContext->SetColor(0.0f, 0.0f, 0.0f, 1.0f); + mContext->DrawIndexedPrimitives(GL_LINES, 6, GL_UNSIGNED_SHORT, 0); + + mContext->SetColor(0.8f, 0.0f, 0.0f, 1.0f); + mContext->DrawIndexedPrimitives(GL_TRIANGLES, 24, GL_UNSIGNED_SHORT, 6 * 2); + mContext->SetColor(0.0f, 0.8f, 0.0f, 1.0f); + mContext->DrawIndexedPrimitives(GL_TRIANGLES, 24, GL_UNSIGNED_SHORT, (6 + 24) * 2); + mContext->SetColor(0.0f, 0.0f, 0.8f, 1.0f); + mContext->DrawIndexedPrimitives(GL_TRIANGLES, 24, GL_UNSIGNED_SHORT, (6 + 48) * 2); + + mContext->SetMaterial(lcMaterialType::UnlitTextureModulate); + mContext->SetViewMatrix(TranslationMatrix); + mContext->BindTexture2D(gTexFont.GetTexture()); + glEnable(GL_BLEND); + + float TextBuffer[6 * 5 * 3]; +/*** Native viewer camera globe mod, switch Y and Z axis with -Y(LC -Z) in the up direction ***/ + lcVector3 PosX = lcMul30(lcVector3(25.0f, 0.0f, 0.0f), WorldViewMatrix); + gTexFont.GetGlyphTriangles(PosX.x, PosX.y, PosX.z, 'X', TextBuffer); + lcVector3 PosY = lcMul30(lcVector3(0.0f, 25.0f, 0.0f), WorldViewMatrix); + gTexFont.GetGlyphTriangles(PosY.x, PosY.y, PosY.z, 'Z', TextBuffer + 5 * 6); + lcVector3 PosZ = lcMul30(lcVector3(0.0f, 0.0f, 25.0f), WorldViewMatrix); + gTexFont.GetGlyphTriangles(PosZ.x, PosZ.y, PosZ.z, 'Y', TextBuffer + 5 * 6 * 2); +/*** Camera globe mod end ***/ + + mContext->SetVertexBufferPointer(TextBuffer); + mContext->SetVertexFormat(0, 3, 0, 2, 0, false); + + mContext->SetColor(lcVector4FromColor(lcGetPreferences().mAxesColor)); + mContext->DrawPrimitives(GL_TRIANGLES, 0, 6 * 3); + + glDisable(GL_BLEND); +} + +lcTool lcPreviewWidget::GetCurrentTool() const +{ + const lcTool ToolFromTrackTool[] = + { + LC_TOOL_SELECT, // LC_TRACKTOOL_NONE + LC_TOOL_PAN, // LC_TRACKTOOL_PAN + LC_TOOL_ROTATE_VIEW, // LC_TRACKTOOL_ORBIT_XY + }; + + return ToolFromTrackTool[mTrackTool]; +} + +void lcPreviewWidget::StartTracking(lcTrackButton TrackButton) +{ + mTrackButton = TrackButton; + mTrackUpdated = false; + mMouseDownX = mInputState.x; + mMouseDownY = mInputState.y; + lcTool Tool = GetCurrentTool(); // Either LC_TRACKTOOL_NONE (LC_TOOL_SELECT) or LC_TRACKTOOL_ORBIT_XY (LC_TOOL_ROTATE_VIEW) + lcModel* ActiveModel = GetActiveModel(); + + switch (Tool) + { + case LC_TOOL_SELECT: + break; + + case LC_TOOL_PAN: + case LC_TOOL_ROTATE_VIEW: + ActiveModel->BeginMouseTool(); + break; + + case LC_NUM_TOOLS: + default: + break; + } + + OnUpdateCursor(); +} + +void lcPreviewWidget::StopTracking(bool Accept) +{ + if (mTrackButton == lcTrackButton::None) + return; + + lcTool Tool = GetCurrentTool(); // Either LC_TRACKTOOL_NONE (LC_TOOL_SELECT) or LC_TRACKTOOL_ORBIT_XY (LC_TOOL_ROTATE_VIEW) + lcModel* ActiveModel = GetActiveModel(); + + switch (Tool) + { + case LC_TOOL_SELECT: + break; + + case LC_TOOL_PAN: + case LC_TOOL_ROTATE_VIEW: + ActiveModel->EndMouseTool(Tool, Accept); + break; + + case LC_NUM_TOOLS: + default: + break; + } + + mTrackButton = lcTrackButton::None; + + mTrackTool = LC_TRACKTOOL_NONE; + + OnUpdateCursor(); +} + +void lcPreviewWidget::OnButtonDown(lcTrackButton TrackButton) +{ + switch (mTrackTool) + { + case LC_TRACKTOOL_NONE: + break; + + case LC_TRACKTOOL_PAN: + StartTracking(TrackButton); + break; + + case LC_TRACKTOOL_ORBIT_XY: + StartTracking(TrackButton); + break; + + case LC_TRACKTOOL_COUNT: + break; + } +} + +lcCursor lcPreviewWidget::GetCursor() const +{ + const lcCursor CursorFromTrackTool[] = + { + lcCursor::Select, // LC_TRACKTOOL_NONE + lcCursor::Pan, // LC_TRACKTOOL_PAN + lcCursor::RotateView, // LC_TRACKTOOL_ORBIT_XY + }; + + static_assert(LC_ARRAY_COUNT(CursorFromTrackTool) == LC_TRACKTOOL_COUNT, "Tracktool array size mismatch."); + + if (mTrackTool >= 0 && mTrackTool < LC_ARRAY_COUNT(CursorFromTrackTool)) + return CursorFromTrackTool[mTrackTool]; + + return lcCursor::Select; +} + +void lcPreviewWidget::OnInitialUpdate() +{ + MakeCurrent(); + + mContext->SetDefaultState(); +} + +void lcPreviewWidget::OnDraw() +{ + if (!mModel) + return; + + lcPreferences& Preferences = lcGetPreferences(); + const bool DrawInterface = mWidget != nullptr; + + mScene.SetAllowLOD(Preferences.mAllowLOD && mWidget != nullptr); + mScene.SetLODDistance(Preferences.mMeshLODDistance); + + mScene.Begin(mCamera->mWorldView); + + mScene.SetDrawInterface(DrawInterface); + + mModel->GetScene(mScene, mCamera, false /*HighlightNewParts*/, false/*mFadeSteps*/); + + mScene.End(); + + mContext->SetDefaultState(); + + mContext->SetViewport(0, 0, mWidth, mHeight); + + mModel->DrawBackground(this); + + mContext->SetProjectionMatrix(GetProjectionMatrix()); + + mContext->SetLineWidth(Preferences.mLineWidth); + + mScene.Draw(mContext); + + if (DrawInterface) + { + mContext->SetLineWidth(1.0f); + + if (Preferences.mDrawPreviewAxis) + DrawAxes(); + + if (Preferences.mDrawPreviewViewSphere) + mViewSphere.Draw(); + DrawViewport(); + } + + mContext->ClearResources(); +} + +void lcPreviewWidget::OnUpdateCursor() +{ + SetCursor(GetCursor()); +} + +void lcPreviewWidget::OnLeftButtonDown() +{ + if (mTrackButton != lcTrackButton::None) + { + StopTracking(false); + return; + } + + if (mViewSphere.OnLeftButtonDown()) + return; + + lcTrackTool OverrideTool = LC_TRACKTOOL_ORBIT_XY; + + if (OverrideTool != LC_TRACKTOOL_NONE) + { + mTrackTool = OverrideTool; + OnUpdateCursor(); + } + + OnButtonDown(lcTrackButton::Left); +} + +void lcPreviewWidget::OnLeftButtonUp() +{ + StopTracking(mTrackButton == lcTrackButton::Left); + + if (mViewSphere.OnLeftButtonUp()) { + ZoomExtents(); + return; + } +} + +void lcPreviewWidget::OnMiddleButtonDown() +{ + if (mTrackButton != lcTrackButton::None) + { + StopTracking(false); + return; + } + +#if (QT_VERSION >= QT_VERSION_CHECK(4, 7, 0)) + lcTrackTool OverrideTool = LC_TRACKTOOL_NONE; + + if (OverrideTool != LC_TRACKTOOL_NONE) + { + mTrackTool = OverrideTool; + OnUpdateCursor(); + } +#endif + OnButtonDown(lcTrackButton::Middle); +} + +void lcPreviewWidget::OnMiddleButtonUp() +{ + StopTracking(mTrackButton == lcTrackButton::Middle); +} + +void lcPreviewWidget::OnLeftButtonDoubleClick() +{ + ZoomExtents(); + Redraw(); +} + +void lcPreviewWidget::OnRightButtonDown() +{ + if (mTrackButton != lcTrackButton::None) + { + StopTracking(false); + return; + } + + lcTrackTool OverrideTool = LC_TRACKTOOL_PAN; + + if (OverrideTool != LC_TRACKTOOL_NONE) + { + mTrackTool = OverrideTool; + OnUpdateCursor(); + } + + OnButtonDown(lcTrackButton::Middle); +} + +void lcPreviewWidget::OnRightButtonUp() +{ + if (mTrackButton != lcTrackButton::None) + StopTracking(mTrackButton == lcTrackButton::Right); +} + +void lcPreviewWidget::OnMouseMove() +{ + lcModel* ActiveModel = GetActiveModel(); + + if (!ActiveModel) + return; + + if (mTrackButton == lcTrackButton::None) + { + if (mViewSphere.OnMouseMove()) + { + lcTrackTool NewTrackTool = mViewSphere.IsDragging() ? LC_TRACKTOOL_ORBIT_XY : LC_TRACKTOOL_NONE; + + if (NewTrackTool != mTrackTool) + { + mTrackTool = NewTrackTool; + OnUpdateCursor(); + } + + return; + } + + return; + } + + mTrackUpdated = true; + const float MouseSensitivity = 0.5f / (21.0f - lcGetPreferences().mMouseSensitivity); + + switch (mTrackTool) + { + case LC_TRACKTOOL_NONE: + break; + + case LC_TRACKTOOL_PAN: + { + lcVector3 Points[4] = + { + lcVector3((float)mInputState.x, (float)mInputState.y, 0.0f), + lcVector3((float)mInputState.x, (float)mInputState.y, 1.0f), + lcVector3(mMouseDownX, mMouseDownY, 0.0f), + lcVector3(mMouseDownX, mMouseDownY, 1.0f) + }; + + UnprojectPoints(Points, 4); + + const lcVector3& CurrentStart = Points[0]; + const lcVector3& CurrentEnd = Points[1]; + const lcVector3& MouseDownStart = Points[2]; + const lcVector3& MouseDownEnd = Points[3]; + lcVector3 Center = ActiveModel->GetSelectionOrModelCenter(); + + lcVector3 PlaneNormal(mCamera->mPosition - mCamera->mTargetPosition); + lcVector4 Plane(PlaneNormal, -lcDot(PlaneNormal, Center)); + lcVector3 Intersection, MoveStart; + + if (!lcLineSegmentPlaneIntersection(&Intersection, CurrentStart, CurrentEnd, Plane) || !lcLineSegmentPlaneIntersection(&MoveStart, MouseDownStart, MouseDownEnd, Plane)) + { + Center = MouseDownStart + lcNormalize(MouseDownEnd - MouseDownStart) * 10.0f; + Plane = lcVector4(PlaneNormal, -lcDot(PlaneNormal, Center)); + + if (!lcLineSegmentPlaneIntersection(&Intersection, CurrentStart, CurrentEnd, Plane) || !lcLineSegmentPlaneIntersection(&MoveStart, MouseDownStart, MouseDownEnd, Plane)) + break; + } + + ActiveModel->UpdatePanTool(mCamera, MoveStart - Intersection); + Redraw(); + } + break; + + case LC_TRACKTOOL_ORBIT_XY: + ActiveModel->UpdateOrbitTool(mCamera, 0.1f * MouseSensitivity * (mInputState.x - mMouseDownX), 0.1f * MouseSensitivity * (mInputState.y - mMouseDownY)); + Redraw(); + break; + + case LC_TRACKTOOL_COUNT: + break; + } +} + +void lcPreviewWidget::OnMouseWheel(float Direction) +{ + mModel->Zoom(mCamera, (int)(((mInputState.Modifiers & Qt::ControlModifier) ? 100 : 10) * Direction)); + Redraw(); +} diff --git a/common/lc_previewwidget.h b/common/lc_previewwidget.h new file mode 100644 index 00000000..47b020b1 --- /dev/null +++ b/common/lc_previewwidget.h @@ -0,0 +1,145 @@ +#ifndef PREVIEWWIDGET_H +#define PREVIEWWIDGET_H + +#include +#include +#include "lc_global.h" +#include "lc_glwidget.h" +#include "lc_scene.h" +#include "lc_viewsphere.h" +#include "lc_commands.h" +#include "lc_application.h" +#include "camera.h" + +class QLabel; +class Project; +class lcModel; +class lcPiece; +class lcQGLWidget; + +class lcPreviewDockWidget : public QMainWindow +{ + Q_OBJECT + +public: + explicit lcPreviewDockWidget(QMainWindow *parent = nullptr); + bool SetCurrentPiece(const QString &PartType, int ColorCode); + void ClearPreview(); + +protected: + QToolBar *ToolBar; + QLabel *Label; + lcPreviewWidget *Preview; + lcQGLWidget *ViewWidget; +}; + +class lcPreviewWidget : public lcGLWidget +{ +public: + enum class lcTrackButton + { + None, + Left, + Middle, + Right + }; + + enum lcTrackTool + { + LC_TRACKTOOL_NONE, + LC_TRACKTOOL_PAN, + LC_TRACKTOOL_ORBIT_XY, + LC_TRACKTOOL_COUNT + }; + + lcPreviewWidget(); + ~lcPreviewWidget(); + + lcTool GetTool() const + { + return mTool; + } + + lcCamera* GetCamera() const + { + return mCamera; + } + + QString GetDescription() const + { + return mDescription; + } + + lcVector3 UnprojectPoint(const lcVector3& Point) const + { + int Viewport[4] = { 0, 0, mWidth, mHeight }; + return lcUnprojectPoint(Point, mCamera->mWorldView, GetProjectionMatrix(), Viewport); + } + + void UnprojectPoints(lcVector3* Points, int NumPoints) const + { + int Viewport[4] = { 0, 0, mWidth, mHeight }; + lcUnprojectPoints(Points, NumPoints, mCamera->mWorldView, GetProjectionMatrix(), Viewport); + } + + void ClearPreview(); + bool SetCurrentPiece(const QString& PartType, int ColorCode); + lcMatrix44 GetProjectionMatrix() const; + lcModel* GetActiveModel() const; + lcCursor GetCursor() const; + void SetCamera(lcCamera* Camera); + void SetDefaultCamera(); + void ZoomExtents(); + + // exclusively called from viewSphere + void SetViewpoint(const lcVector3& Position); + void StartOrbitTracking(); + bool IsTracking() const + { + return mTrackButton != lcTrackButton::None; + } + + void OnInitialUpdate() override; + void OnDraw() override; + void OnUpdateCursor() override; + void OnLeftButtonDown() override; + void OnLeftButtonUp() override; + void OnLeftButtonDoubleClick() override; + void OnMiddleButtonDown() override; + void OnMiddleButtonUp() override; + void OnRightButtonDown() override; + void OnRightButtonUp() override; + void OnMouseMove() override; + void OnMouseWheel(float Direction) override; + +protected: + void DrawAxes(); + void DrawViewport(); + + lcTool GetCurrentTool() const; + void StartTracking(lcTrackButton TrackButton); + void StopTracking(bool Accept); + void OnButtonDown(lcTrackButton TrackButton); + + Project* mLoader; + lcModel* mModel; + lcCamera* mCamera; + lcViewSphere mViewSphere; + + lcScene mScene; + + lcTool mTool; + lcTrackButton mTrackButton; + lcTrackTool mTrackTool; + + QString mDescription; + + bool mIsPart; + bool mTrackUpdated; + int mMouseDownX; + int mMouseDownY; +}; + +extern class lcPreviewWidget* gPreviewWidget; + +#endif // PREVIEWWIDGET_H diff --git a/common/lc_profile.cpp b/common/lc_profile.cpp index d8a03bc1..3e5a3eea 100644 --- a/common/lc_profile.cpp +++ b/common/lc_profile.cpp @@ -129,7 +129,18 @@ static lcProfileEntry gProfileEntries[LC_NUM_PROFILE_KEYS] = lcProfileEntry("POVRay", "Path", "/usr/bin/povray"), // LC_PROFILE_POVRAY_PATH lcProfileEntry("POVRay", "LGEOPath", ""), // LC_PROFILE_POVRAY_LGEO_PATH lcProfileEntry("POVRay", "Width", 1280), // LC_PROFILE_POVRAY_WIDTH - lcProfileEntry("POVRay", "Height", 720) // LC_PROFILE_POVRAY_HEIGHT + lcProfileEntry("POVRay", "Height", 720), // LC_PROFILE_POVRAY_HEIGHT + + lcProfileEntry("Settings", "PreviewActiveColor", LC_RGBA(69, 69, 69, 255)), // LC_PROFILE_PREVIEW_ACTIVE_COLOR + lcProfileEntry("Settgins", "PreviewViewSphereEnabled", 1), // LC_PROFILE_PREVIEW_VIEW_SPHERE_ENABLED + lcProfileEntry("Settings", "PreviewViewSphereSize", 75), // LC_PROFILE_PREVIEW_VIEW_SPHERE_SIZE + lcProfileEntry("Settings", "PreviewViewSphereLocation", (int)lcViewSphereLocation::TopRight), // LC_PROFILE_PREVIEW_VIEW_SPHERE_LOCATION + lcProfileEntry("Settings", "PreviewEnabled", 1), // LC_PROFILE_PREVIEW_ENABLED + lcProfileEntry("Settings", "PreviewSize", 300), // LC_PROFILE_PREVIEW_SIZE + lcProfileEntry("Settings", "PreviewLocation", (int)lcPreviewLocation::BottomRight), // LC_PROFILE_PREVIEW_LOCATION + lcProfileEntry("Settings", "PreviewPosition", (int)lcPreviewPosition::Dockable), // LC_PROFILE_PREVIEW_POSITION + lcProfileEntry("Settings", "DrawPreviewAxis", 0), // LC_PROFILE_PREVIEW_DRAW_AXES + lcProfileEntry("Settings", "DrawPreviewViewSphere",1) // LC_PROFILE_PREVIEW_DRAW_VIEW_SPHERE }; void lcRemoveProfileKey(LC_PROFILE_KEY Key) diff --git a/common/lc_profile.h b/common/lc_profile.h index 61bc363a..6f2c1d48 100644 --- a/common/lc_profile.h +++ b/common/lc_profile.h @@ -80,6 +80,18 @@ enum LC_PROFILE_KEY LC_PROFILE_POVRAY_WIDTH, LC_PROFILE_POVRAY_HEIGHT, + LC_PROFILE_PREVIEW_ACTIVE_COLOR, + LC_PROFILE_PREVIEW_VIEW_SPHERE_ENABLED, + LC_PROFILE_PREVIEW_VIEW_SPHERE_SIZE, + LC_PROFILE_PREVIEW_VIEW_SPHERE_LOCATION, + + LC_PROFILE_PREVIEW_ENABLED, + LC_PROFILE_PREVIEW_SIZE, + LC_PROFILE_PREVIEW_LOCATION, + LC_PROFILE_PREVIEW_POSITION, + LC_PROFILE_PREVIEW_DRAW_AXES, + LC_PROFILE_PREVIEW_DRAW_VIEW_SPHERE, + LC_NUM_PROFILE_KEYS }; @@ -132,4 +144,3 @@ void lcSetProfileFloat(LC_PROFILE_KEY Key, float Value); void lcSetProfileString(LC_PROFILE_KEY Key, const QString& Value); void lcSetProfileStringList(LC_PROFILE_KEY Key, const QStringList& Value); void lcSetProfileBuffer(LC_PROFILE_KEY Key, const QByteArray& Buffer); - diff --git a/common/lc_timelinewidget.cpp b/common/lc_timelinewidget.cpp index 1696eaeb..14fbc996 100644 --- a/common/lc_timelinewidget.cpp +++ b/common/lc_timelinewidget.cpp @@ -5,6 +5,9 @@ #include "pieceinf.h" #include "lc_mainwindow.h" +#include "lc_qglwidget.h" +#include "lc_previewwidget.h" + lcTimelineWidget::lcTimelineWidget(QWidget* Parent) : QTreeWidget(Parent) { @@ -507,6 +510,96 @@ void lcTimelineWidget::mousePressEvent(QMouseEvent* Event) QTreeWidget::mousePressEvent(Event); } +void lcTimelineWidget::mouseDoubleClickEvent(QMouseEvent *event) +{ + QTreeWidget::mouseDoubleClickEvent(event); + if ( event->button() == Qt::LeftButton ) { + QTreeWidgetItem* CurrentItem = currentItem(); + PreviewSelection(CurrentItem); + } +} + +void lcTimelineWidget::PreviewSelection(QTreeWidgetItem* Current) +{ + lcPiece* Piece = (lcPiece*)Current->data(0, Qt::UserRole).value(); + if (!Piece) + return; + + PieceInfo* Info = Piece->mPieceInfo; + if (!Info) + return; + + bool IsSubfile = Info->IsModel(); + QString PartType = Info->mFileName; + quint32 ColorCode = IsSubfile ? 16 : Piece->mColorCode; + const lcPreferences& Preferences = lcGetPreferences(); + + if (Preferences.mPreviewPosition != lcPreviewPosition::Floating) { + emit gMainWindow->PreviewPiece(PartType, ColorCode); + return; + } + + if (!Preferences.mPreviewEnabled) + return; + + QString TypeLabel = IsSubfile ? "Submodel" : "Part"; + QString WindowTitle = QString("%1 Preview").arg(TypeLabel); + + lcPreviewWidget *Preview = new lcPreviewWidget(); + + lcQGLWidget *ViewWidget = new lcQGLWidget(nullptr, Preview, true/*isView*/, true/*isPreview*/); + + if (Preview && ViewWidget) { + if (!Preview->SetCurrentPiece(PartType, ColorCode)) + QMessageBox::critical(gMainWindow, tr("Error"), tr("Part preview for %1 failed.").arg(PartType)); + + ViewWidget->setWindowTitle(WindowTitle); + int Size[2] = { 300,200 }; + if (Preferences.mPreviewSize == 400) { + Size[0] = 400; Size[1] = 300; + } + ViewWidget->preferredSize = QSize(Size[0], Size[1]); + float Scale = ViewWidget->deviceScale(); + Preview->mWidth = ViewWidget->width() * Scale; + Preview->mHeight = ViewWidget->height() * Scale; + + const QRect desktop = QApplication::desktop()->geometry(); + + QPoint pos; + switch (Preferences.mPreviewLocation) + { + case lcPreviewLocation::TopRight: + pos = mapToGlobal(rect().topRight()); + break; + case lcPreviewLocation::TopLeft: + pos = mapToGlobal(rect().topLeft()); + break; + case lcPreviewLocation::BottomRight: + pos = mapToGlobal(rect().bottomRight()); + break; + default: + pos = mapToGlobal(rect().bottomLeft()); + break; + } + if (pos.x() < desktop.left()) + pos.setX(desktop.left()); + if (pos.y() < desktop.top()) + pos.setY(desktop.top()); + + if ((pos.x() + ViewWidget->width()) > desktop.width()) + pos.setX(desktop.width() - ViewWidget->width()); + if ((pos.y() + ViewWidget->height()) > desktop.bottom()) + pos.setY(desktop.bottom() - ViewWidget->height()); + ViewWidget->move(pos); + + ViewWidget->setMinimumSize(100,100); + ViewWidget->show(); + ViewWidget->setFocus(); + } else { + QMessageBox::critical(gMainWindow, tr("Error"), tr("Preview %1 failed.").arg(Info->mFileName)); + } +} + void lcTimelineWidget::UpdateModel() { QList> PieceSteps; diff --git a/common/lc_timelinewidget.h b/common/lc_timelinewidget.h index dfd92488..96b3c5bd 100644 --- a/common/lc_timelinewidget.h +++ b/common/lc_timelinewidget.h @@ -21,10 +21,12 @@ public slots: void CurrentItemChanged(QTreeWidgetItem* Current, QTreeWidgetItem* Previous); void ItemSelectionChanged(); void CustomMenuRequested(QPoint Pos); + void PreviewSelection(QTreeWidgetItem* Current); protected: void dropEvent(QDropEvent* DropEvent) override; void mousePressEvent(QMouseEvent* MouseEvent) override; + void mouseDoubleClickEvent(QMouseEvent *event) override; void UpdateModel(); void UpdateCurrentStepItem(); @@ -33,4 +35,3 @@ protected: QTreeWidgetItem* mCurrentStepItem; bool mIgnoreUpdates; }; - diff --git a/common/lc_viewsphere.cpp b/common/lc_viewsphere.cpp index 8166c7fb..a764235b 100644 --- a/common/lc_viewsphere.cpp +++ b/common/lc_viewsphere.cpp @@ -1,6 +1,8 @@ #include "lc_global.h" #include "lc_viewsphere.h" #include "view.h" +#include "lc_previewwidget.h" + #include "lc_context.h" #include "lc_stringcache.h" #include "lc_application.h" @@ -15,14 +17,25 @@ const float lcViewSphere::mHighlightRadius = 0.35f; const int lcViewSphere::mSubdivisions = 7; lcViewSphere::lcViewSphere(View* View) - : mView(View) + : mPreview(nullptr), + mView(View), + mIsPreview(false) { mMouseDown = false; } +lcViewSphere::lcViewSphere(lcPreviewWidget* Preview) + : mPreview(Preview), + mView(nullptr), + mIsPreview(true) +{ + mMouseDown = false; + mViewSphereSize = lcGetPreferences().mPreviewViewSphereSize; +} + lcMatrix44 lcViewSphere::GetViewMatrix() const { - lcMatrix44 ViewMatrix = mView->mCamera->mWorldView; + lcMatrix44 ViewMatrix = mIsPreview ? mPreview->GetCamera()->mWorldView : mView->mCamera->mWorldView; ViewMatrix.SetTranslation(lcVector3(0, 0, 0)); return ViewMatrix; } @@ -152,15 +165,15 @@ void lcViewSphere::DestroyResources(lcContext* Context) void lcViewSphere::Draw() { const lcPreferences& Preferences = lcGetPreferences(); - int ViewportSize = Preferences.mViewSphereSize; + int ViewportSize = mIsPreview ? mViewSphereSize : Preferences.mViewSphereSize; if (ViewportSize == 0 || !Preferences.mViewSphereEnabled) return; - lcContext* Context = mView->mContext; - int Width = mView->mWidth; - int Height = mView->mHeight; - lcViewSphereLocation Location = Preferences.mViewSphereLocation; + lcContext* Context = mIsPreview ? mPreview->mContext : mView->mContext; + int Width = mIsPreview ? mPreview->mWidth : mView->mWidth; + int Height = mIsPreview ? mPreview->mHeight : mView->mHeight; + lcViewSphereLocation Location = mIsPreview ? Preferences.mPreviewViewSphereLocation : Preferences.mViewSphereLocation; int Left = (Location == lcViewSphereLocation::BottomLeft || Location == lcViewSphereLocation::TopLeft) ? 0 : Width - ViewportSize; int Bottom = (Location == lcViewSphereLocation::BottomLeft || Location == lcViewSphereLocation::BottomRight) ? 0 : Height - ViewportSize; @@ -221,7 +234,7 @@ void lcViewSphere::Draw() bool lcViewSphere::OnLeftButtonDown() { const lcPreferences& Preferences = lcGetPreferences(); - if (Preferences.mViewSphereSize == 0 || !Preferences.mViewSphereEnabled) + if ((mIsPreview ? !mViewSphereSize : !Preferences.mViewSphereSize) || !Preferences.mViewSphereEnabled) return false; mIntersectionFlags = GetIntersectionFlags(mIntersection); @@ -229,8 +242,8 @@ bool lcViewSphere::OnLeftButtonDown() if (!mIntersectionFlags.any()) return false; - mMouseDownX = mView->mInputState.x; - mMouseDownY = mView->mInputState.y; + mMouseDownX = mIsPreview ? mPreview->mInputState.x : mView->mInputState.x; + mMouseDownY = mIsPreview ? mPreview->mInputState.y : mView->mInputState.y; mMouseDown = true; return true; @@ -239,7 +252,7 @@ bool lcViewSphere::OnLeftButtonDown() bool lcViewSphere::OnLeftButtonUp() { const lcPreferences& Preferences = lcGetPreferences(); - if (Preferences.mViewSphereSize == 0 || !Preferences.mViewSphereEnabled) + if ((mIsPreview ? !mViewSphereSize : !Preferences.mViewSphereSize) || !Preferences.mViewSphereEnabled) return false; if (!mMouseDown) @@ -260,7 +273,7 @@ bool lcViewSphere::OnLeftButtonUp() Position[AxisIdx] = -1250.0f; } - mView->SetViewpoint(Position); + mIsPreview ? mPreview->SetViewpoint(Position) : mView->SetViewpoint(Position); return true; } @@ -268,17 +281,17 @@ bool lcViewSphere::OnLeftButtonUp() bool lcViewSphere::OnMouseMove() { const lcPreferences& Preferences = lcGetPreferences(); - if (Preferences.mViewSphereSize == 0 || !Preferences.mViewSphereEnabled) + if ((mIsPreview ? !mViewSphereSize : !Preferences.mViewSphereSize) || !Preferences.mViewSphereEnabled) return false; if (IsDragging()) { mIntersectionFlags.reset(); - mView->StartOrbitTracking(); + mIsPreview ? mPreview->StartOrbitTracking() : mView->StartOrbitTracking(); return true; } - if (mView->IsTracking()) + if (mIsPreview ? mPreview->IsTracking() : mView->IsTracking()) return false; std::bitset<6> IntersectionFlags = GetIntersectionFlags(mIntersection); @@ -286,7 +299,7 @@ bool lcViewSphere::OnMouseMove() if (IntersectionFlags != mIntersectionFlags) { mIntersectionFlags = IntersectionFlags; - mView->Redraw(); + mIsPreview ? mPreview->Redraw() : mView->Redraw(); } return mIntersectionFlags.any(); @@ -294,21 +307,23 @@ bool lcViewSphere::OnMouseMove() bool lcViewSphere::IsDragging() const { - return mMouseDown && (qAbs(mMouseDownX - mView->mInputState.x) > 3 || qAbs(mMouseDownY - mView->mInputState.y) > 3); + int InputStateX = mIsPreview ? mPreview->mInputState.x : mView->mInputState.x; + int InputStateY = mIsPreview ? mPreview->mInputState.y : mView->mInputState.y; + return mMouseDown && (qAbs(mMouseDownX - InputStateX) > 3 || qAbs(mMouseDownY - InputStateY) > 3); } std::bitset<6> lcViewSphere::GetIntersectionFlags(lcVector3& Intersection) const { const lcPreferences& Preferences = lcGetPreferences(); - lcViewSphereLocation Location = Preferences.mViewSphereLocation; + lcViewSphereLocation Location = mIsPreview ? Preferences.mPreviewViewSphereLocation : Preferences.mViewSphereLocation; - int Width = mView->mWidth; - int Height = mView->mHeight; - int ViewportSize = Preferences.mViewSphereSize; + int Width = mIsPreview ? mPreview->mWidth : mView->mWidth; + int Height = mIsPreview ? mPreview->mHeight : mView->mHeight; + int ViewportSize = mIsPreview ? mViewSphereSize : Preferences.mViewSphereSize; int Left = (Location == lcViewSphereLocation::BottomLeft || Location == lcViewSphereLocation::TopLeft) ? 0 : Width - ViewportSize; int Bottom = (Location == lcViewSphereLocation::BottomLeft || Location == lcViewSphereLocation::BottomRight) ? 0 : Height - ViewportSize; - int x = mView->mInputState.x - Left; - int y = mView->mInputState.y - Bottom; + int x = (mIsPreview ? mPreview->mInputState.x : mView->mInputState.x) - Left; + int y = (mIsPreview ? mPreview->mInputState.y : mView->mInputState.y) - Bottom; std::bitset<6> IntersectionFlags; if (x < 0 || x > Width || y < 0 || y > Height) diff --git a/common/lc_viewsphere.h b/common/lc_viewsphere.h index a9d1913b..e6362694 100644 --- a/common/lc_viewsphere.h +++ b/common/lc_viewsphere.h @@ -5,11 +5,13 @@ #include class View; +class lcPreviewWidget; class lcViewSphere { public: - lcViewSphere(View* View); + lcViewSphere(View *View); + lcViewSphere(lcPreviewWidget *Preview); void Draw(); bool OnMouseMove(); @@ -25,12 +27,15 @@ protected: lcMatrix44 GetProjectionMatrix() const; std::bitset<6> GetIntersectionFlags(lcVector3& Intersection) const; + lcPreviewWidget* mPreview; View* mView; lcVector3 mIntersection; std::bitset<6> mIntersectionFlags; + int mViewSphereSize; int mMouseDownX; int mMouseDownY; bool mMouseDown; + bool mIsPreview; static lcTexture* mTexture; static lcVertexBuffer mVertexBuffer; diff --git a/common/project.cpp b/common/project.cpp index a227e044..27459b76 100644 --- a/common/project.cpp +++ b/common/project.cpp @@ -60,15 +60,17 @@ void lcHTMLExportOptions::SaveDefaults() lcSetProfileInt(LC_PROFILE_HTML_IMAGE_HEIGHT, StepImagesHeight); } -Project::Project() +Project::Project(bool IsPreview) + : mIsPreview(IsPreview) { mModified = false; - mActiveModel = new lcModel(tr("New Model.ldr")); + mActiveModel = new lcModel(tr(mIsPreview ? "Preview.ldr" : "New Model.ldr"), mIsPreview); mActiveModel->CreatePieceInfo(this); mActiveModel->SetSaved(); mModels.Add(mActiveModel); - QObject::connect(&mFileWatcher, SIGNAL(fileChanged(const QString&)), gMainWindow, SLOT(ProjectFileChanged(const QString&))); + if (!mIsPreview) + QObject::connect(&mFileWatcher, SIGNAL(fileChanged(const QString&)), gMainWindow, SLOT(ProjectFileChanged(const QString&))); } Project::~Project() @@ -149,8 +151,10 @@ void Project::SetActiveModel(int ModelIndex) mModels[ModelIdx]->UpdatePieceInfo(UpdatedModels); mActiveModel = mModels[ModelIndex]; - gMainWindow->SetCurrentModelTab(mActiveModel); - mActiveModel->UpdateInterface(); + if (!mIsPreview) { + gMainWindow->SetCurrentModelTab(mActiveModel); + mActiveModel->UpdateInterface(); + } } void Project::SetActiveModel(const QString& FileName) @@ -346,10 +350,10 @@ void Project::SetFileName(const QString& FileName) if (mFileName == FileName) return; - if (!mFileName.isEmpty()) + if (!mIsPreview && !mFileName.isEmpty()) mFileWatcher.removePath(mFileName); - if (!FileName.isEmpty()) + if (!mIsPreview && !FileName.isEmpty()) mFileWatcher.addPath(FileName); mFileName = FileName; @@ -357,11 +361,15 @@ void Project::SetFileName(const QString& FileName) bool Project::Load(const QString& FileName) { + QWidget *parent = nullptr; + if (!mIsPreview) + parent = gMainWindow; + QFile File(FileName); if (!File.open(QIODevice::ReadOnly)) { - QMessageBox::warning(gMainWindow, tr("Error"), tr("Error reading file '%1':\n%2").arg(FileName, File.errorString())); + QMessageBox::warning(parent, tr("Error"), tr("Error reading file '%1':\n%2").arg(FileName, File.errorString())); return false; } @@ -388,7 +396,7 @@ bool Project::Load(const QString& FileName) while (!Buffer.atEnd()) { - lcModel* Model = new lcModel(QString()); + lcModel* Model = new lcModel(QString(), mIsPreview); int Pos = Model->SplitMPD(Buffer); if (Models.empty() || !Model->GetFileName().isEmpty()) @@ -415,7 +423,7 @@ bool Project::Load(const QString& FileName) MemFile.WriteBuffer(FileData.constData(), FileData.size()); MemFile.Seek(0, SEEK_SET); - lcModel* Model = new lcModel(QString()); + lcModel* Model = new lcModel(QString(), mIsPreview); if (Model->LoadBinary(&MemFile)) { @@ -429,7 +437,7 @@ bool Project::Load(const QString& FileName) if (mModels.IsEmpty()) { - QMessageBox::warning(gMainWindow, tr("Error"), tr("Error loading file '%1':\nFile format is not recognized.").arg(FileName)); + QMessageBox::warning(parent, tr("Error"), tr("Error loading file '%1':\nFile format is not recognized.").arg(FileName)); return false; } diff --git a/common/project.h b/common/project.h index 21e1f56a..976a018a 100644 --- a/common/project.h +++ b/common/project.h @@ -41,7 +41,7 @@ struct lcInstructionsPageLayout; class Project { public: - Project(); + Project(bool IsPreview = false); ~Project(); Project(const Project&) = delete; @@ -115,6 +115,7 @@ protected: std::vector GetModelParts(); void SetFileName(const QString& FileName); + bool mIsPreview; bool mModified; QString mFileName; QFileSystemWatcher mFileWatcher; diff --git a/leocad.pro b/leocad.pro index 027c3a8c..fd2fd4e6 100644 --- a/leocad.pro +++ b/leocad.pro @@ -166,153 +166,155 @@ macx { } SOURCES += common/view.cpp \ - common/lc_instructionsdialog.cpp \ - common/texfont.cpp \ - common/project.cpp \ - common/pieceinf.cpp \ - common/piece.cpp \ - common/object.cpp \ - common/minifig.cpp \ - common/light.cpp \ - common/lc_application.cpp \ - common/lc_category.cpp \ - common/lc_colors.cpp \ - common/lc_commands.cpp \ - common/lc_context.cpp \ - common/lc_file.cpp \ - common/lc_glextensions.cpp \ - common/lc_http.cpp \ - common/lc_library.cpp \ - common/lc_lxf.cpp \ - common/lc_mainwindow.cpp \ - common/lc_mesh.cpp \ - common/lc_meshloader.cpp \ - common/lc_model.cpp \ - common/lc_profile.cpp \ - common/lc_scene.cpp \ - common/lc_selectbycolordialog.cpp \ - common/lc_shortcuts.cpp \ - common/lc_stringcache.cpp \ - common/lc_synth.cpp \ - common/lc_texture.cpp \ - common/lc_viewsphere.cpp \ - common/lc_zipfile.cpp \ - common/image.cpp \ - common/group.cpp \ - common/camera.cpp \ - qt/system.cpp \ - qt/qtmain.cpp \ - qt/lc_qarraydialog.cpp \ - qt/lc_qgroupdialog.cpp \ - qt/lc_qaboutdialog.cpp \ - qt/lc_qeditgroupsdialog.cpp \ - qt/lc_qselectdialog.cpp \ - qt/lc_qpropertiesdialog.cpp \ - qt/lc_qhtmldialog.cpp \ - qt/lc_qminifigdialog.cpp \ - qt/lc_qpreferencesdialog.cpp \ - qt/lc_qcategorydialog.cpp \ - qt/lc_qimagedialog.cpp \ - qt/lc_qupdatedialog.cpp \ - qt/lc_qutils.cpp \ - qt/lc_qpropertiestree.cpp \ - qt/lc_qcolorpicker.cpp \ - qt/lc_qglwidget.cpp \ - qt/lc_qcolorlist.cpp \ - qt/lc_qfinddialog.cpp \ - qt/lc_qmodellistdialog.cpp \ - common/lc_partselectionwidget.cpp \ - common/lc_timelinewidget.cpp \ - qt/lc_renderdialog.cpp \ - qt/lc_setsdatabasedialog.cpp \ - common/lc_partpalettedialog.cpp + common/lc_instructionsdialog.cpp \ + common/lc_previewwidget.cpp \ + common/texfont.cpp \ + common/project.cpp \ + common/pieceinf.cpp \ + common/piece.cpp \ + common/object.cpp \ + common/minifig.cpp \ + common/light.cpp \ + common/lc_application.cpp \ + common/lc_category.cpp \ + common/lc_colors.cpp \ + common/lc_commands.cpp \ + common/lc_context.cpp \ + common/lc_file.cpp \ + common/lc_glextensions.cpp \ + common/lc_http.cpp \ + common/lc_library.cpp \ + common/lc_lxf.cpp \ + common/lc_mainwindow.cpp \ + common/lc_mesh.cpp \ + common/lc_meshloader.cpp \ + common/lc_model.cpp \ + common/lc_profile.cpp \ + common/lc_scene.cpp \ + common/lc_selectbycolordialog.cpp \ + common/lc_shortcuts.cpp \ + common/lc_stringcache.cpp \ + common/lc_synth.cpp \ + common/lc_texture.cpp \ + common/lc_viewsphere.cpp \ + common/lc_zipfile.cpp \ + common/image.cpp \ + common/group.cpp \ + common/camera.cpp \ + qt/system.cpp \ + qt/qtmain.cpp \ + qt/lc_qarraydialog.cpp \ + qt/lc_qgroupdialog.cpp \ + qt/lc_qaboutdialog.cpp \ + qt/lc_qeditgroupsdialog.cpp \ + qt/lc_qselectdialog.cpp \ + qt/lc_qpropertiesdialog.cpp \ + qt/lc_qhtmldialog.cpp \ + qt/lc_qminifigdialog.cpp \ + qt/lc_qpreferencesdialog.cpp \ + qt/lc_qcategorydialog.cpp \ + qt/lc_qimagedialog.cpp \ + qt/lc_qupdatedialog.cpp \ + qt/lc_qutils.cpp \ + qt/lc_qpropertiestree.cpp \ + qt/lc_qcolorpicker.cpp \ + qt/lc_qglwidget.cpp \ + qt/lc_qcolorlist.cpp \ + qt/lc_qfinddialog.cpp \ + qt/lc_qmodellistdialog.cpp \ + common/lc_partselectionwidget.cpp \ + common/lc_timelinewidget.cpp \ + qt/lc_renderdialog.cpp \ + qt/lc_setsdatabasedialog.cpp \ + common/lc_partpalettedialog.cpp HEADERS += \ - common/lc_instructionsdialog.h \ - common/view.h \ - common/texfont.h \ - common/project.h \ - common/pieceinf.h \ - common/piece.h \ - common/object.h \ - common/minifig.h \ - common/light.h \ - common/lc_application.h \ - common/lc_array.h \ - common/lc_basewindow.h \ - common/lc_category.h \ - common/lc_colors.h \ - common/lc_commands.h \ - common/lc_context.h \ - common/lc_file.h \ - common/lc_glext.h \ - common/lc_glextensions.h \ - common/lc_global.h \ - common/lc_glwidget.h \ - common/lc_http.h \ - common/lc_library.h \ - common/lc_lxf.h \ - common/lc_mainwindow.h \ - common/lc_math.h \ - common/lc_mesh.h \ - common/lc_meshloader.h \ - common/lc_model.h \ - common/lc_profile.h \ - common/lc_scene.h \ - common/lc_selectbycolordialog.h \ - common/lc_shortcuts.h \ - common/lc_stringcache.h \ - common/lc_synth.h \ - common/lc_texture.h \ - common/lc_viewsphere.h \ - common/lc_zipfile.h \ - common/image.h \ - common/group.h \ - common/camera.h \ - qt/lc_qarraydialog.h \ - qt/lc_qgroupdialog.h \ - qt/lc_qaboutdialog.h \ - qt/lc_qeditgroupsdialog.h \ - qt/lc_qselectdialog.h \ - qt/lc_qpropertiesdialog.h \ - qt/lc_qhtmldialog.h \ - qt/lc_qminifigdialog.h \ - qt/lc_qpreferencesdialog.h \ - qt/lc_qcategorydialog.h \ - qt/lc_qimagedialog.h \ - qt/lc_qupdatedialog.h \ - qt/lc_qutils.h \ - qt/lc_qpropertiestree.h \ - qt/lc_qcolorpicker.h \ - qt/lc_qglwidget.h \ - qt/lc_qcolorlist.h \ - qt/lc_qfinddialog.h \ - qt/lc_qmodellistdialog.h \ - common/lc_partselectionwidget.h \ - common/lc_timelinewidget.h \ - qt/lc_renderdialog.h \ - qt/lc_setsdatabasedialog.h \ - common/lc_partpalettedialog.h + common/lc_instructionsdialog.h \ + common/lc_previewwidget.h \ + common/view.h \ + common/texfont.h \ + common/project.h \ + common/pieceinf.h \ + common/piece.h \ + common/object.h \ + common/minifig.h \ + common/light.h \ + common/lc_application.h \ + common/lc_array.h \ + common/lc_basewindow.h \ + common/lc_category.h \ + common/lc_colors.h \ + common/lc_commands.h \ + common/lc_context.h \ + common/lc_file.h \ + common/lc_glext.h \ + common/lc_glextensions.h \ + common/lc_global.h \ + common/lc_glwidget.h \ + common/lc_http.h \ + common/lc_library.h \ + common/lc_lxf.h \ + common/lc_mainwindow.h \ + common/lc_math.h \ + common/lc_mesh.h \ + common/lc_meshloader.h \ + common/lc_model.h \ + common/lc_profile.h \ + common/lc_scene.h \ + common/lc_selectbycolordialog.h \ + common/lc_shortcuts.h \ + common/lc_stringcache.h \ + common/lc_synth.h \ + common/lc_texture.h \ + common/lc_viewsphere.h \ + common/lc_zipfile.h \ + common/image.h \ + common/group.h \ + common/camera.h \ + qt/lc_qarraydialog.h \ + qt/lc_qgroupdialog.h \ + qt/lc_qaboutdialog.h \ + qt/lc_qeditgroupsdialog.h \ + qt/lc_qselectdialog.h \ + qt/lc_qpropertiesdialog.h \ + qt/lc_qhtmldialog.h \ + qt/lc_qminifigdialog.h \ + qt/lc_qpreferencesdialog.h \ + qt/lc_qcategorydialog.h \ + qt/lc_qimagedialog.h \ + qt/lc_qupdatedialog.h \ + qt/lc_qutils.h \ + qt/lc_qpropertiestree.h \ + qt/lc_qcolorpicker.h \ + qt/lc_qglwidget.h \ + qt/lc_qcolorlist.h \ + qt/lc_qfinddialog.h \ + qt/lc_qmodellistdialog.h \ + common/lc_partselectionwidget.h \ + common/lc_timelinewidget.h \ + qt/lc_renderdialog.h \ + qt/lc_setsdatabasedialog.h \ + common/lc_partpalettedialog.h FORMS += \ - qt/lc_qarraydialog.ui \ - qt/lc_qgroupdialog.ui \ - qt/lc_qaboutdialog.ui \ - qt/lc_qeditgroupsdialog.ui \ - qt/lc_qselectdialog.ui \ - qt/lc_qpropertiesdialog.ui \ - qt/lc_qhtmldialog.ui \ - qt/lc_qminifigdialog.ui \ - qt/lc_qpreferencesdialog.ui \ - qt/lc_qcategorydialog.ui \ - qt/lc_qimagedialog.ui \ - qt/lc_qupdatedialog.ui \ - qt/lc_qfinddialog.ui \ - qt/lc_qmodellistdialog.ui \ - qt/lc_renderdialog.ui \ - qt/lc_setsdatabasedialog.ui \ - common/lc_partpalettedialog.ui + qt/lc_qarraydialog.ui \ + qt/lc_qgroupdialog.ui \ + qt/lc_qaboutdialog.ui \ + qt/lc_qeditgroupsdialog.ui \ + qt/lc_qselectdialog.ui \ + qt/lc_qpropertiesdialog.ui \ + qt/lc_qhtmldialog.ui \ + qt/lc_qminifigdialog.ui \ + qt/lc_qpreferencesdialog.ui \ + qt/lc_qcategorydialog.ui \ + qt/lc_qimagedialog.ui \ + qt/lc_qupdatedialog.ui \ + qt/lc_qfinddialog.ui \ + qt/lc_qmodellistdialog.ui \ + qt/lc_renderdialog.ui \ + qt/lc_setsdatabasedialog.ui \ + common/lc_partpalettedialog.ui OTHER_FILES += RESOURCES += leocad.qrc resources/stylesheet/stylesheet.qrc !win32 { - TRANSLATIONS = resources/leocad_pt.ts resources/leocad_fr.ts resources/leocad_de.ts resources/leocad_uk.ts resources/leocad_cs.ts resources/leocad_es.ts + TRANSLATIONS = resources/leocad_pt.ts resources/leocad_fr.ts resources/leocad_de.ts resources/leocad_uk.ts resources/leocad_cs.ts resources/leocad_es.ts } diff --git a/qt/lc_qglwidget.cpp b/qt/lc_qglwidget.cpp index dd8a16bf..7408127d 100644 --- a/qt/lc_qglwidget.cpp +++ b/qt/lc_qglwidget.cpp @@ -84,8 +84,8 @@ void lcGLWidget::SetCursor(lcCursor CursorType) } } -lcQGLWidget::lcQGLWidget(QWidget *parent, lcGLWidget *owner, bool view) - : QGLWidget(parent, gWidgetList.isEmpty() ? nullptr : gWidgetList.first()) +lcQGLWidget::lcQGLWidget(QWidget *parent, lcGLWidget *owner, bool IsView, bool IsPreview) + : QGLWidget(parent, gWidgetList.isEmpty() ? nullptr : gWidgetList.first()), mIsPreview(IsPreview) { mWheelAccumulator = 0; widget = owner; @@ -110,8 +110,11 @@ lcQGLWidget::lcQGLWidget(QWidget *parent, lcGLWidget *owner, bool view) if (!gSupportsShaderObjects && lcGetPreferences().mShadingMode == lcShadingMode::DefaultLights) lcGetPreferences().mShadingMode = lcShadingMode::Flat; - if (!gSupportsFramebufferObjectARB && !gSupportsFramebufferObjectEXT) - gMainWindow->GetPartSelectionWidget()->DisableIconMode(); + if (!mIsPreview) { + if (!gSupportsFramebufferObjectARB && !gSupportsFramebufferObjectEXT) { + gMainWindow->GetPartSelectionWidget()->DisableIconMode(); + } + } gPlaceholderMesh = new lcMesh; gPlaceholderMesh->CreateBox(); @@ -124,11 +127,12 @@ lcQGLWidget::lcQGLWidget(QWidget *parent, lcGLWidget *owner, bool view) preferredSize = QSize(0, 0); setMouseTracking(true); - mIsView = view; + mIsView = IsView; if (mIsView) { setFocusPolicy(Qt::StrongFocus); - setAcceptDrops(true); + if (!mIsPreview) + setAcceptDrops(true); } } @@ -142,7 +146,8 @@ lcQGLWidget::~lcQGLWidget() gTexFont.Reset(); lcGetPiecesLibrary()->ReleaseBuffers(widget->mContext); - View::DestroyResources(widget->mContext); + if (!mIsPreview) + View::DestroyResources(widget->mContext); lcContext::DestroyResources(); lcViewSphere::DestroyResources(widget->mContext); @@ -180,7 +185,7 @@ void lcQGLWidget::paintGL() void lcQGLWidget::keyPressEvent(QKeyEvent *event) { - if (mIsView && (event->key() == Qt::Key_Control || event->key() == Qt::Key_Shift)) + if (!mIsPreview && mIsView && (event->key() == Qt::Key_Control || event->key() == Qt::Key_Shift)) { widget->mInputState.Modifiers = event->modifiers(); widget->OnUpdateCursor(); @@ -191,7 +196,7 @@ void lcQGLWidget::keyPressEvent(QKeyEvent *event) void lcQGLWidget::keyReleaseEvent(QKeyEvent *event) { - if (mIsView && (event->key() == Qt::Key_Control || event->key() == Qt::Key_Shift)) + if (!mIsPreview && mIsView && (event->key() == Qt::Key_Control || event->key() == Qt::Key_Shift)) { widget->mInputState.Modifiers = event->modifiers(); widget->OnUpdateCursor(); @@ -335,7 +340,7 @@ void lcQGLWidget::wheelEvent(QWheelEvent *event) void lcQGLWidget::dragEnterEvent(QDragEnterEvent* DragEnterEvent) { - if (mIsView) + if (!mIsPreview && mIsView) { const QMimeData* MimeData = DragEnterEvent->mimeData(); @@ -356,8 +361,9 @@ void lcQGLWidget::dragEnterEvent(QDragEnterEvent* DragEnterEvent) void lcQGLWidget::dragLeaveEvent(QDragLeaveEvent *event) { - if (!mIsView) + if (!mIsView || mIsPreview) { return; + } ((View*)widget)->EndDrag(false); @@ -366,7 +372,7 @@ void lcQGLWidget::dragLeaveEvent(QDragLeaveEvent *event) void lcQGLWidget::dragMoveEvent(QDragMoveEvent* DragMoveEvent) { - if (mIsView) + if (!mIsPreview && mIsView) { const QMimeData* MimeData = DragMoveEvent->mimeData(); @@ -390,7 +396,7 @@ void lcQGLWidget::dragMoveEvent(QDragMoveEvent* DragMoveEvent) void lcQGLWidget::dropEvent(QDropEvent* DropEvent) { - if (mIsView) + if (!mIsPreview && mIsView) { const QMimeData* MimeData = DropEvent->mimeData(); diff --git a/qt/lc_qglwidget.h b/qt/lc_qglwidget.h index da704de7..ca0a7d5d 100644 --- a/qt/lc_qglwidget.h +++ b/qt/lc_qglwidget.h @@ -6,7 +6,7 @@ class lcGLWidget; class lcQGLWidget : public QGLWidget { public: - lcQGLWidget(QWidget* Parent, lcGLWidget* Owner, bool IsView); + lcQGLWidget(QWidget* Parent, lcGLWidget* Owner, bool IsView, bool IsPreview = false); ~lcQGLWidget(); QSize sizeHint() const override; @@ -14,6 +14,7 @@ public: lcGLWidget *widget; QSize preferredSize; bool mIsView; + bool mIsPreview; float deviceScale() { diff --git a/qt/lc_qpreferencesdialog.cpp b/qt/lc_qpreferencesdialog.cpp index bcc18006..bb97f198 100644 --- a/qt/lc_qpreferencesdialog.cpp +++ b/qt/lc_qpreferencesdialog.cpp @@ -123,6 +123,55 @@ lcQPreferencesDialog::lcQPreferencesDialog(QWidget* Parent, lcPreferencesDialogO else ui->ViewSphereSizeCombo->setCurrentIndex(0); + ui->PreviewAxisIconCheckBox->setChecked(mOptions->Preferences.mDrawPreviewAxis); + + ui->PreviewViewSphereCheckBox->setChecked(mOptions->Preferences.mDrawPreviewViewSphere); + + ui->PreviewLocationCombo->setCurrentIndex((int)mOptions->Preferences.mPreviewLocation); + + ui->PreviewPositionCombo->setCurrentIndex((int)mOptions->Preferences.mPreviewPosition); + + if (mOptions->Preferences.mPreviewEnabled) + { + switch (mOptions->Preferences.mPreviewSize) + { + case 400: + ui->PreviewSizeCombo->setCurrentIndex(2); + break; + case 300: + ui->PreviewSizeCombo->setCurrentIndex(1); + break; + default: /*Disabled*/ + ui->PreviewSizeCombo->setCurrentIndex(0); + break; + } + } + else + ui->PreviewSizeCombo->setCurrentIndex(0); + + ui->PreviewViewSphereLocationCombo->setCurrentIndex((int)mOptions->Preferences.mPreviewViewSphereLocation); + + if (mOptions->Preferences.mPreviewViewSphereEnabled) + { + switch (mOptions->Preferences.mPreviewViewSphereSize) + { + case 100: + ui->PreviewViewSphereSizeCombo->setCurrentIndex(3); + break; + case 75: + ui->PreviewViewSphereSizeCombo->setCurrentIndex(2); + break; + case 50: + ui->PreviewViewSphereSizeCombo->setCurrentIndex(1); + break; + default: + ui->PreviewViewSphereSizeCombo->setCurrentIndex(0); + break; + } + } + else + ui->PreviewViewSphereSizeCombo->setCurrentIndex(0); + ui->studLogo->setChecked(mOptions->StudLogo); if (ui->studLogo->isChecked()) ui->studLogoCombo->setCurrentIndex(mOptions->StudLogo - 1); @@ -176,6 +225,13 @@ lcQPreferencesDialog::lcQPreferencesDialog(QWidget* Parent, lcPreferencesDialogO on_gridLines_toggled(); on_ViewSphereSizeCombo_currentIndexChanged(ui->ViewSphereSizeCombo->currentIndex()); + on_PreviewViewSphereSizeCombo_currentIndexChanged(ui->PreviewViewSphereSizeCombo->currentIndex()); + on_PreviewSizeCombo_currentIndexChanged(ui->PreviewSizeCombo->currentIndex()); + on_PreviewPositionCombo_currentIndexChanged(ui->PreviewPositionCombo->currentIndex()); + ui->PreviewLocationCombo->setEnabled( + ui->PreviewSizeCombo->currentIndex() != 0 && + ui->PreviewPositionCombo->currentIndex() != 0); + updateCategories(); ui->categoriesTree->setCurrentItem(ui->categoriesTree->topLevelItem(0)); @@ -220,7 +276,7 @@ void lcQPreferencesDialog::accept() mOptions->Preferences.mColorTheme = static_cast(ui->ColorTheme->currentIndex()); int Language = ui->Language->currentIndex(); - if (Language < 0 || Language > static_cast(LC_ARRAY_COUNT(gLanguageLocales))) + if (Language < 0 || Language > static_cast(LC_ARRAY_COUNT(gLanguageLocales))) Language = 0; mOptions->Language = gLanguageLocales[Language]; @@ -275,6 +331,44 @@ void lcQPreferencesDialog::accept() else mOptions->StudLogo = 0; + mOptions->Preferences.mDrawPreviewAxis = ui->PreviewAxisIconCheckBox->isChecked(); + + mOptions->Preferences.mDrawPreviewViewSphere = ui->PreviewViewSphereCheckBox->isChecked(); + + mOptions->Preferences.mPreviewLocation = (lcPreviewLocation)ui->PreviewLocationCombo->currentIndex(); + + mOptions->Preferences.mPreviewPosition = (lcPreviewPosition)ui->PreviewPositionCombo->currentIndex(); + + switch (ui->PreviewSizeCombo->currentIndex()) + { + case 2: + mOptions->Preferences.mPreviewSize = 400; + break; + case 1: + mOptions->Preferences.mPreviewSize = 300; + break; + default: + mOptions->Preferences.mPreviewEnabled = 0; + break; + } + + mOptions->Preferences.mPreviewViewSphereLocation = (lcViewSphereLocation)ui->PreviewViewSphereLocationCombo->currentIndex(); + + switch (ui->PreviewViewSphereSizeCombo->currentIndex()) + { + case 3: + mOptions->Preferences.mPreviewViewSphereSize = 100; + break; + case 2: + mOptions->Preferences.mPreviewViewSphereSize = 75; + break; + case 1: + mOptions->Preferences.mPreviewViewSphereSize = 50; + break; + default: + break; + } + QDialog::accept(); } @@ -473,6 +567,26 @@ void lcQPreferencesDialog::on_gridLines_toggled() ui->gridLineSpacing->setEnabled(ui->gridLines->isChecked()); } +void lcQPreferencesDialog::on_PreviewViewSphereSizeCombo_currentIndexChanged(int Index) +{ + ui->PreviewViewSphereLocationCombo->setEnabled(Index != 0); +} + +void lcQPreferencesDialog::on_PreviewSizeCombo_currentIndexChanged(int Index) +{ + ui->PreviewLocationCombo->setEnabled(Index != 0); + if (ui->PreviewPositionCombo->currentIndex() != 0) + ui->PreviewPositionCombo->setEnabled(Index != 0); + ui->PreviewAxisIconCheckBox->setEnabled(Index != 0); + ui->PreviewViewSphereCheckBox->setEnabled(Index != 0); +} + +void lcQPreferencesDialog::on_PreviewPositionCombo_currentIndexChanged(int Index) +{ + ui->PreviewSizeCombo->setEnabled(Index != 0); + ui->PreviewLocationCombo->setEnabled(Index != 0); +} + void lcQPreferencesDialog::on_ViewSphereSizeCombo_currentIndexChanged(int Index) { bool Enabled = Index != 0; diff --git a/qt/lc_qpreferencesdialog.h b/qt/lc_qpreferencesdialog.h index 922dbd48..ffa297f1 100644 --- a/qt/lc_qpreferencesdialog.h +++ b/qt/lc_qpreferencesdialog.h @@ -65,6 +65,10 @@ public slots: void on_studLogo_toggled(); void MouseTreeItemChanged(QTreeWidgetItem* Current); + void on_PreviewSizeCombo_currentIndexChanged(int Index); + void on_PreviewViewSphereSizeCombo_currentIndexChanged(int Index); + void on_PreviewPositionCombo_currentIndexChanged(int Index); + private: Ui::lcQPreferencesDialog *ui; diff --git a/qt/lc_qpreferencesdialog.ui b/qt/lc_qpreferencesdialog.ui index 4b36eb84..67aa905d 100644 --- a/qt/lc_qpreferencesdialog.ui +++ b/qt/lc_qpreferencesdialog.ui @@ -202,7 +202,7 @@ - + :/resources/file_open.png:/resources/file_open.png @@ -210,7 +210,7 @@ - + :/resources/archive.png:/resources/archive.png @@ -551,7 +551,14 @@ Overlays - + + + + Axis icon + + + + Qt::Horizontal @@ -564,17 +571,24 @@ - - + + - Axis icon + - - + + - Overlay Color: + + + + + + + + Active View: @@ -585,24 +599,10 @@ - - + + - - - - - - - - Active View: - - - - - - - + Overlay Color: @@ -719,55 +719,13 @@ - - - - Highlight Color: - - - - - - - Size: - - - - - + + - - - - Color: - - - - - - - - - - - - - - Text Color: - - - - - - - Location: - - - @@ -792,13 +750,231 @@ - - + + + + + + Preview Location + + + + + + + Color: + + + + + + + Text Color: + + + + + + + Location: + + + + + + + + Disabled + + + + + Small + + + + + Medium + + + + + Large + + + + + + + + Preview Size: + + + + + + + Size: + + + + + + + Highlight Color: + + + + + + + + + + + + + + + Top Left + + + + + Top Right + + + + + Bottom Left + + + + + Bottom Right + + + + + + + + + + + Preview + + + + + + Location: + + + + + + + View Sphere + + + + + + + + Dockable + + + + + Floating + + + + + + + + Position: + + + + + + + Size: + + + + + + + + Top Left + + + + + Top Right + + + + + Bottom Left + + + + + Bottom Right + + + + + + + + Axis Icon + + + + + + + + Disabled + + + + + Small + + + + + Large + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + @@ -1384,9 +1560,16 @@ gridLineColor ViewSphereSizeCombo ViewSphereLocationCombo + PreviewViewSphereSizeCombo + PreviewViewSphereLocationCombo ViewSphereColorButton ViewSphereTextColorButton ViewSphereHighlightColorButton + PreviewSizeCombo + PreviewLocationCombo + PreviewPositionCombo + PreviewViewSphereCheckBox + PreviewAxisIconCheckBox categoriesTree partsTree importCategories @@ -1415,7 +1598,9 @@ mouseRemove mouseSensitivity - + + + buttonBox