From e44fa0f1ca62fbcc640530abb2d085939f470d34 Mon Sep 17 00:00:00 2001 From: Stijn Buys Date: Mon, 11 Nov 2013 18:35:13 +0000 Subject: Added box selection, deleted selected, duplicate selected, move selected. --- src/entitywidget.cc | 31 ++++++----- src/entitywidget.h | 15 ++++-- src/mainwindow.cc | 27 +++++++--- src/mainwindow.h | 1 + src/mapwidget.cc | 144 ++++++++++++++++++++++++++++++++++++++++++---------- src/mapwidget.h | 6 +++ 6 files changed, 174 insertions(+), 50 deletions(-) diff --git a/src/entitywidget.cc b/src/entitywidget.cc index 6878b28..70be280 100644 --- a/src/entitywidget.cc +++ b/src/entitywidget.cc @@ -18,21 +18,21 @@ namespace editor EntityWidget::EntityWidget(QWidget *parent) : QWidget(parent) { - is_selected = false; + entitywidget_selected = SelectNone; is_dragging = false; } EntityWidget::EntityWidget(EntityWidget &entity_widget, QWidget *parent) : QWidget(parent) { - is_selected = false; + entitywidget_selected = SelectNone; is_dragging = false; assign(entity_widget); } -void EntityWidget::set_selected(const bool selected) +void EntityWidget::set_selected(const Selected selected) { - is_selected = selected; + entitywidget_selected = selected; update(); } @@ -47,13 +47,20 @@ void EntityWidget::paintEvent(QPaintEvent *event) QPen pen(Qt::black, 1, Qt::SolidLine); QPainter painter(this); - if (is_selected) { - pen.setColor(Qt::red); - painter.setPen(pen); - - painter.setClipping(false); - } else { - painter.setClipping(true); + switch (entitywidget_selected) { + case SelectNone: + painter.setClipping(true); + break; + case SelectHighlight: + pen.setColor(QColor(191, 0, 0)); + painter.setPen(pen); + painter.setClipping(false); + break; + case SelectActive: + pen.setColor(QColor(255, 0, 0)); + painter.setPen(pen); + painter.setClipping(false); + break; } painter.setPen(pen); @@ -81,7 +88,7 @@ void EntityWidget::mousePressEvent(QMouseEvent *event) if (event->button() == Qt::LeftButton) { //qDebug() << "clicked entity " << name(); event->accept(); - if (is_selected) { + if ((selected() == SelectHighlight) || (selected() == SelectActive)) { is_dragging = true; emit dragStart(); } diff --git a/src/entitywidget.h b/src/entitywidget.h index e284650..05a5502 100644 --- a/src/entitywidget.h +++ b/src/entitywidget.h @@ -25,13 +25,18 @@ class EntityWidget : public QWidget Q_OBJECT public: + enum Selected {SelectNone = 0, SelectHighlight = 1, SelectActive = 2}; + + /** + * @brief default constructor with parent widget + * */ EntityWidget(QWidget *parent = 0); /** * @brief copy another EntityWidget * */ EntityWidget(EntityWidget &entity_widget, QWidget *parent = 0); - + /** * @brief returns the entity propertie * */ @@ -39,8 +44,8 @@ public: return &entitywidget_entityproperties; } - inline const bool selected() const { - return is_selected; + inline const Selected selected() const { + return entitywidget_selected; } /** @@ -74,7 +79,7 @@ public slots: /** * @brief set the selected state * */ - void set_selected(const bool selected); + void set_selected(Selected selected); protected: /** @@ -100,7 +105,7 @@ protected: private: EntityProperties entitywidget_entityproperties; - bool is_selected; + Selected entitywidget_selected; bool is_dragging; }; diff --git a/src/mainwindow.cc b/src/mainwindow.cc index 4a0f84a..6aaf48a 100644 --- a/src/mainwindow.cc +++ b/src/mainwindow.cc @@ -8,6 +8,8 @@ #include "mainwindow.h" #include "editorwindow.h" +#include "config.h" + namespace editor { @@ -18,7 +20,7 @@ namespace editor MainWindow::MainWindow() { // set window title - setWindowTitle(tr("Project::OSiRiON world editor")); + setWindowTitle(tr("Project::OSiRiON world editor") + " " + PACKAGE_VERSION); // initialize MDI (multiple document interface) area mainwindow_mdiarea = new QMdiArea(); @@ -34,6 +36,9 @@ MainWindow::MainWindow() // initialize menu bar initMenus(); updateMenus(); + + // initialize status bar + initStatus(); } @@ -41,24 +46,24 @@ void MainWindow::initActions() { // File -> New action_new = new QAction( tr("&New..."), this); - action_new->setShortcuts(QKeySequence::New); action_new->setStatusTip(tr("Create a new zone")); + action_new->setShortcuts(QKeySequence::New); connect(action_new, SIGNAL(triggered()), this, SLOT(slot_new())); // File -> Open action_open = new QAction( tr("&Open..."), this); action_open->setShortcuts(QKeySequence::Open); - action_open->setStatusTip(tr("Open an existing zone ini file")); + action_open->setStatusTip(tr("Open an existing zone .ini file")); connect(action_open, SIGNAL(triggered()), this, SLOT(slot_open())); action_save = new QAction( tr("&Save"), this); + action_save->setStatusTip(tr("Save zone to current .ini file")); action_save->setShortcuts(QKeySequence::Save); - action_save->setStatusTip(tr("Save zone")); connect(action_save, SIGNAL(triggered()), this, SLOT(slot_save())); action_save_as = new QAction( tr("Save &As..."), this); + action_save_as->setStatusTip(tr("Save zone to a new .ini file")); action_save_as->setShortcuts(QKeySequence::SaveAs); - action_save_as->setStatusTip(tr("Save zone as ini file")); connect(action_save_as, SIGNAL(triggered()), this, SLOT(slot_save_as())); // File -> Quit @@ -69,16 +74,18 @@ void MainWindow::initActions() // Edit -> Add action_add = new QAction(tr("&Add"), this); + action_add->setStatusTip(tr("Add a new entity")); connect(action_add, SIGNAL(triggered()), this, SLOT(slot_add())); action_delete = new QAction(tr("&Delete"), this); + action_delete->setStatusTip(tr("Delete selected entities")); action_delete->setShortcuts(QKeySequence::Delete); connect(action_delete, SIGNAL(triggered()), this, SLOT(slot_delete())); action_duplicate = new QAction(tr("D&uplicate"), this); + action_duplicate->setStatusTip(tr("Duplicate selected entities")); action_duplicate->setShortcut(QKeySequence(Qt::Key_Space)); - connect(action_duplicate, SIGNAL(triggered()), this, SLOT(slot_duplicate())); - + connect(action_duplicate, SIGNAL(triggered()), this, SLOT(slot_duplicate())); } void MainWindow::initMenus() @@ -97,6 +104,12 @@ void MainWindow::initMenus() mainwindow_editmenu->addAction(action_duplicate); } +void MainWindow::initStatus() +{ + setStatusBar(new QStatusBar(this)); + statusBar()->showMessage(tr("Project::OSiRiON world editor") + " " + PACKAGE_VERSION); +} + void MainWindow::updateMenus() { bool active =(mainwindow_mdiarea->activeSubWindow() != 0); diff --git a/src/mainwindow.h b/src/mainwindow.h index 0563aa9..4bf2ffb 100644 --- a/src/mainwindow.h +++ b/src/mainwindow.h @@ -43,6 +43,7 @@ private slots: private: void initActions(); void initMenus(); + void initStatus(); /// add a new child window EditorWindow *add_child(); diff --git a/src/mapwidget.cc b/src/mapwidget.cc index d960c0a..b5f52d1 100644 --- a/src/mapwidget.cc +++ b/src/mapwidget.cc @@ -16,6 +16,7 @@ #include #include +#include namespace editor { @@ -32,6 +33,7 @@ MapWidget::MapWidget(QWidget *parent) : QWidget(parent) dragstart_x = 0; dragstart_y = 0; is_dragging = false; + is_box_selecting = false; mapwidget_selected = 0; @@ -63,19 +65,35 @@ void MapWidget::wheelEvent(QWheelEvent *event) void MapWidget::mousePressEvent(QMouseEvent *event) { - if (event->button() == Qt::RightButton) { + if (event->button() == Qt::LeftButton) { + dragstart_x = event->pos().x(); + dragstart_y = event->pos().y(); + + dragstop_x = dragstart_x; + dragstop_y = dragstart_y; + + is_dragging = false; + is_box_selecting = true; + event->accept(); + } else if (event->button() == Qt::RightButton) { dragstart_x = event->pos().x(); dragstart_y = event->pos().y(); - event->accept(); is_dragging = true; + is_box_selecting = false; + event->accept(); } else { is_dragging = false; + is_box_selecting = false; } } void MapWidget::mouseReleaseEvent(QMouseEvent *event) { - if (event->button() == Qt::RightButton) { + if (event->button() == Qt::LeftButton) { + doBoxSelect(); + is_box_selecting = false; + update(); + } else if (event->button() == Qt::RightButton) { is_dragging = false; } } @@ -97,6 +115,13 @@ void MapWidget::mouseMoveEvent(QMouseEvent *event) resizeChildren(); + update(); + } else if (is_box_selecting) { + dragstop_x = event->pos().x(); + dragstop_y = event->pos().y(); + + event->accept(); + update(); } } @@ -120,7 +145,7 @@ void MapWidget::resizeChildren() entity->setGeometry(x, y, radius * 2 , radius * 2); - if (entity->selected()) { + if (entity->selected()== EntityWidget::SelectActive) { mapwidget_manipulator->setSize(entity); mapwidget_manipulator->setProperties(entity->properties()); mapwidget_manipulator->update(); @@ -129,11 +154,50 @@ void MapWidget::resizeChildren() } +void MapWidget::doBoxSelect() +{ + // deselect all + for (int i = 0; i < mapwidget_enties.size(); ++i) { + EntityWidget *entitywidget = mapwidget_enties.at(i); + entitywidget->set_selected(EntityWidget::SelectNone); + } + + const int x = dragstop_x < dragstart_x ? dragstop_x : dragstart_x; + const int y = dragstop_y < dragstart_y ? dragstop_y : dragstart_y; + const int w = abs(dragstop_x - dragstart_x); + const int h = abs(dragstop_y - dragstart_y); + + QRect box(x, y, w, h); + + mapwidget_selected = 0; + + for (int i = 0; i < mapwidget_enties.size(); ++i) { + EntityWidget *entitywidget = mapwidget_enties.at(i); + + if (box.contains(entitywidget->geometry())) { + entitywidget->set_selected(EntityWidget::SelectHighlight); + mapwidget_selected = entitywidget; + } + } + + if (mapwidget_selected) { + mapwidget_selected->set_selected(EntityWidget::SelectActive); + emit propertiesChanged(mapwidget_selected->properties()); + mapwidget_manipulator->setMode(Manipulator::Select); + mapwidget_manipulator->setProperties(mapwidget_selected->properties()); + mapwidget_manipulator->setSize(mapwidget_selected); + } else { + mapwidget_selected = 0; + emit propertiesChanged(0); + mapwidget_manipulator->setMode(Manipulator::None); + } + mapwidget_manipulator->update(); +} void MapWidget::deselect() { for (int i = 0; i < mapwidget_enties.size(); ++i) { EntityWidget *entitywidget = mapwidget_enties.at(i); - entitywidget->set_selected(false); + entitywidget->set_selected(EntityWidget::SelectNone); } mapwidget_selected = 0; @@ -147,12 +211,20 @@ void MapWidget::dragEntity(EntityWidget *entity, int x, int y) int radius = (int) (entity->properties()->radius() * zoom()); if (radius < 6) radius = 6; - - entity->properties()->set_location( - entity->properties()->location()[0] - (int) ((float) (y - radius) / zoom()), - entity->properties()->location()[1] - (int) ((float) (x - radius) / zoom()), - entity->properties()->location()[2] - ); + + for (int i = 0; i < mapwidget_enties.size(); ++i) { + + EntityWidget *entitywidget = mapwidget_enties.at(i); + + if ((entitywidget->selected() == EntityWidget::SelectHighlight) || (entitywidget->selected() == EntityWidget::SelectActive)) { + + entitywidget->properties()->set_location( + entitywidget->properties()->location()[0] - (int) ((float) (y - radius) / zoom()), + entitywidget->properties()->location()[1] - (int) ((float) (x - radius) / zoom()), + entitywidget->properties()->location()[2] + ); + } + } emit propertiesChanged(entity->properties()); resizeChildren(); @@ -161,6 +233,10 @@ void MapWidget::dragEntity(EntityWidget *entity, int x, int y) void MapWidget::select(EntityWidget *entity) { + if (mapwidget_selected == entity) { + return; + } + mapwidget_selected = 0; mapwidget_manipulator->setMode(Manipulator::None); @@ -170,7 +246,7 @@ void MapWidget::select(EntityWidget *entity) if (entity == entitywidget) { - entity->set_selected(true); + entity->set_selected(EntityWidget::SelectActive); //qDebug() << "selected entity " << entity->name(); emit propertiesChanged(entity->properties()); mapwidget_manipulator->setMode(Manipulator::Select); @@ -178,8 +254,7 @@ void MapWidget::select(EntityWidget *entity) mapwidget_manipulator->setSize(entity); mapwidget_selected = entity; } else { - - entitywidget->set_selected(false); + entitywidget->set_selected(EntityWidget::SelectNone); } } update(); @@ -259,6 +334,18 @@ void MapWidget::paintEvent(QPaintEvent *event) painter.drawLine(0, y, width(), y); y += gridsize; } + + if (is_box_selecting) { + x = dragstop_x < dragstart_x ? dragstop_x : dragstart_x; + y = dragstop_y < dragstart_y ? dragstop_y : dragstart_y; + int w = abs(dragstop_x - dragstart_x); + int h = abs(dragstop_y - dragstart_y); + + pen.setColor(QColor(255, 0, 0)); + painter.setPen(pen); + painter.drawRect(x, y, w ,h); + } + } @@ -290,15 +377,17 @@ EntityWidget *MapWidget::addEntity() void MapWidget::duplicateSelected() { - std::vector new_widgets; + // obtain count only once, this will exclude the new widgets copying itself in an endless loop + const int count = mapwidget_enties.size(); - for (int i = 0; i < mapwidget_enties.size(); ++i) { + for (int i = 0; i < count; ++i) { EntityWidget *entitywidget = mapwidget_enties.at(i); - if (entitywidget->selected()) { + + if ((entitywidget->selected() == EntityWidget::SelectHighlight) || (entitywidget->selected() == EntityWidget::SelectActive)) { + // duplicate the child widget EntityWidget *new_entitywidget = addEntity(); - new_widgets.push_back(new_entitywidget); new_entitywidget->assign(*entitywidget); // offset the new widget's position @@ -306,16 +395,19 @@ void MapWidget::duplicateSelected() Vector3f location = new_entitywidget->properties()->location(); new_entitywidget->properties()->set_location(location.x() + offset, location.y() - offset, location.z()); + // copy selection state to the new widget + new_entitywidget->set_selected(entitywidget->selected()); + // deselect the old widgets - entitywidget->set_selected(false); - } else { + entitywidget->set_selected(EntityWidget::SelectNone); + + if (entitywidget == mapwidget_selected) { + mapwidget_selected = new_entitywidget; + } } } - - // select the new widgets - for(int i = 0; i < new_widgets.size(); ++i) - new_widgets.at(i)->set_selected(true); - + + emit propertiesChanged(mapwidget_selected->properties()); resizeChildren(); update(); } @@ -327,7 +419,7 @@ void MapWidget::deleteSelected() while (i != mapwidget_enties.end()) { EntityWidget *entitywidget = (*i); - if (entitywidget->selected()) { + if ((entitywidget->selected() == EntityWidget::SelectHighlight) || (entitywidget->selected() == EntityWidget::SelectActive)) { // delete the child widget delete entitywidget; // set the pointer in the list to NULL diff --git a/src/mapwidget.h b/src/mapwidget.h index d418602..559fdde 100644 --- a/src/mapwidget.h +++ b/src/mapwidget.h @@ -125,12 +125,18 @@ private slots: void dragEntity(EntityWidget *entity, int x, int y); private: + void doBoxSelect(); + typedef QList Entities; int dragstart_x; int dragstart_y; + int dragstop_x; + int dragstop_y; + bool is_dragging; + bool is_box_selecting; // zoom factor, as a power of 2 int mapwidget_zoomfactor; -- cgit v1.2.3