Commits

Ian Chen committed 6ee219d

Auto expand floor

  • Participants
  • Parent commits f4cbb1d
  • Branches ian-building

Comments (0)

Files changed (7)

File gazebo/gui/model_editor/CMakeLists.txt

   WallItem.hh
   DoorItem.hh
   WindowItem.hh
+  FloorItem.hh
   EditorView.hh
 )
 
   GrabberHandle.hh
   RotateHandle.hh
   BuildingItem.hh
-  FloorItem.hh
   LineSegmentItem.hh
   GridLines.hh
   PolylineItem.hh

File gazebo/gui/model_editor/EditorView.cc

   newLevel->level = 0;
   newLevel->name = "Level 1";
   this->levels.push_back(newLevel);
-//  this->levelHeights[0] = 0;
-//  this->levelNames[0] = "Level 1";
 
   this->levelInspector = new LevelInspectorDialog();
   this->levelInspector->setModal(false);
     wallList.push_back(wallItem);
 //    this->buildingMaker->RemoveWall(this->lastWallSegmentName);
     this->lastWallSegmentName = "";
+    if (wallItem->GetLevel() > 0)
+      floorList[wallItem->GetLevel()-1]->AttachWall(wallItem);
+
     this->currentMouseItem = NULL;
     this->drawMode = NONE;
     this->drawInProgress = false;
   if (!_item)
     return;
 
-  QGraphicsItem *qItem = qobject_cast<QGraphicsItem *>(_item);
-
   if (_item->GetType() == "Wall")
   {
     wallList.erase(std::remove(wallList.begin(), wallList.end(),
 
   if (_item->GetType() == "Line")
   {
+    QGraphicsItem *qItem = dynamic_cast<QGraphicsItem *>(_item);
     QGraphicsItem *itemParent = qItem->parentItem();
     wallList.erase(std::remove(wallList.begin(), wallList.end(),
         dynamic_cast<WallItem *>(itemParent)), wallList.end());
     this->itemToModelMap.erase(_item);
-    delete itemParent;
+    delete dynamic_cast<WallItem *>(itemParent);
   }
-  else {
+  else
+  {
     this->itemToModelMap.erase(_item);
     delete _item;
   }
     this->scene()->addItem(wallItem);
     this->currentMouseItem = wallItem;
     this->drawInProgress = true;
-
-    lastLineCornerPos = _pos;
   }
   else
   {
   if (this->drawMode == WALL)
     QApplication::setOverrideCursor(QCursor(Qt::CrossCursor));
 
-//  this->grabKeyboard();
+  this->grabKeyboard();
 }
 
 /////////////////////////////////////////////////
   }
   newlevel->height = maxHeight;
 
-  QPolygonF wallBound;
+  FloorItem *floorItem = new FloorItem();
   std::vector<WallItem *> newWalls;
   for (std::vector<WallItem *>::iterator it = wallList.begin();
       it  != this->wallList.end(); ++it)
       QVector3D segmentSize = segment->GetSize();
       segmentSize.setZ(wallItem->GetHeight());
       QVector3D segmentPosition = segment->GetScenePosition();
-      segmentPosition.setZ(wallItem->GetLevelBaseHeight() + segmentPosition.z());
+      segmentPosition.setZ(wallItem->GetLevelBaseHeight()
+          + segmentPosition.z());
       std::string wallSegmentName = this->buildingMaker->AddWall(
           segmentSize, segmentPosition, segment->GetSceneRotation());
-
       this->buildingMaker->ConnectItem(wallSegmentName, segment);
       this->buildingMaker->ConnectItem(wallSegmentName, wallItem);
       this->itemToModelMap[segment] = wallSegmentName;
     }
-    if (wallBound.isEmpty())
-      wallBound = wallItem->mapToScene(wallItem->boundingRect());
-    else wallBound.united(wallItem->mapToScene(wallItem->boundingRect()));
+    floorItem->AttachWall(wallItem);
   }
   this->wallList.insert(this->wallList.end(), newWalls.begin(),
       newWalls.end());
 
-  // FIXME: hack to at least get some floors going
-  QRectF allWallBound = wallBound.boundingRect();
-  QVector3D floorSize(allWallBound.width(), allWallBound.height(), 10);
-  QVector3D floorPosition(allWallBound.x() + allWallBound.width()/2,
-      allWallBound.y()+allWallBound.height()/2,
-      this->levels[this->currentLevel]->height);
-
-  FloorItem *floorItem = new FloorItem();
   floorItem->SetLevel(this->currentLevel);
   floorItem->SetLevelBaseHeight(this->levels[this->currentLevel]->height);
