From 38688ea8836fc65621985a5947beddf4a0e51734 Mon Sep 17 00:00:00 2001 From: dnk-88 Date: Mon, 15 Aug 2011 17:03:28 +0300 Subject: [PATCH] Changed: #1302 Added edit points mode with undo/redo commands and turn undo/redo command for PointWorldItem. --- .../src/plugins/world_editor/primitive_item.h | 1 + .../plugins/world_editor/primitives_view.h | 3 - .../world_editor/world_editor_actions.cpp | 108 ++- .../world_editor/world_editor_actions.h | 43 +- .../world_editor/world_editor_scene.cpp | 438 +++++++--- .../plugins/world_editor/world_editor_scene.h | 23 +- .../world_editor/world_editor_scene_item.cpp | 818 +++++++++++------- .../world_editor/world_editor_scene_item.h | 208 +++-- .../world_editor/world_editor_window.cpp | 3 +- .../world_editor/world_editor_window.ui | 19 +- 10 files changed, 1111 insertions(+), 553 deletions(-) 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 204068db0..1b2a89d4c 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 @@ -177,6 +177,7 @@ typedef QList NodeList; } /* namespace WorldEditor */ +// Enable the use of QVariant with this class. Q_DECLARE_METATYPE(WorldEditor::Node *) #endif // PRIMITIVE_ITEM_H 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 df317a93b..eae9187ac 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 @@ -61,9 +61,6 @@ 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 db4abcaa8..45adf49ce 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 @@ -204,12 +204,16 @@ QList graphicsItemsToPaths(const QList &items, Primitives return result; } -/* -QList pathsToGraphicsItems(const QList &items, PrimitivesTreeModel *model) +QList polygonsFromItems(const QList &items) { - QList result; + QList result; + Q_FOREACH(QGraphicsItem *item, items) + { + AbstractWorldItem *worldItem = qgraphicsitem_cast(item); + result.push_back(worldItem->polygon()); + } + return result; } -*/ CreateWorldCommand::CreateWorldCommand(const QString &fileName, PrimitivesTreeModel *model, QUndoCommand *parent) : QUndoCommand(parent), @@ -310,6 +314,8 @@ LoadRootPrimitiveCommand::~LoadRootPrimitiveCommand() void LoadRootPrimitiveCommand::undo() { + m_scene->setEnabledEditPoints(false); + QModelIndex index = m_model->pathToIndex(m_rootPrimIndex); removeGraphicsItems(index, m_model, m_scene); @@ -323,6 +329,8 @@ void LoadRootPrimitiveCommand::undo() void LoadRootPrimitiveCommand::redo() { + m_scene->setEnabledEditPoints(false); + NLLIGO::CPrimitives *primitives = new NLLIGO::CPrimitives(); // set the primitive context @@ -365,6 +373,8 @@ AddPrimitiveByClassCommand::~AddPrimitiveByClassCommand() void AddPrimitiveByClassCommand::undo() { + m_scene->setEnabledEditPoints(false); + QModelIndex index = m_model->pathToIndex(m_newPrimIndex); PrimitiveNode *node = static_cast(index.internalPointer()); @@ -381,6 +391,8 @@ void AddPrimitiveByClassCommand::undo() void AddPrimitiveByClassCommand::redo() { + m_scene->setEnabledEditPoints(false); + QModelIndex parentIndex = m_model->pathToIndex(m_parentIndex); PrimitiveNode *parentNode = static_cast(parentIndex.internalPointer()); const NLLIGO::CPrimitiveClass *primClass = parentNode->primitiveClass(); @@ -404,11 +416,12 @@ void AddPrimitiveByClassCommand::redo() } MoveWorldItemsCommand::MoveWorldItemsCommand(const QList &items, const QPointF &offset, - PrimitivesTreeModel *model, QUndoCommand *parent) + WorldEditorScene *scene, PrimitivesTreeModel *model, QUndoCommand *parent) : QUndoCommand(parent), m_listPaths(graphicsItemsToPaths(items, model)), m_offset(offset), m_model(model), + m_scene(scene), m_firstRun(true) { setText("Move item(s)"); @@ -420,35 +433,42 @@ MoveWorldItemsCommand::~MoveWorldItemsCommand() void MoveWorldItemsCommand::undo() { + bool pointsMode = m_scene->isEnabledEditPoints(); + m_scene->setEnabledEditPoints(false); for (int i = 0; i < m_listPaths.count(); ++i) { Node *node = m_model->pathToNode(m_listPaths.at(i)); AbstractWorldItem *item = qvariant_cast(node->data(Constants::GRAPHICS_DATA_QT4_2D)); item->moveBy(-m_offset.x(), -m_offset.y()); } + m_scene->setEnabledEditPoints(pointsMode); } void MoveWorldItemsCommand::redo() { if (!m_firstRun) { + bool pointsMode = m_scene->isEnabledEditPoints(); + m_scene->setEnabledEditPoints(false); for (int i = 0; i < m_listPaths.count(); ++i) { Node *node = m_model->pathToNode(m_listPaths.at(i)); AbstractWorldItem *item = qvariant_cast(node->data(Constants::GRAPHICS_DATA_QT4_2D)); item->moveBy(m_offset.x(), m_offset.y()); } + m_scene->setEnabledEditPoints(pointsMode); } m_firstRun = false; } RotateWorldItemsCommand::RotateWorldItemsCommand(const QList &items, const qreal angle, - const QPointF &pivot, PrimitivesTreeModel *model, QUndoCommand *parent) + const QPointF &pivot, WorldEditorScene *scene, PrimitivesTreeModel *model, QUndoCommand *parent) : QUndoCommand(parent), m_listPaths(graphicsItemsToPaths(items, model)), m_angle(angle), m_pivot(pivot), m_model(model), + m_scene(scene), m_firstRun(true) { setText(QString("Rotate item(s) %1").arg(m_angle)); @@ -460,35 +480,42 @@ RotateWorldItemsCommand::~RotateWorldItemsCommand() void RotateWorldItemsCommand::undo() { + bool pointsMode = m_scene->isEnabledEditPoints(); + m_scene->setEnabledEditPoints(false); for (int i = 0; i < m_listPaths.count(); ++i) { Node *node = m_model->pathToNode(m_listPaths.at(i)); AbstractWorldItem *item = qvariant_cast(node->data(Constants::GRAPHICS_DATA_QT4_2D)); item->rotateOn(m_pivot, -m_angle); } + m_scene->setEnabledEditPoints(pointsMode); } void RotateWorldItemsCommand::redo() { if (!m_firstRun) { + bool pointsMode = m_scene->isEnabledEditPoints(); + m_scene->setEnabledEditPoints(false); for (int i = 0; i < m_listPaths.count(); ++i) { Node *node = m_model->pathToNode(m_listPaths.at(i)); AbstractWorldItem *item = qvariant_cast(node->data(Constants::GRAPHICS_DATA_QT4_2D)); item->rotateOn(m_pivot, m_angle); } + m_scene->setEnabledEditPoints(pointsMode); } m_firstRun = false; } ScaleWorldItemsCommand::ScaleWorldItemsCommand(const QList &items, const QPointF &factor, - const QPointF &pivot, PrimitivesTreeModel *model, QUndoCommand *parent) + const QPointF &pivot, WorldEditorScene *scene, PrimitivesTreeModel *model, QUndoCommand *parent) : QUndoCommand(parent), m_listPaths(graphicsItemsToPaths(items, model)), m_factor(factor), m_pivot(pivot), m_model(model), + m_scene(scene), m_firstRun(true) { setText("Scale item(s)"); @@ -500,6 +527,8 @@ ScaleWorldItemsCommand::~ScaleWorldItemsCommand() void ScaleWorldItemsCommand::undo() { + bool pointsMode = m_scene->isEnabledEditPoints(); + m_scene->setEnabledEditPoints(false); QPointF m_invertFactor(1 / m_factor.x(), 1 / m_factor.y()); for (int i = 0; i < m_listPaths.count(); ++i) { @@ -507,28 +536,33 @@ void ScaleWorldItemsCommand::undo() AbstractWorldItem *item = qvariant_cast(node->data(Constants::GRAPHICS_DATA_QT4_2D)); item->scaleOn(m_pivot, m_invertFactor); } + m_scene->setEnabledEditPoints(pointsMode); } void ScaleWorldItemsCommand::redo() { if (!m_firstRun) { + bool pointsMode = m_scene->isEnabledEditPoints(); + m_scene->setEnabledEditPoints(false); for (int i = 0; i < m_listPaths.count(); ++i) { Node *node = m_model->pathToNode(m_listPaths.at(i)); AbstractWorldItem *item = qvariant_cast(node->data(Constants::GRAPHICS_DATA_QT4_2D)); item->scaleOn(m_pivot, m_factor); } + m_scene->setEnabledEditPoints(pointsMode); } m_firstRun = false; } TurnWorldItemsCommand::TurnWorldItemsCommand(const QList &items, const qreal angle, - PrimitivesTreeModel *model, QUndoCommand *parent) + WorldEditorScene *scene, PrimitivesTreeModel *model, QUndoCommand *parent) : QUndoCommand(parent), m_listPaths(graphicsItemsToPaths(items, model)), m_angle(angle), m_model(model), + m_scene(scene), m_firstRun(true) { setText(QString("Turn item(s) %1").arg(m_angle)); @@ -540,24 +574,82 @@ TurnWorldItemsCommand::~TurnWorldItemsCommand() void TurnWorldItemsCommand::undo() { + bool pointsMode = m_scene->isEnabledEditPoints(); + m_scene->setEnabledEditPoints(false); for (int i = 0; i < m_listPaths.count(); ++i) { Node *node = m_model->pathToNode(m_listPaths.at(i)); AbstractWorldItem *item = qvariant_cast(node->data(Constants::GRAPHICS_DATA_QT4_2D)); item->turnOn(-m_angle); } + m_scene->setEnabledEditPoints(pointsMode); } void TurnWorldItemsCommand::redo() { if (!m_firstRun) { + bool pointsMode = m_scene->isEnabledEditPoints(); + m_scene->setEnabledEditPoints(false); for (int i = 0; i < m_listPaths.count(); ++i) { Node *node = m_model->pathToNode(m_listPaths.at(i)); AbstractWorldItem *item = qvariant_cast(node->data(Constants::GRAPHICS_DATA_QT4_2D)); item->turnOn(m_angle); } + m_scene->setEnabledEditPoints(pointsMode); + } + + m_firstRun = false; +} + +ShapeWorldItemsCommand::ShapeWorldItemsCommand(const QList &items, const QList &polygons, + WorldEditorScene *scene, PrimitivesTreeModel *model, + QUndoCommand *parent) + : QUndoCommand(parent), + m_listPaths(graphicsItemsToPaths(items, model)), + m_redoPolygons(polygons), + m_undoPolygons(polygonsFromItems(items)), + m_model(model), + m_scene(scene), + m_firstRun(true) +{ + setText("Change shape"); +} + +ShapeWorldItemsCommand::~ShapeWorldItemsCommand() +{ +} + +void ShapeWorldItemsCommand::undo() +{ + bool pointsMode = m_scene->isEnabledEditPoints(); + m_scene->setEnabledEditPoints(false); + + for (int i = 0; i < m_listPaths.count(); ++i) + { + Node *node = m_model->pathToNode(m_listPaths.at(i)); + AbstractWorldItem *item = qvariant_cast(node->data(Constants::GRAPHICS_DATA_QT4_2D)); + item->setPolygon(m_redoPolygons.at(i)); + } + + m_scene->setEnabledEditPoints(pointsMode); +} + +void ShapeWorldItemsCommand::redo() +{ + if (!m_firstRun) + { + bool pointsMode = m_scene->isEnabledEditPoints(); + m_scene->setEnabledEditPoints(false); + + for (int i = 0; i < m_listPaths.count(); ++i) + { + Node *node = m_model->pathToNode(m_listPaths.at(i)); + AbstractWorldItem *item = qvariant_cast(node->data(Constants::GRAPHICS_DATA_QT4_2D)); + item->setPolygon(m_undoPolygons.at(i)); + } + m_scene->setEnabledEditPoints(pointsMode); } m_firstRun = false; } 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 a76e49466..fcb510605 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 @@ -47,7 +47,8 @@ void addNewGraphicsItems(const QModelIndex &primIndex, PrimitivesTreeModel *mode // 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); + +QList polygonsFromItems(const QList &items); /** @class CreateWorldCommand @@ -161,7 +162,8 @@ class MoveWorldItemsCommand: public QUndoCommand { public: MoveWorldItemsCommand(const QList &items, const QPointF &offset, - PrimitivesTreeModel *model, QUndoCommand *parent = 0); + WorldEditorScene *scene, PrimitivesTreeModel *model, + QUndoCommand *parent = 0); virtual ~MoveWorldItemsCommand(); virtual void undo(); @@ -171,6 +173,7 @@ private: const QList m_listPaths; const QPointF m_offset; PrimitivesTreeModel *const m_model; + WorldEditorScene *m_scene; bool m_firstRun; }; @@ -183,7 +186,8 @@ class RotateWorldItemsCommand: public QUndoCommand { public: RotateWorldItemsCommand(const QList &items, const qreal angle, - const QPointF &pivot, PrimitivesTreeModel *model, QUndoCommand *parent = 0); + const QPointF &pivot, WorldEditorScene *scene, + PrimitivesTreeModel *model, QUndoCommand *parent = 0); virtual ~RotateWorldItemsCommand(); virtual void undo(); @@ -194,6 +198,7 @@ private: const qreal m_angle; const QPointF m_pivot; PrimitivesTreeModel *const m_model; + WorldEditorScene *m_scene; bool m_firstRun; }; @@ -206,7 +211,8 @@ class ScaleWorldItemsCommand: public QUndoCommand { public: ScaleWorldItemsCommand(const QList &items, const QPointF &factor, - const QPointF &pivot, PrimitivesTreeModel *model, QUndoCommand *parent = 0); + const QPointF &pivot, WorldEditorScene *scene, + PrimitivesTreeModel *model, QUndoCommand *parent = 0); virtual ~ScaleWorldItemsCommand(); virtual void undo(); @@ -217,6 +223,7 @@ private: const QPointF m_factor; const QPointF m_pivot; PrimitivesTreeModel *const m_model; + WorldEditorScene *m_scene; bool m_firstRun; }; @@ -229,7 +236,8 @@ class TurnWorldItemsCommand: public QUndoCommand { public: TurnWorldItemsCommand(const QList &items, const qreal angle, - PrimitivesTreeModel *model, QUndoCommand *parent = 0); + WorldEditorScene *scene, PrimitivesTreeModel *model, + QUndoCommand *parent = 0); virtual ~TurnWorldItemsCommand(); virtual void undo(); @@ -239,9 +247,34 @@ private: const QList m_listPaths; const qreal m_angle; PrimitivesTreeModel *const m_model; + WorldEditorScene *m_scene; bool m_firstRun; }; +/** +@class TurnWorldItemsCommand +@brief +@details +*/ +class ShapeWorldItemsCommand: public QUndoCommand +{ +public: + ShapeWorldItemsCommand(const QList &items, const QList &polygons, + WorldEditorScene *scene, PrimitivesTreeModel *model, + QUndoCommand *parent = 0); + virtual ~ShapeWorldItemsCommand(); + + virtual void undo(); + virtual void redo(); +private: + + const QList m_listPaths; + const QList m_redoPolygons; + const QList m_undoPolygons; + PrimitivesTreeModel *const m_model; + WorldEditorScene *m_scene; + bool m_firstRun; +}; } /* namespace WorldEditor */ 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 7ec656f85..749392631 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 @@ -36,7 +36,7 @@ WorldEditorScene::WorldEditorScene(int sizeCell, PrimitivesTreeModel *model, QUn m_editedSelectedItems(false), m_lastPickedPrimitive(0), m_mode(SelectMode), - m_editMode(false), + m_pointsMode(false), m_undoStack(undoStack), m_model(model) { @@ -86,7 +86,7 @@ AbstractWorldItem *WorldEditorScene::addWorldItemZone(const QPolygonF &polygon) void WorldEditorScene::removeWorldItem(QGraphicsItem *item) { - updateSelectedItems(true); + updateSelectedWorldItems(true); m_selectedItems.clear(); m_editedSelectedItems = false; m_firstSelection = false; @@ -106,14 +106,26 @@ WorldEditorScene::ModeEdit WorldEditorScene::editMode() const return m_mode; } -bool WorldEditorScene::isEnabledEditPoint() const +bool WorldEditorScene::isEnabledEditPoints() const { - return m_editMode; + return m_pointsMode; } -void WorldEditorScene::setEnabledEditPoint(bool enabled) +void WorldEditorScene::setEnabledEditPoints(bool enabled) { - m_editMode = enabled; + if (m_pointsMode == enabled) + return; + + m_pointsMode = enabled; + + Q_FOREACH(QGraphicsItem *item, m_selectedItems) + { + AbstractWorldItem *worldItem = qgraphicsitem_cast(item); + if (worldItem != 0) + worldItem->setEnabledSubPoints(enabled); + } + + m_selectedPoints.clear(); } void WorldEditorScene::updateSelection(const QList &selected, const QList &deselected) @@ -125,7 +137,7 @@ void WorldEditorScene::updateSelection(const QList &selected, c int i = m_selectedItems.indexOf(item); if (i != -1) { - updateSelectedItem(item, false); + updateSelectedWorldItem(item, false); m_selectedItems.takeAt(i); } } @@ -133,12 +145,17 @@ void WorldEditorScene::updateSelection(const QList &selected, c // Select and add from list graphics items. Q_FOREACH(QGraphicsItem *item, selected) { - updateSelectedItem(item, true); - m_selectedItems.push_back(item); + // Item is selected? + int i = m_selectedItems.indexOf(item); + if (i == -1) + { + updateSelectedWorldItem(item, true); + m_selectedItems.push_back(item); + } } update(); - m_editedSelectedItems = true; + m_firstSelection = true; } void WorldEditorScene::drawForeground(QPainter *painter, const QRectF &rect) @@ -164,65 +181,68 @@ void WorldEditorScene::drawForeground(QPainter *painter, const QRectF &rect) void WorldEditorScene::mousePressEvent(QGraphicsSceneMouseEvent *mouseEvent) { - LandscapeEditor::LandscapeSceneBase::mousePressEvent(mouseEvent); - - if (mouseEvent->button() != Qt::LeftButton) - return; - m_firstPick = mouseEvent->scenePos(); - if ((!m_editedSelectedItems && m_selectedItems.isEmpty()) || - (!calcBoundingRect(m_selectedItems).contains(mouseEvent->scenePos()))) + if (m_pointsMode) { - updatePickSelection(mouseEvent->scenePos()); - m_firstSelection = true; + m_polygons = polygonsFromItems(m_selectedItems); + + if (mouseEvent->button() == Qt::LeftButton) + { + // Create new sub-points + // Call method mousePressEvent for point located under mouse + LandscapeEditor::LandscapeSceneBase::mousePressEvent(mouseEvent); + + if ((!m_editedSelectedItems && m_selectedPoints.isEmpty()) || + (!calcBoundingRect(m_selectedPoints).contains(mouseEvent->scenePos()))) + { + updatePickSelectionPoints(mouseEvent->scenePos()); + m_firstSelection = true; + } + m_pivot = calcBoundingRect(m_selectedPoints).center(); + } + else if (mouseEvent->button() == Qt::RightButton) + { + updateSelectedPointItems(false); + m_selectedPoints.clear(); + + // Delete sub-points if it located under mouse + // Call method mousePressEvent for point located under mouse + LandscapeEditor::LandscapeSceneBase::mousePressEvent(mouseEvent); + } + } + else + { + LandscapeEditor::LandscapeSceneBase::mousePressEvent(mouseEvent); + + if (mouseEvent->button() != Qt::LeftButton) + return; + + if ((!m_editedSelectedItems && m_selectedItems.isEmpty()) || + (!calcBoundingRect(m_selectedItems).contains(mouseEvent->scenePos()))) + { + updatePickSelection(mouseEvent->scenePos()); + m_firstSelection = true; + } + + m_pivot = calcBoundingRect(m_selectedItems).center(); } m_editedSelectedItems = false; + m_angle = 0; + m_scaleFactor = QPointF(1.0, 1.0); - switch (m_mode) - { - case WorldEditorScene::SelectMode: - { + if (m_mode == WorldEditorScene::SelectMode) m_selectionArea.setTopLeft(mouseEvent->scenePos()); - break; - } - case WorldEditorScene::MoveMode: - { - break; - } - case WorldEditorScene::RotateMode: - m_angle = 0; - m_pivot = calcBoundingRect(m_selectedItems).center(); - break; - case WorldEditorScene::ScaleMode: - m_scaleFactor = QPointF(1.0, 1.0); - m_pivot = calcBoundingRect(m_selectedItems).center(); - break; - case WorldEditorScene::TurnMode: - m_angle = 0; - m_pivot = calcBoundingRect(m_selectedItems).center(); - break; - case WorldEditorScene::RadiusMode: - 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) { - QPointF offset(mouseEvent->scenePos() - mouseEvent->lastScenePos()); m_selectionArea.setBottomRight(mouseEvent->scenePos()); @@ -233,9 +253,19 @@ void WorldEditorScene::mouseMoveEvent(QGraphicsSceneMouseEvent *mouseEvent) break; case WorldEditorScene::MoveMode: { - Q_FOREACH(QGraphicsItem *item, m_selectedItems) + if (m_pointsMode) { - item->moveBy(offset.x(), offset.y()); + Q_FOREACH(QGraphicsItem *item, m_selectedPoints) + { + item->moveBy(offset.x(), offset.y()); + } + } + else + { + Q_FOREACH(QGraphicsItem *item, m_selectedItems) + { + item->moveBy(offset.x(), offset.y()); + } } break; } @@ -248,9 +278,19 @@ void WorldEditorScene::mouseMoveEvent(QGraphicsSceneMouseEvent *mouseEvent) m_angle += angle; - Q_FOREACH(QGraphicsItem *item, m_selectedItems) + if (m_pointsMode) { - qgraphicsitem_cast(item)->rotateOn(m_pivot, angle); + Q_FOREACH(QGraphicsItem *item, m_selectedPoints) + { + qgraphicsitem_cast(item)->rotateOn(m_pivot, angle); + } + } + else + { + Q_FOREACH(QGraphicsItem *item, m_selectedItems) + { + qgraphicsitem_cast(item)->rotateOn(m_pivot, angle); + } } break; } @@ -270,9 +310,19 @@ void WorldEditorScene::mouseMoveEvent(QGraphicsSceneMouseEvent *mouseEvent) m_scaleFactor.setX(offset.x() * m_scaleFactor.x()); m_scaleFactor.setY(offset.y() * m_scaleFactor.y()); - Q_FOREACH(QGraphicsItem *item, m_selectedItems) + if (m_pointsMode) { - qgraphicsitem_cast(item)->scaleOn(m_pivot, offset); + Q_FOREACH(QGraphicsItem *item, m_selectedPoints) + { + qgraphicsitem_cast(item)->scaleOn(m_pivot, offset); + } + } + else + { + Q_FOREACH(QGraphicsItem *item, m_selectedItems) + { + qgraphicsitem_cast(item)->scaleOn(m_pivot, offset); + } } break; } @@ -296,91 +346,133 @@ void WorldEditorScene::mouseMoveEvent(QGraphicsSceneMouseEvent *mouseEvent) break; }; - if ((editMode() != WorldEditorScene::SelectMode) && (!m_selectedItems.isEmpty())) - m_editedSelectedItems = true; + if (m_pointsMode) + { + if ((editMode() != WorldEditorScene::SelectMode) && (!m_selectedPoints.isEmpty())) + m_editedSelectedItems = true; + else + m_editedSelectedItems = false; + } else - m_editedSelectedItems = false; + { + if ((editMode() != WorldEditorScene::SelectMode) && (!m_selectedItems.isEmpty())) + m_editedSelectedItems = true; + else + m_editedSelectedItems = false; + } update(); } - /*m_mouseX = mouseEvent->scenePos().x(); - m_mouseY = mouseEvent->scenePos().y() - m_cellSize; - */ + LandscapeEditor::LandscapeSceneBase::mouseMoveEvent(mouseEvent); } void WorldEditorScene::mouseReleaseEvent(QGraphicsSceneMouseEvent *mouseEvent) { - if (mouseEvent->button() != Qt::LeftButton) - return; - - if (m_editedSelectedItems) + if (m_pointsMode) { - switch (m_mode) + if (mouseEvent->button() == Qt::LeftButton) { - case WorldEditorScene::SelectMode: - break; + if ((m_selectionArea.left() != 0) && (m_selectionArea.right() != 0)) + { + QList listItems; - case WorldEditorScene::MoveMode: - { - QPointF offset = mouseEvent->scenePos() - m_firstPick; - m_undoStack->push(new MoveWorldItemsCommand(m_selectedItems, offset, m_model)); - break; + // Clear selection + updateSelectedPointItems(false); + m_selectedPoints.clear(); + + if (m_selectionArea.left() < m_selectionArea.right()) + listItems = items(m_selectionArea, Qt::IntersectsItemShape, Qt::AscendingOrder); + else + listItems = items(m_selectionArea, Qt::ContainsItemShape, Qt::AscendingOrder); + + Q_FOREACH(QGraphicsItem *item, listItems) + { + if (qgraphicsitem_cast(item) == 0) + continue; + + m_selectedPoints.push_back(item); + } + updateSelectedPointItems(true); + m_selectionArea = QRectF(); + update(); + } + else + { + if ((!m_editedSelectedItems) && (!m_firstSelection)) + updatePickSelectionPoints(mouseEvent->scenePos()); + else + m_firstSelection = false; + } } - case WorldEditorScene::RotateMode: - m_undoStack->push(new RotateWorldItemsCommand(m_selectedItems, m_angle, m_pivot, m_model)); - break; - case WorldEditorScene::ScaleMode: - m_undoStack->push(new ScaleWorldItemsCommand(m_selectedItems, m_scaleFactor, m_pivot, m_model)); - break; - case WorldEditorScene::TurnMode: - m_undoStack->push(new TurnWorldItemsCommand(m_selectedItems, m_angle, m_model)); - break; - case WorldEditorScene::RadiusMode: - break; - }; - } - - if ((m_selectionArea.left() != 0) && (m_selectionArea.right() != 0)) - { - QList listItems; - - // Clear selection - updateSelectedItems(false); - m_selectedItems.clear(); - - if (m_selectionArea.left() < m_selectionArea.right()) - { - listItems = items(m_selectionArea, Qt::IntersectsItemShape, - Qt::AscendingOrder); - } - else - { - listItems = items(m_selectionArea, Qt::ContainsItemShape, - Qt::AscendingOrder); - } - - Q_FOREACH(QGraphicsItem *item, listItems) - { - if (qgraphicsitem_cast(item) == 0) - continue; - - m_selectedItems.push_back(item); - } - updateSelectedItems(true); - m_selectionArea = QRectF(); - update(); + checkUndo(); } else { - if ((!m_editedSelectedItems) && (!m_firstSelection)) - updatePickSelection(mouseEvent->scenePos()); - else - m_firstSelection = false; + if (mouseEvent->button() != Qt::LeftButton) + return; - m_selectionArea = QRectF(); + if (m_editedSelectedItems) + { + switch (m_mode) + { + case WorldEditorScene::SelectMode: + break; + + case WorldEditorScene::MoveMode: + { + QPointF offset = mouseEvent->scenePos() - m_firstPick; + m_undoStack->push(new MoveWorldItemsCommand(m_selectedItems, offset, this, m_model)); + break; + } + case WorldEditorScene::RotateMode: + m_undoStack->push(new RotateWorldItemsCommand(m_selectedItems, m_angle, m_pivot, this, m_model)); + break; + case WorldEditorScene::ScaleMode: + m_undoStack->push(new ScaleWorldItemsCommand(m_selectedItems, m_scaleFactor, m_pivot, this, m_model)); + break; + case WorldEditorScene::TurnMode: + m_undoStack->push(new TurnWorldItemsCommand(m_selectedItems, m_angle, this, m_model)); + break; + case WorldEditorScene::RadiusMode: + break; + }; + } + + if ((m_selectionArea.left() != 0) && (m_selectionArea.right() != 0)) + { + QList listItems; + + // Clear selection + updateSelectedWorldItems(false); + m_selectedItems.clear(); + + if (m_selectionArea.left() < m_selectionArea.right()) + listItems = items(m_selectionArea, Qt::IntersectsItemShape, Qt::AscendingOrder); + else + listItems = items(m_selectionArea, Qt::ContainsItemShape, Qt::AscendingOrder); + + Q_FOREACH(QGraphicsItem *item, listItems) + { + if (qgraphicsitem_cast(item) == 0) + continue; + + m_selectedItems.push_back(item); + } + updateSelectedWorldItems(true); + m_selectionArea = QRectF(); + update(); + } + else + { + if ((!m_editedSelectedItems) && (!m_firstSelection)) + updatePickSelection(mouseEvent->scenePos()); + else + m_firstSelection = false; + } } + m_selectionArea = QRectF(); LandscapeEditor::LandscapeSceneBase::mouseReleaseEvent(mouseEvent); } @@ -390,7 +482,7 @@ QRectF WorldEditorScene::calcBoundingRect(const QList &listItem Q_FOREACH(QGraphicsItem *item, listItems) { QRectF itemRect = item->boundingRect(); - rect = rect.united(itemRect.translated(item->pos())); + rect = rect.united(itemRect.translated(item->scenePos())); } return rect; } @@ -401,38 +493,46 @@ QPainterPath WorldEditorScene::calcBoundingShape(const QList &l Q_FOREACH(QGraphicsItem *item, listItems) { QPainterPath itemPath = item->shape(); - painterPath = painterPath.united(itemPath.translated(item->pos())); + painterPath = painterPath.united(itemPath.translated(item->scenePos())); } return painterPath; } -void WorldEditorScene::updateSelectedItems(bool value) +void WorldEditorScene::updateSelectedWorldItems(bool value) { Q_FOREACH(QGraphicsItem *item, m_selectedItems) { - updateSelectedItem(item, value); + updateSelectedWorldItem(item, value); } + update(); } -void WorldEditorScene::updateSelectedItem(QGraphicsItem *item, bool value) +void WorldEditorScene::updateSelectedWorldItem(QGraphicsItem *item, bool value) { - if (value) + AbstractWorldItem *worldItem = qgraphicsitem_cast(item); + if (worldItem != 0) + worldItem->setActived(value); +} + +void WorldEditorScene::updateSelectedPointItems(bool value) +{ + Q_FOREACH(QGraphicsItem *item, m_selectedPoints) { - item->setFlag(QGraphicsItem::ItemIsSelectable); - //item->setZValue(SELECTED_LAYER); + updateSelectedPointItem(item, value); } - else - { - item->setFlag(QGraphicsItem::ItemIsSelectable, false); - //item->setZValue(UNSELECTED_LAYER); - } - item->setSelected(value); + update(); +} + +void WorldEditorScene::updateSelectedPointItem(QGraphicsItem *item, bool value) +{ + WorldItemSubPoint *worldItem = qgraphicsitem_cast(item); + if (worldItem != 0) + worldItem->setActived(value); } void WorldEditorScene::updatePickSelection(const QPointF &point) { - //clearSelection(); - updateSelectedItems(false); + updateSelectedWorldItems(false); m_selectedItems.clear(); QList listItems = items(point, Qt::ContainsItemShape, @@ -454,7 +554,63 @@ void WorldEditorScene::updatePickSelection(const QPointF &point) m_lastPickedPrimitive %= worldItemsItems.size(); m_selectedItems.push_back(worldItemsItems.at(m_lastPickedPrimitive)); - updateSelectedItems(true); + updateSelectedWorldItems(true); + } +} + +void WorldEditorScene::updatePickSelectionPoints(const QPointF &point) +{ + updateSelectedPointItems(false); + m_selectedPoints.clear(); + + QList listItems = items(point, Qt::IntersectsItemBoundingRect, + Qt::AscendingOrder); + + QList subPointsItems; + + Q_FOREACH(QGraphicsItem *item, listItems) + { + WorldItemSubPoint *subPointItem = qgraphicsitem_cast(item); + if (subPointItem != 0) + { + if (subPointItem->subPointType() == WorldItemSubPoint::EdgeType) + subPointsItems.push_back(subPointItem); + } + } + + if (!subPointsItems.isEmpty()) + { + // Next primitives + m_lastPickedPrimitive++; + m_lastPickedPrimitive %= subPointsItems.size(); + + m_selectedPoints.push_back(subPointsItems.at(m_lastPickedPrimitive)); + updateSelectedPointItems(true); + } +} + +void WorldEditorScene::checkUndo() +{ + if (m_pointsMode) + { + QList items; + QList polygons; + Q_FOREACH(QGraphicsItem *item, m_selectedItems) + { + AbstractWorldItem *worldItem = qgraphicsitem_cast(item); + if (worldItem->isShapeChanged()) + { + items.push_back(item); + polygons.push_back(m_polygons.at(m_selectedItems.indexOf(item))); + worldItem->setShapeChanged(false); + } + } + + if (!items.isEmpty()) + { + m_undoStack->push(new ShapeWorldItemsCommand(items, polygons, this, m_model)); + m_polygons.clear(); + } } } 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 3ca055786..adf491889 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 @@ -65,10 +65,13 @@ public: void setModeEdit(WorldEditorScene::ModeEdit mode); WorldEditorScene::ModeEdit editMode() const; - bool isEnabledEditPoint() const; + bool isEnabledEditPoints() const; + +Q_SIGNALS: + void selectionUpdated(const QList &selected, const QList &deselected); public Q_SLOTS: - void setEnabledEditPoint(bool enabled); + void setEnabledEditPoints(bool enabled); void updateSelection(const QList &selected, const QList &deselected); protected: @@ -79,25 +82,31 @@ protected: virtual void mouseReleaseEvent(QGraphicsSceneMouseEvent *mouseEvent); private: - QRectF calcBoundingRect(const QList &listItems); QPainterPath calcBoundingShape(const QList &listItems); - void updateSelectedItems(bool value); - void updateSelectedItem(QGraphicsItem *item, bool value); + + void updateSelectedWorldItems(bool value); + void updateSelectedWorldItem(QGraphicsItem *item, bool value); + void updateSelectedPointItems(bool value); + void updateSelectedPointItem(QGraphicsItem *item, bool value); void updatePickSelection(const QPointF &point); + void updatePickSelectionPoints(const QPointF &point); + + void checkUndo(); 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; QList m_selectedItems; + QList m_selectedPoints; + QList m_polygons; bool m_editedSelectedItems, m_firstSelection; uint m_lastPickedPrimitive; ModeEdit m_mode; - bool m_editMode; + bool m_pointsMode; QUndoStack *m_undoStack; PrimitivesTreeModel *m_model; }; 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 89ddd80a5..056a4f01e 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 @@ -51,265 +51,11 @@ static QPainterPath qt_graphicsItem_shapeFromPath(const QPainterPath &path, cons p.addPath(path); return p; } -/* -GraphicsItemNode::GraphicsItemNode(GraphicsItemZone *itemZone, QGraphicsItem *parent) - : QGraphicsObject(parent) -{ - m_itemZone = itemZone; - m_color = QColor(12, 150, 215); - //setFlag(ItemIgnoresTransformations, true); - //setFlag(ItemClipsToShape); - - QPropertyAnimation *animation = new QPropertyAnimation(this, "colorNode"); - animation->setDuration(3000); - animation->setStartValue(QColor(10, 0, 50)); - animation->setKeyValueAt(0.5, QColor(155, 255, 0)); - animation->setEndValue(QColor(10, 0, 50)); - animation->setLoopCount(2000); - animation->setEasingCurve(QEasingCurve::OutInExpo); - animation->start(); - - setFlag(ItemIsSelectable); - setFlag(ItemIsMovable); - setFlag(ItemSendsScenePositionChanges); - m_type = EdgeType; - - setAcceptedMouseButtons(Qt::LeftButton | Qt::RightButton); - setZValue(10000000); -} - -GraphicsItemNode::~GraphicsItemNode() -{ -} - -void GraphicsItemNode::setColorNode(const QColor &color) -{ - m_color = color; - update(); -} - -void GraphicsItemNode::setNodeType(NodeType nodeType) -{ - m_type = nodeType; - if (m_type == EdgeType) - { - setFlag(ItemIsSelectable); - setFlag(ItemIsMovable); - setFlag(ItemSendsScenePositionChanges); - setAcceptedMouseButtons(Qt::LeftButton | Qt::RightButton); - setZValue(10000); - } - else if (m_type == MiddleType) - { - setFlag(ItemIsSelectable, false); - setFlag(ItemIsMovable, false); - setFlag(ItemSendsScenePositionChanges, false); - setAcceptedMouseButtons(Qt::LeftButton); - setZValue(10001); - } - update(); -} - -QRectF GraphicsItemNode::boundingRect() const -{ - return QRectF(QPointF(0, 0), QSizeF(20, 20)); -} - -void GraphicsItemNode::paint(QPainter *painter, - const QStyleOptionGraphicsItem *option, - QWidget *) -{ - // Here comes the magic: - //painter->setClipRect(option->exposedRect); - - painter->setPen(Qt::NoPen); - - if (m_type == EdgeType) - { - painter->setBrush(QColor(255, 0, 0)); - } - else if (m_type == MiddleType) - { - painter->setBrush(QColor(0, 0, 255)); - } - if (option->state & QStyle::State_Selected) - { - painter->setBrush(QColor(0, 255, 0)); - } - - painter->drawRect(2, 2, 18, 18); -} - -QVariant GraphicsItemNode::itemChange(GraphicsItemChange change, - const QVariant &value) -{ - if (change == ItemPositionHasChanged) - { - m_itemZone->updateZone(); - } - return QGraphicsItem::itemChange(change, value); -} - -void GraphicsItemNode::mousePressEvent(QGraphicsSceneMouseEvent *event) -{ - if ((m_type == MiddleType) && (event->button() == Qt::LeftButton)) - { - m_itemZone->updateMiddleNode(this); - setNodeType(EdgeType); - } - else if ((m_type == EdgeType) && (event->button() == Qt::RightButton)) - { - if (m_itemZone->deleteEdgePoint(this)) - setNodeType(MiddleType); - } -} - -GraphicsItemZone::GraphicsItemZone(QGraphicsScene *scene, QGraphicsItem *parent) - : QGraphicsPolygonItem(parent) -{ - m_scene = scene; - - m_color = QColor(12, 150, 215); - - setBrush(QBrush(QColor(100, 100, 255, 128))); - updateZone(); - setZValue(100); - //setFlag(ItemClipsToShape); - //setFlag(ItemIsSelectable, true); - //setFlag(ItemIsMovable, true); - //setFlag(ItemHasNoContents, true); -} - -GraphicsItemZone::~GraphicsItemZone() -{ -} - -void GraphicsItemZone::updateMiddleNode(GraphicsItemNode *node) -{ - for (int i = 0; i < m_listLines.size(); ++i) - { - if (node == m_listLines.at(i).itemPoint) - { - LineItem oldLineItem = m_listLines[i]; - - GraphicsItemNode *newNode1 = new GraphicsItemNode(this); - newNode1->setPos((oldLineItem.lineNode.first->pos() + node->pos()) / 2); - newNode1->setNodeType(GraphicsItemNode::MiddleType); - m_scene->addItem(newNode1); - - GraphicsItemNode *newNode2 = new GraphicsItemNode(this); - newNode2->setPos((oldLineItem.lineNode.second->pos() + node->pos()) / 2); - newNode2->setNodeType(GraphicsItemNode::MiddleType); - m_scene->addItem(newNode2); - - LineItem newLineItem1; - newLineItem1.itemPoint = newNode1; - newLineItem1.lineNode = LineNode(oldLineItem.lineNode.first, node); - m_listLines.push_back(newLineItem1); - - LineItem newLineItem2; - newLineItem2.itemPoint = newNode2; - newLineItem2.lineNode = LineNode(node, oldLineItem.lineNode.second); - m_listLines.push_back(newLineItem2); - - m_listLines.removeAt(i); - - int pos = m_listItems.indexOf(oldLineItem.lineNode.second); - m_listItems.insert(pos, node); - - break; - } - } -} - -bool GraphicsItemZone::deleteEdgePoint(GraphicsItemNode *node) -{ - if (m_listItems.size() < 4) - return false; - - int pos = m_listItems.indexOf(node); - m_listItems.takeAt(pos); - - LineItem newLineItem; - - newLineItem.itemPoint = node; - - for (int i = 0; i < m_listLines.size(); ++i) - { - if (node == m_listLines.at(i).lineNode.first) - { - // Saving second point for new line - newLineItem.lineNode.second = m_listLines.at(i).lineNode.second; - delete m_listLines.at(i).itemPoint; - m_listLines.removeAt(i); - break; - } - } - - for (int i = 0; i < m_listLines.size(); ++i) - { - if (node == m_listLines.at(i).lineNode.second) - { - newLineItem.lineNode.first = m_listLines.at(i).lineNode.first; - delete m_listLines.at(i).itemPoint; - m_listLines.removeAt(i); - break; - } - } - node->setPos((newLineItem.lineNode.first->pos() + newLineItem.lineNode.second->pos()) / 2); - m_listLines.push_back(newLineItem); - - return true; -} - -void GraphicsItemZone::scanPolygon(const QPolygonF &polygon) -{ - GraphicsItemNode *node1; - node1 = new GraphicsItemNode(this); - node1->setPos(*polygon.begin()); - m_listItems.push_back(node1); - m_scene->addItem(node1); - for (int i = 1; i < polygon.count(); ++i) - { - GraphicsItemNode *node2 = new GraphicsItemNode(this); - node2->setPos(polygon.at(i)); - m_listItems.push_back(node2); - - GraphicsItemNode *node3 = new GraphicsItemNode(this); - node3->setPos((node1->pos() + node2->pos()) / 2); - node3->setNodeType(GraphicsItemNode::MiddleType); - m_scene->addItem(node3); - - LineItem newLineItem; - newLineItem.itemPoint = node3; - newLineItem.lineNode = LineNode(node1, node2); - m_listLines.push_back(newLineItem); - - node1 = node2; - m_scene->addItem(node1); - } - setPolygon(polygon); -} - -void GraphicsItemZone::updateZone() -{ - QPolygonF polygon; - Q_FOREACH(GraphicsItemNode *node, m_listItems) - { - polygon << node->pos(); - } - - for (int i = 0; i < m_listLines.size(); ++i) - { - m_listLines.at(i).itemPoint->setPos((m_listLines.at(i).lineNode.first->pos() + m_listLines.at(i).lineNode.second->pos()) / 2); - } - - setPolygon(polygon); -} -*/ AbstractWorldItem::AbstractWorldItem(QGraphicsItem *parent) - : QGraphicsItem(parent) + : QGraphicsItem(parent), + m_active(false), + m_shapeChanged(false) { } @@ -322,6 +68,26 @@ int AbstractWorldItem::type() const return Type; } +void AbstractWorldItem::setActived(bool actived) +{ + m_active = actived; +} + +bool AbstractWorldItem::isActived() const +{ + return m_active; +} + +void AbstractWorldItem::setShapeChanged(bool value) +{ + m_shapeChanged = value; +} + +bool AbstractWorldItem::isShapeChanged() const +{ + return m_shapeChanged; +} + WorldItemPoint::WorldItemPoint(const QPointF &point, const qreal angle, const qreal radius, bool showArrow, QGraphicsItem *parent) : AbstractWorldItem(parent), @@ -360,7 +126,6 @@ WorldItemPoint::WorldItemPoint(const QPointF &point, const qreal angle, const qr } updateBoundingRect(); - //setFlag(ItemIsSelectable); } WorldItemPoint::~WorldItemPoint() @@ -373,9 +138,7 @@ void WorldItemPoint::rotateOn(const QPointF &pivot, const qreal deltaAngle) QPolygonF rotatedPolygon(m_rect); - // TODO rotatedPolygon.translate(pos() - pivot); - //rotatedPolygon.translate(-pivot); QTransform trans; trans = trans.rotate(deltaAngle); @@ -391,9 +154,7 @@ void WorldItemPoint::scaleOn(const QPointF &pivot, const QPointF &factor) QPolygonF scaledPolygon(m_rect); - // TODO scaledPolygon.translate(pos() - pivot); - //scaledPolygon.translate(-pivot); QTransform trans; trans = trans.scale(factor.x(), factor.y()); @@ -478,7 +239,8 @@ void WorldItemPoint::paint(QPainter *painter, const QStyleOptionGraphicsItem *op painter->drawLines(m_arrow); painter->setPen(Qt::NoPen); - if (option->state & QStyle::State_Selected) +// if (option->state & QStyle::State_Selected) + if (isActived()) painter->setBrush(m_selectedBrush); else painter->setBrush(m_brush); @@ -487,17 +249,10 @@ void WorldItemPoint::paint(QPainter *painter, const QStyleOptionGraphicsItem *op painter->drawRect(m_rect); } -QVariant WorldItemPoint::itemChange(GraphicsItemChange change, const QVariant &value) -{ - if (change == ItemPositionHasChanged) - { - } - return QGraphicsItem::itemChange(change, value); -} - WorldItemPath::WorldItemPath(const QPolygonF &polygon, QGraphicsItem *parent) : AbstractWorldItem(parent), - m_polygon(polygon) + m_polygon(polygon), + m_pointEdit(false) { //setFlag(ItemIsSelectable); @@ -548,19 +303,144 @@ void WorldItemPath::scaleOn(const QPointF &pivot, const QPointF &factor) m_polygon.translate(pivot - pos()); } -void WorldItemPath::turnOn(const qreal angle) -{ -} - -void WorldItemPath::radiusOn(const qreal radius) -{ -} - void WorldItemPath::setColor(const QColor &color) { m_pen.setColor(color); } + +void WorldItemPath::setEnabledSubPoints(bool enabled) +{ + m_pointEdit = enabled; + if (m_pointEdit) + createSubPoints(); + else + removeSubPoints(); +} + +void WorldItemPath::moveSubPoint(WorldItemSubPoint *subPoint) +{ + prepareGeometryChange(); + + QPolygonF polygon; + + // Update polygon + Q_FOREACH(WorldItemSubPoint *node, m_listItems) + { + polygon << node->pos(); + } + + // Update middle points + for (int i = 0; i < m_listLines.size(); ++i) + m_listLines.at(i).itemPoint->setPos((m_listLines.at(i).lineItem.first->pos() + m_listLines.at(i).lineItem.second->pos()) / 2); + + m_polygon = polygon; + update(); +} + +void WorldItemPath::addSubPoint(WorldItemSubPoint *subPoint) +{ + prepareGeometryChange(); + + for (int i = 0; i < m_listLines.size(); ++i) + { + if (subPoint == m_listLines.at(i).itemPoint) + { + LineStruct oldLineItem = m_listLines[i]; + + // Create the first middle sub-point + WorldItemSubPoint *firstItem = new WorldItemSubPoint(WorldItemSubPoint::MiddleType, this); + firstItem->setPos((oldLineItem.lineItem.first->pos() + subPoint->pos()) / 2); + + // Create the second middle sub-point + WorldItemSubPoint *secondItem = new WorldItemSubPoint(WorldItemSubPoint::MiddleType, this); + secondItem->setPos((oldLineItem.lineItem.second->pos() + subPoint->pos()) / 2); + + // Add first line in the list + LineStruct firstNewLineItem; + firstNewLineItem.itemPoint = firstItem; + firstNewLineItem.lineItem = LineItem(oldLineItem.lineItem.first, subPoint); + m_listLines.push_back(firstNewLineItem); + + // Add second line in the list + LineStruct secondNewLineItem; + secondNewLineItem.itemPoint = secondItem; + secondNewLineItem.lineItem = LineItem(subPoint, oldLineItem.lineItem.second); + m_listLines.push_back(secondNewLineItem); + + m_listLines.removeAt(i); + + int pos = m_listItems.indexOf(oldLineItem.lineItem.second); + m_listItems.insert(pos, subPoint); + subPoint->setFlag(ItemSendsScenePositionChanges); + + break; + } + } +} + +bool WorldItemPath::removeSubPoint(WorldItemSubPoint *subPoint) +{ + int pos = m_listItems.indexOf(subPoint); + + // First and second points can not be removed + if ((pos == 0) || (pos == m_listItems.size() - 1)) + return false; + + prepareGeometryChange(); + + m_listItems.takeAt(pos); + + LineStruct newLineItem; + + newLineItem.itemPoint = subPoint; + + // Delete first line + for (int i = 0; i < m_listLines.size(); ++i) + { + if (subPoint == m_listLines.at(i).lineItem.first) + { + // Saving second point for new line + newLineItem.lineItem.second = m_listLines.at(i).lineItem.second; + delete m_listLines.at(i).itemPoint; + m_listLines.removeAt(i); + break; + } + } + + // Delete second line + for (int i = 0; i < m_listLines.size(); ++i) + { + if (subPoint == m_listLines.at(i).lineItem.second) + { + // Saving first point for new line + newLineItem.lineItem.first = m_listLines.at(i).lineItem.first; + delete m_listLines.at(i).itemPoint; + m_listLines.removeAt(i); + break; + } + } + subPoint->setPos((newLineItem.lineItem.first->pos() + newLineItem.lineItem.second->pos()) / 2); + m_listLines.push_back(newLineItem); + subPoint->setFlag(ItemSendsScenePositionChanges, false); + + return true; +} + +void WorldItemPath::setPolygon(const QPolygonF &polygon) +{ + prepareGeometryChange(); + + m_polygon = polygon; + + update(); +} + +QPolygonF WorldItemPath::polygon() const +{ + return m_polygon; +} + QPainterPath WorldItemPath::shape() const { QPainterPath path; @@ -582,7 +462,8 @@ void WorldItemPath::paint(QPainter *painter, const QStyleOptionGraphicsItem *opt // Here comes the magic: //painter->setClipRect(option->exposedRect); - if (option->state & QStyle::State_Selected) + //if (option->state & QStyle::State_Selected) + if (isActived()) painter->setPen(m_selectedPen); else painter->setPen(m_pen); @@ -590,17 +471,49 @@ void WorldItemPath::paint(QPainter *painter, const QStyleOptionGraphicsItem *opt painter->drawPolyline(m_polygon); } -QVariant WorldItemPath::itemChange(GraphicsItemChange change, const QVariant &value) +void WorldItemPath::createSubPoints() { - if (change == ItemPositionHasChanged) + WorldItemSubPoint *firstPoint; + firstPoint = new WorldItemSubPoint(WorldItemSubPoint::EdgeType, this); + firstPoint->setPos(m_polygon.front()); + firstPoint->setFlag(ItemSendsScenePositionChanges); + m_listItems.push_back(firstPoint); + + for (int i = 1; i < m_polygon.count(); ++i) { + WorldItemSubPoint *secondPoint = new WorldItemSubPoint(WorldItemSubPoint::EdgeType, this); + secondPoint->setPos(m_polygon.at(i)); + secondPoint->setFlag(ItemSendsScenePositionChanges); + + WorldItemSubPoint *middlePoint = new WorldItemSubPoint(WorldItemSubPoint::MiddleType, this); + middlePoint->setPos((firstPoint->pos() + secondPoint->pos()) / 2); + + LineStruct newLineItem; + newLineItem.itemPoint = middlePoint; + newLineItem.lineItem = LineItem(firstPoint, secondPoint); + m_listLines.push_back(newLineItem); + + firstPoint = secondPoint; + m_listItems.push_back(firstPoint); } - return QGraphicsItem::itemChange(change, value); +} + +void WorldItemPath::removeSubPoints() +{ + for (int i = 0; i < m_listLines.count(); ++i) + delete m_listLines.at(i).itemPoint; + + for (int i = 0; i < m_listItems.count(); ++i) + delete m_listItems.at(i); + + m_listItems.clear(); + m_listLines.clear(); } WorldItemZone::WorldItemZone(const QPolygonF &polygon, QGraphicsItem *parent) : AbstractWorldItem(parent), - m_polygon(polygon) + m_polygon(polygon), + m_pointEdit(false) { //setFlag(ItemIsSelectable); @@ -646,7 +559,6 @@ void WorldItemZone::scaleOn(const QPointF &pivot, const QPointF &factor) prepareGeometryChange(); QPolygonF scaledPolygon(m_polygon); - scaledPolygon.translate(pos() - pivot); QTransform trans; @@ -656,14 +568,6 @@ void WorldItemZone::scaleOn(const QPointF &pivot, const QPointF &factor) m_polygon.translate(pivot - pos()); } -void WorldItemZone::turnOn(const qreal angle) -{ -} - -void WorldItemZone::radiusOn(const qreal radius) -{ -} - void WorldItemZone::setColor(const QColor &color) { m_pen.setColor(color); @@ -674,6 +578,143 @@ void WorldItemZone::setColor(const QColor &color) m_brush.setColor(brushColor); } +void WorldItemZone::setEnabledSubPoints(bool enabled) +{ + m_pointEdit = enabled; + if (m_pointEdit) + createSubPoints(); + else + removeSubPoints(); + + setShapeChanged(false); +} + +void WorldItemZone::moveSubPoint(WorldItemSubPoint *subPoint) +{ + prepareGeometryChange(); + + QPolygonF polygon; + + // Update polygon + Q_FOREACH(WorldItemSubPoint *node, m_listItems) + { + polygon << node->pos(); + } + + // Update middle points + for (int i = 0; i < m_listLines.size(); ++i) + m_listLines.at(i).itemPoint->setPos((m_listLines.at(i).lineItem.first->pos() + m_listLines.at(i).lineItem.second->pos()) / 2); + + m_polygon = polygon; + update(); + + setShapeChanged(true); +} + +void WorldItemZone::addSubPoint(WorldItemSubPoint *subPoint) +{ + prepareGeometryChange(); + + for (int i = 0; i < m_listLines.size(); ++i) + { + if (subPoint == m_listLines.at(i).itemPoint) + { + LineStruct oldLineItem = m_listLines[i]; + + // Create the first middle sub-point + WorldItemSubPoint *firstItem = new WorldItemSubPoint(WorldItemSubPoint::MiddleType, this); + firstItem->setPos((oldLineItem.lineItem.first->pos() + subPoint->pos()) / 2); + + // Create the second middle sub-point + WorldItemSubPoint *secondItem = new WorldItemSubPoint(WorldItemSubPoint::MiddleType, this); + secondItem->setPos((oldLineItem.lineItem.second->pos() + subPoint->pos()) / 2); + + // Add first line in the list + LineStruct firstNewLineItem; + firstNewLineItem.itemPoint = firstItem; + firstNewLineItem.lineItem = LineItem(oldLineItem.lineItem.first, subPoint); + m_listLines.push_back(firstNewLineItem); + + // Add second line in the list + LineStruct secondNewLineItem; + secondNewLineItem.itemPoint = secondItem; + secondNewLineItem.lineItem = LineItem(subPoint, oldLineItem.lineItem.second); + m_listLines.push_back(secondNewLineItem); + + m_listLines.removeAt(i); + + int pos = m_listItems.indexOf(oldLineItem.lineItem.second); + m_listItems.insert(pos, subPoint); + subPoint->setFlag(ItemSendsScenePositionChanges); + + break; + } + } + setShapeChanged(true); +} + +bool WorldItemZone::removeSubPoint(WorldItemSubPoint *subPoint) +{ + prepareGeometryChange(); + + if (m_listItems.size() < 4) + return false; + + int pos = m_listItems.indexOf(subPoint); + m_listItems.takeAt(pos); + + LineStruct newLineItem; + + newLineItem.itemPoint = subPoint; + + // Delete first line + for (int i = 0; i < m_listLines.size(); ++i) + { + if (subPoint == m_listLines.at(i).lineItem.first) + { + // Saving second point for new line + newLineItem.lineItem.second = m_listLines.at(i).lineItem.second; + delete m_listLines.at(i).itemPoint; + m_listLines.removeAt(i); + break; + } + } + + // Delete second line + for (int i = 0; i < m_listLines.size(); ++i) + { + if (subPoint == m_listLines.at(i).lineItem.second) + { + // Saving first point for new line + newLineItem.lineItem.first = m_listLines.at(i).lineItem.first; + delete m_listLines.at(i).itemPoint; + m_listLines.removeAt(i); + break; + } + } + m_listLines.push_back(newLineItem); + subPoint->setPos((newLineItem.lineItem.first->pos() + newLineItem.lineItem.second->pos()) / 2); + subPoint->setFlag(ItemSendsScenePositionChanges, false); + + setShapeChanged(true); + + return true; +} + +void WorldItemZone::setPolygon(const QPolygonF &polygon) +{ + prepareGeometryChange(); + + m_polygon = polygon; + + update(); +} + +QPolygonF WorldItemZone::polygon() const +{ + return m_polygon; +} + QRectF WorldItemZone::boundingRect() const { return m_polygon.boundingRect(); @@ -688,7 +729,8 @@ QPainterPath WorldItemZone::shape() const void WorldItemZone::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *) { - if (option->state & QStyle::State_Selected) +// if (option->state & QStyle::State_Selected) + if (isActived()) { painter->setPen(m_selectedPen); painter->setBrush(m_selectedBrush); @@ -702,12 +744,192 @@ void WorldItemZone::paint(QPainter *painter, const QStyleOptionGraphicsItem *opt painter->drawPolygon(m_polygon); } -QVariant WorldItemZone::itemChange(GraphicsItemChange change, const QVariant &value) +void WorldItemZone::createSubPoints() +{ + WorldItemSubPoint *firstPoint; + firstPoint = new WorldItemSubPoint(WorldItemSubPoint::EdgeType, this); + firstPoint->setPos(m_polygon.front()); + firstPoint->setFlag(ItemSendsScenePositionChanges); + m_listItems.push_back(firstPoint); + + for (int i = 1; i < m_polygon.count(); ++i) + { + WorldItemSubPoint *secondPoint = new WorldItemSubPoint(WorldItemSubPoint::EdgeType, this); + secondPoint->setPos(m_polygon.at(i)); + secondPoint->setFlag(ItemSendsScenePositionChanges); + + WorldItemSubPoint *middlePoint = new WorldItemSubPoint(WorldItemSubPoint::MiddleType, this); + middlePoint->setPos((firstPoint->pos() + secondPoint->pos()) / 2); + + LineStruct newLineItem; + newLineItem.itemPoint = middlePoint; + newLineItem.lineItem = LineItem(firstPoint, secondPoint); + m_listLines.push_back(newLineItem); + + firstPoint = secondPoint; + m_listItems.push_back(firstPoint); + } + + LineStruct endLineItem; + endLineItem.itemPoint = new WorldItemSubPoint(WorldItemSubPoint::MiddleType, this); + endLineItem.itemPoint->setPos((m_listItems.first()->pos() + m_listItems.last()->pos()) / 2); + endLineItem.lineItem = LineItem(m_listItems.last(), m_listItems.first()); + m_listLines.push_back(endLineItem); +} + +void WorldItemZone::removeSubPoints() +{ + for (int i = 0; i < m_listLines.count(); ++i) + delete m_listLines.at(i).itemPoint; + + for (int i = 0; i < m_listItems.count(); ++i) + delete m_listItems.at(i); + + m_listItems.clear(); + m_listLines.clear(); +} + +//******************************************* + +WorldItemSubPoint::WorldItemSubPoint(SubPointType pointType, AbstractWorldItem *parent) + : QGraphicsObject(parent), + m_type(pointType), + m_active(false), + m_parent(parent) +{ + setZValue(WORLD_POINT_LAYER); + + m_brush.setColor(QColor(20, 100, 255)); + m_brush.setStyle(Qt::SolidPattern); + + m_brushMiddle.setColor(QColor(255, 25, 100)); + m_brushMiddle.setStyle(Qt::SolidPattern); + + m_selectedBrush.setColor(QColor(255, 255, 255, 100)); + m_selectedBrush.setStyle(Qt::SolidPattern); + + m_rect.setCoords(-SIZE_POINT, -SIZE_POINT, SIZE_POINT, SIZE_POINT); + updateBoundingRect(); + + //setFlag(ItemIgnoresTransformations); + //setFlag(ItemSendsScenePositionChanges); +} + +WorldItemSubPoint::~WorldItemSubPoint() +{ +} + +void WorldItemSubPoint::setSubPointType(SubPointType nodeType) +{ + m_type = nodeType; + setFlag(ItemSendsScenePositionChanges); +} + +WorldItemSubPoint::SubPointType WorldItemSubPoint::subPointType() const +{ + return m_type; +} + +void WorldItemSubPoint::rotateOn(const QPointF &pivot, const qreal deltaAngle) +{ + prepareGeometryChange(); + + QPolygonF rotatedPolygon(m_rect); + + // TODO + rotatedPolygon.translate(scenePos() - pivot); + + QTransform trans; + trans = trans.rotate(deltaAngle); + rotatedPolygon = trans.map(rotatedPolygon); + rotatedPolygon.translate(pivot); + + setPos(m_parent->mapFromParent(rotatedPolygon.boundingRect().center())); +} + +void WorldItemSubPoint::scaleOn(const QPointF &pivot, const QPointF &factor) +{ + prepareGeometryChange(); + + QPolygonF scaledPolygon(m_rect); + + // TODO + scaledPolygon.translate(scenePos() - pivot); + //scaledPolygon.translate(-pivot); + + QTransform trans; + trans = trans.scale(factor.x(), factor.y()); + scaledPolygon = trans.map(scaledPolygon); + scaledPolygon.translate(pivot); + + setPos(m_parent->mapFromParent(scaledPolygon.boundingRect().center())); +} + +QRectF WorldItemSubPoint::boundingRect() const +{ + return m_boundingRect; +} + +void WorldItemSubPoint::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) +{ + painter->setPen(Qt::NoPen); + + if (m_type == WorldItemSubPoint::EdgeType) + { + if (isActived()) + painter->setBrush(m_selectedBrush); + else + painter->setBrush(m_brush); + } + else + { + painter->setBrush(m_brushMiddle); + } + + // Draw point + painter->drawRect(m_rect); +} + +int WorldItemSubPoint::type() const +{ + return Type; +} + +void WorldItemSubPoint::setActived(bool actived) +{ + m_active = actived; +} + +bool WorldItemSubPoint::isActived() const +{ + return m_active; +} + +QVariant WorldItemSubPoint::itemChange(GraphicsItemChange change, const QVariant &value) { if (change == ItemPositionHasChanged) - { - } + m_parent->moveSubPoint(this); return QGraphicsItem::itemChange(change, value); } +void WorldItemSubPoint::mousePressEvent(QGraphicsSceneMouseEvent *event) +{ + if ((m_type == MiddleType) && (event->button() == Qt::LeftButton)) + { + m_parent->addSubPoint(this); + setSubPointType(EdgeType); + } + else if ((m_type == EdgeType) && (event->button() == Qt::RightButton)) + { + if (m_parent->removeSubPoint(this)) + setSubPointType(MiddleType); + } + update(); +} + +void WorldItemSubPoint::updateBoundingRect() +{ + m_boundingRect.setCoords(-SIZE_POINT, -SIZE_POINT, SIZE_POINT, SIZE_POINT); +} + } /* namespace WorldEditor */ 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 0625084bd..1b934d77b 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 @@ -32,10 +32,15 @@ namespace WorldEditor { -class GraphicsItemZone; -class GraphicsItemNode; +class WorldItemSubPoint; -typedef QPair LineNode; +typedef QPair LineItem; + +struct LineStruct +{ + WorldItemSubPoint *itemPoint; + LineItem lineItem; +}; const int SELECTED_LAYER = 200; const int UNSELECTED_LAYER = 100; @@ -46,75 +51,6 @@ const int MIDDLE_POINT_LAYER = 201; const int EDGE_POINT_LAYER = 201; const int SIZE_ARROW = 20; -/* -// Deprecated -class GraphicsItemNode: public QGraphicsObject -{ - Q_OBJECT - Q_PROPERTY(QColor colorNode READ colorNode WRITE setColorNode) -public: - enum NodeType - { - EdgeType = 0, - MiddleType - }; - - GraphicsItemNode(GraphicsItemZone *itemZone, QGraphicsItem *parent = 0); - virtual ~GraphicsItemNode(); - - void setColorNode(const QColor &color); - QColor colorNode() const - { - return m_color; - } - - void setNodeType(NodeType nodeType); - - virtual QRectF boundingRect() const; - //QPainterPath shape() const; - virtual void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget); - -protected: - virtual QVariant itemChange(GraphicsItemChange change, const QVariant &value); - virtual void mousePressEvent(QGraphicsSceneMouseEvent *event); - -private: - - NodeType m_type; - GraphicsItemZone *m_itemZone; - QColor m_color; -}; - -// Deprecated -class GraphicsItemZone: public QGraphicsPolygonItem -{ -public: - GraphicsItemZone(QGraphicsScene *scene, QGraphicsItem *parent = 0); - virtual ~GraphicsItemZone(); - - void scanPolygon(const QPolygonF &polygon); - void updateMiddleNode(GraphicsItemNode *node); - bool deleteEdgePoint(GraphicsItemNode *node); - //void addNode(GraphicsItemNode *node); - void updateZone(); - //QRectF boundingRect() const; - //void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget); - -protected: - // QVariant itemChange(GraphicsItemChange change, const QVariant &value); - -private: - struct LineItem - { - GraphicsItemNode *itemPoint; - LineNode lineNode; - }; - QGraphicsScene *m_scene; - QColor m_color; - QList m_listItems; - QList m_listLines; -}; -*/ /* @class WorldItemPoint @@ -129,16 +65,40 @@ public: enum { Type = QGraphicsItem::UserType + 1 }; - virtual void rotateOn(const QPointF &pivot, const qreal deltaAngle) = 0; + virtual void rotateOn(const QPointF &pivot, const qreal deltaAngle) {}; // TODO: add modes: IgnoreAspectRatio, KeepAspectRatio - virtual void scaleOn(const QPointF &pivot, const QPointF &factor) = 0; - virtual void turnOn(const qreal angle) = 0; - virtual void radiusOn(const qreal radius) = 0; + virtual void scaleOn(const QPointF &pivot, const QPointF &factor) {}; + virtual void turnOn(const qreal angle) {}; + virtual void radiusOn(const qreal radius) {}; virtual void setColor(const QColor &color) = 0; + virtual void setEnabledSubPoints(bool enabled) = 0; + + virtual void moveSubPoint(WorldItemSubPoint *subPoint) {} + virtual void addSubPoint(WorldItemSubPoint *subPoint) {} + virtual bool removeSubPoint(WorldItemSubPoint *subPoint) + { + return false; + } + + virtual void setPolygon(const QPolygonF &polygon) {} + virtual QPolygonF polygon() const + { + return QPolygonF(); + } + + void setActived(bool actived); + bool isActived() const; + + void setShapeChanged(bool value); + bool isShapeChanged() const; // Enable the use of qgraphicsitem_cast with this item. int type() const; + +protected: + + bool m_active, m_shapeChanged; }; /* @@ -159,19 +119,16 @@ public: virtual void radiusOn(const qreal radius); virtual void setColor(const QColor &color); + virtual void setEnabledSubPoints(bool enabled) {} virtual QRectF boundingRect() const; virtual QPainterPath shape() const; virtual void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget); -protected: - virtual QVariant itemChange(GraphicsItemChange change, const QVariant &value); - private: void createCircle(); void updateBoundingRect(); - // TODO static const int SIZE_POINT = 3; QPen m_pen, m_selectedPen; @@ -197,20 +154,31 @@ public: virtual void rotateOn(const QPointF &pivot, const qreal deltaAngle); virtual void scaleOn(const QPointF &pivot, const QPointF &factor); - virtual void turnOn(const qreal angle); - virtual void radiusOn(const qreal radius); virtual void setColor(const QColor &color); + virtual void setEnabledSubPoints(bool enabled); + + virtual void moveSubPoint(WorldItemSubPoint *subPoint); + virtual void addSubPoint(WorldItemSubPoint *subPoint); + virtual bool removeSubPoint(WorldItemSubPoint *subPoint); + + virtual void setPolygon(const QPolygonF &polygon); + virtual QPolygonF polygon() const; virtual QRectF boundingRect() const; virtual QPainterPath shape() const; virtual void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget); -protected: - virtual QVariant itemChange(GraphicsItemChange change, const QVariant &value); +private: + void createSubPoints(); + void removeSubPoints(); QPen m_pen, m_selectedPen; QPolygonF m_polygon; + bool m_pointEdit; + + QList m_listItems; + QList m_listLines; }; /* @@ -226,27 +194,91 @@ public: virtual void rotateOn(const QPointF &pivot, const qreal deltaAngle); virtual void scaleOn(const QPointF &pivot, const QPointF &factor); - virtual void turnOn(const qreal angle); - virtual void radiusOn(const qreal radius); virtual void setColor(const QColor &color); + virtual void setEnabledSubPoints(bool enabled); + + virtual void moveSubPoint(WorldItemSubPoint *subPoint); + virtual void addSubPoint(WorldItemSubPoint *subPoint); + virtual bool removeSubPoint(WorldItemSubPoint *subPoint); + + virtual void setPolygon(const QPolygonF &polygon); + virtual QPolygonF polygon() const; virtual QRectF boundingRect() const; virtual QPainterPath shape() const; virtual void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget); -protected: - virtual QVariant itemChange(GraphicsItemChange change, const QVariant &value); +private: + void createSubPoints(); + void removeSubPoints(); static const int TRANSPARENCY = 38; QPen m_pen, m_selectedPen; QBrush m_brush, m_selectedBrush; QPolygonF m_polygon; + bool m_pointEdit; + + QList m_listItems; + QList m_listLines; +}; + +/* +@class WorldItemSubPoint +@brief +@details +*/ +class WorldItemSubPoint: public QGraphicsObject +{ + Q_OBJECT +public: + enum SubPointType + { + EdgeType = 0, + MiddleType + }; + + enum { Type = QGraphicsItem::UserType + 2 }; + + WorldItemSubPoint(SubPointType pointType, AbstractWorldItem *parent = 0); + virtual ~WorldItemSubPoint(); + + void setSubPointType(SubPointType nodeType); + SubPointType subPointType() const; + + void rotateOn(const QPointF &pivot, const qreal deltaAngle); + void scaleOn(const QPointF &pivot, const QPointF &factor); + + virtual QRectF boundingRect() const; + virtual void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget); + + void setActived(bool actived); + bool isActived() const; + + // Enable the use of qgraphicsitem_cast with this item. + int type() const; + +protected: + virtual QVariant itemChange(GraphicsItemChange change, const QVariant &value); + virtual void mousePressEvent(QGraphicsSceneMouseEvent *event); + +private: + void updateBoundingRect(); + + static const int SIZE_POINT = 6; + + QBrush m_brush, m_brushMiddle, m_selectedBrush; + + QRectF m_rect, m_boundingRect; + SubPointType m_type; + bool m_active; + AbstractWorldItem *m_parent; }; } /* namespace WorldEditor */ +// Enable the use of QVariant with this class. Q_DECLARE_METATYPE(WorldEditor::AbstractWorldItem *) #endif // WORLD_EDITOR_SCENE_ITEM_H 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 e00e804f3..009ede2e1 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 @@ -98,7 +98,7 @@ WorldEditorWindow::WorldEditorWindow(QWidget *parent) m_modeMapper->setMapping(m_ui.radiusAction, 5); connect(m_modeMapper, SIGNAL(mapped(int)), this, SLOT(setMode(int))); - connect(m_ui.pointsAction, SIGNAL(triggered(bool)), m_worldEditorScene, SLOT(setEnabledEditPoint(bool))); + connect(m_ui.pointsAction, SIGNAL(triggered(bool)), m_worldEditorScene, SLOT(setEnabledEditPoints(bool))); connect(m_ui.settingsAction, SIGNAL(triggered()), this, SLOT(openProjectSettings())); connect(m_ui.newWorldEditAction, SIGNAL(triggered()), this, SLOT(newWorldEditFile())); @@ -256,6 +256,7 @@ void WorldEditorWindow::updateStatusBar() void WorldEditorWindow::updateSelection(const QItemSelection &selected, const QItemSelection &deselected) { m_ui.pointsAction->setChecked(false); + m_worldEditorScene->setEnabledEditPoints(false); NodeList nodesSelected; Q_FOREACH(QModelIndex modelIndex, selected.indexes()) diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_window.ui b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_window.ui index c556514b7..1de6cbdc3 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_window.ui +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_window.ui @@ -37,7 +37,7 @@ QGraphicsView::AnchorUnderMouse - QGraphicsView::BoundingRectViewportUpdate + QGraphicsView::FullViewportUpdate QGraphicsView::DontAdjustForAntialiasing|QGraphicsView::DontClipPainter @@ -129,6 +129,15 @@ + + + Property Editor + + + 2 + + + loadPrimitive @@ -319,7 +328,7 @@ true - false + true Edit points @@ -346,6 +355,12 @@ QTreeView
primitives_view.h
+ + WorldEditor::PropertyEditorWidget + QWidget +
property_editor_widget.h
+ 1 +