Refactored part picker popups.

This commit is contained in:
Leonardo Zide
2025-07-08 19:31:27 -07:00
parent 548b2218af
commit 2e507036d9
11 changed files with 185 additions and 299 deletions
+4 -1
View File
@@ -11,6 +11,7 @@
#include "camera.h"
#include "lc_doublespinbox.h"
#include "lc_qutils.h"
#include "lc_partselectionpopup.h"
lcMinifigDialog::lcMinifigDialog(QWidget* Parent)
: QDialog(Parent), ui(new Ui::lcMinifigDialog)
@@ -309,7 +310,9 @@ void lcMinifigDialog::PieceButtonClicked()
if (Setting.Info)
Parts.emplace_back(Setting.Info, Setting.Description);
std::optional<PieceInfo*> Result = lcShowPieceListPopup(PieceButton, CurrentInfo, Parts, mMinifigWizard->mMinifig.Colors[ItemIndex], false, true, Position);
int ColorIndex = mMinifigWizard->mMinifig.Colors[ItemIndex];
std::optional<PieceInfo*> Result = lcShowPartSelectionPopup(CurrentInfo, Parts, ColorIndex, PieceButton, PieceButton->mapToGlobal(PieceButton->rect().bottomLeft()));
if (!Result.has_value())
return;
+77
View File
@@ -0,0 +1,77 @@
#include "lc_global.h"
#include "lc_partselectionpopup.h"
#include "lc_partselectionwidget.h"
#include "pieceinf.h"
lcPartSelectionPopup::lcPartSelectionPopup(PieceInfo* InitialPart, QWidget* Parent)
: QWidget(Parent), mInitialPart(InitialPart)
{
QVBoxLayout* Layout = new QVBoxLayout(this);
mPartSelectionWidget = new lcPartSelectionWidget(this);
Layout->addWidget(mPartSelectionWidget);
mPartSelectionWidget->SetDragEnabled(false);
connect(mPartSelectionWidget, &lcPartSelectionWidget::PartPicked, this, &lcPartSelectionPopup::Accept);
QDialogButtonBox* ButtonBox = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel, this);
Layout->addWidget(ButtonBox);
QObject::connect(ButtonBox, &QDialogButtonBox::accepted, this, &lcPartSelectionPopup::Accept);
QObject::connect(ButtonBox, &QDialogButtonBox::rejected, this, &lcPartSelectionPopup::Reject);
}
void lcPartSelectionPopup::showEvent(QShowEvent* ShowEvent)
{
QWidget::showEvent(ShowEvent);
mPartSelectionWidget->SetOrientation(Qt::Horizontal);
mPartSelectionWidget->SetCurrentPart(mInitialPart);
mPartSelectionWidget->FocusPartFilterWidget();
}
void lcPartSelectionPopup::Accept()
{
mPickedPiece = mPartSelectionWidget->GetCurrentPart();
mAccepted = true;
Close();
}
void lcPartSelectionPopup::Reject()
{
Close();
}
void lcPartSelectionPopup::Close()
{
QMenu* Menu = qobject_cast<QMenu*>(parent());
if (Menu)
Menu->close();
}
std::optional<PieceInfo*> lcShowPartSelectionPopup(PieceInfo* InitialPart, const std::vector<std::pair<PieceInfo*, std::string>>& CustomParts, int ColorIndex, QWidget* Parent, QPoint Position)
{
std::unique_ptr<QMenu> Menu(new QMenu(Parent));
QWidgetAction* Action = new QWidgetAction(Menu.get());
lcPartSelectionPopup* Popup = new lcPartSelectionPopup(InitialPart, Menu.get());
lcPartSelectionWidget* PartSelectionWidget = Popup->GetPartSelectionWidget();
if (CustomParts.empty())
{
PartSelectionWidget->SetCategory(lcPartCategoryType::AllParts, 0);
PartSelectionWidget->SetColorIndex(ColorIndex);
}
else
PartSelectionWidget->SetCustomParts(CustomParts, ColorIndex);
Action->setDefaultWidget(Popup);
Menu->addAction(Action);
Menu->exec(Position);
return Popup->GetPickedPart();
}
+38
View File
@@ -0,0 +1,38 @@
#pragma once
class PieceInfo;
class lcPartSelectionWidget;
class lcPartSelectionPopup : public QWidget
{
Q_OBJECT
public:
lcPartSelectionPopup(PieceInfo* InitialPart, QWidget* Parent);
virtual ~lcPartSelectionPopup() = default;
std::optional<PieceInfo*> GetPickedPart() const
{
return mAccepted ? std::optional<PieceInfo*>(mPickedPiece) : std::nullopt;
}
lcPartSelectionWidget* GetPartSelectionWidget() const
{
return mPartSelectionWidget;
}
protected slots:
void Accept();
void Reject();
protected:
void showEvent(QShowEvent* ShowEvent) override;
void Close();
lcPartSelectionWidget* mPartSelectionWidget = nullptr;
PieceInfo* mInitialPart = nullptr;
PieceInfo* mPickedPiece = nullptr;
bool mAccepted = false;
};
std::optional<PieceInfo*> lcShowPartSelectionPopup(PieceInfo* InitialPart, const std::vector<std::pair<PieceInfo*, std::string>>& CustomParts, int ColorIndex, QWidget* Parent, QPoint Position);
+18 -41
View File
@@ -234,7 +234,7 @@ void lcPartSelectionListModel::SetCurrentModelCategory()
SetFilter(mFilter);
}
void lcPartSelectionListModel::SetCustomParts(const std::vector<std::pair<PieceInfo*, std::string>>& Parts, int ColorIndex, bool Sort)
void lcPartSelectionListModel::SetCustomParts(const std::vector<std::pair<PieceInfo*, std::string>>& Parts, int ColorIndex)
{
beginResetModel();
@@ -255,22 +255,6 @@ void lcPartSelectionListModel::SetCustomParts(const std::vector<std::pair<PieceI
Entry.ColorIndex = mColorIndex;
}
if (Sort)
{
auto lcPartSortFunc = [](const lcPartSelectionListModelEntry& a, const lcPartSelectionListModelEntry& b)
{
if (!a.Info)
return true;
if (!b.Info)
return false;
return strcmp(a.Info->m_strDescription, b.Info->m_strDescription) < 0;
};
std::sort(mParts.begin(), mParts.end(), lcPartSortFunc);
}
endResetModel();
SetFilter(mFilter);
@@ -694,11 +678,11 @@ void lcPartSelectionListView::SetCategory(lcPartCategoryType Type, int Index)
}
}
void lcPartSelectionListView::SetCustomParts(const std::vector<std::pair<PieceInfo*, std::string>>& Parts, int ColorIndex, bool Sort)
void lcPartSelectionListView::SetCustomParts(const std::vector<std::pair<PieceInfo*, std::string>>& Parts, int ColorIndex)
{
mCategoryType = lcPartCategoryType::Custom;
mListModel->SetCustomParts(Parts, ColorIndex, Sort);
mListModel->SetCustomParts(Parts, ColorIndex);
setCurrentIndex(mListModel->index(0, 0));
}
@@ -871,28 +855,11 @@ QSize lcPartSelectionListView::sizeHint() const
if (mListModel->GetIconSize() == 0)
return QSize(500, 350);
QRect CellRect1 = visualRect(model()->index(0, 0));
QRect RightRect(CellRect1.topRight(), CellRect1.size());
QRect BottomRect(CellRect1.bottomLeft(), CellRect1.size());
for (int Row = 1; Row < model()->rowCount(); Row++)
{
QRect Rect = visualRect(model()->index(Row, 0));
if (Row == 1)
RightRect = Rect;
if (Rect.top() != CellRect1.top())
{
BottomRect = Rect;
break;
}
}
int Columns = 5;
int Rows = qMin(4, (model()->rowCount() + Columns - 1) / Columns);
QSize CellSize(RightRect.left() - CellRect1.left(), BottomRect.top() - CellRect1.top());
QStyleOptionViewItem option = viewOptions();
QSize CellSize = itemDelegate()->sizeHint(option, model()->index(0,0));
QSize Size(CellSize.width() * Columns + frameWidth() * 2, CellSize.height() * Rows + frameWidth() * 2);
if (verticalScrollBar())
@@ -1042,11 +1009,22 @@ void lcPartSelectionWidget::DisableIconMode()
void lcPartSelectionWidget::SetCurrentPart(PieceInfo* Info)
{
mCategoriesWidget->setCurrentItem(mAllPartsCategoryItem);
mPartsWidget->SetCurrentPart(Info);
mPartsWidget->setFocus();
}
void lcPartSelectionWidget::SetCategory(lcPartCategoryType Type, int Index)
{
mPartsWidget->SetCategory(Type, Index);
}
void lcPartSelectionWidget::SetCustomParts(const std::vector<std::pair<PieceInfo*, std::string>>& Parts, int ColorIndex)
{
mSplitter->widget(0)->setVisible(false);
mPartsWidget->SetCustomParts(Parts, ColorIndex);
}
void lcPartSelectionWidget::SetOrientation(Qt::Orientation Orientation)
{
mSplitter->setOrientation(Orientation);
@@ -1175,8 +1153,7 @@ void lcPartSelectionWidget::PartViewSelectionChanged(const QModelIndex& Current,
void lcPartSelectionWidget::PartViewPartPicked(PieceInfo* Info)
{
if (Info)
emit PartPicked(Info);
emit PartPicked(Info);
}
void lcPartSelectionWidget::OptionsMenuAboutToShow()
+9 -2
View File
@@ -151,7 +151,7 @@ public:
void SetModelsCategory();
void SetPaletteCategory(int SetIndex);
void SetCurrentModelCategory();
void SetCustomParts(const std::vector<std::pair<PieceInfo*, std::string>>& Parts, int ColorIndex, bool Sort);
void SetCustomParts(const std::vector<std::pair<PieceInfo*, std::string>>& Parts, int ColorIndex);
void SetFilter(const QString& Filter);
void RequestThumbnail(int PartIndex);
void SetShowDecoratedParts(bool Show);
@@ -196,7 +196,7 @@ public:
QSize sizeHint() const override;
void SetCategory(lcPartCategoryType Type, int Index);
void SetCustomParts(const std::vector<std::pair<PieceInfo*, std::string>>& Parts, int ColorIndex, bool Sort);
void SetCustomParts(const std::vector<std::pair<PieceInfo*, std::string>>& Parts, int ColorIndex);
void SetCurrentPart(PieceInfo* Info);
PieceInfo* GetCurrentPart() const
@@ -277,6 +277,8 @@ public:
void DisableIconMode();
void SetOrientation(Qt::Orientation Orientation);
void SetCurrentPart(PieceInfo* Info);
void SetCategory(lcPartCategoryType Type, int Index);
void SetCustomParts(const std::vector<std::pair<PieceInfo*, std::string>>& Parts, int ColorIndex);
int GetColorIndex() const
{
@@ -298,6 +300,11 @@ public:
return mPartsWidget->GetCurrentPart();
}
void SetDragEnabled(bool Enabled)
{
mPartsWidget->setDragEnabled(Enabled);
}
void FocusPartFilterWidget() const
{
mFilterWidget->setFocus();
+14 -24
View File
@@ -11,6 +11,7 @@
#include "lc_collapsiblewidget.h"
#include "lc_colorpicker.h"
#include "lc_qutils.h"
#include "lc_partselectionpopup.h"
lcPropertiesWidget::lcPropertiesWidget(QWidget* Parent)
: QWidget(Parent)
@@ -1088,35 +1089,24 @@ void lcPropertiesWidget::PieceIdButtonClicked()
std::tie(Value, Partial) = GetUpdateValue(PropertyId);
PieceInfo* Info = static_cast<PieceInfo*>(Value.value<void*>());
PieceInfo* Info = Partial ? nullptr : static_cast<PieceInfo*>(Value.value<void*>());
QMenu* Menu = new QMenu(PieceIdButton);
std::tie(Value, Partial) = GetUpdateValue(lcObjectPropertyId::PieceColor);
int ColorIndex = Partial ? gDefaultColor : Value.toInt();
QWidgetAction* Action = new QWidgetAction(Menu);
lcPieceIdPickerPopup* Popup = new lcPieceIdPickerPopup(Partial ? nullptr : Info, Menu);
Action->setDefaultWidget(Popup);
Menu->addAction(Action);
std::optional<PieceInfo*> Result = lcShowPartSelectionPopup(Info, std::vector<std::pair<PieceInfo*, std::string>>(), ColorIndex, PieceIdButton, PieceIdButton->mapToGlobal(PieceIdButton->rect().bottomLeft()));
connect(Popup, &lcPieceIdPickerPopup::PieceIdSelected, this, &lcPropertiesWidget::PieceIdChanged);
if (Result.has_value())
{
lcModel* Model = gMainWindow->GetActiveModel();
Info = Result.value();
Menu->exec(PieceIdButton->mapToGlobal(PieceIdButton->rect().bottomLeft()));
if (!Model || !Info)
return;
delete Menu;
}
void lcPropertiesWidget::PieceIdChanged(PieceInfo* Info)
{
lcPieceIdPickerPopup* Popup = qobject_cast<lcPieceIdPickerPopup*>(sender());
QMenu* Menu = qobject_cast<QMenu*>(Popup->parent());
QToolButton* PieceIdButton = qobject_cast<QToolButton*>(Menu->parent());
lcObjectPropertyId PropertyId = GetEditorWidgetPropertyId(PieceIdButton);
lcModel* Model = gMainWindow->GetActiveModel();
if (!Model || !Info)
return;
Model->SetObjectsProperty(mFocusObject ? std::vector<lcObject*>{ mFocusObject } : mSelection, PropertyId, QVariant::fromValue<void*>(Info));
Model->SetObjectsProperty(mFocusObject ? std::vector<lcObject*>{ mFocusObject } : mSelection, PropertyId, QVariant::fromValue<void*>(Info));
}
}
void lcPropertiesWidget::AddPieceIdProperty(lcObjectPropertyId PropertyId, const QString& Text, const QString& ToolTip, bool SupportsKeyFrames)
-1
View File
@@ -30,7 +30,6 @@ protected slots:
void PieceColorButtonClicked();
void PieceColorChanged(int ColorIndex);
void PieceIdButtonClicked();
void PieceIdChanged(PieceInfo* Info);
protected:
enum class CategoryIndex
+23 -1
View File
@@ -18,6 +18,7 @@
#include "lc_findreplacewidget.h"
#include "lc_library.h"
#include "lc_qutils.h"
#include "lc_partselectionpopup.h"
lcFindReplaceParams lcView::mFindReplaceParams;
QPointer<lcFindReplaceWidget> lcView::mFindWidget;
@@ -330,8 +331,29 @@ void lcView::ShowTrainTrackPopup()
int ConnectionIndex = mTrackToolSection - LC_PIECE_SECTION_TRAIN_TRACK_CONNECTION_FIRST;
const lcTrainTrackConnectionType& ConnectionType = TrainTrackInfo->GetConnections()[ConnectionIndex].Type;
std::vector<PieceInfo*> TrainTrackParts = lcGetPiecesLibrary()->GetVisibleTrainTrackParts(ConnectionType);
std::optional<PieceInfo*> Result = lcShowTrainTrackPopup(mWidget, ConnectionType);
auto PartSortFunc = [](const PieceInfo* a, const PieceInfo* b)
{
if (!a)
return true;
if (!b)
return false;
return strcmp(a->m_strDescription, b->m_strDescription) < 0;
};
std::sort(TrainTrackParts.begin(), TrainTrackParts.end(), PartSortFunc);
std::vector<std::pair<PieceInfo*, std::string>> Parts;
Parts.reserve(TrainTrackParts.size());
for (PieceInfo* Info : TrainTrackParts)
Parts.emplace_back(Info, std::string());
std::optional<PieceInfo*> Result = lcShowPartSelectionPopup(nullptr, Parts, gMainWindow->mColorIndex, mWidget, QCursor::pos());
PieceInfo* Info = Result.has_value() ? Result.value() : nullptr;
if (Info)
+2
View File
@@ -210,6 +210,7 @@ SOURCES += \
common/lc_objectproperty.cpp \
common/lc_pagesetupdialog.cpp \
common/lc_partpalettedialog.cpp \
common/lc_partselectionpopup.cpp \
common/lc_partselectionwidget.cpp \
common/lc_previewwidget.cpp \
common/lc_profile.cpp \
@@ -286,6 +287,7 @@ HEADERS += \
common/lc_modellistdialog.h \
common/lc_objectproperty.h \
common/lc_pagesetupdialog.h \
common/lc_partselectionpopup.h \
common/lc_partselectionwidget.h \
common/lc_previewwidget.h \
common/lc_profile.h \
-172
View File
@@ -172,178 +172,6 @@ QVariant lcPieceIdStringModel::data(const QModelIndex& Index, int Role) const
return QVariant();
}
lcPieceIdPickerPopup::lcPieceIdPickerPopup(PieceInfo* Current, QWidget* Parent)
: QWidget(Parent), mInitialPart(Current)
{
QVBoxLayout* Layout = new QVBoxLayout(this);
mPartSelectionWidget = new lcPartSelectionWidget(this);
Layout->addWidget(mPartSelectionWidget);
mPartSelectionWidget->setMinimumWidth(450);
connect(mPartSelectionWidget, &lcPartSelectionWidget::PartPicked, this, &lcPieceIdPickerPopup::PartPicked);
QDialogButtonBox* ButtonBox = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel, this);
Layout->addWidget(ButtonBox);
QObject::connect(ButtonBox, &QDialogButtonBox::accepted, this, &lcPieceIdPickerPopup::Accept);
QObject::connect(ButtonBox, &QDialogButtonBox::rejected, this, &lcPieceIdPickerPopup::Reject);
}
void lcPieceIdPickerPopup::showEvent(QShowEvent* ShowEvent)
{
QWidget::showEvent(ShowEvent);
mPartSelectionWidget->SetOrientation(Qt::Horizontal);
mPartSelectionWidget->SetCurrentPart(mInitialPart);
mPartSelectionWidget->FocusPartFilterWidget();
}
void lcPieceIdPickerPopup::Accept()
{
PieceInfo* Info = mPartSelectionWidget->GetCurrentPart();
emit PieceIdSelected(Info);
Close();
}
void lcPieceIdPickerPopup::Reject()
{
Close();
}
void lcPieceIdPickerPopup::PartPicked(PieceInfo* Info)
{
emit PieceIdSelected(Info);
Close();
}
void lcPieceIdPickerPopup::Close()
{
QMenu* Menu = qobject_cast<QMenu*>(parent());
if (Menu)
Menu->close();
}
lcPieceListPickerPopup::lcPieceListPickerPopup(QWidget* Parent, PieceInfo* InitialPart, const std::vector<std::pair<PieceInfo*, std::string>>& Parts, int ColorIndex, bool Sort, bool ShowFilter)
: QWidget(Parent), mInitialPart(InitialPart)
{
QVBoxLayout* Layout = new QVBoxLayout(this);
if (ShowFilter)
{
mFilterWidget = new QLineEdit(this);
mFilterWidget->setPlaceholderText(tr("Filter Parts"));
Layout->addWidget(mFilterWidget);
connect(mFilterWidget, &QLineEdit::textChanged, this, &lcPieceListPickerPopup::FilterChanged);
}
mPartSelectionListView = new lcPartSelectionListView(this, nullptr);
Layout->addWidget(mPartSelectionListView);
mPartSelectionListView->setMinimumWidth(450);
mPartSelectionListView->setDragEnabled(false);
mPartSelectionListView->SetCustomParts(Parts, ColorIndex, Sort);
connect(mPartSelectionListView, &lcPartSelectionListView::PartPicked, this, &lcPieceListPickerPopup::Accept);
QDialogButtonBox* ButtonBox = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel, this);
Layout->addWidget(ButtonBox);
QObject::connect(ButtonBox, &QDialogButtonBox::accepted, this, &lcPieceListPickerPopup::Accept);
QObject::connect(ButtonBox, &QDialogButtonBox::rejected, this, &lcPieceListPickerPopup::Reject);
}
void lcPieceListPickerPopup::showEvent(QShowEvent* ShowEvent)
{
QWidget::showEvent(ShowEvent);
mPartSelectionListView->SetCurrentPart(mInitialPart);
mPartSelectionListView->setFocus();
}
void lcPieceListPickerPopup::Accept()
{
mPickedPiece = mPartSelectionListView->GetCurrentPart();
mAccepted = true;
Close();
}
void lcPieceListPickerPopup::Reject()
{
Close();
}
void lcPieceListPickerPopup::Close()
{
QMenu* Menu = qobject_cast<QMenu*>(parent());
if (Menu)
Menu->close();
}
void lcPieceListPickerPopup::FilterChanged(const QString& Text)
{
if (mFilterAction)
{
if (Text.isEmpty())
{
delete mFilterAction;
mFilterAction = nullptr;
}
}
else
{
if (!Text.isEmpty())
{
mFilterAction = mFilterWidget->addAction(QIcon(":/stylesheet/close.svg"), QLineEdit::TrailingPosition);
connect(mFilterAction, &QAction::triggered, this, &lcPieceListPickerPopup::FilterTriggered);
}
}
mPartSelectionListView->GetListModel()->SetFilter(Text);
}
void lcPieceListPickerPopup::FilterTriggered()
{
mFilterWidget->clear();
}
std::optional<PieceInfo*> lcShowPieceListPopup(QWidget* Parent, PieceInfo* InitialPart, const std::vector<std::pair<PieceInfo*, std::string>>& Parts, int ColorIndex, bool Sort, bool ShowFilter, QPoint Position)
{
std::unique_ptr<QMenu> Menu(new QMenu(Parent));
QWidgetAction* Action = new QWidgetAction(Menu.get());
lcPieceListPickerPopup* Popup = new lcPieceListPickerPopup(Menu.get(), InitialPart, Parts, ColorIndex, Sort, ShowFilter);
Action->setDefaultWidget(Popup);
Menu->addAction(Action);
Menu->exec(Position);
return Popup->GetPickedPiece();
}
std::optional<PieceInfo*> lcShowTrainTrackPopup(QWidget* Parent, const lcTrainTrackConnectionType& ConnectionType)
{
std::vector<PieceInfo*> TrainTrackParts = lcGetPiecesLibrary()->GetVisibleTrainTrackParts(ConnectionType);
std::vector<std::pair<PieceInfo*, std::string>> Parts;
Parts.reserve(TrainTrackParts.size());
for (PieceInfo* Info : TrainTrackParts)
Parts.emplace_back(Info, std::string());
return lcShowPieceListPopup(Parent, nullptr, Parts, gMainWindow->mColorIndex, true, false, QCursor::pos());
}
lcColorDialogPopup::lcColorDialogPopup(const QColor& InitialColor, QWidget* Parent)
: QWidget(Parent)
{
-57
View File
@@ -169,63 +169,6 @@ protected:
std::vector<PieceInfo*> mSortedPieces;
};
class lcPieceIdPickerPopup : public QWidget
{
Q_OBJECT
public:
lcPieceIdPickerPopup(PieceInfo* Current, QWidget* Parent);
signals:
void PieceIdSelected(PieceInfo* Info);
protected slots:
void Accept();
void Reject();
void PartPicked(PieceInfo* Info);
protected:
void showEvent(QShowEvent* ShowEvent) override;
void Close();
lcPartSelectionWidget* mPartSelectionWidget = nullptr;
PieceInfo* mInitialPart = nullptr;
};
class lcPieceListPickerPopup : public QWidget
{
Q_OBJECT
public:
lcPieceListPickerPopup(QWidget* Parent, PieceInfo* InitialPart, const std::vector<std::pair<PieceInfo*, std::string>>& Parts, int ColorIndex, bool Sort, bool ShowFilter);
virtual ~lcPieceListPickerPopup() = default;
std::optional<PieceInfo*> GetPickedPiece() const
{
return mAccepted ? std::optional<PieceInfo*>(mPickedPiece) : std::nullopt;
}
protected slots:
void Accept();
void Reject();
void FilterChanged(const QString& Text);
void FilterTriggered();
protected:
void showEvent(QShowEvent* ShowEvent) override;
void Close();
lcPartSelectionListView* mPartSelectionListView = nullptr;
QLineEdit* mFilterWidget = nullptr;
QAction* mFilterAction = nullptr;
PieceInfo* mInitialPart = nullptr;
PieceInfo* mPickedPiece = nullptr;
bool mAccepted = false;
};
std::optional<PieceInfo*> lcShowPieceListPopup(QWidget* Parent, PieceInfo* InitialPart, const std::vector<std::pair<PieceInfo*, std::string>>& Parts, int ColorIndex, bool Sort, bool ShowFilter, QPoint Position);
std::optional<PieceInfo*> lcShowTrainTrackPopup(QWidget* Parent, const lcTrainTrackConnectionType& ConnectionType);
class lcColorDialogPopup : public QWidget
{
Q_OBJECT