Use the part selection widget in the properties widget.
Some checks failed
LeoCAD CI / build-ubuntu (push) Has been cancelled
LeoCAD CI / build-macos (push) Has been cancelled

This commit is contained in:
Leonardo Zide 2024-07-25 14:16:23 -07:00
parent ed53e5ffe0
commit b2074a7c0a
8 changed files with 151 additions and 108 deletions

View file

@ -706,6 +706,10 @@ void lcMainWindow::CreateToolBars()
mPartsToolBar->setWidget(mPartSelectionWidget);
addDockWidget(Qt::RightDockWidgetArea, mPartsToolBar);
connect(mPartsToolBar, &QDockWidget::dockLocationChanged, mPartSelectionWidget, &lcPartSelectionWidget::DockLocationChanged);
connect(mPartSelectionWidget, &lcPartSelectionWidget::PartDoubleClicked, this, &lcMainWindow::PartListDoubleClicked);
connect(mPartSelectionWidget, &lcPartSelectionWidget::PartChanged, this, &lcMainWindow::SetCurrentPieceInfo);
mColorsToolBar = new QDockWidget(tr("Colors"), this);
mColorsToolBar->setObjectName("ColorsToolbar");
mColorsToolBar->setSizePolicy(QSizePolicy::Maximum, QSizePolicy::Maximum);
@ -1104,6 +1108,16 @@ void lcMainWindow::ColorChanged(int ColorIndex)
SetColorIndex(ColorIndex);
}
void lcMainWindow::PartListDoubleClicked(PieceInfo* Info)
{
if (!Info)
return;
quint32 ColorCode = lcGetColorCode(mPartSelectionWidget->GetColorIndex());
gMainWindow->PreviewPiece(Info->mFileName, ColorCode, true);
}
void lcMainWindow::ColorButtonClicked()
{
lcModel* ActiveModel = GetActiveModel();

View file

@ -230,7 +230,6 @@ public:
void SetAngleSnapIndex(int Index);
void SetRelativeTransform(bool RelativeTransform);
void SetSeparateTransform(bool SelectionTransform);
void SetCurrentPieceInfo(PieceInfo* Info);
void SetShadingMode(lcShadingMode ShadingMode);
void SetSelectionMode(lcSelectionMode SelectionMode);
void ToggleViewSphere();
@ -289,6 +288,7 @@ public slots:
void ProjectFileChanged(const QString& Path);
void PreviewPiece(const QString& PartId, int ColorCode, bool ShowPreview);
void TogglePreviewWidget(bool Visible);
void SetCurrentPieceInfo(PieceInfo* Info);
protected slots:
void CameraMenuAboutToShow();
@ -303,6 +303,7 @@ protected slots:
void ClipboardChanged();
void ActionTriggered();
void ColorChanged(int ColorIndex);
void PartListDoubleClicked(PieceInfo* Info);
void ColorButtonClicked();
void Print(QPrinter* Printer);
void EnableWindowFlags(bool);

View file

@ -4739,7 +4739,9 @@ void lcModel::SetPreviewPieceInfo(PieceInfo* Info, int ColorIndex)
AddPiece(Piece);
Piece->UpdatePosition(1);
SetCurrentStep(LC_STEP_MAX);
mCurrentStep = LC_STEP_MAX;
CalculateStep(LC_STEP_MAX);
SaveCheckpoint(QString());
}

View file

