368 lines
11 KiB
C++
368 lines
11 KiB
C++
#include "ui/ModelBrowser/ModelTreeWidget.h"
|
||
|
||
#include <QResizeEvent>
|
||
#include <QUuid>
|
||
#include <QVariant>
|
||
#include <QMenu>
|
||
|
||
#include "common/RecourceHelper.h"
|
||
#include "common/SpdLogger.h"
|
||
#include "entities/EntitiesManager.h"
|
||
#include "entities/ComponentFactory.h"
|
||
#include "viewer/OsgViewer.h"
|
||
#include "viewer/OsgView.h"
|
||
#include "viewer/OsgCameraManipulator.h"
|
||
#include "viewer/CameraControlManipulator.h"
|
||
#include "ui/ModelBrowser/EntityConstent.h"
|
||
|
||
#include "ui_ModelBrowserPannal.h"
|
||
|
||
|
||
ModelTreeWidget::ModelTreeWidget(QWidget* parent)
|
||
: QTreeWidget(parent){
|
||
setColumnCount(1);
|
||
connect(this, &QTreeWidget::itemClicked, this, &ModelTreeWidget::OnWorkItemCliecked);
|
||
connect(this, &QTreeWidget::itemDoubleClicked, this, &ModelTreeWidget::OnItemDoubleClicked);
|
||
}
|
||
|
||
ModelTreeWidget::~ModelTreeWidget() {
|
||
}
|
||
|
||
void ModelTreeWidget::OnWorkspaceChange(WorkSpace* workSpace) {
|
||
LOG_INFO("WorkSpace change");
|
||
|
||
clear();
|
||
|
||
currentWorkSpace_ = workSpace;
|
||
if (nullptr == currentWorkSpace_) {
|
||
LOG_WARN("workspace is nullptr");
|
||
return;
|
||
}
|
||
|
||
connect(workSpace, &WorkSpace::EntityAdded, this, &ModelTreeWidget::OnEntityAdded);
|
||
connect(workSpace, &WorkSpace::EntityRemoved, this, &ModelTreeWidget::OnEntityRemoved);
|
||
|
||
const QString& name = currentWorkSpace_->GetName();
|
||
root_ = new QTreeWidgetItem(this);
|
||
root_->setText(0, name);
|
||
QVariant root;
|
||
root.setValue(currentWorkSpace_);
|
||
root_->setData(0, E_Workspace, root);
|
||
root_->setData(0, E_UUid, currentWorkSpace_->GetUUid());
|
||
addTopLevelItem(root_);
|
||
|
||
const std::vector<Entity*>& entities = currentWorkSpace_->GetEntities();
|
||
for (const auto& entity : entities) {
|
||
AddEntity(root_, entity);
|
||
}
|
||
}
|
||
|
||
void ModelTreeWidget::OnEntityAdded(Entity* entity) {
|
||
if (nullptr == entity) {
|
||
LOG_WARN("entity is nullptr");
|
||
return;
|
||
}
|
||
|
||
const QString& entityName = entity->GetName();
|
||
|
||
QTreeWidgetItem* item = new QTreeWidgetItem;
|
||
connect(entity, &Entity::NameChanged, [item](const QString& name) {
|
||
LOG_WARN("entity name changed: {}", name.toStdString());
|
||
item->setText(0, name);
|
||
}
|
||
);
|
||
item->setText(0, entityName);
|
||
QVariant root;
|
||
root.setValue(entity);
|
||
item->setData(0, E_Entity, root);
|
||
item->setData(0, E_UUid, entity->GetUUid());
|
||
root_->addChild(item);
|
||
}
|
||
|
||
void ModelTreeWidget::OnEntityRemoved(Entity* entity) {
|
||
if (nullptr == entity) {
|
||
LOG_WARN("entity is nullptr");
|
||
return;
|
||
}
|
||
|
||
const QString& uuid = entity->GetUUid();
|
||
FindAndRemoveItem(uuid);
|
||
}
|
||
|
||
void ModelTreeWidget::contextMenuEvent(QContextMenuEvent* event) {
|
||
QTreeWidgetItem* item = itemAt(event->pos());
|
||
if (nullptr == item) {
|
||
QMenu menu(this);
|
||
QAction* addEntiy = new QAction(tr("Release Track"), this);
|
||
connect(addEntiy, &QAction::triggered, [this]() {
|
||
OnTrackEntity(nullptr);
|
||
}
|
||
);
|
||
menu.addAction(addEntiy);
|
||
menu.exec(event->globalPos());
|
||
return;
|
||
}
|
||
QVariant value = item->data(0, E_Entity);
|
||
if (nullptr != item && value.isValid()) {
|
||
Entity* entity = value.value<Entity*>();
|
||
PopupEntityMenu(event, entity);
|
||
} else {
|
||
QMenu menu(this);
|
||
|
||
// <20><><EFBFBD>Ӳ˵<D3B2><CBB5><EFBFBD>
|
||
QAction* addEntiy = new QAction(tr("Add boke Entity"), this);
|
||
connect(addEntiy, &QAction::triggered, [this]() {
|
||
OnAddMeshEntity("boke/boke.ive", "boke");
|
||
}
|
||
);
|
||
menu.addAction(addEntiy);
|
||
|
||
addEntiy = new QAction(tr("Add lsjhqt Entity"), this);
|
||
connect(addEntiy, &QAction::triggered, [this]() {
|
||
OnAddMeshEntity("lsjhqt/lsjhqt.flt", "lsjhqt");
|
||
}
|
||
);
|
||
menu.addAction(addEntiy);
|
||
|
||
addEntiy = new QAction(tr("Add nimizi Entity"), this);
|
||
connect(addEntiy, &QAction::triggered, [this]() {
|
||
OnAddMeshEntity("nimizi/nimizi.ive", "nimizi");
|
||
}
|
||
);
|
||
menu.addAction(addEntiy);
|
||
|
||
addEntiy = new QAction(tr("Add tkdlj Entity"), this);
|
||
connect(addEntiy, &QAction::triggered, [this]() {
|
||
OnAddMeshEntity("tkdlj/tkdlj.ive", "tkdlj");
|
||
}
|
||
);
|
||
menu.addAction(addEntiy);
|
||
|
||
addEntiy = new QAction(tr("Add jiaofan Entity"), this);
|
||
connect(addEntiy, &QAction::triggered, [this]() {
|
||
OnAddMeshEntity("jf/decorative-shape-008.obj", "jiaofan");
|
||
}
|
||
);
|
||
menu.addAction(addEntiy);
|
||
|
||
addEntiy = new QAction(tr("Add satellite Entity"), this);
|
||
connect(addEntiy, &QAction::triggered, [this]() {
|
||
OnAddSatelliteEntity();
|
||
}
|
||
);
|
||
menu.addAction(addEntiy);
|
||
|
||
// <20><>ʾ<EFBFBD>˵<EFBFBD>
|
||
menu.exec(event->globalPos());
|
||
}
|
||
|
||
}
|
||
|
||
void ModelTreeWidget::OnWorkItemChanged(WorkSpaceItem* item) {
|
||
LOG_INFO("WorkItemChanged");
|
||
if (nullptr == item) {
|
||
LOG_WARN("item is nullptr");
|
||
return;
|
||
}
|
||
|
||
}
|
||
|
||
void ModelTreeWidget::OnWorkItemCliecked(QTreeWidgetItem* item, int column) {
|
||
QVariant value = item->data(column, E_Entity);
|
||
bool isEntity = true;
|
||
if (!value.isValid()) {
|
||
value = item->data(column, E_Workspace);
|
||
isEntity = false;
|
||
}
|
||
if (!value.isValid()) {
|
||
LOG_WARN("unknown data rol");
|
||
return;
|
||
}
|
||
|
||
if (isEntity) {
|
||
emit EntityChange(value);
|
||
} else {
|
||
emit WorkSpaceChange(value);
|
||
}
|
||
}
|
||
|
||
void ModelTreeWidget::OnItemDoubleClicked(QTreeWidgetItem* item, int column) {
|
||
QVariant value = item->data(column, E_Entity);
|
||
bool isEntity = true;
|
||
if (!value.isValid()) {
|
||
LOG_WARN("unknown data E_Entity");
|
||
return;
|
||
}
|
||
|
||
Entity* entity = value.value<Entity*>();
|
||
if (nullptr == entity) {
|
||
LOG_WARN("entity is nullptr");
|
||
return;
|
||
}
|
||
|
||
OnTrackEntity(entity);
|
||
}
|
||
|
||
void ModelTreeWidget::OnAddMeshEntity(const QString& mesh, const QString& name) {
|
||
if (nullptr == currentWorkSpace_) {
|
||
LOG_WARN("currentWorkSpace_ is nullptr");
|
||
return;
|
||
}
|
||
|
||
Entity* entity = EntitiesManager::Get().CreateMesh(mesh);
|
||
|
||
int count = currentWorkSpace_->GetEntities().size();
|
||
entity->SetName(QString("%1_%2").arg(name).arg(count));
|
||
currentWorkSpace_->AddEntity(entity);
|
||
}
|
||
|
||
SceneComponent* ModelTreeWidget::OnAddComponent(const QString& typeName, Entity* entity) {
|
||
LOG_INFO("enter, typename:{}", typeName.toStdString().c_str());
|
||
if (nullptr == entity) {
|
||
LOG_WARN("entity is nullptr");
|
||
return nullptr;
|
||
}
|
||
|
||
SceneComponent* rootComponent = entity->GetRootComponent();
|
||
SceneComponent* conponent = ComponentFactory::Create(typeName, rootComponent);
|
||
conponent->AttachTo(rootComponent);
|
||
//conponent->AttachEntity(entity);
|
||
|
||
QVariant value;
|
||
value.setValue(entity);
|
||
emit EntityChange(value);
|
||
return conponent;
|
||
}
|
||
|
||
void ModelTreeWidget::OnDeleteEntity(Entity* entity) {
|
||
LOG_INFO("enter");
|
||
if (nullptr == entity) {
|
||
LOG_WARN("entity is nullptr");
|
||
return;
|
||
}
|
||
|
||
entity->Destory();
|
||
}
|
||
|
||
void ModelTreeWidget::PopupEntityMenu(QContextMenuEvent* event, Entity* entity) {
|
||
QMenu menu(this);
|
||
|
||
QAction* addEntiy = new QAction(tr("Track"), this);
|
||
menu.addAction(addEntiy);
|
||
connect(addEntiy, &QAction::triggered, [this, entity]() {
|
||
OnTrackEntity(entity);
|
||
}
|
||
);
|
||
|
||
// <20><><EFBFBD>Ӳ˵<D3B2><CBB5><EFBFBD>
|
||
addEntiy = new QAction(tr("Add Mesh Component"), this);
|
||
menu.addAction(addEntiy);
|
||
|
||
// <20><><EFBFBD>˵<EFBFBD><CBB5><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ӵ<EFBFBD><D3B5>˵<EFBFBD><CBB5><EFBFBD>
|
||
addEntiy = new QAction(tr("Add Path Component"), this);
|
||
menu.addAction(addEntiy);
|
||
connect(addEntiy, &QAction::triggered, [this, entity]() {
|
||
OnAddComponent("PathComponent", entity);
|
||
}
|
||
);
|
||
|
||
addEntiy = new QAction(tr("Delete"), this);
|
||
menu.addAction(addEntiy);
|
||
connect(addEntiy, &QAction::triggered, [this, entity]() {
|
||
OnDeleteEntity(entity);
|
||
}
|
||
);
|
||
|
||
// <20><>ʾ<EFBFBD>˵<EFBFBD>
|
||
menu.exec(event->globalPos());
|
||
}
|
||
|
||
void ModelTreeWidget::FindAndRemoveItem(const QString& itemToRemove) {
|
||
for (int i = 0; i < topLevelItemCount(); ++i) {
|
||
QTreeWidgetItem* topItem = topLevelItem(i);
|
||
if (RemoveItemFromParent(topItem, itemToRemove)) {
|
||
break;
|
||
}
|
||
}
|
||
}
|
||
|
||
bool ModelTreeWidget::RemoveItemFromParent(QTreeWidgetItem* parentItem, const QString& itemToRemove) {
|
||
for (int i = 0; i < parentItem->childCount(); ++i) {
|
||
QTreeWidgetItem* childItem = parentItem->child(i);
|
||
const QString uuid = childItem->data(0, E_UUid).toString();
|
||
if (uuid == itemToRemove) {
|
||
while (childItem->childCount() > 0) {
|
||
QTreeWidgetItem* grandChildItem = childItem->child(0);
|
||
childItem->removeChild(grandChildItem);
|
||
}
|
||
|
||
parentItem->removeChild(childItem);
|
||
return true;
|
||
}
|
||
|
||
if (RemoveItemFromParent(childItem, itemToRemove)) {
|
||
return true;
|
||
}
|
||
}
|
||
|
||
return false;
|
||
}
|
||
|
||
void ModelTreeWidget::OnAddSatelliteEntity() {
|
||
if (nullptr == currentWorkSpace_) {
|
||
LOG_WARN("currentWorkSpace_ is nullptr");
|
||
return;
|
||
}
|
||
|
||
//const QString mesh("sat/sat.ive");
|
||
const QString mesh("satellite/satellite.ive");
|
||
Entity* entity = EntitiesManager::Get().CreateMesh(mesh);
|
||
int count = currentWorkSpace_->GetEntities().size();
|
||
entity->SetName(QString("%1_%2").arg("satellite").arg(count));
|
||
OnAddComponent("ConeWaveComponent", entity);
|
||
currentWorkSpace_->AddEntity(entity);
|
||
}
|
||
|
||
void ModelTreeWidget::OnTrackEntity(Entity* entity) {
|
||
OsgCameraManipulator* manipulator = OsgViewer::Get().GetView()->GetCameraManipulator();
|
||
if (nullptr == manipulator) {
|
||
LOG_WARN("manipulator is nullptr");
|
||
return;
|
||
}
|
||
|
||
|
||
osgGA::CameraManipulator* gaManipulator = manipulator->GetManipulator();
|
||
CameraControlManipulator* ccm = dynamic_cast<CameraControlManipulator*>(gaManipulator);
|
||
if (nullptr != ccm) {
|
||
if (nullptr != entity) {
|
||
osg::MatrixTransform* mt = entity->GetRootComponent()->GetMatrixTransform();
|
||
ccm->setManipulatorMode(CameraControlManipulator::Tracker_ManipulatorMode);
|
||
ccm->setTrackNode(mt);
|
||
} else {
|
||
ccm->setManipulatorMode(CameraControlManipulator::Roam_ManipulatorMode);
|
||
}
|
||
}
|
||
}
|
||
|
||
void ModelTreeWidget::AddEntity(class QTreeWidgetItem* parent, Entity* entity) {
|
||
const QString& entityName = entity->GetName();
|
||
|
||
QTreeWidgetItem* item = new QTreeWidgetItem;
|
||
connect(entity, &Entity::NameChanged, [item](const QString& name) {
|
||
LOG_WARN("entity name changed: {}", name.toStdString());
|
||
item->setText(0, name);
|
||
}
|
||
);
|
||
item->setText(0, entityName);
|
||
QVariant root;
|
||
root.setValue(entity);
|
||
item->setData(0, E_Entity, root);
|
||
item->setData(0, E_UUid, entity->GetUUid());
|
||
parent->addChild(item);
|
||
|
||
const std::vector<Entity*>& childer = entity->GetChilder();
|
||
for (const auto& child : childer) {
|
||
AddEntity(item, child);
|
||
}
|
||
}
|