Added minifig wizard templates. Closes #212.

This commit is contained in:
Leonardo Zide
2018-03-11 20:35:04 -07:00
parent 6d7423efb4
commit b07631d4a9
7 changed files with 370 additions and 38 deletions
+111 -34
View File
@@ -13,6 +13,27 @@
#include "lc_scene.h"
#include "lc_file.h"
const char* MinifigWizard::mSectionNames[LC_MFW_NUMITEMS] =
{
"HATS", // LC_MFW_HATS
"HATS2", // LC_MFW_HATS2
"HEAD", // LC_MFW_HEAD
"NECK", // LC_MFW_NECK
"BODY", // LC_MFW_BODY
"BODY2", // LC_MFW_BODY2
"BODY3", // LC_MFW_BODY3
"RARM", // LC_MFW_RARM
"LARM", // LC_MFW_LARM
"RHAND", // LC_MFW_RHAND
"LHAND", // LC_MFW_LHAND
"RHANDA", // LC_MFW_RHANDA
"LHANDA", // LC_MFW_LHANDA
"RLEG", // LC_MFW_RLEG
"LLEG", // LC_MFW_LLEG
"RLEGA", // LC_MFW_RLEGA
"LLEGA", // LC_MFW_LLEGA
};
MinifigWizard::MinifigWizard()
{
lcDiskFile DiskSettings(lcGetPiecesLibrary()->mLibraryDir.absoluteFilePath(QLatin1String("mlcad.ini")));
@@ -38,6 +59,8 @@ MinifigWizard::MinifigWizard()
}
}
LoadTemplates();
mRotateX = 75.0f;
mRotateZ = 180.0f;
mDistance = 10.0f;
@@ -45,6 +68,17 @@ MinifigWizard::MinifigWizard()
mTracking = LC_TRACK_NONE;
}
MinifigWizard::~MinifigWizard()
{
lcPiecesLibrary* Library = lcGetPiecesLibrary();
for (int i = 0; i < LC_MFW_NUMITEMS; i++)
if (mMinifig.Parts[i])
Library->ReleasePieceInfo(mMinifig.Parts[i]);
SaveTemplates();
}
void MinifigWizard::OnInitialUpdate()
{
MakeCurrent();
@@ -52,6 +86,8 @@ void MinifigWizard::OnInitialUpdate()
memset(&mMinifig, 0, sizeof(lcMinifig));
static_assert(sizeof(MinifigWizard::mSectionNames) / sizeof(MinifigWizard::mSectionNames[0]) == LC_MFW_NUMITEMS, "Array size mismatch.");
const int ColorCodes[LC_MFW_NUMITEMS] = { 4, 7, 14, 7, 1, 0, 7, 4, 4, 14, 14, 7, 7, 0, 0, 7, 7 };
const char* Pieces[LC_MFW_NUMITEMS] = { "3624.dat", "", "3626bp01.dat", "", "973.dat", "3815.dat", "", "3819.dat", "3818.dat", "3820.dat", "3820.dat", "", "", "3817.dat", "3816.dat", "", "" };
lcPiecesLibrary* Library = lcGetPiecesLibrary();
@@ -72,38 +108,8 @@ void MinifigWizard::OnInitialUpdate()
Calculate();
}
MinifigWizard::~MinifigWizard()
{
lcPiecesLibrary* Library = lcGetPiecesLibrary();
for (int i = 0; i < LC_MFW_NUMITEMS; i++)
if (mMinifig.Parts[i])
Library->ReleasePieceInfo(mMinifig.Parts[i]);
}
void MinifigWizard::ParseSettings(lcFile& Settings)
{
const char* SectionNames[LC_MFW_NUMITEMS] =
{
"[HATS]", // LC_MFW_HATS
"[HATS2]", // LC_MFW_HATS2
"[HEAD]", // LC_MFW_HEAD
"[NECK]", // LC_MFW_NECK
"[BODY]", // LC_MFW_BODY
"[BODY2]", // LC_MFW_BODY2
"[BODY3]", // LC_MFW_BODY3
"[RARM]", // LC_MFW_RARM
"[LARM]", // LC_MFW_LARM
"[RHAND]", // LC_MFW_RHAND
"[LHAND]", // LC_MFW_LHAND
"[RHANDA]", // LC_MFW_RHANDA
"[LHANDA]", // LC_MFW_LHANDA
"[RLEG]", // LC_MFW_RLEG
"[LLEG]", // LC_MFW_LLEG
"[RLEGA]", // LC_MFW_RLEGA
"[LLEGA]", // LC_MFW_LLEGA
};
for (int SectionIndex = 0; SectionIndex < LC_MFW_NUMITEMS; SectionIndex++)
{
lcArray<lcMinifigPieceInfo>& InfoArray = mSettings[SectionIndex];
@@ -113,13 +119,12 @@ void MinifigWizard::ParseSettings(lcFile& Settings)
char Line[1024];
bool FoundSection = false;
const char* SectionName = SectionNames[SectionIndex];
const char* SectionName = mSectionNames[SectionIndex];
size_t SectionNameLength = strlen(SectionName);
// Find start of section
while (Settings.ReadLine(Line, sizeof(Line)))
{
if (!strncmp(Line, SectionName, SectionNameLength))
if (Line[0] == '[' && !strncmp(Line + 1, SectionName, SectionNameLength) && Line[SectionNameLength + 1] == ']')
{
FoundSection = true;
break;
@@ -139,7 +144,6 @@ void MinifigWizard::ParseSettings(lcFile& Settings)
continue;
}
// Parse section.
while (Settings.ReadLine(Line, sizeof(Line)))
{
if (Line[0] == '[')
@@ -204,6 +208,79 @@ void MinifigWizard::ParseSettings(lcFile& Settings)
}
}
void MinifigWizard::SaveTemplate(const QString& TemplateName, const lcMinifigTemplate& Template)
{
mTemplates[TemplateName] = Template;
}
void MinifigWizard::DeleteTemplate(const QString& TemplateName)
{
mTemplates.erase(TemplateName);
}
void MinifigWizard::LoadTemplates()
{
#if (QT_VERSION >= QT_VERSION_CHECK(5, 0, 0))
QSettings Settings;
Settings.beginGroup("Minifig");
QByteArray TemplateData = Settings.value("Templates").toByteArray();
mTemplates.clear();
QJsonDocument Document = QJsonDocument::fromJson(TemplateData);
QJsonObject RootObject = Document.object();
for (QJsonObject::const_iterator ElementIt = RootObject.constBegin(); ElementIt != RootObject.constEnd(); ElementIt++)
{
QJsonObject TemplateObject = ElementIt.value().toObject();
lcMinifigTemplate Template;
for (int PartIdx = 0; PartIdx < LC_MFW_NUMITEMS; PartIdx++)
{
QJsonObject PartObject = TemplateObject.value(QLatin1String(mSectionNames[PartIdx])).toObject();
Template.Parts[PartIdx] = PartObject["Id"].toString();
Template.Colors[PartIdx] = PartObject["Color"].toInt();
Template.Angles[PartIdx] = PartObject["Angle"].toDouble();
}
mTemplates.emplace(ElementIt.key(), std::move(Template));
}
#endif
}
void MinifigWizard::SaveTemplates()
{
#if (QT_VERSION >= QT_VERSION_CHECK(5, 0, 0))
QJsonObject RootObject;
for (const auto& TemplateEntry : mTemplates)
{
const lcMinifigTemplate& Template = TemplateEntry.second;
QJsonObject TemplateObject;
for (int PartIdx = 0; PartIdx < LC_MFW_NUMITEMS; PartIdx++)
{
QJsonObject PartObject;
PartObject["Id"] = Template.Parts[PartIdx];
PartObject["Color"] = Template.Colors[PartIdx];
PartObject["Angle"] = Template.Angles[PartIdx];
TemplateObject[QLatin1String(mSectionNames[PartIdx])] = PartObject;
}
RootObject[TemplateEntry.first] = TemplateObject;
}
QByteArray TemplateData = QJsonDocument(RootObject).toJson(QJsonDocument::Compact);
QSettings Settings;
Settings.beginGroup("Minifig");
Settings.setValue("Templates", TemplateData);
#endif
}
void MinifigWizard::OnDraw()
{
mContext->SetDefaultState();
+22
View File
@@ -41,12 +41,27 @@ struct lcMinifig
lcMatrix44 Matrices[LC_MFW_NUMITEMS];
};
struct lcMinifigTemplate
{
QString Parts[LC_MFW_NUMITEMS];
int Colors[LC_MFW_NUMITEMS];
float Angles[LC_MFW_NUMITEMS];
};
class MinifigWizard : public lcGLWidget
{
public:
MinifigWizard();
~MinifigWizard();
const std::map<QString, lcMinifigTemplate>& GetTemplates() const
{
return mTemplates;
}
void SaveTemplate(const QString& TemplateName, const lcMinifigTemplate& Template);
void DeleteTemplate(const QString& TemplateName);
void OnDraw();
void OnLeftButtonDown();
void OnLeftButtonUp();
@@ -76,5 +91,12 @@ public:
float mRotateX;
float mRotateZ;
bool mAutoZoom;
protected:
void LoadTemplates();
void SaveTemplates();
std::map<QString, lcMinifigTemplate> mTemplates;
static const char* mSectionNames[LC_MFW_NUMITEMS];
};
+10
View File
@@ -99,11 +99,21 @@ void lcQColorPicker::setCurrentColor(int colorIndex)
selected(colorIndex);
}
void lcQColorPicker::setCurrentColorCode(int colorCode)
{
setCurrentColor(lcGetColorIndex(colorCode));
}
int lcQColorPicker::currentColor() const
{
return currentColorIndex;
}
int lcQColorPicker::currentColorCode() const
{
return gColorList[currentColorIndex].Code;
}
void lcQColorPicker::buttonPressed(bool toggled)
{
if (!toggled)
+2
View File
@@ -41,7 +41,9 @@ public:
~lcQColorPicker();
int currentColor() const;
int currentColorCode() const;
void setCurrentColor(int colorIndex);
void setCurrentColorCode(int colorCode);
public slots:
void changed(int colorIndex);
+128 -2
View File
@@ -5,6 +5,8 @@
#include "lc_qcolorpicker.h"
#include "minifig.h"
#include "lc_mainwindow.h"
#include "pieceinf.h"
#include "lc_library.h"
lcQMinifigDialog::lcQMinifigDialog(QWidget *parent) :
QDialog(parent),
@@ -102,7 +104,12 @@ lcQMinifigDialog::lcQMinifigDialog(QWidget *parent) :
colorPicker->blockSignals(false);
}
#if (QT_VERSION < QT_VERSION_CHECK(5, 0, 0))
ui->TemplateGroup->hide();
#endif
mMinifigWidget->OnInitialUpdate();
UpdateTemplateCombo();
}
lcQMinifigDialog::~lcQMinifigDialog()
@@ -110,9 +117,85 @@ lcQMinifigDialog::~lcQMinifigDialog()
delete ui;
}
void lcQMinifigDialog::accept()
void lcQMinifigDialog::UpdateTemplateCombo()
{
QDialog::accept();
ui->TemplateComboBox->clear();
const auto& Templates = mMinifigWidget->GetTemplates();
for (const auto& Template : Templates)
ui->TemplateComboBox->addItem(Template.first);
}
void lcQMinifigDialog::on_TemplateComboBox_currentIndexChanged(const QString& TemplateName)
{
const auto& Templates = mMinifigWidget->GetTemplates();
const auto& Position = Templates.find(TemplateName);
if (Position == Templates.end())
return;
const lcMinifigTemplate& Template = Position->second;
for (int PartIdx = 0; PartIdx < LC_MFW_NUMITEMS; PartIdx++)
{
PieceInfo* Info = lcGetPiecesLibrary()->FindPiece(Template.Parts[PartIdx].toLatin1(), nullptr, false, false);
if (Info)
{
for (const lcMinifigPieceInfo& MinifigPieceInfo : mMinifigWidget->mSettings[PartIdx])
{
if (Info == MinifigPieceInfo.Info)
{
getTypeComboBox(PartIdx)->setCurrentText(MinifigPieceInfo.Description);
break;
}
}
}
getColorPicker(PartIdx)->setCurrentColorCode(Template.Colors[PartIdx]);
QDoubleSpinBox* AngleSpinBox = getAngleEdit(PartIdx);
if (AngleSpinBox)
AngleSpinBox->setValue(Template.Angles[PartIdx]);
}
}
void lcQMinifigDialog::on_TemplateSaveButton_clicked()
{
bool Ok;
QString TemplateName = QInputDialog::getText(this, tr("Save Template"), tr("Template Name:"), QLineEdit::Normal, ui->TemplateComboBox->currentText(), &Ok);
if (!Ok)
return;
if (TemplateName.isEmpty())
{
QMessageBox::information(this, tr("Save Template"), tr("Template name cannot be empty."));
return;
}
lcMinifigTemplate Template;
for (int PartIdx = 0; PartIdx < LC_MFW_NUMITEMS; PartIdx++)
{
Template.Parts[PartIdx] = mMinifigWidget->mSettings[PartIdx][getTypeComboBox(PartIdx)->currentIndex()].Info->mFileName;
Template.Colors[PartIdx] = getColorPicker(PartIdx)->currentColorCode();
QDoubleSpinBox* AngleSpinBox = getAngleEdit(PartIdx);
Template.Angles[PartIdx] = AngleSpinBox ? AngleSpinBox->value() : 0.0f;
}
mMinifigWidget->SaveTemplate(TemplateName, Template);
ui->TemplateComboBox->blockSignals(true);
UpdateTemplateCombo();
ui->TemplateComboBox->setCurrentText(TemplateName);
ui->TemplateComboBox->blockSignals(false);
}
void lcQMinifigDialog::on_TemplateDeleteButton_clicked()
{
mMinifigWidget->DeleteTemplate(ui->TemplateComboBox->currentText());
UpdateTemplateCombo();
}
void lcQMinifigDialog::typeChanged(int index)
@@ -299,6 +382,49 @@ int lcQMinifigDialog::getColorIndex(QObject *widget)
return -1;
}
QDoubleSpinBox* lcQMinifigDialog::getAngleEdit(int index)
{
switch (index)
{
case LC_MFW_HATS:
return ui->hatsAngle;
case LC_MFW_HATS2:
return ui->hats2Angle;
case LC_MFW_HEAD:
return ui->headAngle;
case LC_MFW_NECK:
return nullptr;
case LC_MFW_BODY:
return nullptr;
case LC_MFW_BODY2:
return nullptr;
case LC_MFW_BODY3:
return nullptr;
case LC_MFW_RARM:
return ui->rarmAngle;
case LC_MFW_LARM:
return ui->larmAngle;
case LC_MFW_RHAND:
return ui->rhandAngle;
case LC_MFW_LHAND:
return ui->lhandAngle;
case LC_MFW_RHANDA:
return ui->rhandaAngle;
case LC_MFW_LHANDA:
return ui->lhandaAngle;
case LC_MFW_RLEG:
return ui->rlegAngle;
case LC_MFW_LLEG:
return ui->llegAngle;
case LC_MFW_RLEGA:
return ui->rlegaAngle;
case LC_MFW_LLEGA:
return ui->llegaAngle;
}
return nullptr;
}
int lcQMinifigDialog::getAngleIndex(QObject *widget)
{
if (widget == ui->hatsAngle)
+6 -2
View File
@@ -20,18 +20,22 @@ public:
MinifigWizard* mMinifigWidget;
public slots:
void accept();
void on_TemplateComboBox_currentIndexChanged(const QString& TemplateName);
void on_TemplateSaveButton_clicked();
void on_TemplateDeleteButton_clicked();
void typeChanged(int index);
void colorChanged(int index);
void angleChanged(double value);
private:
protected:
Ui::lcQMinifigDialog *ui;
void UpdateTemplateCombo();
QComboBox *getTypeComboBox(int type);
int getTypeIndex(QObject *widget);
lcQColorPicker* getColorPicker(int index);
int getColorIndex(QObject *widget);
QDoubleSpinBox* getAngleEdit(int index);
int getAngleIndex(QObject *widget);
};
+91
View File
@@ -674,6 +674,45 @@
</layout>
</widget>
</item>
<item>
<widget class="QGroupBox" name="TemplateGroup">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="title">
<string>Templates</string>
</property>
<layout class="QHBoxLayout" name="horizontalLayout_2">
<item>
<widget class="QComboBox" name="TemplateComboBox">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="TemplateSaveButton">
<property name="text">
<string>Save...</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="TemplateDeleteButton">
<property name="text">
<string>Delete...</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QFrame" name="frame">
<property name="frameShape">
@@ -703,6 +742,58 @@
<header>lc_qcolorpicker.h</header>
</customwidget>
</customwidgets>
<tabstops>
<tabstop>hatsType</tabstop>
<tabstop>hatsColor</tabstop>
<tabstop>hatsAngle</tabstop>
<tabstop>headAngle</tabstop>
<tabstop>headColor</tabstop>
<tabstop>headType</tabstop>
<tabstop>hats2Type</tabstop>
<tabstop>hats2Color</tabstop>
<tabstop>hats2Angle</tabstop>
<tabstop>neckType</tabstop>
<tabstop>neckColor</tabstop>
<tabstop>bodyColor</tabstop>
<tabstop>bodyType</tabstop>
<tabstop>larmType</tabstop>
<tabstop>larmColor</tabstop>
<tabstop>larmAngle</tabstop>
<tabstop>rarmAngle</tabstop>
<tabstop>rarmColor</tabstop>
<tabstop>rarmType</tabstop>
<tabstop>lhandType</tabstop>
<tabstop>lhandColor</tabstop>
<tabstop>lhandAngle</tabstop>
<tabstop>rhandAngle</tabstop>
<tabstop>rhandColor</tabstop>
<tabstop>rhandType</tabstop>
<tabstop>lhandaType</tabstop>
<tabstop>lhandaColor</tabstop>
<tabstop>lhandaAngle</tabstop>
<tabstop>rhandaAngle</tabstop>
<tabstop>rhandaColor</tabstop>
<tabstop>rhandaType</tabstop>
<tabstop>body2Type</tabstop>
<tabstop>body2Color</tabstop>
<tabstop>body3Color</tabstop>
<tabstop>body3Type</tabstop>
<tabstop>llegType</tabstop>
<tabstop>llegColor</tabstop>
<tabstop>llegAngle</tabstop>
<tabstop>rlegAngle</tabstop>
<tabstop>rlegColor</tabstop>
<tabstop>rlegType</tabstop>
<tabstop>llegaType</tabstop>
<tabstop>llegaColor</tabstop>
<tabstop>llegaAngle</tabstop>
<tabstop>rlegaAngle</tabstop>
<tabstop>rlegaColor</tabstop>
<tabstop>rlegaType</tabstop>
<tabstop>TemplateComboBox</tabstop>
<tabstop>TemplateSaveButton</tabstop>
<tabstop>TemplateDeleteButton</tabstop>
</tabstops>
<resources/>
<connections>
<connection>