diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/primitive_item.h b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/primitive_item.h index 4940a622b..204068db0 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/primitive_item.h +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/primitive_item.h @@ -173,6 +173,8 @@ private: NLLIGO::CPrimitives *m_primitives; }; +typedef QList NodeList; + } /* namespace WorldEditor */ Q_DECLARE_METATYPE(WorldEditor::Node *) diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/primitives_view.cpp b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/primitives_view.cpp index f324da9b9..896218a54 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/primitives_view.cpp +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/primitives_view.cpp @@ -16,7 +16,6 @@ // Project includes #include "primitives_view.h" -#include "primitive_item.h" #include "primitives_model.h" #include "world_editor_actions.h" @@ -208,7 +207,7 @@ void PrimitivesView::addNewPrimitiveByClass(int value) QString className = node->primitiveClass()->DynamicChildren[value].ClassName.c_str(); m_undoStack->push(new AddPrimitiveByClassCommand(className, m_primitivesTreeModel->pathFromIndex(indexList.first()), - m_primitivesTreeModel)); + m_worldEditorScene, m_primitivesTreeModel)); } void PrimitivesView::generatePrimitives(int value) diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/primitives_view.h b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/primitives_view.h index 18785b909..df317a93b 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/primitives_view.h +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/primitives_view.h @@ -18,6 +18,9 @@ #ifndef PRIMITIVES_VIEW_H #define PRIMITIVES_VIEW_H +// Project includes +#include "primitive_item.h" + // NeL includes #include @@ -28,6 +31,7 @@ #include #include #include +#include namespace LandscapeEditor { @@ -57,6 +61,9 @@ public: void setWorldScene(WorldEditorScene *worldEditorScene); virtual void setModel(PrimitivesTreeModel *model); +public Q_SLOTS: + //void selectPrimitives(); + private Q_SLOTS: void loadLandscape(); void loadRootPrimitive(); diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_actions.cpp b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_actions.cpp index 41de05f85..db4abcaa8 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_actions.cpp +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_actions.cpp @@ -43,6 +43,29 @@ namespace WorldEditor { +QGraphicsItem *getGraphicsItem(Node *node) +{ + QGraphicsItem *result = 0; + if (node->type() == Node::PrimitiveNodeType) + { + PrimitiveNode *primitiveNode = static_cast(node); + if (primitiveNode != 0) + { + switch (primitiveNode->primitiveClass()->Type) + { + case NLLIGO::CPrimitiveClass::Point: + case NLLIGO::CPrimitiveClass::Path: + case NLLIGO::CPrimitiveClass::Zone: + { + result = qvariant_cast(primitiveNode->data(Constants::GRAPHICS_DATA_QT4_2D)); + break; + } + } + } + } + return result; +} + void addNewGraphicsItems(const QModelIndex &primIndex, PrimitivesTreeModel *model, WorldEditorScene *scene) { PrimitiveNode *node = static_cast(primIndex.internalPointer()); @@ -53,6 +76,10 @@ void addNewGraphicsItems(const QModelIndex &primIndex, PrimitivesTreeModel *mode NLLIGO::IPrimitive *primitive = node->primitive(); NLLIGO::CPrimVector *vec = 0; AbstractWorldItem *item = 0; + + // Draw arrow ? + bool showArrow = node->primitiveClass()->ShowArrow; + switch (node->primitiveClass()->Type) { case NLLIGO::CPrimitiveClass::Point: @@ -60,9 +87,6 @@ void addNewGraphicsItems(const QModelIndex &primIndex, PrimitivesTreeModel *mode vec = primitive->getPrimVector(); NLLIGO::CPrimPoint *primPoint = static_cast(primitive); - // Draw arrow ? - bool showArrow = node->primitiveClass()->ShowArrow; - // Have a radius ? std::string strRadius; qreal radius = 0; @@ -85,7 +109,7 @@ void addNewGraphicsItems(const QModelIndex &primIndex, PrimitivesTreeModel *mode ++vec; } - item = scene->addWorldItemPath(polygon); + item = scene->addWorldItemPath(polygon, showArrow); break; } case NLLIGO::CPrimitiveClass::Zone: @@ -153,22 +177,13 @@ void addNewGraphicsItems(const QModelIndex &primIndex, PrimitivesTreeModel *mode void removeGraphicsItems(const QModelIndex &primIndex, PrimitivesTreeModel *model, WorldEditorScene *scene) { - PrimitiveNode *node = static_cast(primIndex.internalPointer()); + Node *node = static_cast(primIndex.internalPointer()); if (node != 0) { - switch (node->primitiveClass()->Type) - { - case NLLIGO::CPrimitiveClass::Point: - case NLLIGO::CPrimitiveClass::Path: - case NLLIGO::CPrimitiveClass::Zone: - { - QGraphicsItem *item = qvariant_cast(node->data(Constants::GRAPHICS_DATA_QT4_2D)); - if (item != 0) - scene->removeWorldItem(item); - break; - } - } + QGraphicsItem *item = getGraphicsItem(node); + if (item != 0) + scene->removeWorldItem(item); } int count = model->rowCount(primIndex); @@ -334,10 +349,11 @@ void LoadRootPrimitiveCommand::redo() } AddPrimitiveByClassCommand::AddPrimitiveByClassCommand(const QString &className, const Path &parentIndex, - PrimitivesTreeModel *model, QUndoCommand *parent) + WorldEditorScene *scene, PrimitivesTreeModel *model, QUndoCommand *parent) : QUndoCommand(parent), m_className(className), m_parentIndex(parentIndex), + m_scene(scene), m_model(model) { setText(QString("Add %1").arg(m_className)); diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_actions.h b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_actions.h index 2eda788b4..a76e49466 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_actions.h +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_actions.h @@ -36,7 +36,15 @@ namespace WorldEditor { class WorldEditorScene; +// Auxiliary operations + +// Return QGraphicsItem if node contains it +QGraphicsItem *getGraphicsItem(Node *node); + +// Scan primitives model for create/add necessary QGraphicsItems void addNewGraphicsItems(const QModelIndex &primIndex, PrimitivesTreeModel *model, WorldEditorScene *scene); + +// Recursive scan primitives model for delete Graphics Items void removeGraphicsItems(const QModelIndex &primIndex, PrimitivesTreeModel *model, WorldEditorScene *scene); QList graphicsItemsToPaths(const QList &items, PrimitivesTreeModel *model); //QList pathsToGraphicsItems(const QList &items, PrimitivesTreeModel *model); @@ -130,7 +138,8 @@ class AddPrimitiveByClassCommand: public QUndoCommand { public: AddPrimitiveByClassCommand(const QString &className, const Path &parentIndex, - PrimitivesTreeModel *model, QUndoCommand *parent = 0); + WorldEditorScene *scene, PrimitivesTreeModel *model, + QUndoCommand *parent = 0); virtual ~AddPrimitiveByClassCommand(); virtual void undo(); @@ -139,6 +148,7 @@ private: const QString m_className; Path m_parentIndex, m_newPrimIndex; + WorldEditorScene *m_scene; PrimitivesTreeModel *m_model; }; diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_scene.cpp b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_scene.cpp index b986d7c0c..7ec656f85 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_scene.cpp +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_scene.cpp @@ -42,6 +42,9 @@ WorldEditorScene::WorldEditorScene(int sizeCell, PrimitivesTreeModel *model, QUn { setItemIndexMethod(NoIndex); + // TODO: get params from settings + setSceneRect(QRectF(-20 * 160, -20 * 160, 256 * 160, 256 * 160)); + m_pen1.setColor(QColor(50, 255, 155)); m_pen1.setWidth(0); @@ -67,7 +70,7 @@ AbstractWorldItem *WorldEditorScene::addWorldItemPoint(const QPointF &point, con return item; } -AbstractWorldItem *WorldEditorScene::addWorldItemPath(const QPolygonF &polyline) +AbstractWorldItem *WorldEditorScene::addWorldItemPath(const QPolygonF &polyline, bool showArrow) { WorldItemPath *item = new WorldItemPath(polyline); addItem(item); @@ -113,6 +116,31 @@ void WorldEditorScene::setEnabledEditPoint(bool enabled) m_editMode = enabled; } +void WorldEditorScene::updateSelection(const QList &selected, const QList &deselected) +{ + // Deselect and remove from list graphics items. + Q_FOREACH(QGraphicsItem *item, deselected) + { + // Item is selected? + int i = m_selectedItems.indexOf(item); + if (i != -1) + { + updateSelectedItem(item, false); + m_selectedItems.takeAt(i); + } + } + + // Select and add from list graphics items. + Q_FOREACH(QGraphicsItem *item, selected) + { + updateSelectedItem(item, true); + m_selectedItems.push_back(item); + } + + update(); + m_editedSelectedItems = true; +} + void WorldEditorScene::drawForeground(QPainter *painter, const QRectF &rect) { QGraphicsScene::drawForeground(painter, rect); @@ -138,15 +166,11 @@ void WorldEditorScene::mousePressEvent(QGraphicsSceneMouseEvent *mouseEvent) { LandscapeEditor::LandscapeSceneBase::mousePressEvent(mouseEvent); - qreal x = mouseEvent->scenePos().x(); - qreal y = mouseEvent->scenePos().y(); - if (mouseEvent->button() != Qt::LeftButton) return; m_firstPick = mouseEvent->scenePos(); -// if ((!m_editedSelectedItems) && (m_mode != WorldEditorScene::SelectMode)) if ((!m_editedSelectedItems && m_selectedItems.isEmpty()) || (!calcBoundingRect(m_selectedItems).contains(mouseEvent->scenePos()))) { @@ -183,12 +207,19 @@ void WorldEditorScene::mousePressEvent(QGraphicsSceneMouseEvent *mouseEvent) break; }; + m_selectHack = true; // if (m_selectedItems.isEmpty()) // m_selectionArea.setTopLeft(mouseEvent->scenePos()); } void WorldEditorScene::mouseMoveEvent(QGraphicsSceneMouseEvent *mouseEvent) { + if (m_selectHack) + { + m_selectHack = false; + updateSelectedItems(true); + } + if (QApplication::mouseButtons() == Qt::LeftButton) { @@ -379,20 +410,25 @@ void WorldEditorScene::updateSelectedItems(bool value) { Q_FOREACH(QGraphicsItem *item, m_selectedItems) { - if (value) - { - item->setFlag(QGraphicsItem::ItemIsSelectable); - //item->setZValue(SELECTED_LAYER); - } - else - { - item->setFlag(QGraphicsItem::ItemIsSelectable, false); - //item->setZValue(UNSELECTED_LAYER); - } - item->setSelected(value); + updateSelectedItem(item, value); } } +void WorldEditorScene::updateSelectedItem(QGraphicsItem *item, bool value) +{ + if (value) + { + item->setFlag(QGraphicsItem::ItemIsSelectable); + //item->setZValue(SELECTED_LAYER); + } + else + { + item->setFlag(QGraphicsItem::ItemIsSelectable, false); + //item->setZValue(UNSELECTED_LAYER); + } + item->setSelected(value); +} + void WorldEditorScene::updatePickSelection(const QPointF &point) { //clearSelection(); diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_scene.h b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_scene.h index c7868b15a..3ca055786 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_scene.h +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_scene.h @@ -58,9 +58,8 @@ public: AbstractWorldItem *addWorldItemPoint(const QPointF &point, const qreal angle, const qreal radius, bool showArrow); - AbstractWorldItem *addWorldItemPath(const QPolygonF &polyline); + AbstractWorldItem *addWorldItemPath(const QPolygonF &polyline, bool showArrow); AbstractWorldItem *addWorldItemZone(const QPolygonF &polygon); - void removeWorldItem(QGraphicsItem *item); void setModeEdit(WorldEditorScene::ModeEdit mode); @@ -70,6 +69,7 @@ public: public Q_SLOTS: void setEnabledEditPoint(bool enabled); + void updateSelection(const QList &selected, const QList &deselected); protected: virtual void drawForeground(QPainter *painter, const QRectF &rect); @@ -83,12 +83,13 @@ private: QRectF calcBoundingRect(const QList &listItems); QPainterPath calcBoundingShape(const QList &listItems); void updateSelectedItems(bool value); - + void updateSelectedItem(QGraphicsItem *item, bool value); void updatePickSelection(const QPointF &point); QPen m_pen1, m_pen2; QBrush m_brush1, m_brush2; + bool m_selectHack; QPointF m_firstPick, m_scaleFactor, m_pivot; QRectF m_selectionArea; qreal m_firstPickX, m_firstPickY, m_angle; diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_scene_item.cpp b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_scene_item.cpp index 0e65e6455..89ddd80a5 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_scene_item.cpp +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_scene_item.cpp @@ -349,21 +349,7 @@ WorldItemPoint::WorldItemPoint(const QPointF &point, const qreal angle, const qr m_selectedBrush.setColor(Qt::white); m_selectedBrush.setStyle(Qt::SolidPattern); - - if (m_radius != 0) - { - // Create circle - int segmentCount = 30; - QPointF circlePoint(m_radius, 0); - m_circle << circlePoint; - for (int i = 1; i < segmentCount + 1; ++i) - { - qreal angle = i * (2 * NLMISC::Pi / segmentCount); - circlePoint.setX(cos(angle) * m_radius); - circlePoint.setY(sin(angle) * m_radius); - m_circle << circlePoint; - } - } + createCircle(); // Create arrow if (showArrow) @@ -373,6 +359,7 @@ WorldItemPoint::WorldItemPoint(const QPointF &point, const qreal angle, const qr m_arrow.push_back(QLine(SIZE_ARROW - 2, 2, SIZE_ARROW, 0)); } + updateBoundingRect(); //setFlag(ItemIsSelectable); } @@ -424,6 +411,8 @@ void WorldItemPoint::turnOn(const qreal angle) void WorldItemPoint::radiusOn(const qreal radius) { + if (m_radius == 0) + return; } void WorldItemPoint::setColor(const QColor &color) @@ -432,18 +421,43 @@ void WorldItemPoint::setColor(const QColor &color) m_brush.setColor(color); } +void WorldItemPoint::createCircle() +{ + if (m_radius != 0) + { + // Create circle + int segmentCount = 30; + QPointF circlePoint(m_radius, 0); + m_circle << circlePoint; + for (int i = 1; i < segmentCount + 1; ++i) + { + qreal angle = i * (2 * NLMISC::Pi / segmentCount); + circlePoint.setX(cos(angle) * m_radius); + circlePoint.setY(sin(angle) * m_radius); + m_circle << circlePoint; + } + } +} + +void WorldItemPoint::updateBoundingRect() +{ + m_boundingRect.setCoords(-SIZE_POINT, -SIZE_POINT, SIZE_POINT, SIZE_POINT); + QRectF circleBoundingRect; + circleBoundingRect.setCoords(-m_radius, -m_radius, m_radius, m_radius); + m_boundingRect = m_boundingRect.united(circleBoundingRect); +} + QPainterPath WorldItemPoint::shape() const { QPainterPath path; - path.addRect(m_rect); - + path.addRect(m_boundingRect); return qt_graphicsItem_shapeFromPath(path, m_pen); } QRectF WorldItemPoint::boundingRect() const { - return m_rect; + return m_boundingRect; } void WorldItemPoint::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *) diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_scene_item.h b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_scene_item.h index af30c3470..0625084bd 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_scene_item.h +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_scene_item.h @@ -168,6 +168,8 @@ protected: virtual QVariant itemChange(GraphicsItemChange change, const QVariant &value); private: + void createCircle(); + void updateBoundingRect(); // TODO static const int SIZE_POINT = 3; @@ -177,7 +179,7 @@ private: QPolygonF m_circle; QVector m_arrow; - QRectF m_rect; + QRectF m_rect, m_boundingRect; qreal m_angle, m_radius; bool m_showArrow; }; @@ -236,7 +238,7 @@ public: protected: virtual QVariant itemChange(GraphicsItemChange change, const QVariant &value); - static const int TRANSPARENCY = 28; + static const int TRANSPARENCY = 38; QPen m_pen, m_selectedPen; QBrush m_brush, m_selectedBrush; diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_window.cpp b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_window.cpp index 1e8a65506..e00e804f3 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_window.cpp +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_window.cpp @@ -105,6 +105,9 @@ WorldEditorWindow::WorldEditorWindow(QWidget *parent) connect(m_ui.saveWorldEditAction, SIGNAL(triggered()), this, SLOT(saveWorldEditFile())); connect(m_ui.visibleGridAction, SIGNAL(toggled(bool)), m_ui.graphicsView, SLOT(setVisibleGrid(bool))); + connect(m_ui.treePrimitivesView->selectionModel(), SIGNAL(selectionChanged(QItemSelection, QItemSelection)), + this, SLOT(updateSelection(QItemSelection, QItemSelection))); + m_statusBarTimer = new QTimer(this); connect(m_statusBarTimer, SIGNAL(timeout()), this, SLOT(updateStatusBar())); @@ -250,6 +253,47 @@ void WorldEditorWindow::updateStatusBar() m_statusInfo->setText(m_worldEditorScene->zoneNameFromMousePos()); } +void WorldEditorWindow::updateSelection(const QItemSelection &selected, const QItemSelection &deselected) +{ + m_ui.pointsAction->setChecked(false); + + NodeList nodesSelected; + Q_FOREACH(QModelIndex modelIndex, selected.indexes()) + { + Node *node = static_cast(modelIndex.internalPointer()); + nodesSelected.push_back(node); + } + + NodeList nodesDeselected; + Q_FOREACH(QModelIndex modelIndex, deselected.indexes()) + { + Node *node = static_cast(modelIndex.internalPointer()); + nodesDeselected.push_back(node); + } + + // TODO: update property editor + // ... + + QList itemSelected; + Q_FOREACH(Node *node, nodesSelected) + { + QGraphicsItem *item = getGraphicsItem(node); + if (item != 0) + itemSelected.push_back(item); + } + + QList itemDeselected; + Q_FOREACH(Node *node, nodesDeselected) + { + QGraphicsItem *item = getGraphicsItem(node); + if (item != 0) + itemDeselected.push_back(item); + } + + // Update world editor scene + m_worldEditorScene->updateSelection(itemSelected, itemDeselected); +} + void WorldEditorWindow::showEvent(QShowEvent *showEvent) { QMainWindow::showEvent(showEvent); diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_window.h b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_window.h index 58cd3a532..5844489f6 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_window.h +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_window.h @@ -60,6 +60,8 @@ private Q_SLOTS: void setMode(int value); void updateStatusBar(); + void updateSelection(const QItemSelection &selected, const QItemSelection &deselected); + protected: virtual void showEvent(QShowEvent *showEvent); virtual void hideEvent(QHideEvent *hideEvent);