Add bone manage widgets
parent
c0fba4879a
commit
d4be107518
|
@ -97,8 +97,12 @@ HEADERS += sources/about_widget.h
|
|||
SOURCES += sources/about_widget.cc
|
||||
HEADERS += sources/bone_list_model.h
|
||||
SOURCES += sources/bone_list_model.cc
|
||||
HEADERS += sources/bone_manage_widget.h
|
||||
SOURCES += sources/bone_manage_widget.cc
|
||||
HEADERS += sources/bone_preview_grid_widget.h
|
||||
SOURCES += sources/bone_preview_grid_widget.cc
|
||||
HEADERS += sources/bone_property_widget.h
|
||||
SOURCES += sources/bone_property_widget.cc
|
||||
HEADERS += sources/ccd_ik_resolver.h
|
||||
SOURCES += sources/ccd_ik_resolver.cc
|
||||
HEADERS += sources/component_list_model.h
|
||||
|
|
|
@ -0,0 +1,117 @@
|
|||
#include "bone_manage_widget.h"
|
||||
#include "bone_list_model.h"
|
||||
#include "bone_preview_grid_widget.h"
|
||||
#include "bone_property_widget.h"
|
||||
#include "document.h"
|
||||
#include "theme.h"
|
||||
#include <QMenu>
|
||||
#include <QVBoxLayout>
|
||||
#include <QWidgetAction>
|
||||
|
||||
BoneManageWidget::BoneManageWidget(Document* document, QWidget* parent)
|
||||
: QWidget(parent)
|
||||
, m_document(document)
|
||||
{
|
||||
setContextMenuPolicy(Qt::CustomContextMenu);
|
||||
|
||||
QHBoxLayout* toolsLayout = new QHBoxLayout;
|
||||
toolsLayout->setSpacing(0);
|
||||
toolsLayout->setMargin(0);
|
||||
|
||||
setStyleSheet("QPushButton:disabled {border: 0; color: " + Theme::gray.name() + "}");
|
||||
|
||||
auto createButton = [](QChar icon, const QString& title) {
|
||||
QPushButton* button = new QPushButton(icon);
|
||||
Theme::initIconButton(button);
|
||||
button->setToolTip(title);
|
||||
return button;
|
||||
};
|
||||
|
||||
m_selectButton = createButton(QChar(fa::objectgroup), tr("Select them on canvas"));
|
||||
m_propertyButton = createButton(QChar(fa::sliders), tr("Configure properties"));
|
||||
|
||||
toolsLayout->addWidget(m_selectButton);
|
||||
toolsLayout->addWidget(m_propertyButton);
|
||||
toolsLayout->addStretch();
|
||||
|
||||
QWidget* toolsWidget = new QWidget();
|
||||
toolsWidget->setObjectName("tools");
|
||||
toolsWidget->setStyleSheet("QWidget#tools {background: qlineargradient( x1:0 y1:0, x2:1 y2:0, stop:0 transparent, stop:0.5 " + Theme::black.name() + ", stop:1 transparent)};");
|
||||
toolsWidget->setLayout(toolsLayout);
|
||||
|
||||
m_bonePreviewGridWidget = new BonePreviewGridWidget(document);
|
||||
|
||||
connect(m_bonePreviewGridWidget->selectionModel(), &QItemSelectionModel::selectionChanged, this, &BoneManageWidget::updateToolButtons);
|
||||
connect(m_bonePreviewGridWidget, &BonePreviewGridWidget::unselectAllOnCanvas, this, &BoneManageWidget::unselectAllOnCanvas);
|
||||
connect(m_bonePreviewGridWidget, &BonePreviewGridWidget::selectNodeOnCanvas, this, &BoneManageWidget::selectNodeOnCanvas);
|
||||
|
||||
connect(m_propertyButton, &QPushButton::clicked, this, &BoneManageWidget::showSelectedBoneProperties);
|
||||
|
||||
connect(this, &BoneManageWidget::groupOperationAdded, m_document, &Document::saveSnapshot);
|
||||
|
||||
connect(this, &BoneManageWidget::customContextMenuRequested, this, &BoneManageWidget::showContextMenu);
|
||||
|
||||
QVBoxLayout* mainLayout = new QVBoxLayout;
|
||||
mainLayout->addWidget(toolsWidget);
|
||||
mainLayout->addWidget(m_bonePreviewGridWidget);
|
||||
|
||||
setLayout(mainLayout);
|
||||
|
||||
updateToolButtons();
|
||||
}
|
||||
|
||||
void BoneManageWidget::showSelectedBoneProperties()
|
||||
{
|
||||
auto boneIds = m_bonePreviewGridWidget->getSelectedBoneIds();
|
||||
if (boneIds.empty())
|
||||
return;
|
||||
|
||||
auto* propertyWidget = new BonePropertyWidget(m_document, boneIds);
|
||||
|
||||
auto menu = std::make_unique<QMenu>(this->parentWidget());
|
||||
QWidgetAction* widgetAction = new QWidgetAction(menu.get());
|
||||
widgetAction->setDefaultWidget(propertyWidget);
|
||||
menu->addAction(widgetAction);
|
||||
|
||||
auto x = mapToGlobal(QPoint(0, 0)).x();
|
||||
if (x <= 0)
|
||||
x = QCursor::pos().x();
|
||||
menu->exec(QPoint(
|
||||
x - propertyWidget->width(),
|
||||
QCursor::pos().y()));
|
||||
}
|
||||
|
||||
void BoneManageWidget::selectBoneByBoneId(const dust3d::Uuid& boneId)
|
||||
{
|
||||
QModelIndex index = m_bonePreviewGridWidget->boneListModel()->boneIdToIndex(boneId);
|
||||
if (index.isValid()) {
|
||||
m_bonePreviewGridWidget->selectionModel()->select(index, QItemSelectionModel::ClearAndSelect);
|
||||
m_bonePreviewGridWidget->scrollTo(index);
|
||||
return;
|
||||
}
|
||||
dust3dDebug << "Unable to select bone:" << boneId.toString();
|
||||
}
|
||||
|
||||
void BoneManageWidget::updateToolButtons()
|
||||
{
|
||||
auto selectedBones = m_bonePreviewGridWidget->getSelectedBones();
|
||||
bool enableSelectButton = false;
|
||||
bool enablePropertyButton = false;
|
||||
for (const auto& bone : selectedBones) {
|
||||
enablePropertyButton = true;
|
||||
enableSelectButton = true;
|
||||
}
|
||||
m_selectButton->setEnabled(enableSelectButton);
|
||||
m_propertyButton->setEnabled(enablePropertyButton);
|
||||
}
|
||||
|
||||
void BoneManageWidget::showContextMenu(const QPoint& pos)
|
||||
{
|
||||
auto selectedBoneIds = m_bonePreviewGridWidget->getSelectedBoneIds();
|
||||
if (selectedBoneIds.empty())
|
||||
return;
|
||||
|
||||
QMenu contextMenu(this);
|
||||
|
||||
contextMenu.exec(mapToGlobal(pos));
|
||||
}
|
|
@ -0,0 +1,34 @@
|
|||
#ifndef DUST3D_APPLICATION_BONE_MANAGE_WIDGET_H_
|
||||
#define DUST3D_APPLICATION_BONE_MANAGE_WIDGET_H_
|
||||
|
||||
#include <QWidget>
|
||||
#include <dust3d/base/uuid.h>
|
||||
|
||||
class Document;
|
||||
class BonePreviewGridWidget;
|
||||
class BonePropertyWidget;
|
||||
class QPushButton;
|
||||
|
||||
class BoneManageWidget : public QWidget {
|
||||
Q_OBJECT
|
||||
signals:
|
||||
void unselectAllOnCanvas();
|
||||
void selectNodeOnCanvas(const dust3d::Uuid& boneId);
|
||||
void groupOperationAdded();
|
||||
public slots:
|
||||
void selectBoneByBoneId(const dust3d::Uuid& boneId);
|
||||
void showSelectedBoneProperties();
|
||||
void showContextMenu(const QPoint& pos);
|
||||
|
||||
public:
|
||||
BoneManageWidget(Document* document, QWidget* parent = nullptr);
|
||||
|
||||
private:
|
||||
Document* m_document = nullptr;
|
||||
BonePreviewGridWidget* m_bonePreviewGridWidget = nullptr;
|
||||
QPushButton* m_selectButton = nullptr;
|
||||
QPushButton* m_propertyButton = nullptr;
|
||||
void updateToolButtons();
|
||||
};
|
||||
|
||||
#endif
|
|
@ -0,0 +1,38 @@
|
|||
#include "bone_property_widget.h"
|
||||
#include "float_number_widget.h"
|
||||
#include "image_preview_widget.h"
|
||||
#include "theme.h"
|
||||
#include <QGroupBox>
|
||||
#include <QHBoxLayout>
|
||||
#include <QPushButton>
|
||||
#include <QVBoxLayout>
|
||||
#include <unordered_set>
|
||||
|
||||
BonePropertyWidget::BonePropertyWidget(Document* document,
|
||||
const std::vector<dust3d::Uuid>& boneIds,
|
||||
QWidget* parent)
|
||||
: QWidget(parent)
|
||||
, m_document(document)
|
||||
, m_boneIds(boneIds)
|
||||
{
|
||||
prepareBoneIds();
|
||||
|
||||
QVBoxLayout* mainLayout = new QVBoxLayout;
|
||||
|
||||
mainLayout->setSizeConstraint(QLayout::SetFixedSize);
|
||||
|
||||
connect(this, &BonePropertyWidget::groupOperationAdded, m_document, &Document::saveSnapshot);
|
||||
|
||||
setLayout(mainLayout);
|
||||
|
||||
setFixedSize(minimumSizeHint());
|
||||
}
|
||||
|
||||
void BonePropertyWidget::prepareBoneIds()
|
||||
{
|
||||
if (1 == m_boneIds.size()) {
|
||||
m_bone = m_document->findBone(m_boneIds.front());
|
||||
if (nullptr != m_bone)
|
||||
m_boneId = m_boneIds.front();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,27 @@
|
|||
#ifndef DUST3D_APPLICATION_BONE_PROPERTY_WIDGET_H_
|
||||
#define DUST3D_APPLICATION_BONE_PROPERTY_WIDGET_H_
|
||||
|
||||
#include "document.h"
|
||||
#include <QWidget>
|
||||
#include <dust3d/base/uuid.h>
|
||||
|
||||
class BonePropertyWidget : public QWidget {
|
||||
Q_OBJECT
|
||||
signals:
|
||||
void groupOperationAdded();
|
||||
|
||||
public:
|
||||
BonePropertyWidget(Document* document,
|
||||
const std::vector<dust3d::Uuid>& boneIds,
|
||||
QWidget* parent = nullptr);
|
||||
public slots:
|
||||
|
||||
private:
|
||||
Document* m_document = nullptr;
|
||||
std::vector<dust3d::Uuid> m_boneIds;
|
||||
dust3d::Uuid m_boneId;
|
||||
const Document::Bone* m_bone = nullptr;
|
||||
void prepareBoneIds();
|
||||
};
|
||||
|
||||
#endif
|
|
@ -1,5 +1,6 @@
|
|||
#include "document_window.h"
|
||||
#include "about_widget.h"
|
||||
#include "bone_manage_widget.h"
|
||||
#include "cut_face_preview.h"
|
||||
#include "document.h"
|
||||
#include "document_saver.h"
|
||||
|
@ -269,10 +270,12 @@ DocumentWindow::DocumentWindow()
|
|||
partsDocker->setWidget(m_partManageWidget);
|
||||
addDockWidget(Qt::RightDockWidgetArea, partsDocker);
|
||||
|
||||
//QDockWidget* motionsDocker = new QDockWidget(tr("Motions"), this);
|
||||
//motionsDocker->setAllowedAreas(Qt::RightDockWidgetArea);
|
||||
QDockWidget* bonesDocker = new QDockWidget(tr("Bones"), this);
|
||||
m_boneManageWidget = new BoneManageWidget(m_document);
|
||||
bonesDocker->setWidget(m_boneManageWidget);
|
||||
bonesDocker->setAllowedAreas(Qt::RightDockWidgetArea);
|
||||
|
||||
//tabifyDockWidget(partsDocker, motionsDocker);
|
||||
tabifyDockWidget(partsDocker, bonesDocker);
|
||||
|
||||
partsDocker->raise();
|
||||
|
||||
|
|
|
@ -20,6 +20,7 @@
|
|||
class Document;
|
||||
class SkeletonGraphicsWidget;
|
||||
class PartManageWidget;
|
||||
class BoneManageWidget;
|
||||
class ToolbarButton;
|
||||
class SpinnableToolbarIcon;
|
||||
|
||||
|
@ -170,6 +171,7 @@ private:
|
|||
bool m_isComponentPreviewImageDecorationsObsolete = false;
|
||||
|
||||
PartManageWidget* m_partManageWidget = nullptr;
|
||||
BoneManageWidget* m_boneManageWidget = nullptr;
|
||||
|
||||
SpinnableToolbarIcon* m_inprogressIndicator = nullptr;
|
||||
|
||||
|
|
Loading…
Reference in New Issue