Changed: #1302 When selecting primitives in the primitives dialog will be selected the appropriate graphics items in scene.

--HG--
branch : gsoc2011-worldeditorqt
This commit is contained in:
dnk-88 2011-08-13 13:07:06 +03:00
parent 14964373fb
commit 9c303dbf2f
11 changed files with 193 additions and 60 deletions

View file

@ -173,6 +173,8 @@ private:
NLLIGO::CPrimitives *m_primitives;
};
typedef QList<Node *> NodeList;
} /* namespace WorldEditor */
Q_DECLARE_METATYPE(WorldEditor::Node *)

View file

@ -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)

View file

@ -18,6 +18,9 @@
#ifndef PRIMITIVES_VIEW_H
#define PRIMITIVES_VIEW_H
// Project includes
#include "primitive_item.h"
// NeL includes
#include <nel/ligo/primitive.h>
@ -28,6 +31,7 @@
#include <QtCore/QVariant>
#include <QtCore/QSignalMapper>
#include <QtGui/QUndoStack>
#include <QtGui/QItemSelection>
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();

View file

@ -43,6 +43,29 @@
namespace WorldEditor
{
QGraphicsItem *getGraphicsItem(Node *node)
{
QGraphicsItem *result = 0;
if (node->type() == Node::PrimitiveNodeType)
{
PrimitiveNode *primitiveNode = static_cast<PrimitiveNode *>(node);
if (primitiveNode != 0)
{
switch (primitiveNode->primitiveClass()->Type)
{
case NLLIGO::CPrimitiveClass::Point:
case NLLIGO::CPrimitiveClass::Path:
case NLLIGO::CPrimitiveClass::Zone:
{
result = qvariant_cast<AbstractWorldItem *>(primitiveNode->data(Constants::GRAPHICS_DATA_QT4_2D));
break;
}
}
}
}
return result;
}
void addNewGraphicsItems(const QModelIndex &primIndex, PrimitivesTreeModel *model, WorldEditorScene *scene)
{
PrimitiveNode *node = static_cast<PrimitiveNode *>(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<NLLIGO::CPrimPoint *>(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<PrimitiveNode *>(primIndex.internalPointer());
Node *node = static_cast<Node *>(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<AbstractWorldItem *>(node->data(Constants::GRAPHICS_DATA_QT4_2D));
QGraphicsItem *item = getGraphicsItem(node);
if (item != 0)
scene->removeWorldItem(item);
break;
}
}
}
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));

View file

@ -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<Path> graphicsItemsToPaths(const QList<QGraphicsItem *> &items, PrimitivesTreeModel *model);
//QList<GraphicsItem *> pathsToGraphicsItems(const QList<Path> &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;
};

View file

@ -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<QGraphicsItem *> &selected, const QList<QGraphicsItem *> &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)
{
@ -378,6 +409,12 @@ QPainterPath WorldEditorScene::calcBoundingShape(const QList<QGraphicsItem *> &l
void WorldEditorScene::updateSelectedItems(bool value)
{
Q_FOREACH(QGraphicsItem *item, m_selectedItems)
{
updateSelectedItem(item, value);
}
}
void WorldEditorScene::updateSelectedItem(QGraphicsItem *item, bool value)
{
if (value)
{
@ -391,7 +428,6 @@ void WorldEditorScene::updateSelectedItems(bool value)
}
item->setSelected(value);
}
}
void WorldEditorScene::updatePickSelection(const QPointF &point)
{

View file

@ -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<QGraphicsItem *> &selected, const QList<QGraphicsItem *> &deselected);
protected:
virtual void drawForeground(QPainter *painter, const QRectF &rect);
@ -83,12 +83,13 @@ private:
QRectF calcBoundingRect(const QList<QGraphicsItem *> &listItems);
QPainterPath calcBoundingShape(const QList<QGraphicsItem *> &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;

View file

@ -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 *)

View file

@ -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<QLine> 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;

View file

@ -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<Node *>(modelIndex.internalPointer());
nodesSelected.push_back(node);
}
NodeList nodesDeselected;
Q_FOREACH(QModelIndex modelIndex, deselected.indexes())
{
Node *node = static_cast<Node *>(modelIndex.internalPointer());
nodesDeselected.push_back(node);
}
// TODO: update property editor
// ...
QList<QGraphicsItem *> itemSelected;
Q_FOREACH(Node *node, nodesSelected)
{
QGraphicsItem *item = getGraphicsItem(node);
if (item != 0)
itemSelected.push_back(item);
}
QList<QGraphicsItem *> 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);

View file

@ -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);