Added thumbnail manager.

This commit is contained in:
Leonardo Zide 2024-07-11 15:04:07 -07:00
parent 7451d336f7
commit f06a231816
8 changed files with 307 additions and 192 deletions

View file

@ -1,5 +1,6 @@
#include "lc_global.h"
#include "lc_library.h"
#include "lc_thumbnailmanager.h"
#include "lc_zipfile.h"
#include "lc_file.h"
#include "pieceinf.h"
@ -33,6 +34,7 @@ lcPiecesLibrary::lcPiecesLibrary()
: mLoadMutex(QMutex::Recursive)
#endif
{
mThumbnailManager = std::unique_ptr<lcThumbnailManager>(new lcThumbnailManager(this));
QStringList cachePathList = QStandardPaths::standardLocations(QStandardPaths::CacheLocation);
mCachePath = cachePathList.first();
@ -49,6 +51,7 @@ lcPiecesLibrary::lcPiecesLibrary()
lcPiecesLibrary::~lcPiecesLibrary()
{
mThumbnailManager.reset();
mLoadMutex.lock();
mLoadQueue.clear();
mLoadMutex.unlock();

View file

@ -7,6 +7,7 @@
class PieceInfo;
class lcZipFile;
class lcLibraryMeshData;
class lcThumbnailManager;
enum class lcStudStyle
{
@ -126,6 +127,11 @@ public:
lcPiecesLibrary& operator=(const lcPiecesLibrary&) = delete;
lcPiecesLibrary& operator=(lcPiecesLibrary&&) = delete;
lcThumbnailManager* GetThumbnailManager() const
{
return mThumbnailManager.get();
}
bool Load(const QString& LibraryPath, bool ShowProgress);
void LoadColors();
void Unload();
@ -234,6 +240,7 @@ protected:
lcStudStyle mStudStyle;
bool mStudCylinderColorEnabled;
std::unique_ptr<lcThumbnailManager> mThumbnailManager;
QString mCachePath;
qint64 mArchiveCheckSum[4];
std::unique_ptr<lcZipFile> mZipFiles[static_cast<int>(lcZipFileType::Count)];

View file

@ -1341,7 +1341,7 @@ void lcMainWindow::SetShadingMode(lcShadingMode ShadingMode)
lcView::UpdateAllViews();
if (mPartSelectionWidget)
mPartSelectionWidget->Redraw();
mPartSelectionWidget->UpdateThumbnails();
}
void lcMainWindow::SetSelectionMode(lcSelectionMode SelectionMode)

View file

@ -5,12 +5,9 @@
#include "lc_application.h"
#include "lc_mainwindow.h"
#include "lc_library.h"
#include "lc_model.h"
#include "lc_thumbnailmanager.h"
#include "project.h"
#include "pieceinf.h"
#include "camera.h"
#include "lc_scene.h"
#include "lc_view.h"
#include "lc_glextensions.h"
#include "lc_category.h"
@ -18,7 +15,7 @@ Q_DECLARE_METATYPE(QList<int>)
void lcPartSelectionItemDelegate::paint(QPainter* Painter, const QStyleOptionViewItem& Option, const QModelIndex& Index) const
{
mListModel->RequestPreview(Index.row());
mListModel->RequestThumbnail(Index.row());
QStyledItemDelegate::paint(Painter, Option, Index);
}
@ -60,38 +57,19 @@ lcPartSelectionListModel::lcPartSelectionListModel(QObject* Parent)
mColorLocked = true;
}
connect(lcGetPiecesLibrary(), &lcPiecesLibrary::PartLoaded, this, &lcPartSelectionListModel::PartLoaded);
connect(lcGetPiecesLibrary()->GetThumbnailManager(), &lcThumbnailManager::ThumbnailReady, this, &lcPartSelectionListModel::ThumbnailReady);
}
lcPartSelectionListModel::~lcPartSelectionListModel()
{
ClearRequests();
mView.reset();
mModel.reset();
ReleaseThumbnails();
}
void lcPartSelectionListModel::ClearRequests()
void lcPartSelectionListModel::UpdateThumbnails()
{
lcPiecesLibrary* Library = lcGetPiecesLibrary();
for (int RequestIdx : mRequestedPreviews)
{
PieceInfo* Info = mParts[RequestIdx].first;
Library->ReleasePieceInfo(Info);
}
mRequestedPreviews.clear();
}
void lcPartSelectionListModel::Redraw()
{
ClearRequests();
beginResetModel();
for (size_t PartIdx = 0; PartIdx < mParts.size(); PartIdx++)
mParts[PartIdx].second = QPixmap();
ReleaseThumbnails();
endResetModel();
@ -103,8 +81,9 @@ void lcPartSelectionListModel::SetColorIndex(int ColorIndex)
if (mColorLocked || ColorIndex == mColorIndex)
return;
UpdateThumbnails();
mColorIndex = ColorIndex;
Redraw();
}
void lcPartSelectionListModel::ToggleColorLocked()
@ -125,10 +104,10 @@ void lcPartSelectionListModel::ToggleListMode()
void lcPartSelectionListModel::SetCategory(int CategoryIndex)
{
ClearRequests();
beginResetModel();
ReleaseThumbnails();
lcPiecesLibrary* Library = lcGetPiecesLibrary();
std::vector<PieceInfo*> SingleParts, GroupedParts;
@ -160,8 +139,8 @@ void lcPartSelectionListModel::SetCategory(int CategoryIndex)
mParts.resize(SingleParts.size());
for (size_t PartIdx = 0; PartIdx < SingleParts.size(); PartIdx++)
mParts[PartIdx] = std::pair<PieceInfo*, QPixmap>(SingleParts[PartIdx], QPixmap());
for (size_t PartIndex = 0; PartIndex < SingleParts.size(); PartIndex++)
mParts[PartIndex].Info = SingleParts[PartIndex];
endResetModel();
@ -170,10 +149,9 @@ void lcPartSelectionListModel::SetCategory(int CategoryIndex)
void lcPartSelectionListModel::SetModelsCategory()
{
ClearRequests();
beginResetModel();
ReleaseThumbnails();
mParts.clear();
const std::vector<std::unique_ptr<lcModel>>& Models = lcGetActiveProject()->GetModels();
@ -181,11 +159,11 @@ void lcPartSelectionListModel::SetModelsCategory()
for (const std::unique_ptr<lcModel>& Model : Models)
if (!Model->IncludesModel(ActiveModel))
mParts.emplace_back(std::pair<PieceInfo*, QPixmap>(Model->GetPieceInfo(), QPixmap()));
mParts.emplace_back().Info = Model->GetPieceInfo();
auto lcPartSortFunc = [](const std::pair<PieceInfo*, QPixmap>& a, const std::pair<PieceInfo*, QPixmap>& b)
auto lcPartSortFunc = [](const lcPartSelectionListModelEntry& a, const lcPartSelectionListModelEntry& b)
{
return strcmp(a.first->m_strDescription, b.first->m_strDescription) < 0;
return strcmp(a.Info->m_strDescription, b.Info->m_strDescription) < 0;
};
std::sort(mParts.begin(), mParts.end(), lcPartSortFunc);
@ -197,10 +175,9 @@ void lcPartSelectionListModel::SetModelsCategory()
void lcPartSelectionListModel::SetPaletteCategory(int SetIndex)
{
ClearRequests();
beginResetModel();
ReleaseThumbnails();
mParts.clear();
lcPartSelectionWidget* PartSelectionWidget = mListView->GetPartSelectionWidget();
@ -216,8 +193,8 @@ void lcPartSelectionListModel::SetPaletteCategory(int SetIndex)
mParts.reserve(PartsList.size());
for (PieceInfo* Favorite : PartsList)
mParts.emplace_back(std::pair<PieceInfo*, QPixmap>(Favorite, QPixmap()));
for (PieceInfo* Info : PartsList)
mParts.emplace_back().Info = Info;
endResetModel();
@ -226,10 +203,9 @@ void lcPartSelectionListModel::SetPaletteCategory(int SetIndex)
void lcPartSelectionListModel::SetCurrentModelCategory()
{
ClearRequests();
beginResetModel();
ReleaseThumbnails();
mParts.clear();
lcModel* ActiveModel = gMainWindow->GetActiveModel();
@ -239,11 +215,11 @@ void lcPartSelectionListModel::SetCurrentModelCategory()
ActiveModel->GetPartsList(gDefaultColor, true, true, PartsList);
for (const auto& PartIt : PartsList)
mParts.emplace_back(std::pair<PieceInfo*, QPixmap>((PieceInfo*)PartIt.first, QPixmap()));
mParts.emplace_back().Info = (PieceInfo*)PartIt.first;
auto lcPartSortFunc = [](const std::pair<PieceInfo*, QPixmap>& a, const std::pair<PieceInfo*, QPixmap>& b)
auto lcPartSortFunc = [](const lcPartSelectionListModelEntry& a, const lcPartSelectionListModelEntry& b)
{
return strcmp(a.first->m_strDescription, b.first->m_strDescription) < 0;
return strcmp(a.Info->m_strDescription, b.Info->m_strDescription) < 0;
};
std::sort(mParts.begin(), mParts.end(), lcPartSortFunc);
@ -259,7 +235,7 @@ void lcPartSelectionListModel::SetFilter(const QString& Filter)
for (size_t PartIdx = 0; PartIdx < mParts.size(); PartIdx++)
{
PieceInfo* Info = mParts[PartIdx].first;
PieceInfo* Info = mParts[PartIdx].Info;
bool Visible;
if (!mShowDecoratedParts && Info->IsPatterned() && !Info->IsProjectPiece())
@ -307,7 +283,7 @@ QVariant lcPartSelectionListModel::data(const QModelIndex& Index, int Role) cons
if (Index.isValid() && InfoIndex < mParts.size())
{
PieceInfo* Info = mParts[InfoIndex].first;
PieceInfo* Info = mParts[InfoIndex].Info;
switch (Role)
{
@ -320,8 +296,8 @@ QVariant lcPartSelectionListModel::data(const QModelIndex& Index, int Role) cons
return QVariant(QString("%1 (%2)").arg(QString::fromLatin1(Info->m_strDescription), QString::fromLatin1(Info->mFileName)));
case Qt::DecorationRole:
if (!mParts[InfoIndex].second.isNull() && mIconSize)
return QVariant(mParts[InfoIndex].second);
if (mIconSize && !mParts[InfoIndex].Pixmap.isNull())
return QVariant(mParts[InfoIndex].Pixmap);
else
return QVariant(QColor(0, 0, 0, 0));
@ -351,119 +327,51 @@ Qt::ItemFlags lcPartSelectionListModel::flags(const QModelIndex& Index) const
return DefaultFlags;
}
void lcPartSelectionListModel::RequestPreview(int InfoIndex)
void lcPartSelectionListModel::ReleaseThumbnails()
{
if (!mIconSize || !mParts[InfoIndex].second.isNull())
return;
lcThumbnailManager* ThumbnailManager = lcGetPiecesLibrary()->GetThumbnailManager();
if (std::find(mRequestedPreviews.begin(), mRequestedPreviews.end(), InfoIndex) != mRequestedPreviews.end())
return;
PieceInfo* Info = mParts[InfoIndex].first;
lcGetPiecesLibrary()->LoadPieceInfo(Info, false, false);
if (Info->mState == lcPieceInfoState::Loaded)
DrawPreview(InfoIndex);
else
mRequestedPreviews.push_back(InfoIndex);
for (lcPartSelectionListModelEntry& Part : mParts)
{
ThumbnailManager->ReleaseThumbnail(Part.ThumbnailId);
Part.ThumbnailId = lcPartThumbnailId::Invalid;
Part.Pixmap = QPixmap();
}
}
void lcPartSelectionListModel::PartLoaded(PieceInfo* Info)
void lcPartSelectionListModel::RequestThumbnail(int PartIndex)
{
for (size_t PartIdx = 0; PartIdx < mParts.size(); PartIdx++)
if (!mIconSize || !mParts[PartIndex].Pixmap.isNull() || mParts[PartIndex].ThumbnailId != lcPartThumbnailId::Invalid)
return;
PieceInfo* Info = mParts[PartIndex].Info;
auto [ThumbnailId, Thumbnail] = lcGetPiecesLibrary()->GetThumbnailManager()->RequestThumbnail(Info, mColorIndex, mIconSize);
mParts[PartIndex].ThumbnailId = ThumbnailId;
if (!Thumbnail.isNull())
{
if (mParts[PartIdx].first == Info)
mParts[PartIndex].Pixmap = Thumbnail;
emit dataChanged(index(PartIndex, 0), index(PartIndex, 0), { Qt::DecorationRole });
}
}
void lcPartSelectionListModel::ThumbnailReady(lcPartThumbnailId ThumbnailId, QPixmap Pixmap)
{
for (int PartIndex = 0; PartIndex < static_cast<int>(mParts.size()); PartIndex++)
{
if (mParts[PartIndex].ThumbnailId == ThumbnailId)
{
auto PreviewIt = std::find(mRequestedPreviews.begin(), mRequestedPreviews.end(), static_cast<int>(PartIdx));
if (PreviewIt != mRequestedPreviews.end())
{
mRequestedPreviews.erase(PreviewIt);
DrawPreview((int)PartIdx);
}
mParts[PartIndex].Pixmap = Pixmap;
emit dataChanged(index(PartIndex, 0), index(PartIndex, 0), { Qt::DecorationRole });
break;
}
}
}
void lcPartSelectionListModel::DrawPreview(int InfoIndex)
{
const int Width = mIconSize * 2;
const int Height = mIconSize * 2;
if (mView && (mView->GetWidth() != Width || mView->GetHeight() != Height))
mView.reset();
if (!mView)
{
if (!mModel)
mModel = std::unique_ptr<lcModel>(new lcModel(QString(), nullptr, true));
mView = std::unique_ptr<lcView>(new lcView(lcViewType::PartsList, mModel.get()));
mView->SetOffscreenContext();
mView->MakeCurrent();
mView->SetSize(Width, Height);
if (!mView->BeginRenderToImage(Width, Height))
{
mView.reset();
return;
}
}
mView->MakeCurrent();
mView->BindRenderFramebuffer();
const uint BackgroundColor = mListView->palette().color(QPalette::Base).rgba();
mView->SetBackgroundColorOverride(LC_RGBA(qRed(BackgroundColor), qGreen(BackgroundColor), qBlue(BackgroundColor), 0));
PieceInfo* Info = mParts[InfoIndex].first;
mModel->SetPreviewPieceInfo(Info, mColorIndex);
const lcVector3 Center = (Info->GetBoundingBox().Min + Info->GetBoundingBox().Max) / 2.0f;
const lcVector3 Position = Center + lcVector3(100.0f, -100.0f, 75.0f);
mView->GetCamera()->SetViewpoint(Position, Center, lcVector3(0, 0, 1));
mView->GetCamera()->m_fovy = 20.0f;
mView->ZoomExtents();
mView->OnDraw();
mView->UnbindRenderFramebuffer();
QImage Image = mView->GetRenderFramebufferImage().convertToFormat(QImage::Format_ARGB32);
if (Info->GetSynthInfo())
{
QPainter Painter(&Image);
QImage Icon = QImage(":/resources/flexible.png");
uchar* ImageBits = Icon.bits();
QRgb TextColor = mListView->palette().color(QPalette::WindowText).rgba();
int Red = qRed(TextColor);
int Green = qGreen(TextColor);
int Blue = qBlue(TextColor);
for (int y = 0; y < Icon.height(); y++)
{
for (int x = 0; x < Icon.width(); x++)
{
QRgb& Pixel = ((QRgb*)ImageBits)[x];
Pixel = qRgba(Red, Green, Blue, qAlpha(Pixel));
}
ImageBits += Icon.bytesPerLine();
}
Painter.drawImage(QPoint(0, 0), Icon);
Painter.end();
}
mParts[InfoIndex].second = QPixmap::fromImage(Image).scaled(mIconSize, mIconSize, Qt::IgnoreAspectRatio, Qt::SmoothTransformation);
lcGetPiecesLibrary()->ReleasePieceInfo(Info);
emit dataChanged(index(InfoIndex, 0), index(InfoIndex, 0), QVector<int>() << Qt::DecorationRole);
}
void lcPartSelectionListModel::SetShowDecoratedParts(bool Show)
{
if (Show == mShowDecoratedParts)
@ -493,8 +401,7 @@ void lcPartSelectionListModel::SetIconSize(int Size)
beginResetModel();
for (size_t PartIdx = 0; PartIdx < mParts.size(); PartIdx++)
mParts[PartIdx].second = QPixmap();
ReleaseThumbnails();
endResetModel();
@ -1036,9 +943,9 @@ void lcPartSelectionWidget::EditPartPalettes()
UpdateCategories();
}
void lcPartSelectionWidget::Redraw()
void lcPartSelectionWidget::UpdateThumbnails()
{
mPartsWidget->GetListModel()->Redraw();
mPartsWidget->GetListModel()->UpdateThumbnails();
}
void lcPartSelectionWidget::SetDefaultPart()

View file

@ -1,6 +1,6 @@
#pragma once
#include "lc_context.h"
#include "lc_thumbnailmanager.h"
class lcPartSelectionListModel;
class lcPartSelectionListView;
@ -45,6 +45,13 @@ protected:
lcPartSelectionListModel* mListModel;
};
struct lcPartSelectionListModelEntry
{
PieceInfo* Info = nullptr;
QPixmap Pixmap;
lcPartThumbnailId ThumbnailId = lcPartThumbnailId::Invalid;
};
class lcPartSelectionListModel : public QAbstractListModel
{
Q_OBJECT
@ -60,12 +67,12 @@ public:
PieceInfo* GetPieceInfo(const QModelIndex& Index) const
{
return Index.isValid() ? mParts[Index.row()].first : nullptr;
return Index.isValid() ? mParts[Index.row()].Info : nullptr;
}
PieceInfo* GetPieceInfo(int Row) const
{
return mParts[Row].first;
return mParts[Row].Info;
}
bool GetShowDecoratedParts() const
@ -103,7 +110,7 @@ public:
return mListMode;
}
void Redraw();
void UpdateThumbnails();
void SetColorIndex(int ColorIndex);
void ToggleColorLocked();
void ToggleListMode();
@ -112,22 +119,20 @@ public:
void SetPaletteCategory(int SetIndex);
void SetCurrentModelCategory();
void SetFilter(const QString& Filter);
void RequestPreview(int InfoIndex);
void RequestThumbnail(int PartIndex);
void SetShowDecoratedParts(bool Show);
void SetShowPartAliases(bool Show);
void SetIconSize(int Size);
void SetShowPartNames(bool Show);
protected slots:
void PartLoaded(PieceInfo* Info);
void ThumbnailReady(lcPartThumbnailId ThumbnailId, QPixmap Pixmap);
protected:
void ClearRequests();
void DrawPreview(int InfoIndex);
void ReleaseThumbnails();
lcPartSelectionListView* mListView;
std::vector<std::pair<PieceInfo*, QPixmap>> mParts;
std::vector<int> mRequestedPreviews;
std::vector<lcPartSelectionListModelEntry> mParts;
int mIconSize;
bool mColorLocked;
int mColorIndex;
@ -136,8 +141,6 @@ protected:
bool mShowDecoratedParts;
bool mShowPartAliases;
QByteArray mFilter;
std::unique_ptr<lcView> mView;
std::unique_ptr<lcModel> mModel;
};
class lcPartSelectionListView : public QListView
@ -205,7 +208,7 @@ class lcPartSelectionWidget : public QWidget
public:
lcPartSelectionWidget(QWidget* Parent);
void Redraw();
void UpdateThumbnails();
void SetDefaultPart();
void UpdateModels();
void UpdateCategories();

View file

@ -0,0 +1,148 @@
#include "lc_global.h"
#include "lc_thumbnailmanager.h"
#include "lc_library.h"
#include "pieceinf.h"
#include "lc_view.h"
#include "lc_model.h"
#include "camera.h"
lcThumbnailManager::lcThumbnailManager(lcPiecesLibrary* Library)
: QObject(Library), mLibrary(Library)
{
connect(mLibrary, &lcPiecesLibrary::PartLoaded, this, &lcThumbnailManager::PartLoaded);
}
lcThumbnailManager::~lcThumbnailManager()
{
for (auto &[ThumbnailId, Thumbnail] : mThumbnails)
if (Thumbnail.Pixmap.isNull())
mLibrary->ReleasePieceInfo(Thumbnail.Info);
}
std::pair<lcPartThumbnailId, QPixmap> lcThumbnailManager::RequestThumbnail(PieceInfo* Info, int ColorIndex, int Size)
{
for (auto &[ThumbnailId, Thumbnail] : mThumbnails)
if (Thumbnail.Info == Info && Thumbnail.ColorIndex == ColorIndex && Thumbnail.Size == Size)
return { ThumbnailId, Thumbnail.Pixmap };
lcPartThumbnailId ThumbnailId = static_cast<lcPartThumbnailId>(mNextThumbnailId++);
lcPartThumbnail& Thumbnail = mThumbnails[ThumbnailId];
Thumbnail.Info = Info;
Thumbnail.ColorIndex = ColorIndex;
Thumbnail.Size = Size;
Thumbnail.ReferenceCount = 1;
mLibrary->LoadPieceInfo(Info, false, false);
if (Info->mState == lcPieceInfoState::Loaded)
DrawThumbnail(ThumbnailId, Thumbnail);
return { ThumbnailId, Thumbnail.Pixmap };
}
void lcThumbnailManager::ReleaseThumbnail(lcPartThumbnailId ThumbnailId)
{
auto ThumbnailIt = mThumbnails.find(ThumbnailId);
if (ThumbnailIt == mThumbnails.end())
return;
lcPartThumbnail& Thumbnail = ThumbnailIt->second;
Thumbnail.ReferenceCount--;
if (Thumbnail.ReferenceCount == 0)
{
if (Thumbnail.Pixmap.isNull())
mLibrary->ReleasePieceInfo(Thumbnail.Info);
mThumbnails.erase(ThumbnailIt);
}
}
void lcThumbnailManager::PartLoaded(PieceInfo* Info)
{
for (auto& [ThumbnailId, Thumbnail] : mThumbnails)
if (Thumbnail.Info == Info && Thumbnail.Pixmap.isNull())
DrawThumbnail(ThumbnailId, Thumbnail);
}
void lcThumbnailManager::DrawThumbnail(lcPartThumbnailId ThumbnailId, lcPartThumbnail& Thumbnail)
{
const int Width = Thumbnail.Size * 2;
const int Height = Thumbnail.Size * 2;
if (mView && (mView->GetWidth() != Width || mView->GetHeight() != Height))
mView.reset();
if (!mView)
{
if (!mModel)
mModel = std::unique_ptr<lcModel>(new lcModel(QString(), nullptr, true));
mView = std::unique_ptr<lcView>(new lcView(lcViewType::PartsList, mModel.get()));
mView->SetOffscreenContext();
mView->MakeCurrent();
mView->SetSize(Width, Height);
if (!mView->BeginRenderToImage(Width, Height))
{
mView.reset();
return;
}
}
mView->MakeCurrent();
mView->BindRenderFramebuffer();
const uint BackgroundColor = QApplication::palette().color(QPalette::Base).rgba();
mView->SetBackgroundColorOverride(LC_RGBA(qRed(BackgroundColor), qGreen(BackgroundColor), qBlue(BackgroundColor), 0));
PieceInfo* Info = Thumbnail.Info;
mModel->SetPreviewPieceInfo(Info, Thumbnail.ColorIndex);
const lcVector3 Center = (Info->GetBoundingBox().Min + Info->GetBoundingBox().Max) / 2.0f;
const lcVector3 Position = Center + lcVector3(100.0f, -100.0f, 75.0f);
mView->GetCamera()->SetViewpoint(Position, Center, lcVector3(0, 0, 1));
mView->GetCamera()->m_fovy = 20.0f;
mView->ZoomExtents();
mView->OnDraw();
mView->UnbindRenderFramebuffer();
QImage Image = mView->GetRenderFramebufferImage().convertToFormat(QImage::Format_ARGB32);
if (Info->GetSynthInfo())
{
QPainter Painter(&Image);
QImage Icon = QImage(":/resources/flexible.png");
uchar* ImageBits = Icon.bits();
QRgb TextColor = QApplication::palette().color(QPalette::WindowText).rgba();
int Red = qRed(TextColor);
int Green = qGreen(TextColor);
int Blue = qBlue(TextColor);
for (int y = 0; y < Icon.height(); y++)
{
for (int x = 0; x < Icon.width(); x++)
{
QRgb& Pixel = ((QRgb*)ImageBits)[x];
Pixel = qRgba(Red, Green, Blue, qAlpha(Pixel));
}
ImageBits += Icon.bytesPerLine();
}
Painter.drawImage(QPoint(0, 0), Icon);
Painter.end();
}
Thumbnail.Pixmap = QPixmap::fromImage(Image).scaled(Thumbnail.Size, Thumbnail.Size, Qt::IgnoreAspectRatio, Qt::SmoothTransformation);
mLibrary->ReleasePieceInfo(Info);
emit ThumbnailReady(ThumbnailId, Thumbnail.Pixmap);
}

View file

@ -0,0 +1,45 @@
#pragma once
class lcPiecesLibrary;
struct lcPartThumbnail
{
QPixmap Pixmap;
PieceInfo* Info;
int ColorIndex;
int Size;
int ReferenceCount;
};
enum class lcPartThumbnailId : uint64_t
{
Invalid = 0
};
class lcThumbnailManager : public QObject
{
Q_OBJECT
public:
lcThumbnailManager(lcPiecesLibrary* Library);
~lcThumbnailManager();
std::pair<lcPartThumbnailId, QPixmap> RequestThumbnail(PieceInfo* Info, int ColorIndex, int Size);
void ReleaseThumbnail(lcPartThumbnailId ThumbnailId);
signals:
void ThumbnailReady(lcPartThumbnailId ThumbnailId, QPixmap Pixmap);
protected slots:
void PartLoaded(PieceInfo* Info);
protected:
void DrawThumbnail(lcPartThumbnailId ThumbnailId, lcPartThumbnail& Thumbnail);
lcPiecesLibrary* mLibrary = nullptr;
std::map<lcPartThumbnailId, lcPartThumbnail> mThumbnails;
int mNextThumbnailId = 1;
std::unique_ptr<lcView> mView;
std::unique_ptr<lcModel> mModel;
};

View file

@ -165,13 +165,16 @@ macx {
}
SOURCES += \
common/texfont.cpp \
common/project.cpp \
common/pieceinf.cpp \
common/piece.cpp \
common/object.cpp \
common/minifig.cpp \
common/camera.cpp \
common/group.cpp \
common/image.cpp \
common/light.cpp \
common/minifig.cpp \
common/object.cpp \
common/piece.cpp \
common/pieceinf.cpp \
common/project.cpp \
common/texfont.cpp \
common/lc_aboutdialog.cpp \
common/lc_application.cpp \
common/lc_arraydialog.cpp \
@ -204,6 +207,7 @@ SOURCES += \
common/lc_modellistdialog.cpp \
common/lc_objectproperty.cpp \
common/lc_pagesetupdialog.cpp \
common/lc_partpalettedialog.cpp \
common/lc_partselectionwidget.cpp \
common/lc_previewwidget.cpp \
common/lc_profile.cpp \
@ -213,15 +217,13 @@ SOURCES += \
common/lc_stringcache.cpp \
common/lc_synth.cpp \
common/lc_texture.cpp \
common/lc_thumbnailmanager.cpp \
common/lc_timelinewidget.cpp \
common/lc_view.cpp \
common/lc_viewmanipulator.cpp \
common/lc_viewsphere.cpp \
common/lc_viewwidget.cpp \
common/lc_zipfile.cpp \
common/image.cpp \
common/group.cpp \
common/camera.cpp \
qt/system.cpp \
qt/qtmain.cpp \
qt/lc_qeditgroupsdialog.cpp \
@ -233,16 +235,18 @@ SOURCES += \
qt/lc_qupdatedialog.cpp \
qt/lc_qutils.cpp \
qt/lc_renderdialog.cpp \
qt/lc_setsdatabasedialog.cpp \
common/lc_partpalettedialog.cpp
qt/lc_setsdatabasedialog.cpp
HEADERS += \
common/texfont.h \
common/project.h \
common/pieceinf.h \
common/piece.h \
common/object.h \
common/minifig.h \
common/camera.h \
common/group.h \
common/image.h \
common/light.h \
common/minifig.h \
common/object.h \
common/piece.h \
common/pieceinf.h \
common/project.h \
common/texfont.h \
common/lc_aboutdialog.h \
common/lc_application.h \
common/lc_arraydialog.h \
@ -277,6 +281,7 @@ HEADERS += \
common/lc_modellistdialog.h \
common/lc_objectproperty.h \
common/lc_pagesetupdialog.h \
common/lc_partselectionwidget.h \
common/lc_previewwidget.h \
common/lc_profile.h \
common/lc_propertieswidget.h \
@ -285,16 +290,13 @@ HEADERS += \
common/lc_stringcache.h \
common/lc_synth.h \
common/lc_texture.h \
common/lc_thumbnailmanager.h \
common/lc_timelinewidget.h \
common/lc_view.h \
common/lc_viewmanipulator.h \
common/lc_viewsphere.h \
common/lc_viewwidget.h \
common/lc_zipfile.h \
common/lc_partselectionwidget.h \
common/lc_timelinewidget.h \
common/image.h \
common/group.h \
common/camera.h \
qt/lc_qeditgroupsdialog.h \
qt/lc_qselectdialog.h \
qt/lc_qpropertiesdialog.h \