Add tool button tips especially when failed to generate mesh #20

This commit add tips for buttons, to show what the function of the button.
Also, fixed a issue, there was no useful infos to tell user when the mesh was failed to generate, now user should see a warning icon with tips to show why the preview disappear.

Thanks the following contributors:
@RubenSandwich <https://github.com/RubenSandwich>
boynet <https://dust3d.discourse.group/u/boynet>
fornclake <https://www.reddit.com/user/fornclake>
master
Jeremy Hu 2019-01-07 22:33:42 +09:30
parent 2bbb222e02
commit b65205a48c
8 changed files with 65 additions and 5 deletions

View File

@ -35,6 +35,7 @@ Document::Document() :
m_isResultMeshObsolete(false),
m_meshGenerator(nullptr),
m_resultMesh(nullptr),
m_isMeshGenerationSucceed(true),
m_batchChangeRefCount(0),
m_currentOutcome(nullptr),
m_isTextureObsolete(false),
@ -1355,6 +1356,11 @@ MeshLoader *Document::takeResultMesh()
return resultMesh;
}
bool Document::isMeshGenerationSucceed()
{
return m_isMeshGenerationSucceed;
}
MeshLoader *Document::takeResultTextureMesh()
{
if (nullptr == m_resultTextureMesh)
@ -1375,6 +1381,7 @@ void Document::meshReady()
{
MeshLoader *resultMesh = m_meshGenerator->takeResultMesh();
Outcome *outcome = m_meshGenerator->takeOutcome();
bool isSucceed = m_meshGenerator->isSucceed();
for (auto &partId: m_meshGenerator->generatedPreviewPartIds()) {
auto part = partMap.find(partId);
@ -1388,6 +1395,8 @@ void Document::meshReady()
delete m_resultMesh;
m_resultMesh = resultMesh;
m_isMeshGenerationSucceed = isSucceed;
delete m_currentOutcome;
m_currentOutcome = outcome;

View File

@ -491,6 +491,7 @@ public:
const Pose *findPose(QUuid poseId) const;
const Motion *findMotion(QUuid motionId) const;
MeshLoader *takeResultMesh();
bool isMeshGenerationSucceed();
MeshLoader *takeResultTextureMesh();
MeshLoader *takeResultRigWeightMesh();
const std::vector<RiggerBone> *resultRigBones() const;
@ -630,6 +631,7 @@ private: // need initialize
bool m_isResultMeshObsolete;
MeshGenerator *m_meshGenerator;
MeshLoader *m_resultMesh;
bool m_isMeshGenerationSucceed;
int m_batchChangeRefCount;
Outcome *m_currentOutcome;
bool m_isTextureObsolete;

View File

@ -104,7 +104,8 @@ DocumentWindow::DocumentWindow() :
m_firstShow(true),
m_documentSaved(true),
m_exportPreviewWidget(nullptr),
m_advanceSettingWidget(nullptr)
m_advanceSettingWidget(nullptr),
m_isLastMeshGenerationSucceed(true)
{
if (!g_logBrowser) {
g_logBrowser = new LogBrowser;
@ -120,47 +121,71 @@ DocumentWindow::DocumentWindow() :
toolButtonLayout->setContentsMargins(5, 10, 4, 0);
QPushButton *addButton = new QPushButton(QChar(fa::plus));
addButton->setToolTip(tr("Add node to canvas"));
Theme::initAwesomeButton(addButton);
QPushButton *selectButton = new QPushButton(QChar(fa::mousepointer));
selectButton->setToolTip(tr("Select node on canvas"));
Theme::initAwesomeButton(selectButton);
QPushButton *dragButton = new QPushButton(QChar(fa::handrocko));
dragButton->setToolTip(tr("Enter drag mode"));
Theme::initAwesomeButton(dragButton);
QPushButton *zoomInButton = new QPushButton(QChar(fa::searchplus));
zoomInButton->setToolTip(tr("Enter zoom in mode"));
Theme::initAwesomeButton(zoomInButton);
QPushButton *zoomOutButton = new QPushButton(QChar(fa::searchminus));
zoomOutButton->setToolTip(tr("Enter zoom out mode"));
Theme::initAwesomeButton(zoomOutButton);
m_xlockButton = new QPushButton(QChar('X'));
m_xlockButton->setToolTip(tr("X axis locker"));
initLockButton(m_xlockButton);
updateXlockButtonState();
m_ylockButton = new QPushButton(QChar('Y'));
m_ylockButton->setToolTip(tr("Y axis locker"));
initLockButton(m_ylockButton);
updateYlockButtonState();
m_zlockButton = new QPushButton(QChar('Z'));
m_zlockButton->setToolTip(tr("Z axis locker"));
initLockButton(m_zlockButton);
updateZlockButtonState();
m_radiusLockButton = new QPushButton(QChar(fa::bullseye));
m_radiusLockButton->setToolTip(tr("Node radius locker"));
Theme::initAwesomeButton(m_radiusLockButton);
updateRadiusLockButtonState();
QPushButton *rotateCounterclockwiseButton = new QPushButton(QChar(fa::rotateleft));
rotateCounterclockwiseButton->setToolTip(tr("Rotate whole model (CCW)"));
Theme::initAwesomeButton(rotateCounterclockwiseButton);
QPushButton *rotateClockwiseButton = new QPushButton(QChar(fa::rotateright));
rotateClockwiseButton->setToolTip(tr("Rotate whole model"));
Theme::initAwesomeButton(rotateClockwiseButton);
auto updateRegenerateIconAndTips = [&](SpinnableAwesomeButton *regenerateButton, bool isSucceed, bool forceUpdate=false) {
if (!forceUpdate) {
if (m_isLastMeshGenerationSucceed == isSucceed)
return;
}
m_isLastMeshGenerationSucceed = isSucceed;
regenerateButton->setToolTip(m_isLastMeshGenerationSucceed ? tr("Regenerate") : tr("Mesh generation failed, please undo or adjust recent changed nodes\nTips:\n - Don't let generated mesh self-intersect\n - Make multiple parts instead of one single part for whole model"));
regenerateButton->setAwesomeIcon(m_isLastMeshGenerationSucceed ? QChar(fa::recycle) : QChar(fa::warning));
};
SpinnableAwesomeButton *regenerateButton = new SpinnableAwesomeButton();
regenerateButton->setAwesomeIcon(QChar(fa::recycle));
updateRegenerateIconAndTips(regenerateButton, m_isLastMeshGenerationSucceed, true);
connect(m_document, &Document::meshGenerating, this, [=]() {
regenerateButton->showSpinner(true);
});
connect(m_document, &Document::resultMeshChanged, this, [=]() {
updateRegenerateIconAndTips(regenerateButton, m_document->isMeshGenerationSucceed());
});
connect(m_document, &Document::postProcessing, this, [=]() {
regenerateButton->showSpinner(true);
});

View File

@ -72,6 +72,7 @@ private:
ExportPreviewWidget *m_exportPreviewWidget;
AdvanceSettingWidget *m_advanceSettingWidget;
std::vector<QWidget *> m_dialogs;
bool m_isLastMeshGenerationSucceed;
private:
QString m_currentFilename;

View File

@ -25,8 +25,8 @@ int main(int argc, char ** argv)
darkPalette.setColor(QPalette::WindowText, Theme::white);
darkPalette.setColor(QPalette::Base, QColor(25,25,25));
darkPalette.setColor(QPalette::AlternateBase, QColor(53,53,53));
darkPalette.setColor(QPalette::ToolTipBase, Theme::white);
darkPalette.setColor(QPalette::ToolTipText, Theme::white);
//darkPalette.setColor(QPalette::ToolTipBase, Theme::white);
//darkPalette.setColor(QPalette::ToolTipText, Theme::white);
darkPalette.setColor(QPalette::Text, Theme::white);
darkPalette.setColor(QPalette::Disabled, QPalette::Text, Theme::black);
darkPalette.setColor(QPalette::Button, QColor(53,53,53));
@ -36,7 +36,7 @@ int main(int argc, char ** argv)
darkPalette.setColor(QPalette::Highlight, Theme::red);
darkPalette.setColor(QPalette::HighlightedText, Theme::black);
qApp->setPalette(darkPalette);
qApp->setStyleSheet("QToolTip { color: #ffffff; background-color: #fc6621; border: 1px solid white; }");
//qApp->setStyleSheet("QToolTip { color: #ffffff; background-color: #fc6621; border: 1px solid white; }");
QCoreApplication::setApplicationName(APP_NAME);

View File

@ -36,6 +36,7 @@ void GeneratedCacheContext::updateComponentCombinableMesh(QString componentId, v
MeshGenerator::MeshGenerator(Snapshot *snapshot) :
m_snapshot(snapshot),
m_isSucceed(false),
m_mesh(nullptr),
m_outcome(nullptr),
m_sharedContextWidget(nullptr),
@ -81,6 +82,11 @@ void MeshGenerator::setSharedContextWidget(QOpenGLWidget *widget)
m_sharedContextWidget = widget;
}
bool MeshGenerator::isSucceed()
{
return m_isSucceed;
}
MeshLoader *MeshGenerator::takeResultMesh()
{
MeshLoader *resultMesh = m_mesh;
@ -697,6 +703,10 @@ void *MeshGenerator::combineComponentMesh(QString componentId, CombineMode *comb
cachedComponentPositions.clear();
loadCombinableMeshVerticesPositions(resultMesh, cachedComponentPositions);
if (nullptr == resultMesh) {
m_isSucceed = false;
}
return resultMesh;
}
@ -707,6 +717,8 @@ void MeshGenerator::generate()
QElapsedTimer countTimeConsumed;
countTimeConsumed.start();
m_isSucceed = true;
m_meshliteContext = meshlite_create_context();
initMeshUtils();

View File

@ -39,6 +39,7 @@ public:
void setGeneratedCacheContext(GeneratedCacheContext *cacheContext);
void setSmoothNormal(bool smoothNormal);
void setWeldEnabled(bool weldEnabled);
bool isSucceed();
MeshLoader *takeResultMesh();
MeshLoader *takePartPreviewMesh(const QUuid &partId);
const std::set<QUuid> &requirePreviewPartIds();
@ -51,6 +52,7 @@ public slots:
void process();
private:
Snapshot *m_snapshot;
bool m_isSucceed;
MeshLoader *m_mesh;
std::map<QUuid, MeshLoader *> m_partPreviewMeshMap;
std::set<QUuid> m_requirePreviewPartIds;

View File

@ -21,38 +21,47 @@ PartWidget::PartWidget(const Document *document, QUuid partId) :
retainSizePolicy.setRetainSizeWhenHidden(true);
m_visibleButton = new QPushButton();
m_visibleButton->setToolTip(tr("Show/hide nodes"));
m_visibleButton->setSizePolicy(retainSizePolicy);
initButton(m_visibleButton);
m_lockButton = new QPushButton();
m_lockButton->setToolTip(tr("Lock/unlock nodes"));
m_lockButton->setSizePolicy(retainSizePolicy);
initButton(m_lockButton);
m_subdivButton = new QPushButton();
m_subdivButton->setToolTip(tr("Square/Round"));
m_subdivButton->setSizePolicy(retainSizePolicy);
initButton(m_subdivButton);
m_disableButton = new QPushButton();
m_disableButton->setToolTip(tr("Join/Remove from final result"));
m_disableButton->setSizePolicy(retainSizePolicy);
initButton(m_disableButton);
m_xMirrorButton = new QPushButton();
m_xMirrorButton->setToolTip(tr("Toggle mirror"));
m_xMirrorButton->setSizePolicy(retainSizePolicy);
initButton(m_xMirrorButton);
m_deformButton = new QPushButton();
m_deformButton->setToolTip(tr("Deform"));
m_deformButton->setSizePolicy(retainSizePolicy);
initButton(m_deformButton);
m_roundButton = new QPushButton;
m_roundButton->setToolTip(tr("Toggle round end"));
m_roundButton->setSizePolicy(retainSizePolicy);
initButton(m_roundButton);
m_colorButton = new QPushButton;
m_colorButton->setToolTip(tr("Color and material picker"));
m_colorButton->setSizePolicy(retainSizePolicy);
initButton(m_colorButton);
m_wrapButton = new QPushButton;
m_wrapButton->setToolTip(tr("Toggle convex wrap"));
m_wrapButton->setSizePolicy(retainSizePolicy);
initButton(m_wrapButton);