-  floorItem->setPos(floorPosition.x(), floorPosition.y());
-  floorItem->SetSize(QSize(floorSize.x(), floorSize.y()));
   std::string floorName = this->buildingMaker->AddFloor(
-      floorSize, floorPosition, 0);
+      floorItem->GetSize(), floorItem->GetScenePosition(), 0);
   for (std::vector<StairsItem *>::iterator it = this->stairsList.begin();
       it != this->stairsList.end(); ++it)
   {
       {
         WallItem* wallItem = dynamic_cast<WallItem*>(this->currentMouseItem);
         wallItem->PopEndPoint();
-        wallList.push_back(wallItem);
-        //this->buildingMaker->RemoveWall(this->lastWallSegmentName);
-        this->lastWallSegmentName = "";
+        if (wallItem->GetVertexCount() >= 2)
+        {
+          wallList.push_back(wallItem);
+          //this->buildingMaker->RemoveWall(this->lastWallSegmentName);
+          this->lastWallSegmentName = "";
+          if (wallItem->GetLevel() > 0)
+            floorList[wallItem->GetLevel()-1]->AttachWall(wallItem);
+        }
+        else
+        {
+          this->scene()->removeItem(this->currentMouseItem);
+          delete wallItem;
+        }
       }
       else
       {
+        this->scene()->removeItem(this->currentMouseItem);
         delete this->currentMouseItem;
       }
     }

File gazebo/gui/model_editor/EditorView.hh

 
       private: std::map<EditorItem *, std::string> itemToModelMap;
 
-      private: QPoint lastLineCornerPos;
-
       private: std::vector<event::ConnectionPtr> connections;
 
       private: QGraphicsItem *currentMouseItem;

File gazebo/gui/model_editor/FloorItem.cc

 #include "gazebo/gui/model_editor/RectItem.hh"
 #include "gazebo/gui/model_editor/BuildingItem.hh"
 #include "gazebo/gui/model_editor/BuildingMaker.hh"
+#include "gazebo/gui/model_editor/WallItem.hh"
+#include "gazebo/gui/model_editor/LineSegmentItem.hh"
 #include "gazebo/gui/model_editor/FloorItem.hh"
 
 using namespace gazebo;
   this->floorPos = this->scenePos();
 
   this->setFlag(QGraphicsItem::ItemIsSelectable, false);
-//  this->setVisible(false);
+  this->wallGroup = new QGraphicsItemGroup();
+  this->dirty = false;
+
+  QTimer *timer = new QTimer(this);
+  connect(timer, SIGNAL(timeout()), this, SLOT(RecalculateBoundingBox()));
+  timer->start(300);
 }
 
 /////////////////////////////////////////////////
 FloorItem::~FloorItem()
 {
+  if (this->wallGroup)
+    delete this->wallGroup;
 }
 
-/////////////////////////////////////////////////
-/*void FloorItem::SetSize(QVector3D _size)
-{
-  this->floorWidth = _size.x();
-  this->floorDepth = _size.y();
-  this->floorHeight = _size.z();
-  this->SetSize(QSize(this->floorWidth, this->floorDepth));
-  this->FloorChanged();
-}*/
 
 /////////////////////////////////////////////////
 QVector3D FloorItem::GetSize() const
 /////////////////////////////////////////////////
 QVector3D FloorItem::GetScenePosition() const
 {
-  return QVector3D(this->floorPos.x(), this->floorPos.y(), 0);
+  return QVector3D(this->floorPos.x(), this->floorPos.y(),
+      this->levelBaseHeight);
 }
 
 /////////////////////////////////////////////////
 }
 
 /////////////////////////////////////////////////