@ -327,6 +327,18 @@ Qt::ItemFlags lcPartSelectionListModel::flags(const QModelIndex& Index) const
return DefaultFlags;
}
QModelIndex lcPartSelectionListModel::GetPieceInfoIndex(PieceInfo* Info) const
{
if (Info)
{
for (int PartIndex = 0; PartIndex < static_cast<int>(mParts.size()); PartIndex++)
if (mParts[PartIndex].Info == Info)
return index(PartIndex, 0);
}
return QModelIndex();
}
void lcPartSelectionListModel::ReleaseThumbnails()
{
lcThumbnailManager* ThumbnailManager = lcGetPiecesLibrary()->GetThumbnailManager();
@ -502,6 +514,17 @@ void lcPartSelectionListView::SetCategory(lcPartCategoryType Type, int Index)
setCurrentIndex(mListModel->index(0, 0));
}
void lcPartSelectionListView::SetCurrentPart(PieceInfo* Info)
{
QModelIndex Index = mListModel->GetPieceInfoIndex(Info);
if (Index.isValid())
{
setCurrentIndex(Index);
scrollTo(Index, QAbstractItemView::EnsureVisible);
}
}
void lcPartSelectionListView::SetNoIcons()
{
SetIconSize(0);
@ -603,26 +626,6 @@ void lcPartSelectionListView::startDrag(Qt::DropActions SupportedActions)
Drag->exec(Qt::CopyAction);
}
void lcPartSelectionListView::mouseDoubleClickEvent(QMouseEvent* MouseEvent)
{
if (MouseEvent->button() == Qt::LeftButton )
PreviewSelection(currentIndex().row());
QListView::mouseDoubleClickEvent(MouseEvent);
}
void lcPartSelectionListView::PreviewSelection(int InfoIndex)
{
PieceInfo* Info = mListModel->GetPieceInfo(InfoIndex);
if (!Info)
return;
quint32 ColorCode = lcGetColorCode(mListModel->GetColorIndex());
gMainWindow->PreviewPiece(Info->mFileName, ColorCode, true);
}
lcPartSelectionWidget::lcPartSelectionWidget(QWidget* Parent)
: QWidget(Parent), mFilterAction(nullptr)
{
@ -698,18 +701,17 @@ lcPartSelectionWidget::lcPartSelectionWidget(QWidget* Parent)
Layout->addWidget(mSplitter);
setLayout(Layout);
connect(mPartsWidget->selectionModel(), SIGNAL(currentChanged(const QModelIndex&, const QModelIndex&)), this, SLOT(PartChanged(const QModelIndex&, const QModelIndex&)));
connect(mFilterWidget, SIGNAL(textChanged(const QString&)), this, SLOT(FilterChanged(const QString&)));
connect(mCategoriesWidget, SIGNAL(currentItemChanged(QTreeWidgetItem*, QTreeWidgetItem*)), this, SLOT(CategoryChanged(QTreeWidgetItem*, QTreeWidgetItem*)));
connect(mFilterCategoriesWidget, SIGNAL(textChanged(const QString&)), this, SLOT(FilterCategoriesChanged(const QString&)));
connect(mPartsWidget, &QListView::doubleClicked, this, &lcPartSelectionWidget::PartViewDoubleClicked);
connect(mPartsWidget->selectionModel(), &QItemSelectionModel::currentChanged, this, &lcPartSelectionWidget::PartViewSelectionChanged);
connect(mFilterWidget, &QLineEdit::textChanged, this, &lcPartSelectionWidget::FilterChanged);
connect(mCategoriesWidget, &QTreeWidget::currentItemChanged, this, &lcPartSelectionWidget::CategoryChanged);
connect(mFilterCategoriesWidget, &QLineEdit::textChanged, this, &lcPartSelectionWidget::FilterCategoriesChanged);
LoadPartPalettes();
UpdateCategories();
mSplitter->setStretchFactor(0, 0);
mSplitter->setStretchFactor(1, 1);
connect(Parent, SIGNAL(dockLocationChanged(Qt::DockWidgetArea)), this, SLOT(DockLocationChanged(Qt::DockWidgetArea)));
}
bool lcPartSelectionWidget::event(QEvent* Event)
@ -750,7 +752,7 @@ void lcPartSelectionWidget::LoadState(QSettings& Settings)
if (Sizes.size() != 2)
{
int Length = mSplitter->orientation() == Qt::Horizontal ? mSplitter->width() : mSplitter->height();
Sizes << Length / 3 << 2 * Length / 3;
Sizes = { Length / 3, 2 * Length / 3 };
}
mSplitter->setSizes(Sizes);
@ -767,6 +769,22 @@ void lcPartSelectionWidget::DisableIconMode()
mPartsWidget->SetNoIcons();
}
void lcPartSelectionWidget::SetCurrentPart(PieceInfo* Info)
{
mCategoriesWidget->setCurrentItem(mAllPartsCategoryItem);
mPartsWidget->SetCurrentPart(Info);
}
void lcPartSelectionWidget::SetOrientation(Qt::Orientation Orientation)
{
mSplitter->setOrientation(Orientation);
int Length = mSplitter->orientation() == Qt::Horizontal ? mSplitter->width() : mSplitter->height();
QList<int> Sizes = { Length / 3, 2 * Length / 3 };
mSplitter->setSizes(Sizes);
}
void lcPartSelectionWidget::DockLocationChanged(Qt::DockWidgetArea Area)
{
if (Area == Qt::LeftDockWidgetArea || Area == Qt::RightDockWidgetArea)
@ -777,7 +795,9 @@ void lcPartSelectionWidget::DockLocationChanged(Qt::DockWidgetArea Area)
void lcPartSelectionWidget::resizeEvent(QResizeEvent* Event)
{
if (((QDockWidget*)parent())->isFloating())
QDockWidget* DockWidget = qobject_cast<QDockWidget*>(parent());
if (DockWidget && DockWidget->isFloating())
{
if (Event->size().width() > Event->size().height())
mSplitter->setOrientation(Qt::Horizontal);
@ -855,12 +875,20 @@ void lcPartSelectionWidget::CategoryChanged(QTreeWidgetItem* Current, QTreeWidge
mPartsWidget->SetCategory(static_cast<lcPartCategoryType>(Type), Index);
}
void lcPartSelectionWidget::PartChanged(const QModelIndex& Current, const QModelIndex& Previous)
void lcPartSelectionWidget::PartViewSelectionChanged(const QModelIndex& Current, const QModelIndex& Previous)
{
Q_UNUSED(Current);
Q_UNUSED(Previous);
gMainWindow->SetCurrentPieceInfo(mPartsWidget->GetCurrentPart());
emit PartChanged(mPartsWidget->GetCurrentPart());
}
void lcPartSelectionWidget::PartViewDoubleClicked(const QModelIndex& Index)
{
PieceInfo* Info = mPartsWidget->GetListModel()->GetPieceInfo(Index.row());
if (Info)
emit PartDoubleClicked(Info);
}
void lcPartSelectionWidget::OptionsMenuAboutToShow()
@ -1084,11 +1112,11 @@ void lcPartSelectionWidget::UpdateCategories()
mCategoriesWidget->clear();
QTreeWidgetItem* AllPartsCategoryItem = new QTreeWidgetItem(mCategoriesWidget, QStringList(tr("All Parts")));
AllPartsCategoryItem->setData(0, static_cast<int>(lcPartCategoryRole::Type), static_cast<int>(lcPartCategoryType::AllParts));
mAllPartsCategoryItem = new QTreeWidgetItem(mCategoriesWidget, QStringList(tr("All Parts")));
mAllPartsCategoryItem->setData(0, static_cast<int>(lcPartCategoryRole::Type), static_cast<int>(lcPartCategoryType::AllParts));
if (CurrentType == lcPartCategoryType::AllParts && CurrentIndex == 0)
CurrentItem = AllPartsCategoryItem;
CurrentItem = mAllPartsCategoryItem;
QTreeWidgetItem* CurrentModelCategoryItem = new QTreeWidgetItem(mCategoriesWidget, QStringList(tr("In Use")));
CurrentModelCategoryItem->setData(0, static_cast<int>(lcPartCategoryRole::Type), static_cast<int>(lcPartCategoryType::PartsInUse));

View file

@ -65,6 +65,8 @@ public:
QVariant headerData(int Section, Qt::Orientation Orientation, int Role = Qt::DisplayRole) const override;
Qt::ItemFlags flags(const QModelIndex& Index) const override;
QModelIndex GetPieceInfoIndex(PieceInfo* Info) const;
PieceInfo* GetPieceInfo(const QModelIndex& Index) const
{
return Index.isValid() ? mParts[Index.row()].Info : nullptr;
@ -153,6 +155,7 @@ public:
void startDrag(Qt::DropActions SupportedActions) override;
void SetCategory(lcPartCategoryType Type, int Index);
void SetCurrentPart(PieceInfo* Info);
PieceInfo* GetCurrentPart() const
{
@ -191,8 +194,6 @@ public slots:
protected:
void SetIconSize(int Size);
void PreviewSelection(int InfoIndex);
void mouseDoubleClickEvent(QMouseEvent* MouseEvent) override;
lcPartSelectionListModel* mListModel;
lcPartSelectionWidget* mPartSelectionWidget;
@ -215,6 +216,13 @@ public:
void LoadState(QSettings& Settings);
void SaveState(QSettings& Settings);
void DisableIconMode();
void SetOrientation(Qt::Orientation Orientation);
void SetCurrentPart(PieceInfo* Info);
int GetColorIndex() const
{
return mPartsWidget->GetListModel()->GetColorIndex();
}
void SetColorIndex(int ColorIndex)
{
@ -226,19 +234,29 @@ public:
return mPartPalettes;
}
PieceInfo* GetCurrentPart() const
{
return mPartsWidget->GetCurrentPart();
}
signals:
void PartDoubleClicked(PieceInfo* Info);
void PartChanged(PieceInfo* Info);
public slots:
void AddToPalette();
void RemoveFromPalette();
void DockLocationChanged(Qt::DockWidgetArea Area);
protected slots:
void DockLocationChanged(Qt::DockWidgetArea Area);
void FilterChanged(const QString& Text);
void FilterCategoriesChanged(const QString& Text);
void FilterTriggered();
void FilterCaseTriggered();
void FilterCategoriesTriggered();
void CategoryChanged(QTreeWidgetItem* Current, QTreeWidgetItem* Previous);
void PartChanged(const QModelIndex& Current, const QModelIndex& Previous);
void PartViewSelectionChanged(const QModelIndex& Current, const QModelIndex& Previous);
void PartViewDoubleClicked(const QModelIndex& Index);
void OptionsMenuAboutToShow();
void EditPartPalettes();
@ -257,5 +275,6 @@ protected:
QAction* mFilterAction;
lcPartSelectionListView* mPartsWidget;
QSplitter* mSplitter;
QTreeWidgetItem* mAllPartsCategoryItem;
std::vector<lcPartPalette> mPartPalettes;
};

View file

@ -898,7 +898,7 @@ void lcPropertiesWidget::PieceIdButtonClicked()
QMenu* Menu = new QMenu(PieceIdButton);
QWidgetAction* Action = new QWidgetAction(Menu);
lcPieceIdPickerPopup* Popup = new lcPieceIdPickerPopup(gMainWindow->GetActiveModel(), Partial ? nullptr : Info, Menu);
lcPieceIdPickerPopup* Popup = new lcPieceIdPickerPopup(Partial ? nullptr : Info, Menu);
Action->setDefaultWidget(Popup);
Menu->addAction(Action);

View file

@ -4,6 +4,7 @@
#include "lc_library.h"
#include "lc_model.h"
#include "pieceinf.h"
#include "lc_partselectionwidget.h"
QString lcFormatValue(float Value, int Precision)
{
@ -170,82 +171,58 @@ QVariant lcPieceIdStringModel::data(const QModelIndex& Index, int Role) const
return QVariant();
}
lcPieceIdPickerPopup::lcPieceIdPickerPopup(lcModel* Model, PieceInfo* Current, QWidget* Parent)
: QWidget(Parent)
lcPieceIdPickerPopup::lcPieceIdPickerPopup(PieceInfo* Current, QWidget* Parent)
: QWidget(Parent), mInitialPart(Current)
{
QVBoxLayout* Layout = new QVBoxLayout(this);
mFilterEdit = new QLineEdit(this);
mFilterEdit->setPlaceholderText(tr("Filter"));
Layout->addWidget(mFilterEdit);
mPartSelectionWidget = new lcPartSelectionWidget(this);
Layout->addWidget(mPartSelectionWidget);
connect(mFilterEdit, &QLineEdit::textEdited, this, &lcPieceIdPickerPopup::FilterEdited);
mPartSelectionWidget->setMinimumWidth(450);
mListView = new QListView(this);
mListView->setEditTriggers(QAbstractItemView::NoEditTriggers);
mListView->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
mListView->setSelectionBehavior(QAbstractItemView::SelectRows);
mListView->setSelectionMode(QAbstractItemView::SingleSelection);
mListView->setUniformItemSizes(true);
connect(mPartSelectionWidget, &lcPartSelectionWidget::PartDoubleClicked, this, &lcPieceIdPickerPopup::PartDoubleClicked);
mListView->installEventFilter(this);
QDialogButtonBox* ButtonBox = new QDialogButtonBox(QDialogButtonBox::Ok|QDialogButtonBox::Cancel, this);
Layout->addWidget(ButtonBox);
lcPieceIdStringModel* StringModel = new lcPieceIdStringModel(Model, mListView);
mListView->setModel(StringModel);
mListView->setMinimumWidth(450);
mListView->setTextElideMode(Qt::ElideMiddle);
if (Current)
mListView->setCurrentIndex(StringModel->Index(Current));
Layout->addWidget(mListView);
connect(mListView, &QListView::doubleClicked, this, &lcPieceIdPickerPopup::ListViewDoubleClicked);
QObject::connect(ButtonBox, &QDialogButtonBox::accepted, this, &lcPieceIdPickerPopup::Accept);
QObject::connect(ButtonBox, &QDialogButtonBox::rejected, this, &lcPieceIdPickerPopup::Reject);
}
bool lcPieceIdPickerPopup::eventFilter(QObject* Object, QEvent* Event)
void lcPieceIdPickerPopup::showEvent(QShowEvent* ShowEvent)
{
if (Object == mListView && Event->type() == QEvent::KeyPress)
{
EmitSelectedEvent(mListView->currentIndex());
return true;
}
QWidget::showEvent(ShowEvent);
return QWidget::eventFilter(Object, Event);
mPartSelectionWidget->SetOrientation(Qt::Horizontal);
mPartSelectionWidget->SetCurrentPart(mInitialPart);
}
void lcPieceIdPickerPopup::EmitSelectedEvent(const QModelIndex& Index)
void lcPieceIdPickerPopup::Accept()
{
if (!Index.isValid())
return;
PieceInfo* Info = mPartSelectionWidget->GetCurrentPart();
lcPieceIdStringModel* StringModel = qobject_cast<lcPieceIdStringModel*>(mListView->model());
QVariant Variant = StringModel->data(Index, Qt::UserRole);
emit PieceIdSelected(Info);
if (Variant.isValid())
{
emit PieceIdSelected(static_cast<PieceInfo*>(Variant.value<void*>()));
}
Close();
}
void lcPieceIdPickerPopup::Reject()
{
Close();
}
void lcPieceIdPickerPopup::PartDoubleClicked(PieceInfo* Info)
{
emit PieceIdSelected(Info);
Close();
}
void lcPieceIdPickerPopup::Close()
{
QMenu* Menu = qobject_cast<QMenu*>(parent());
Menu->close();
}
void lcPieceIdPickerPopup::ListViewDoubleClicked(const QModelIndex& Index)
{
EmitSelectedEvent(Index);
}
void lcPieceIdPickerPopup::FilterEdited(const QString& Text)
{
lcPieceIdStringModel* StringModel = qobject_cast<lcPieceIdStringModel*>(mListView->model());
std::vector<bool> FilteredRows = StringModel->GetFilteredRows(Text);
mListView->setUpdatesEnabled(false);
for (int Row = 0; Row < static_cast<int>(FilteredRows.size()); Row++)
mListView->setRowHidden(Row, !FilteredRows[Row]);
mListView->setUpdatesEnabled(true);
if (Menu)
Menu->close();
}

View file

@ -2,6 +2,8 @@
#include <QObject>
class lcPartSelectionWidget;
QString lcFormatValue(float Value, int Precision);
QString lcFormatValueLocalized(float Value);
float lcParseValueLocalized(const QString& Value);
@ -170,20 +172,20 @@ class lcPieceIdPickerPopup : public QWidget
Q_OBJECT
public:
lcPieceIdPickerPopup(lcModel* Model, PieceInfo* Current, QWidget* Parent);
bool eventFilter(QObject* Object, QEvent* Event) override;
lcPieceIdPickerPopup(PieceInfo* Current, QWidget* Parent);
signals:
void PieceIdSelected(PieceInfo* Info);
protected slots:
void ListViewDoubleClicked(const QModelIndex& Index);
void FilterEdited(const QString& Text);
void Accept();
void Reject();
void PartDoubleClicked(PieceInfo* Info);
protected:
void EmitSelectedEvent(const QModelIndex& Index);
void showEvent(QShowEvent* ShowEvent) override;
void Close();
QListView* mListView = nullptr;
QLineEdit* mFilterEdit = nullptr;
lcPartSelectionWidget* mPartSelectionWidget = nullptr;
PieceInfo* mInitialPart = nullptr;
};