Project::OSiRiON - Git repositories
Project::OSiRiON
News . About . Screenshots . Downloads . Forum . Wiki . Tracker . Git
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorStijn Buys <ingar@osirion.org>2012-02-25 16:56:25 +0000
committerStijn Buys <ingar@osirion.org>2012-02-25 16:56:25 +0000
commite10c0a7602c612993e6b99348bab507b7def0881 (patch)
tree2d863e946024fc3560221bedcddb149b253b4918
parent01f671303b75f3e4c683e3ff47b7ee120f0cda12 (diff)
Add entity manipulator widget, added support for editing entity angles.
-rw-r--r--src/Makefile.am2
-rw-r--r--src/editorwindow.cc15
-rw-r--r--src/entityproperties.cc4
-rw-r--r--src/entityproperties.h51
-rw-r--r--src/entitywidget.cc31
-rw-r--r--src/entitywidget.h16
-rw-r--r--src/manipulator.cc59
-rw-r--r--src/manipulator.h68
-rw-r--r--src/mapwidget.cc21
-rw-r--r--src/mapwidget.h5
-rw-r--r--src/sidebar.cc72
-rw-r--r--src/sidebar.h9
12 files changed, 344 insertions, 9 deletions
diff --git a/src/Makefile.am b/src/Makefile.am
index 3614a61..35d1496 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -8,6 +8,7 @@ editor_SOURCES = \
entityproperties.cc \
entitywidget.cc \
inistream.cc \
+ manipulator.cc \
mainwindow.cc \
mapwidget.cc \
properties.cc \
@@ -20,6 +21,7 @@ editor_SOURCES = \
nodist_editor_SOURCES = \
moc_editorwindow.cc \
moc_entitywidget.cc \
+ moc_manipulator.cc \
moc_mainwindow.cc \
moc_mapwidget.cc \
moc_sidebar.cc
diff --git a/src/editorwindow.cc b/src/editorwindow.cc
index ae7d024..bd00189 100644
--- a/src/editorwindow.cc
+++ b/src/editorwindow.cc
@@ -137,7 +137,7 @@ bool EditorWindow::loadFile(const QString &filename)
if (ini.got_key_vector3f("location" , x, y, z)) {
entity->properties()->set_comment("location", ini.comment());
entity->properties()->set_location(x, y, z);
- //qDebug() << "got location " << x << " " << y << " " << z;
+ //qDebug() << "got location " << x << " " << y << " " << z;
} else if (ini.got_key_string("label", str)) {
entity->properties()->set_comment("label", ini.comment());
@@ -150,6 +150,19 @@ bool EditorWindow::loadFile(const QString &filename)
} else if (ini.got_key_float("radius", f)) {
entity->properties()->set_comment("radius", ini.comment());
entity->properties()->set_radius(f);
+
+ } else if (ini.got_key_vector3f("angles" , x, y, z)) {
+ entity->properties()->set_comment(ini.key(), ini.comment());
+ entity->properties()->set_angles(x, y, z);
+
+ } else if (ini.got_key_float("yaw", x)) {
+ entity->properties()->set_yaw(x);
+
+ } else if (ini.got_key_float("pitch", y)) {
+ entity->properties()->set_pitch(y);
+
+ } else if (ini.got_key_float("roll", z)) {
+ entity->properties()->set_roll(z);
} else if (ini.got_key_string("info", str)) {
QString comment = entity->properties()->comment("info");
diff --git a/src/entityproperties.cc b/src/entityproperties.cc
index 429b759..bdc2394 100644
--- a/src/entityproperties.cc
+++ b/src/entityproperties.cc
@@ -73,6 +73,10 @@ void EntityProperties::save(QTextStream &textstream)
save_comment(textstream, "location");
textstream << "location=" << location().x() << " " << location().y() << " " << location().z() << '\n';
+ // angles
+ save_comment(textstream, "angles");
+ textstream << "angles=" << angles().x() << " " << angles().y() << " " << angles().z() << '\n';
+
// radius
save_comment(textstream, "radius");
if (radius()) {
diff --git a/src/entityproperties.h b/src/entityproperties.h
index b80a82e..9a276cb 100644
--- a/src/entityproperties.h
+++ b/src/entityproperties.h
@@ -44,6 +44,20 @@ public:
}
/**
+ * @brief returns the angles of this object
+ * */
+ inline const Vector3f &angles() const {
+ return properties_angles;
+ }
+
+ /**
+ * @brief returns the yaw angle of this object
+ * */
+ inline const float yaw() const {
+ return properties_angles[0];
+ }
+
+ /**
* @brief returns the subsections string of this object
* */
inline const QString & subsections() const {
@@ -83,11 +97,48 @@ public:
properties_radius = radius;
}
+ /**
+ * @brief set the object angles
+ * */
+ inline void set_angles(const Vector3f &angles) {
+ properties_angles.assign(angles);
+ }
+
+ /**
+ * @brief set the object yaw angle
+ * */
+ inline void set_yaw(const float yaw) {
+ properties_angles[0] = yaw;
+ }
+
+ /**
+ * @brief set the object pitch angle
+ * */
+ inline void set_pitch(const float pitch) {
+ properties_angles[1] = pitch;
+ }
+
+ /**
+ * @brief set the object roll angle
+ * */
+ inline void set_roll (const float roll ) {
+ properties_angles[2] = roll ;
+ }
+
+ /**
+ * @brief set the object angles
+ * */
+ inline void set_angles(const float yaw, const float pitch, const float roll) {
+ properties_angles.assign(yaw, pitch, roll);
+ }
+
private:
float properties_radius;
QString properties_subsections;
QString properties_type;
+
+ Vector3f properties_angles;
};
} // namespace editor
diff --git a/src/entitywidget.cc b/src/entitywidget.cc
index c903ea8..b589063 100644
--- a/src/entitywidget.cc
+++ b/src/entitywidget.cc
@@ -11,6 +11,8 @@
#include <QMouseEvent>
#include <QDebug>
+#include <cmath>
+
namespace editor
{
@@ -34,10 +36,30 @@ void EntityWidget::paintEvent(QPaintEvent *event)
if (is_selected) {
pen.setColor(Qt::red);
painter.setPen(pen);
+
+ painter.setClipping(false);
+ } else {
+ painter.setClipping(true);
}
painter.setPen(pen);
painter.drawEllipse(0, 0, width() - 1 , height() - 1);
+
+ float r = width() / 2;
+ if (r < 12)
+ r = 12;
+
+ /*
+ float dx = r * sin(entitywidget_entityproperties.yaw());
+ float dy = r * cos(entitywidget_entityproperties.yaw());
+
+ if (!is_selected) {
+ pen.setColor(Qt::yellow);
+ }
+ painter.setPen(pen);
+
+ painter.drawLine(width() /2, height() /2, width() /2 - dx, height() /2 - dy);
+ */
}
void EntityWidget::mousePressEvent(QMouseEvent *event)
@@ -45,8 +67,10 @@ void EntityWidget::mousePressEvent(QMouseEvent *event)
if (event->button() == Qt::LeftButton) {
//qDebug() << "clicked entity " << name();
event->accept();
- if (is_selected)
+ if (is_selected) {
is_dragging = true;
+ emit dragStart();
+ }
emit clicked(this);
} else {
event->ignore();
@@ -57,6 +81,8 @@ void EntityWidget::mousePressEvent(QMouseEvent *event)
void EntityWidget::mouseReleaseEvent(QMouseEvent *event)
{
if (event->button() == Qt::LeftButton) {
+ if (is_dragging)
+ emit dragStop();
is_dragging = false;
}
}
@@ -64,8 +90,7 @@ void EntityWidget::mouseReleaseEvent(QMouseEvent *event)
void EntityWidget::mouseMoveEvent(QMouseEvent *event)
{
if (is_dragging) {
- // TODO add delay
- emit dragged(this, event->pos().x(), event->pos().y());
+ emit dragMove(this, event->pos().x(), event->pos().y());
}
}
diff --git a/src/entitywidget.h b/src/entitywidget.h
index 1bdfb93..2eb1a42 100644
--- a/src/entitywidget.h
+++ b/src/entitywidget.h
@@ -34,6 +34,10 @@ public:
return &entitywidget_entityproperties;
}
+ inline const bool selected() const {
+ return is_selected;
+ }
+
signals:
/**
* @brief this signal is emitted if the entity is clicked with the left mouse button
@@ -41,9 +45,19 @@ signals:
void clicked(EntityWidget *entity);
/**
+ * @brief this signal is emitted when the entity is first dragged
+ * */
+ void dragStart();
+
+ /**
+ * @brief this signal is emitted when the entity stops being dragged
+ * */
+ void dragStop();
+
+ /**
* @brief this signal is emitted if the entity is dragged
* */
- void dragged(EntityWidget *entity, int x, int y);
+ void dragMove(EntityWidget *entity, int x, int y);
public slots:
diff --git a/src/manipulator.cc b/src/manipulator.cc
new file mode 100644
index 0000000..33585a9
--- /dev/null
+++ b/src/manipulator.cc
@@ -0,0 +1,59 @@
+/*
+ manipulator.cc
+ This file is part of the Project::OSiRiON world editor
+ and is distributed under the terms and conditions of
+ the GNU General Public License version 2
+*/
+
+#include "manipulator.h"
+
+#include <QtGui>
+#include <QPainter>
+#include <QMouseEvent>
+#include <QDebug>
+
+namespace editor
+{
+
+Manipulator::Manipulator(QWidget *parent) : QWidget(parent)
+{
+ manipulator_mode = None;
+ manipulator_yaw = 0;
+}
+
+void Manipulator::setSize(const QWidget *widget)
+{
+ const int s = 16;
+ setGeometry(
+ widget->x() - s,
+ widget->y() -s,
+ widget->width() + 2 * s,
+ widget->height() + 2 * s
+ );
+}
+
+void Manipulator::paintEvent(QPaintEvent *event)
+{
+ if (mode() == None)
+ return;
+
+ QColor green;
+ green.setRgb(0, 156, 0);
+ QPen pen(green, 1, Qt::SolidLine);
+ QPainter painter(this);
+
+ painter.setPen(pen);
+ painter.drawEllipse(0, 0, width() - 1 , height() - 1);
+
+ const int r = width() / 2;
+ const float dx = r * sin(manipulator_yaw * M_PI / 180.0f);
+ const float dy = r * cos(manipulator_yaw * M_PI / 180.0f);
+ painter.drawLine(width() /2, height() /2, width() /2 - dx, height() /2 - dy);
+}
+
+void Manipulator::setProperties(const EntityProperties *properties)
+{
+ manipulator_yaw = properties->yaw();
+}
+
+} // namespace editor
diff --git a/src/manipulator.h b/src/manipulator.h
new file mode 100644
index 0000000..9ac28be
--- /dev/null
+++ b/src/manipulator.h
@@ -0,0 +1,68 @@
+/*
+ manipulator.h
+ This file is part of the Project::OSiRiON world editor
+ and is distributed under the terms and conditions of
+ the GNU General Public License version 2
+*/
+
+#ifndef __INCLUDED_EDITOR_MANIPULATOR__
+#define __INCLUDED_EDITOR_MANIPULATOR__
+
+#include "entityproperties.h"
+
+#include <QWidget>
+
+namespace editor
+{
+
+
+/**
+ * @brief a Widget displaying the manipulator state of an entity
+ * */
+class Manipulator : public QWidget
+{
+ Q_OBJECT
+
+public:
+ enum Mode {None = 0, Select = 1, Move = 2, Rotate = 3 };
+
+ Manipulator(QWidget *parent = 0);
+
+ /* ---- inspectors ---- */
+
+ /**
+ * @brief returns the current manipulator Mode
+ * */
+ inline const Mode mode() const {
+ return manipulator_mode;
+ }
+
+ /* ---- mutatorss ---- */
+
+ /**
+ * @brief set the manipulator mode
+ * */
+ inline void setMode(Mode mode) {
+ manipulator_mode = mode;
+ }
+
+ void setSize(const QWidget *widget);
+
+public slots:
+ void setProperties(const EntityProperties *properties);
+
+protected:
+ /**
+ * @brief handle draw events
+ * */
+ virtual void paintEvent(QPaintEvent *event);
+
+private:
+
+ Mode manipulator_mode;
+ float manipulator_yaw;
+};
+
+}
+
+#endif // __INCLUDED_EDITOR_MANIPULATOR__
diff --git a/src/mapwidget.cc b/src/mapwidget.cc
index d2c5676..fe84ada 100644
--- a/src/mapwidget.cc
+++ b/src/mapwidget.cc
@@ -6,6 +6,7 @@
*/
#include "entitywidget.h"
+#include "manipulator.h"
#include "mapwidget.h"
#include <QPainter>
@@ -20,6 +21,7 @@ namespace editor
MapWidget::MapWidget(QWidget *parent) : QWidget(parent)
{
//setMinimumSize(256,256);
+ mapwidget_manipulator = new Manipulator(this);
// zoom sucks but it works
mapwidget_zoom = 16;
@@ -93,6 +95,7 @@ void MapWidget::mouseMoveEvent(QMouseEvent *event)
event->accept();
resizeChildren();
+
update();
}
}
@@ -115,6 +118,11 @@ void MapWidget::resizeChildren()
entity->setGeometry(center_x + x, center_y + y, radius * 2 , radius * 2);
//qDebug() << "Moving entity to " << x << " " << y;
+ if (entity->selected()) {
+ mapwidget_manipulator->setSize(entity);
+ mapwidget_manipulator->setProperties(entity->properties());
+ mapwidget_manipulator->update();
+ }
}
}
@@ -125,7 +133,9 @@ void MapWidget::deselect()
EntityWidget *entitywidget = mapwidget_enties.at(i);
entitywidget->set_selected(false);
}
- emit propertiesChanged(0);
+
+ emit propertiesChanged(0);
+ mapwidget_manipulator->setMode(Manipulator::None);
}
void MapWidget::dragEntity(EntityWidget *entity, int x, int y)
@@ -142,11 +152,13 @@ void MapWidget::dragEntity(EntityWidget *entity, int x, int y)
);
emit propertiesChanged(entity->properties());
- resizeChildren();
+ resizeChildren();
+ mapwidget_manipulator->setMode(Manipulator::Move);
}
void MapWidget::select(EntityWidget *entity)
{
+ mapwidget_manipulator->setMode(Manipulator::None);
for (int i = 0; i < mapwidget_enties.size(); ++i) {
EntityWidget *entitywidget = mapwidget_enties.at(i);
@@ -156,6 +168,9 @@ void MapWidget::select(EntityWidget *entity)
entity->set_selected(true);
//qDebug() << "selected entity " << entity->name();
emit propertiesChanged(entity->properties());
+ mapwidget_manipulator->setMode(Manipulator::Select);
+ mapwidget_manipulator->setProperties(entity->properties());
+ mapwidget_manipulator->setSize(entity);
} else {
@@ -246,7 +261,7 @@ EntityWidget *MapWidget::addEntity()
// connect the EntityWidget::clicked() signal to the MapWidget::selected() slot
connect(entitywidget, SIGNAL(clicked(EntityWidget *)), this, SLOT(select(EntityWidget *)));
- connect(entitywidget, SIGNAL(dragged(EntityWidget *, int, int)), this, SLOT(dragEntity(EntityWidget *, int, int)));
+ connect(entitywidget, SIGNAL(dragMove(EntityWidget *, int, int)), this, SLOT(dragEntity(EntityWidget *, int, int)));
entitywidget->show();
diff --git a/src/mapwidget.h b/src/mapwidget.h
index c68d127..a7dbb66 100644
--- a/src/mapwidget.h
+++ b/src/mapwidget.h
@@ -17,7 +17,8 @@ namespace editor
{
class EntityWidget;
-
+class Manipulator;
+
/**
* @brief MapWidget shows the zone map with the blue grid line
* */
@@ -112,6 +113,8 @@ private:
bool is_dragging;
QList<EntityWidget *> mapwidget_enties;
+
+ Manipulator *mapwidget_manipulator;
};
}
diff --git a/src/sidebar.cc b/src/sidebar.cc
index 77d87ae..bcd944e 100644
--- a/src/sidebar.cc
+++ b/src/sidebar.cc
@@ -56,6 +56,20 @@ SideBar::SideBar(QWidget *parent) : QWidget(parent)
connect(edit_entitylocation_y, SIGNAL(textChanged(const QString &)), this, SLOT(updateEntityLocationY(const QString &)));
connect(edit_entitylocation_z, SIGNAL(textChanged(const QString &)), this, SLOT(updateEntityLocationZ(const QString &)));
+ // entity angles
+ QHBoxLayout *box_entityangles = new QHBoxLayout();
+ QLabel *label_entityangles = new QLabel(tr("angles"));
+ edit_entityangles_yaw = new QLineEdit(tr("yaw"));
+ edit_entityangles_pitch = new QLineEdit(tr("pitch"));
+ edit_entityangles_roll = new QLineEdit(tr("roll"));
+ box_entityangles->addWidget(label_entityangles);
+ box_entityangles->addWidget(edit_entityangles_yaw);
+ box_entityangles->addWidget(edit_entityangles_pitch);
+ box_entityangles->addWidget(edit_entityangles_roll);
+ connect(edit_entityangles_yaw, SIGNAL(textChanged(const QString &)), this, SLOT(updateEntityAnglesYaw(const QString &)));
+ connect(edit_entityangles_pitch, SIGNAL(textChanged(const QString &)), this, SLOT(updateEntityAnglesPitch(const QString &)));
+ connect(edit_entityangles_roll, SIGNAL(textChanged(const QString &)), this, SLOT(updateEntityAnglesRoll(const QString &)));
+
// entity radius
QHBoxLayout *box_entityradius = new QHBoxLayout();
QLabel *label_entityradius = new QLabel(tr("radius"));
@@ -93,6 +107,7 @@ SideBar::SideBar(QWidget *parent) : QWidget(parent)
box_global->addLayout(box_entitylabel);
box_global->addLayout(box_entityname);
box_global->addLayout(box_entitylocation);
+ box_global->addLayout(box_entityangles);
box_global->addLayout(box_entityradius);
box_global->addWidget(label_entityproperties);
@@ -159,6 +174,42 @@ void SideBar::updateEntityLocationZ(const QString &value)
}
}
+void SideBar::updateEntityAnglesYaw(const QString &value)
+{
+ if (last_selected) {
+ bool ok;
+ float yaw = value.toFloat(&ok);
+ if (ok) {
+ last_selected->set_angles(yaw, last_selected->angles()[1], last_selected->angles()[2]);
+ emit entityChanged();
+ }
+ }
+}
+
+void SideBar::updateEntityAnglesPitch(const QString &value)
+{
+ if (last_selected) {
+ bool ok;
+ float pitch = value.toFloat(&ok);
+ if (ok) {
+ last_selected->set_angles(last_selected->angles()[0], pitch, last_selected->angles()[2]);
+ emit entityChanged();
+ }
+ }
+}
+
+void SideBar::updateEntityAnglesRoll(const QString &value)
+{
+ if (last_selected) {
+ bool ok;
+ float roll = value.toFloat(&ok);
+ if (ok) {
+ last_selected->set_angles(last_selected->angles()[0], last_selected->angles()[1], roll);
+ emit entityChanged();
+ }
+ }
+}
+
void SideBar::updateEntityRadius(const QString &value)
{
if (last_selected) {
@@ -216,6 +267,15 @@ void SideBar::setProperties(EntityProperties *properties)
edit_entitylocation_z->setEnabled(false);
edit_entitylocation_z->clear();
+ edit_entityangles_yaw->setEnabled(false);
+ edit_entityangles_yaw->clear();
+
+ edit_entityangles_pitch->setEnabled(false);
+ edit_entityangles_pitch->clear();
+
+ edit_entityangles_roll->setEnabled(false);
+ edit_entityangles_roll->clear();
+
edit_entityradius->setEnabled(false);
edit_entityradius->clear();
@@ -254,6 +314,18 @@ void SideBar::setProperties(EntityProperties *properties)
value.setNum(properties->location()[2]);
edit_entitylocation_z->setText(value);
+ edit_entityangles_yaw->setEnabled(true);
+ value.setNum(properties->angles()[0]);
+ edit_entityangles_yaw->setText(value);
+
+ edit_entityangles_pitch->setEnabled(true);
+ value.setNum(properties->angles()[1]);
+ edit_entityangles_pitch->setText(value);
+
+ edit_entityangles_roll->setEnabled(true);
+ value.setNum(properties->angles()[2]);
+ edit_entityangles_roll->setText(value);
+
edit_entityradius->setEnabled(true);
value.setNum(properties->radius());
edit_entityradius->setText(value);
diff --git a/src/sidebar.h b/src/sidebar.h
index e731327..0ed8d2a 100644
--- a/src/sidebar.h
+++ b/src/sidebar.h
@@ -57,6 +57,12 @@ private slots:
void updateEntityLocationZ(const QString &value);
+ void updateEntityAnglesYaw(const QString &value);
+
+ void updateEntityAnglesPitch(const QString &value);
+
+ void updateEntityAnglesRoll(const QString &value);
+
void updateEntityRadius(const QString &value);
void updateEntityValues();
@@ -77,6 +83,9 @@ private:
QLineEdit *edit_entitylocation_x;
QLineEdit *edit_entitylocation_y;
QLineEdit *edit_entitylocation_z;
+ QLineEdit *edit_entityangles_yaw;
+ QLineEdit *edit_entityangles_pitch;
+ QLineEdit *edit_entityangles_roll;
QLineEdit *edit_entityradius;
QTextEdit *text_entityvalues;
QTextEdit *text_subsections;