+void FloorItem::AttachWall(WallItem *_wallItem)
+{
+  if (this->floorBoundingRect.isEmpty())
+    this->floorBoundingRect = _wallItem->mapToScene(_wallItem->boundingRect());
+  else this->floorBoundingRect = this->floorBoundingRect.united(
+      _wallItem->mapToScene(_wallItem->boundingRect()));
+  this->walls.push_back(_wallItem);
+
+  for (unsigned int i = 0; i < _wallItem->GetSegmentCount(); ++i)
+  {
+    LineSegmentItem *segment = _wallItem->GetSegment(i);
+    connect(segment, SIGNAL(widthChanged(double)), this,
+        SLOT(NotifyChange()));
+    connect(segment, SIGNAL(depthChanged(double)), this,
+        SLOT(NotifyChange()));
+    connect(segment, SIGNAL(posXChanged(double)), this,
+        SLOT(NotifyChange()));
+    connect(segment, SIGNAL(posYChanged(double)), this,
+        SLOT(NotifyChange()));
+  }
+  connect(_wallItem, SIGNAL(itemDeleted()), this,
+      SLOT(WallDeleted()));
+  this->Update();
+}
+
+/////////////////////////////////////////////////
+void FloorItem:: WallDeleted()
+{
+  EditorItem *wallItem = dynamic_cast<EditorItem *>(QObject::sender());
+  if (wallItem)
+  {
+    this->walls.erase(std::remove(this->walls.begin(), this->walls.end(),
+      wallItem), this->walls.end());
+  }
+  this->dirty = true;
+}
+
+/////////////////////////////////////////////////
+void FloorItem:: NotifyChange()
+{
+  this->dirty = true;
+}
+
+/////////////////////////////////////////////////
+void FloorItem::RecalculateBoundingBox()
+{
+  if ((this->walls.size() == 0) || !this->dirty)
+    return;
+
+  WallItem *wallItem = this->walls[0];
+  this->floorBoundingRect = wallItem->mapToScene(
+      wallItem->boundingRect());
+  for (unsigned int i = 1; i < this->walls.size(); ++i)
+  {
+    this->floorBoundingRect = this->floorBoundingRect.united(
+        this->walls[i]->mapToScene(this->walls[i]->boundingRect()));
+  }
+  this->Update();
+  this->dirty = false;
+}
+
+/////////////////////////////////////////////////
+void FloorItem::Update()
+{
+  QRectF allWallBound = this->floorBoundingRect.boundingRect();
+  this->floorWidth = allWallBound.width();
+  this->floorDepth = allWallBound.height();
+
+  this->floorPos = QPointF(allWallBound.x()  + allWallBound.width()/2,
+      allWallBound.y()+allWallBound.height()/2);
+
+  this->drawingWidth = this->floorWidth;
+  this->drawingHeight = this->floorDepth;
+  this->setPos(this->floorPos);
+
+  this->FloorChanged();
+}
+
+
+/////////////////////////////////////////////////
 void FloorItem::mousePressEvent(QGraphicsSceneMouseEvent *_event)
 {
 //  if (!this->isSelected())

File gazebo/gui/model_editor/FloorItem.hh

 #define _FLOOR_ITEM_HH_
 
 #include "gazebo/gui/qt.h"
+#include "gazebo/gui/model_editor/RectItem.hh"
+#include "gazebo/gui/model_editor/BuildingItem.hh"
+
 
 namespace gazebo
 {
   {
     class BuildingItem;
 
+    class WallItem;
+
     class FloorItem : public RectItem, public BuildingItem
     {
+        Q_OBJECT
+
         public: FloorItem();
 
         public: ~FloorItem();
 
         public: virtual double GetSceneRotation() const;
 
+        public: void AttachWall(WallItem *_wallItem);
+
         private: virtual void paint (QPainter *_painter,
             const QStyleOptionGraphicsItem *_option, QWidget *_widget);
 
         private: virtual void contextMenuEvent(
             QGraphicsSceneContextMenuEvent *_event);
 
+        private slots: void NotifyChange();
+
+        private slots: void RecalculateBoundingBox();
+
+        private slots: void WallDeleted();
+
+        private: void Update();
+
         private: void FloorChanged();
 
         private: void SizeChanged();
 
         private: QPointF floorPos;
 
+        private: bool dirty;
+
         private: double scale;
+
+        private: std::vector<WallItem *> walls;
+
+        private: QGraphicsItemGroup *wallGroup;
+
+        private: QPolygonF floorBoundingRect;
     };
   }
 }

File gazebo/gui/model_editor/LevelWidget.cc

     boost::bind(&LevelWidget::OnDiscard, this)));
 
   this->setLayout(levelLayout);
-
-  this->setAttribute(Qt::WA_TransparentForMouseEvents);
 }
 
 //////////////////////////////////////////////////

File gazebo/gui/model_editor/LineSegmentItem.cc

 /////////////////////////////////////////////////
 void LineSegmentItem::mouseReleaseEvent(QGraphicsSceneMouseEvent *_event)
 {
-  _event->setAccepted(false);
+  _event->setAccepted(true);
 }
 
 /////////////////////////////////////////////////
 void LineSegmentItem::mousePressEvent(QGraphicsSceneMouseEvent *_event)
 {
-  _event->setAccepted(false);
+
+  _event->setAccepted(true);
 }
 
 /////////////////////////////////////////////////
 void LineSegmentItem::mouseMoveEvent(QGraphicsSceneMouseEvent *_event)
 {
-  _event->setAccepted(false);
+  _event->setAccepted(true);
 }
 
 /////////////////////////////////////////////////
-void LineSegmentItem::hoverLeaveEvent(QGraphicsSceneHoverEvent *)
+void LineSegmentItem::hoverLeaveEvent(QGraphicsSceneHoverEvent *_event)
 {
+  if (!this->isSelected())
+  {
+    _event->ignore();
+    return;
+  }
   QApplication::setOverrideCursor(QCursor(Qt::ArrowCursor));
 }
 
 /////////////////////////////////////////////////
-void LineSegmentItem::hoverMoveEvent(QGraphicsSceneHoverEvent *)
+void LineSegmentItem::hoverMoveEvent(QGraphicsSceneHoverEvent *_event)
 {
+  if (!this->isSelected())
+  {
+    _event->ignore();
+    return;
+  }
   QApplication::setOverrideCursor(QCursor(Qt::SizeAllCursor));
 }
 
 /////////////////////////////////////////////////
-void LineSegmentItem::hoverEnterEvent(QGraphicsSceneHoverEvent *)
+void LineSegmentItem::hoverEnterEvent(QGraphicsSceneHoverEvent *_event)
 {
+  if (!this->isSelected())
+  {
+    _event->ignore();
+    return;
+  }
   QApplication::setOverrideCursor(QCursor(Qt::SizeAllCursor));
 }