diff --git a/.gitignore b/.gitignore index 2698053..78b1bab 100644 --- a/.gitignore +++ b/.gitignore @@ -18,7 +18,7 @@ *.tar *.rar *.qm -Makefile +Makefile* prototypes/sdl/run prototypes/wx-01-simple/run prototypes/wx-03-polyline/run @@ -38,5 +38,6 @@ html/ .qmake.stash Info.plist *.xcodeproj/ -*.pro.user +*.pro.user* *.app +DMGVERSION.txt diff --git a/Commands.cpp b/Commands.cpp index 0425e9b..a6fa151 100644 --- a/Commands.cpp +++ b/Commands.cpp @@ -4,6 +4,7 @@ AddShapesCommand::AddShapesCommand(MainWindow *mainWindow, uid mappingId, QUndoCommand *parent): QUndoCommand(parent) { + setText(QObject::tr("Add mapping")); m_mainWindow = mainWindow; m_mappingId = mappingId; } @@ -24,60 +25,120 @@ void AddShapesCommand::redo() } -MoveVertexCommand::MoveVertexCommand(MapperGLCanvas *mapperGLCanvas, int activeVertex, const QPointF &point, QUndoCommand *parent) : - QUndoCommand(parent) -{ - m_mapperGLCanvas = mapperGLCanvas; - m_shape = m_mapperGLCanvas->getCurrentShape(); - m_activeVertex = activeVertex; - vertexPosition = point; +TransformShapeCommand::TransformShapeCommand(MapperGLCanvas* canvas, TransformShapeOption option, QUndoCommand* parent) + : QUndoCommand(parent), + _canvas(canvas), _option(option) { + // Copy shape. + _shape = canvas->getCurrentShape(); + _option = option; + + // Clone shape before applying transform. + _originalShape.reset(_shape.toStrongRef()->clone()); } -void MoveVertexCommand::undo() -{ - m_shape->setVertex(m_activeVertex, vertexPosition); - m_mapperGLCanvas->update(); -// emit m_mapperGLCanvas->shapeChanged(m_mapperGLCanvas->getCurrentShape()); +void TransformShapeCommand::undo() { + // Copy back shape. + _shape.toStrongRef()->copyFrom(*_originalShape); + + // Update everything. + _canvas->currentShapeWasChanged(); + _canvas->update(); } -void MoveVertexCommand::redo() +void TransformShapeCommand::redo() { + // Call transformation. + _doTransform(_shape); + + // Update everything. + _canvas->currentShapeWasChanged(); + _canvas->update(); +} + +bool TransformShapeCommand::mergeWith(const QUndoCommand* other) { + // Make sure other is of the same type (id). + if (other->id() != id()) + return false; + + const TransformShapeCommand* cmd = static_cast(other); + + // Don't merge a new transform with a dropped tranform move (ie. each drag'n'drop is considered + // as a single separate command). + if (_option == RELEASE && cmd->_option == FREE) + return false; + + // Don't merge transforms + if (cmd->_canvas != _canvas || + cmd->_shape != _shape) + return false; + + return true; +} + +MoveVertexCommand::MoveVertexCommand(MapperGLCanvas* canvas, TransformShapeOption option, int activeVertex, const QPointF &point, QUndoCommand *parent) + : TransformShapeCommand(canvas, option, parent), + _movedVertex(activeVertex), + _vertexPosition(point) { - m_shape->setVertex(m_activeVertex, vertexPosition); - m_mapperGLCanvas->update(); -// emit m_mapperGLCanvas->shapeChanged(m_mapperGLCanvas->getCurrentShape()); + setText(QObject::tr("Move vertex")); +} + +int MoveVertexCommand::id() const { return (_option == STEP ? CMD_KEY_MOVE_VERTEX : CMD_MOUSE_MOVE_VERTEX); } + +void MoveVertexCommand::_doTransform(MShape::ptr shape) +{ + shape->setVertex(_movedVertex, _vertexPosition); +} + +bool MoveVertexCommand::mergeWith(const QUndoCommand* other) +{ + if (!TransformShapeCommand::mergeWith(other)) + return false; + + const MoveVertexCommand* cmd = static_cast(other); + + // Needs to be the same vertex. + if (cmd->_movedVertex != _movedVertex) + return false; + + _vertexPosition = cmd->_vertexPosition; + _option = cmd->_option; + return true; } -MoveShapesCommand::MoveShapesCommand(MapperGLCanvas *mapperGLCanvas, QMouseEvent *event, const QPointF &point, QUndoCommand *parent) : - QUndoCommand(parent) +TranslateShapeCommand::TranslateShapeCommand(MapperGLCanvas *canvas, TransformShapeOption option, const QPointF &translation, QUndoCommand *parent) + : TransformShapeCommand(canvas, option, parent), + _translation(translation) { - m_mapperGLCanvas = mapperGLCanvas; - m_shape = m_mapperGLCanvas->getCurrentShape(); - m_event = event; - newPosition = point; + setText(QObject::tr("Move shape")); } -void MoveShapesCommand::undo() +int TranslateShapeCommand::id() const { return (_option == STEP ? CMD_KEY_TRANSLATE_SHAPE : CMD_MOUSE_TRANSLATE_SHAPE); } + +bool TranslateShapeCommand::mergeWith(const QUndoCommand* other) { - m_shape->translate(oldPosition.x(), oldPosition.y()); - m_mapperGLCanvas->update(); -// emit m_mapperGLCanvas->shapeChanged(m_mapperGLCanvas->getCurrentShape()); + if (!TransformShapeCommand::mergeWith(other)) + return false; + + const TranslateShapeCommand* cmd = static_cast(other); + + // Update translation. + _translation += cmd->_translation; + _option = cmd->_option; + return true; } -void MoveShapesCommand::redo() +void TranslateShapeCommand::_doTransform(MShape::ptr shape) { - m_shape->translate(m_event->x() - newPosition.x(), m_event->y() - newPosition.y()); - m_mapperGLCanvas->update(); -// emit m_mapperGLCanvas->shapeChanged(m_mapperGLCanvas->getCurrentShape()); - - oldPosition.setX(newPosition.x() - m_event->x()); - oldPosition.setY(newPosition.y() - m_event->y()); + // Apply translation. + shape->translate(_translation); } DeleteMappingCommand::DeleteMappingCommand(MainWindow *mainWindow, uid mappingId, QUndoCommand *parent) : QUndoCommand(parent) { + setText(QObject::tr("Delete mapping")); m_mainWindow = mainWindow; m_mappingId = mappingId; } @@ -96,3 +157,4 @@ void DeleteMappingCommand::redo() m_mappingPtr = m_mainWindow->getMappingManager().getMappingById(m_mappingId); m_mainWindow->deleteMapping(m_mappingId); } + diff --git a/Commands.h b/Commands.h index aab5c96..106a0b7 100644 --- a/Commands.h +++ b/Commands.h @@ -26,6 +26,13 @@ #include "MainWindow.h" #include "MapperGLCanvas.h" +enum CommandId { + CMD_KEY_MOVE_VERTEX, + CMD_MOUSE_MOVE_VERTEX, + CMD_KEY_TRANSLATE_SHAPE, + CMD_MOUSE_TRANSLATE_SHAPE, +}; + class AddShapesCommand : public QUndoCommand { public: @@ -40,33 +47,66 @@ private: }; -class MoveVertexCommand : public QUndoCommand +class TransformShapeCommand : public QUndoCommand { public: - MoveVertexCommand(MapperGLCanvas *mapperGLCanvas, int activeVertex, const QPointF &point, QUndoCommand *parent = 0); - void undo(); - void redo(); + enum TransformShapeOption { + STEP, + FREE, + RELEASE, + }; + TransformShapeCommand(MapperGLCanvas* canvas, TransformShapeOption option, QUndoCommand *parent = 0); -private: - MapperGLCanvas *m_mapperGLCanvas; - MShape *m_shape; - int m_activeVertex; - QPointF vertexPosition; + virtual void undo(); + virtual void redo(); + virtual bool mergeWith(const QUndoCommand* other); +protected: + // Perform the actual transformation on the shape. + virtual void _doTransform(MShape::ptr shape) = 0; + + // Information pertaining to the shape context. + MapperGLCanvas* _canvas; + QWeakPointer _shape; + + // Did we use keys to move that vertex? + int _option; + + // Clone of the original shape used for undoing purposes. + MShape::ptr _originalShape; }; -class MoveShapesCommand : public QUndoCommand +class MoveVertexCommand : public TransformShapeCommand { public: - MoveShapesCommand(MapperGLCanvas *mapperGLCanvas, QMouseEvent *event, const QPointF &point, QUndoCommand *parent = 0); - void undo(); - void redo(); + MoveVertexCommand(MapperGLCanvas* canvas, TransformShapeOption option, int activeVertex, const QPointF &point, QUndoCommand *parent = 0); + + int id() const; + bool mergeWith(const QUndoCommand* other); + +protected: + // Perform the actual transformation on the shape. + virtual void _doTransform(MShape::ptr shape); + + // Information pertaining to the moving of vertex. + int _movedVertex; + QPointF _vertexPosition; +}; + +class TranslateShapeCommand : public TransformShapeCommand +{ +public: + TranslateShapeCommand(MapperGLCanvas *canvas, TransformShapeOption option, const QPointF &translation, QUndoCommand *parent = 0); + + int id() const; + bool mergeWith(const QUndoCommand* other); + +protected: + // Perform the actual transformation on the shape. + virtual void _doTransform(MShape::ptr shape); private: - MapperGLCanvas *m_mapperGLCanvas; - MShape *m_shape; - QMouseEvent *m_event; - QPointF newPosition, oldPosition; + QPointF _translation; }; class DeleteMappingCommand : public QUndoCommand diff --git a/DestinationGLCanvas.cpp b/DestinationGLCanvas.cpp index 71f3740..05c507d 100644 --- a/DestinationGLCanvas.cpp +++ b/DestinationGLCanvas.cpp @@ -26,19 +26,18 @@ DestinationGLCanvas::DestinationGLCanvas(MainWindow* mainWindow, QWidget* parent { } -MShape* DestinationGLCanvas::getShapeFromMappingId(uid mappingId) const +MShape::ptr DestinationGLCanvas::getShapeFromMappingId(uid mappingId) const { if (mappingId == NULL_UID) - return NULL; + return MShape::ptr(); else - return getMainWindow()->getMappingManager().getMappingById(mappingId)->getShape().get(); + return getMainWindow()->getMappingManager().getMappingById(mappingId)->getShape(); } -ShapeGraphicsItem* DestinationGLCanvas::getShapeGraphicsItemFromMappingId(uid mappingId) const +QSharedPointer DestinationGLCanvas::getShapeGraphicsItemFromMappingId(uid mappingId) const { if (mappingId == NULL_UID) - return NULL; - + return QSharedPointer(); else { return MainWindow::instance()->getMapperByMappingId(mappingId)->getGraphicsItem(); diff --git a/DestinationGLCanvas.cpp.orig b/DestinationGLCanvas.cpp.orig new file mode 100644 index 0000000..f1963d2 --- /dev/null +++ b/DestinationGLCanvas.cpp.orig @@ -0,0 +1,215 @@ +/* + * DestinationGLCanvas.cpp + * + * (c) 2013 Sofian Audry -- info(@)sofianaudry(.)com + * (c) 2013 Alexandre Quessy -- alexandre(@)quessy(.)net + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include "DestinationGLCanvas.h" +#include "MainWindow.h" + +<<<<<<< HEAD +DestinationGLCanvas::DestinationGLCanvas(MainWindow* mainWindow, QWidget* parent, const QGLWidget * shareWidget) +: MapperGLCanvas(mainWindow, parent, shareWidget), + _displayCrosshair(false), + _svg_test_signal(":/test-signal"), + _brush_test_signal(_svg_test_signal) +======= +DestinationGLCanvas::DestinationGLCanvas(MainWindow* mainWindow, QWidget* parent, const QGLWidget* shareWidget, QGraphicsScene* scene) +: MapperGLCanvas(mainWindow, parent, shareWidget, scene), + _displayCrosshair(false) +>>>>>>> spike-qgraphicsview-zoom-and-scroll +{ +} + +MShape* DestinationGLCanvas::getShapeFromMappingId(uid mappingId) +{ + if (mappingId == NULL_UID) + return NULL; + else + return getMainWindow()->getMappingManager().getMappingById(mappingId)->getShape().get(); +} + +<<<<<<< HEAD +void DestinationGLCanvas::doDraw(QPainter* painter) +{ + if (this->displayTestSignal()) + { + glPushMatrix(); + painter->save(); + this->_drawTestSignal(painter); + painter->restore(); + glPopMatrix(); + return; + } + + glPushMatrix(); + + // Draw the mappings. + QVector mappings = getMainWindow()->getMappingManager().getVisibleMappings(); + for (QVector::const_iterator it = mappings.begin(); it != mappings.end(); ++it) + { + painter->save(); + getMainWindow()->getMapperByMappingId((*it)->getId())->draw(painter); + painter->restore(); + } + + // Draw the controls of current mapping. + if (displayControls() && + getMainWindow()->hasCurrentMapping() && + getCurrentShape() != NULL) + { + painter->save(); + const Mapper::ptr& mapper = getMainWindow()->getMapperByMappingId(getMainWindow()->getCurrentMappingId()); + if (hasActiveVertex()) { + QList selectedVertices; + selectedVertices.append(getActiveVertexIndex()); + mapper->drawControls(painter, &selectedVertices); + } + else + { + mapper->drawControls(painter); + } + painter->restore(); + } + + glPopMatrix(); + + // Display crosshair cursor. +======= +void DestinationGLCanvas::drawForeground(QPainter *painter , const QRectF &rect) { +>>>>>>> spike-qgraphicsview-zoom-and-scroll + if (_displayCrosshair) + { + QPointF cursorPosition = mapToScene(cursor().pos());// - rect.topLeft();//(QCursor::pos());///*this->mapFromGlobal(*/QCursor::pos()/*)*/; + if (rect.contains(cursorPosition)) + { + painter->setPen(MM::CONTROL_COLOR); + painter->drawLine(cursorPosition.x(), rect.y(), cursorPosition.x(), rect.height()); + painter->drawLine(rect.x(), cursorPosition.y(), rect.width(), cursorPosition.y()); + } + } +} + +<<<<<<< HEAD +void DestinationGLCanvas::_drawTestSignal(QPainter* painter) +{ + const QRect& geo = geometry(); + painter->setPen(MM::CONTROL_COLOR); + int height = geo.height(); + int width = geo.width(); + int rect_size = 10; + QColor color_0(191, 191, 191); + QColor color_1(128, 128, 128); + QBrush brush_0(color_0); + QBrush brush_1(color_1); + + painter->setPen(Qt::NoPen); + + for (int x = 0; x < width; x += rect_size) + { + for (int y = 0; y < height; y += rect_size) + { + if (((x + y) % 20) == 0) + { + painter->setBrush(brush_0); + } else { + painter->setBrush(brush_1); + } + painter->drawRect(x, y, rect_size, rect_size); + } + } + + painter->fillRect(geo, this->_brush_test_signal); +} + +void DestinationGLCanvas::resizeGL(int width, int height) +{ + int side_length = width; + if (height < width) + { + side_length = height; + } + + (void) side_length; // to get rid of warnings + // TODO: reload SVG with the new size + // TODO: _svg_test_signal.load(":/test-signal"); + // TODO: _brush_test_signal(_svg_test_signal) +} + +bool DestinationGLCanvas::eventFilter(QObject *target, QEvent *event) +{ + if (event->type() == QEvent::KeyPress) + { + QKeyEvent *keyEvent = static_cast(event); + setActiveVertexIndex(getMainWindow()->getOutputWindow()->getCanvas()->getActiveVertexIndex()); + MapperGLCanvas::keyPressEvent(keyEvent); + return true; + } + else + { + return QObject::eventFilter(target, event); + } +} +======= +//void DestinationGLCanvas::doDraw(QPainter* painter) +//{ +// glPushMatrix(); +// +// // Draw the mappings. +// QVector mappings = getMainWindow()->getMappingManager().getVisibleMappings(); +// for (QVector::const_iterator it = mappings.begin(); it != mappings.end(); ++it) +// { +// painter->save(); +// getMainWindow()->getMapperByMappingId((*it)->getId())->draw(painter); +// painter->restore(); +// } +// +// // Draw the controls of current mapping. +// if (displayControls() && +// getMainWindow()->hasCurrentMapping() && +// getCurrentShape() != NULL) +// { +// painter->save(); +// const Mapper::ptr& mapper = getMainWindow()->getMapperByMappingId(getMainWindow()->getCurrentMappingId()); +// if (hasActiveVertex()) { +// QList selectedVertices; +// selectedVertices.append(getActiveVertexIndex()); +// mapper->drawControls(painter, &selectedVertices); +// } +// else +// mapper->drawControls(painter); +// painter->restore(); +// } +// +// glPopMatrix(); +// +// // Display crosshair cursor. +// if (_displayCrosshair) +// { +// const QPoint& cursorPosition = this->mapFromGlobal(QCursor::pos()); +// const QRect& geo = geometry(); +// if (geo.contains(cursorPosition)) +// { +// painter->setPen(MM::CONTROL_COLOR); +// painter->drawLine(cursorPosition.x(), 0, cursorPosition.x(), geo.height()); +// painter->drawLine(0, cursorPosition.y(), geo.width(), cursorPosition.y()); +// } +// } +// +//} +>>>>>>> spike-qgraphicsview-zoom-and-scroll + diff --git a/DestinationGLCanvas.h b/DestinationGLCanvas.h index ef5b443..df51cb8 100644 --- a/DestinationGLCanvas.h +++ b/DestinationGLCanvas.h @@ -35,8 +35,8 @@ public: virtual ~DestinationGLCanvas() {} virtual bool isOutput() const { return true; } - virtual MShape* getShapeFromMappingId(uid mappingId) const; - virtual ShapeGraphicsItem* getShapeGraphicsItemFromMappingId(uid mappingId) const; + virtual MShape::ptr getShapeFromMappingId(uid mappingId) const; + virtual QSharedPointer getShapeGraphicsItemFromMappingId(uid mappingId) const; }; #endif /* DESTINATIONGLCANVAS_H_ */ diff --git a/Doxyfile b/Doxyfile index 7d8583d..19042cf 100644 --- a/Doxyfile +++ b/Doxyfile @@ -31,7 +31,7 @@ PROJECT_NAME = "MapMap" # This could be handy for archiving the generated documentation or # if some version control system is used. -PROJECT_NUMBER = "0.3.0" +PROJECT_NUMBER = "0.3.1" # The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) # base path where the generated documentation will be put. diff --git a/HACKING b/HACKING index 5aac6b9..33e8181 100644 --- a/HACKING +++ b/HACKING @@ -74,3 +74,10 @@ XML file version number * generally, we should follow the MapMap version, when new changes are introduced. (no need to increment it otherwise) * we will need to implement some fancy XML file version number checking in the future. +Qt resources system +------------------- +* The mapmap.pro file is where the packaging is done +* The mapmap.qrc file is where we specify which resources are packaged with the app. +* Images are set there. They are then available as a path-like alias such as ":/fullscreen" +* See http://doc.qt.io/qt-5/resources.html + diff --git a/INSTALL b/INSTALL index 901f210..867ddd5 100644 --- a/INSTALL +++ b/INSTALL @@ -19,7 +19,6 @@ Install basic development tools fot Qt projects, plus liblo for OSC support:: sudo apt-get install -y \ liblo-dev \ - libglew-dev \ qttools5-dev-tools \ qt5-default @@ -58,14 +57,36 @@ Then, do this:: Build on Mac OS X ----------------- - * Install the Apple Developer Tools. You need to register with a credit card in the Apple Store in order to download it. * Install Qt5. You can get it from http://qt-project.org/downloads and choose the default location. +* Install liblo (compile from the tar.gz - it should install it to /usr/local) * Install the GStreamer framework. You need the runtime and devel packages to be installed: http://gstreamer.freedesktop.org/data/pkg/osx/1.2.4.1/gstreamer-1.0-devel-1.2.4.1-universal.pkg http://gstreamer.freedesktop.org/data/pkg/osx/1.2.4.1/gstreamer-1.0-1.2.4.1-universal.pkg +http://gstreamer.freedesktop.org/data/pkg/osx/1.6.0/gstreamer-1.0-1.6.0-x86_64-packages.dmg +http://gstreamer.freedesktop.org/data/pkg/osx/1.6.0/gstreamer-1.0-1.6.0-x86_64.pkg +http://gstreamer.freedesktop.org/data/pkg/osx/1.6.0/gstreamer-1.0-devel-1.6.0-x86_64.pkg + Do this:: ./build.sh +It will create a .app and a .dmg. + +DMGVERSION.txt should be created automatically with "1" as its contents. Update to "2", and so on, if needed. + + +Use on OS X +----------- +Users can simply the following two packages: + +http://gstreamer.freedesktop.org/data/pkg/osx/1.6.0/gstreamer-1.0-1.6.0-x86_64-packages.dmg +http://gstreamer.freedesktop.org/data/pkg/osx/1.6.0/gstreamer-1.0-1.6.0-x86_64.pkg + +MapMap should then work. + +If the appearance of the window of the OSC port number in the preferences seem corrupted, you might want to reset MapMap's preferences:: + + rm -f ~/Library/Preferences/info.mapmap.MapMap.plist + diff --git a/MM.cpp b/MM.cpp index c6a4ab6..e25b857 100644 --- a/MM.cpp +++ b/MM.cpp @@ -20,7 +20,7 @@ #include "MM.h" const QString MM::APPLICATION_NAME = "MapMap"; -const QString MM::VERSION = "0.3.0"; +const QString MM::VERSION = "0.3.1"; const QString MM::COPYRIGHT_OWNERS = "Sofian Audry, Alexandre Quessy, Mike Latona, Vasilis Liaskovitis, Dame Diongue"; const QString MM::ORGANIZATION_NAME = "MapMap"; const QString MM::ORGANIZATION_DOMAIN = "mapmap.info"; diff --git a/MainWindow.cpp b/MainWindow.cpp index 487e893..86f6fc4 100644 --- a/MainWindow.cpp +++ b/MainWindow.cpp @@ -51,11 +51,15 @@ MainWindow::MainWindow() _stickyVertices = true; _displayTestSignal = false; + // UndoStack + undoStack = new QUndoStack(this); + // Create everything. createLayout(); createActions(); createMenus(); - createContextMenu(); + createMappingContextMenu(); + createPaintContextMenu(); createToolBars(); createStatusBar(); updateRecentFileActions(); @@ -233,7 +237,7 @@ void MainWindow::handlePaintChanged(Paint::ptr paint) { uid paintId = mappingManager->getPaintId(paint); if (paint->getType() == "media") { - std::tr1::shared_ptr media = std::tr1::static_pointer_cast(paint); + QSharedPointer media = qSharedPointerCast(paint); Q_CHECK_PTR(media); updatePaintItem(paintId, createFileIcon(media->getUri()), strippedName(media->getUri())); // QString fileName = QFileDialog::getOpenFileName(this, @@ -243,7 +247,7 @@ void MainWindow::handlePaintChanged(Paint::ptr paint) { // importMediaFile(fileName, paint, false); } if (paint->getType() == "image") { - std::tr1::shared_ptr image = std::tr1::static_pointer_cast(paint); + QSharedPointer image = qSharedPointerCast(paint); Q_CHECK_PTR(image); updatePaintItem(paintId, createImageIcon(image->getUri()), strippedName(image->getUri())); // QString fileName = QFileDialog::getOpenFileName(this, @@ -254,7 +258,7 @@ void MainWindow::handlePaintChanged(Paint::ptr paint) { } else if (paint->getType() == "color") { // Pop-up color-choosing dialog to choose color paint. - std::tr1::shared_ptr color = std::tr1::static_pointer_cast(paint); + QSharedPointer color = qSharedPointerCast(paint); Q_CHECK_PTR(color); updatePaintItem(paintId, createColorIcon(color->getColor()), strippedName(color->getColor().name())); } @@ -296,7 +300,11 @@ bool MainWindow::eventFilter(QObject *obj, QEvent *event) switch (keyEvent->key()) { case Qt::Key_F: if (outputWindow->windowState() != Qt::WindowFullScreen) + { outputWindow->setFullScreen(true); + outputWindowFullScreenAction->setChecked(true); + outputWindowFullScreenAction->setEnabled(true); + } break; case Qt::Key_N: newFile(); @@ -322,19 +330,9 @@ bool MainWindow::eventFilter(QObject *obj, QEvent *event) case Qt::Key_E: addEllipse(); break; - case Qt::Key_D: + case Qt::Key_W: outputWindow->setVisible(true); break; - case Qt::Key_P: - if (_isPlaying) - { - pause(); - } - else - { - play(); - } - break; case Qt::Key_R: rewind(); break; @@ -350,6 +348,19 @@ bool MainWindow::eventFilter(QObject *obj, QEvent *event) else if (keyEvent->key() == Qt::Key_Escape) { outputWindow->setFullScreen(false); + outputWindowFullScreenAction->setChecked(false); + outputWindowFullScreenAction->setEnabled(false); + } + else if (keyEvent->key() == Qt::Key_Space) + { + if (_isPlaying) + { + pause(); + } + else + { + play(); + } } eventKey = false; @@ -525,11 +536,11 @@ void MainWindow::addMesh() } else { - std::tr1::shared_ptr texture = std::tr1::static_pointer_cast(paint); + QSharedPointer texture = qSharedPointerCast(paint); Q_CHECK_PTR(texture); - MShape::ptr outputQuad = MShape::ptr(Util::createMeshForTexture(texture.get(), sourceCanvas->width(), sourceCanvas->height())); - MShape::ptr inputQuad = MShape::ptr(Util::createMeshForTexture(texture.get(), sourceCanvas->width(), sourceCanvas->height())); + MShape::ptr outputQuad = MShape::ptr(Util::createMeshForTexture(texture.data(), sourceCanvas->width(), sourceCanvas->height())); + MShape::ptr inputQuad = MShape::ptr(Util::createMeshForTexture(texture.data(), sourceCanvas->width(), sourceCanvas->height())); mappingPtr = new TextureMapping(paint, outputQuad, inputQuad); } @@ -561,11 +572,11 @@ void MainWindow::addTriangle() } else { - std::tr1::shared_ptr texture = std::tr1::static_pointer_cast(paint); + QSharedPointer texture = qSharedPointerCast(paint); Q_CHECK_PTR(texture); - MShape::ptr outputTriangle = MShape::ptr(Util::createTriangleForTexture(texture.get(), sourceCanvas->width(), sourceCanvas->height())); - MShape::ptr inputTriangle = MShape::ptr(Util::createTriangleForTexture(texture.get(), sourceCanvas->width(), sourceCanvas->height())); + MShape::ptr outputTriangle = MShape::ptr(Util::createTriangleForTexture(texture.data(), sourceCanvas->width(), sourceCanvas->height())); + MShape::ptr inputTriangle = MShape::ptr(Util::createTriangleForTexture(texture.data(), sourceCanvas->width(), sourceCanvas->height())); mappingPtr = new TextureMapping(paint, inputTriangle, outputTriangle); } @@ -597,11 +608,11 @@ void MainWindow::addEllipse() } else { - std::tr1::shared_ptr texture = std::tr1::static_pointer_cast(paint); + QSharedPointer texture = qSharedPointerCast(paint); Q_CHECK_PTR(texture); - MShape::ptr outputEllipse = MShape::ptr(Util::createEllipseForTexture(texture.get(), sourceCanvas->width(), sourceCanvas->height())); - MShape::ptr inputEllipse = MShape::ptr(Util::createEllipseForTexture(texture.get(), sourceCanvas->width(), sourceCanvas->height())); + MShape::ptr outputEllipse = MShape::ptr(Util::createEllipseForTexture(texture.data(), sourceCanvas->width(), sourceCanvas->height())); + MShape::ptr inputEllipse = MShape::ptr(Util::createEllipseForTexture(texture.data(), sourceCanvas->width(), sourceCanvas->height())); mappingPtr = new TextureMapping(paint, inputEllipse, outputEllipse); } @@ -726,12 +737,34 @@ void MainWindow::cloneItem() } } -void MainWindow::renameItem() +void MainWindow::renameMappingItem() { // Set current item editable and rename it QListWidgetItem* item = mappingList->currentItem(); item->setFlags(item->flags() | Qt::ItemIsEditable); mappingList->editItem(item); + contentTab->setCurrentWidget(mappingSplitter); +} + +void MainWindow::deletePaintItem() +{ + if(currentSelectedItem) + { + deletePaint(getItemId(*paintList->currentItem()), false); + } + else + { + qCritical() << "No selected paint" << endl; + } +} + +void MainWindow::renamePaintItem() +{ + // Set current item editable and rename it + QListWidgetItem* item = paintList->currentItem(); + item->setFlags(item->flags() | Qt::ItemIsEditable); + paintList->editItem(item); + contentTab->setCurrentWidget(paintSplitter); } void MainWindow::openRecentFile() @@ -1106,9 +1139,9 @@ void MainWindow::cloneMappingItem(uid mappingId) // Scaling of duplicated mapping if (shapeType == "quad" || shapeType == "mesh") - shapePtr->translate(20, 20); + shapePtr->translate(QPointF(20, 20)); else - shapePtr->translate(0, 20); + shapePtr->translate(QPointF(0, 20)); // Create new duplicated mapping item Mapping::ptr clonedMapping(mapping); @@ -1171,6 +1204,9 @@ void MainWindow::createLayout() mappingPropertyPanel->setDisabled(true); mappingPropertyPanel->setMinimumHeight(MAPPING_PROPERTY_PANEL_MINIMUM_HEIGHT); + // Create undo view. + undoView = new QUndoView(getUndoStack(), this); + // Create canvases. sourceCanvas = new SourceGLCanvas(this); sourceCanvas->setFocusPolicy(Qt::ClickFocus); @@ -1182,7 +1218,7 @@ void MainWindow::createLayout() destinationCanvas->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); destinationCanvas->setMinimumSize(CANVAS_MINIMUM_WIDTH, CANVAS_MINIMUM_HEIGHT); - outputWindow = new OutputGLWindow(destinationCanvas); + outputWindow = new OutputGLWindow(this, destinationCanvas); outputWindow->setVisible(true); outputWindow->installEventFilter(destinationCanvas); outputWindow->installEventFilter(this); @@ -1213,6 +1249,7 @@ void MainWindow::createLayout() contentTab = new QTabWidget; contentTab->addTab(paintSplitter, QIcon(":/add-video"), tr("Paints")); contentTab->addTab(mappingSplitter, QIcon(":/add-mesh"), tr("Mappings")); + contentTab->addTab(undoView, tr("Undo stack")); canvasSplitter = new QSplitter(Qt::Vertical); canvasSplitter->addWidget(sourceCanvas); @@ -1246,9 +1283,6 @@ void MainWindow::createLayout() void MainWindow::createActions() { - // UndoStack - undoStack = new QUndoStack(this); - // New. newAction = new QAction(tr("&New"), this); newAction->setIcon(QIcon(":/new")); @@ -1276,6 +1310,7 @@ void MainWindow::createActions() // Save as. saveAsAction = new QAction(tr("Save &As..."), this); saveAsAction->setIcon(QIcon(":/save-as")); + saveAsAction->setShortcut(tr("Ctrl+Shift+S")); saveAsAction->setStatusTip(tr("Save the project as...")); saveAsAction->setIconVisibleInMenu(false); connect(saveAsAction, SIGNAL(triggered()), this, SLOT(saveAs())); @@ -1303,26 +1338,29 @@ void MainWindow::createActions() connect(clearRecentFileActions, SIGNAL(triggered()), this, SLOT(clearRecentFileList())); // Empty list of recent video action - emptyRecentVideos = new QAction(tr("No Videos"), this); + emptyRecentVideos = new QAction(tr("No Recents Videos"), this); emptyRecentVideos->setEnabled(false); // Import video. - importVideoAction = new QAction(tr("&Import media source file..."), this); + importVideoAction = new QAction(tr("&Import Video File..."), this); + importVideoAction->setShortcut(tr("Ctrl+I")); importVideoAction->setIcon(QIcon(":/add-video")); - importVideoAction->setStatusTip(tr("Import a media source file...")); + importVideoAction->setStatusTip(tr("Import a video source file...")); importVideoAction->setIconVisibleInMenu(false); connect(importVideoAction, SIGNAL(triggered()), this, SLOT(importVideo())); // Import imiage. - importImageAction = new QAction(tr("&Import media source file..."), this); + importImageAction = new QAction(tr("&Import Image File..."), this); + importImageAction->setShortcut(tr("Ctrl+Shift+I")); importImageAction->setIcon(QIcon(":/add-image")); - importImageAction->setStatusTip(tr("Import a media source file...")); + importImageAction->setStatusTip(tr("Import a image source file...")); importImageAction->setIconVisibleInMenu(false); connect(importImageAction, SIGNAL(triggered()), this, SLOT(importImage())); // Add color. - addColorAction = new QAction(tr("Add &Color paint..."), this); + addColorAction = new QAction(tr("Add &Color Paint..."), this); + addColorAction->setShortcut(tr("Ctrl+A")); addColorAction->setIcon(QIcon(":/add-color")); addColorAction->setStatusTip(tr("Add a color paint...")); addColorAction->setIconVisibleInMenu(false); @@ -1355,29 +1393,43 @@ void MainWindow::createActions() // Duplicate. cloneAction = new QAction(tr("Duplicate"), this); - cloneAction->setShortcut(tr("CTRL+V")); + cloneAction->setShortcut(tr("Ctrl+D")); cloneAction->setStatusTip(tr("Duplicate item")); cloneAction->setIconVisibleInMenu(false); connect(cloneAction, SIGNAL(triggered()), this, SLOT(cloneItem())); - // Delete. - deleteAction = new QAction(tr("Delete"), this); - deleteAction->setShortcut(tr("CTRL+DEL")); - deleteAction->setStatusTip(tr("Delete item")); - deleteAction->setIconVisibleInMenu(false); - connect(deleteAction, SIGNAL(triggered()), this, SLOT(deleteItem())); + // Delete mapping. + deleteMappingAction = new QAction(tr("Delete"), this); + deleteMappingAction->setShortcut(tr("CTRL+DEL")); + deleteMappingAction->setStatusTip(tr("Delete item")); + deleteMappingAction->setIconVisibleInMenu(false); + connect(deleteMappingAction, SIGNAL(triggered()), this, SLOT(deleteItem())); - // Rename. - renameAction = new QAction(tr("Rename"), this); - renameAction->setShortcut(Qt::Key_F2); - renameAction->setStatusTip(tr("Rename item")); - renameAction->setIconVisibleInMenu(false); - connect(renameAction, SIGNAL(triggered()), this, SLOT(renameItem())); + // Rename mapping. + renameMappingAction = new QAction(tr("Rename"), this); + renameMappingAction->setShortcut(Qt::Key_F2); + renameMappingAction->setStatusTip(tr("Rename item")); + renameMappingAction->setIconVisibleInMenu(false); + connect(renameMappingAction, SIGNAL(triggered()), this, SLOT(renameMappingItem())); + + // Delete paint. + deletePaintAction = new QAction(tr("Delete"), this); + //deletePaintAction->setShortcut(tr("CTRL+DEL")); + deletePaintAction->setStatusTip(tr("Delete item")); + deletePaintAction->setIconVisibleInMenu(false); + connect(deletePaintAction, SIGNAL(triggered()), this, SLOT(deletePaintItem())); + + // Rename paint. + renamePaintAction = new QAction(tr("Rename"), this); + //renamePaintAction->setShortcut(Qt::Key_F2); + renamePaintAction->setStatusTip(tr("Rename item")); + renamePaintAction->setIconVisibleInMenu(false); + connect(renamePaintAction, SIGNAL(triggered()), this, SLOT(renamePaintItem())); // Preferences... preferencesAction = new QAction(tr("&Preferences..."), this); //preferencesAction->setIcon(QIcon(":/preferences")); - preferencesAction->setShortcut(QKeySequence::Preferences); + preferencesAction->setShortcut(tr("CTRL+,")); preferencesAction->setStatusTip(tr("Configure preferences...")); //preferencesAction->setIconVisibleInMenu(false); connect(preferencesAction, SIGNAL(triggered()), this, SLOT(preferences())); @@ -1411,7 +1463,7 @@ void MainWindow::createActions() // Play. playAction = new QAction(tr("Play"), this); - playAction->setShortcut(tr("CTRL+P")); + playAction->setShortcut(Qt::Key_Space); playAction->setIcon(QIcon(":/play")); playAction->setStatusTip(tr("Play")); playAction->setIconVisibleInMenu(false); @@ -1420,7 +1472,7 @@ void MainWindow::createActions() // Pause. pauseAction = new QAction(tr("Pause"), this); - pauseAction->setShortcut(tr("CTRL+P")); + pauseAction->setShortcut(Qt::Key_Space); pauseAction->setIcon(QIcon(":/pause")); pauseAction->setStatusTip(tr("Pause")); pauseAction->setIconVisibleInMenu(false); @@ -1436,8 +1488,8 @@ void MainWindow::createActions() connect(rewindAction, SIGNAL(triggered()), this, SLOT(rewind())); // Toggle display of output window. - displayOutputWindowAction = new QAction(tr("&Display output window"), this); - displayOutputWindowAction->setShortcut(tr("Ctrl+D")); + displayOutputWindowAction = new QAction(tr("&Display Output Window"), this); + displayOutputWindowAction->setShortcut(tr("Ctrl+W")); displayOutputWindowAction->setIcon(QIcon(":/output-window")); displayOutputWindowAction->setStatusTip(tr("Display output window")); displayOutputWindowAction->setIconVisibleInMenu(false); @@ -1449,7 +1501,7 @@ void MainWindow::createActions() connect(outputWindow, SIGNAL(closed()), displayOutputWindowAction, SLOT(toggle())); // Toggle display of output window. - outputWindowFullScreenAction = new QAction(tr("&Full screen"), this); + outputWindowFullScreenAction = new QAction(tr("&Fullscreen"), this); outputWindowFullScreenAction->setIcon(QIcon(":/fullscreen")); outputWindowFullScreenAction->setShortcut(tr("Ctrl+F")); outputWindowFullScreenAction->setStatusTip(tr("Full screen")); @@ -1464,8 +1516,8 @@ void MainWindow::createActions() connect(displayOutputWindowAction, SIGNAL(toggled(bool)), outputWindowFullScreenAction, SLOT(setEnabled(bool))); // Toggle display of canvas controls. - displayControlsAction = new QAction(tr("&Display canvas controls"), this); - // displayCanvasControls->setShortcut(tr("Ctrl+E")); + displayControlsAction = new QAction(tr("&Display Canvas Controls"), this); + displayControlsAction->setShortcut(tr("Alt+D")); displayControlsAction->setIcon(QIcon(":/control-points")); displayControlsAction->setStatusTip(tr("Display canvas controls")); displayControlsAction->setIconVisibleInMenu(false); @@ -1475,8 +1527,8 @@ void MainWindow::createActions() connect(displayControlsAction, SIGNAL(toggled(bool)), this, SLOT(enableDisplayControls(bool))); // Toggle sticky vertices - stickyVerticesAction = new QAction(tr("&Sticky vertices"), this); - // stickyVertices->setShortcut(tr("Ctrl+E")); + stickyVerticesAction = new QAction(tr("&Sticky Vertices"), this); + stickyVerticesAction->setShortcut(tr("Alt+S")); stickyVerticesAction->setIcon(QIcon(":/control-points")); stickyVerticesAction->setStatusTip(tr("Enable sticky vertices")); stickyVerticesAction->setIconVisibleInMenu(false); @@ -1485,8 +1537,8 @@ void MainWindow::createActions() // Manage sticky vertices connect(stickyVerticesAction, SIGNAL(toggled(bool)), this, SLOT(enableStickyVertices(bool))); - displayTestSignalAction = new QAction(tr("&Display test signal"), this); - // displayTestSignal->setShortcut(tr("Ctrl+T")); + displayTestSignalAction = new QAction(tr("&Display Test Signal"), this); + displayTestSignalAction->setShortcut(tr("Alt+T")); displayTestSignalAction->setIcon(QIcon(":/control-points")); displayTestSignalAction->setStatusTip(tr("Display test signal")); displayTestSignalAction->setIconVisibleInMenu(false); @@ -1530,13 +1582,13 @@ void MainWindow::createMenus() // Recent file separator separatorAction = fileMenu->addSeparator(); - recentFileMenu = fileMenu->addMenu(tr("Recents projects")); + recentFileMenu = fileMenu->addMenu(tr("Open Recents Projects")); for (int i = 0; i < MaxRecentFiles; ++i) recentFileMenu->addAction(recentFileActions[i]); recentFileMenu->addAction(clearRecentFileActions); // Recent import video - recentVideoMenu = fileMenu->addMenu(tr("Recents video")); + recentVideoMenu = fileMenu->addMenu(tr("Open Recents Videos")); recentVideoMenu->addAction(emptyRecentVideos); for (int i = 0; i < MaxRecentVideo; ++i) recentVideoMenu->addAction(recentVideoActions[i]); @@ -1550,7 +1602,7 @@ void MainWindow::createMenus() editMenu = menuBar->addMenu(tr("&Edit")); editMenu->addAction(undoAction); editMenu->addAction(redoAction); - editMenu->addAction(deleteAction); + editMenu->addAction(deleteMappingAction); editMenu->addAction(preferencesAction); // View. @@ -1574,15 +1626,15 @@ void MainWindow::createMenus() } -void MainWindow::createContextMenu() +void MainWindow::createMappingContextMenu() { // Context menu. - contextMenu = new QMenu(); + mappingContextMenu = new QMenu(); // Add different Action - contextMenu->addAction(cloneAction); - contextMenu->addAction(deleteAction); - contextMenu->addAction(renameAction); + mappingContextMenu->addAction(cloneAction); + mappingContextMenu->addAction(deleteMappingAction); + mappingContextMenu->addAction(renameMappingAction); // Set context menu policy mappingList->setContextMenuPolicy(Qt::CustomContextMenu); @@ -1595,6 +1647,24 @@ void MainWindow::createContextMenu() connect(outputWindow, SIGNAL(customContextMenuRequested(const QPoint&)), this, SLOT(showMappingContextMenu(const QPoint&))); } +void MainWindow::createPaintContextMenu() +{ + // Paint Context Menu + paintContextMenu = new QMenu(); + + // Add Actions + paintContextMenu->addAction(deletePaintAction); + paintContextMenu->addAction(renamePaintAction); + + // Define Context policy + paintList->setContextMenuPolicy(Qt::CustomContextMenu); + sourceCanvas->setContextMenuPolicy(Qt::CustomContextMenu); + + // Connexions + connect(paintList, SIGNAL(customContextMenuRequested(const QPoint&)), this, SLOT(showPaintContextMenu(const QPoint&))); + connect(sourceCanvas, SIGNAL(customContextMenuRequested(const QPoint&)), this, SLOT(showPaintContextMenu(const QPoint&))); +} + void MainWindow::createToolBars() { mainToolBar = addToolBar(tr("&File")); @@ -1853,10 +1923,10 @@ void MainWindow::updateRecentFileActions() if (numRecentFiles > 0) { separatorAction->setVisible(true); - clearRecentFileActions->setText(tr("Clear list")); + clearRecentFileActions->setText(tr("Clear List")); clearRecentFileActions->setEnabled(true); } else { - clearRecentFileActions->setText(tr("No Document")); + clearRecentFileActions->setText(tr("No Recents Projects")); clearRecentFileActions->setEnabled(false); } } @@ -1925,7 +1995,7 @@ bool MainWindow::importMediaFile(const QString &fileName, bool isImage) uint mediaId = createMediaPaint(NULL_UID, fileName, 0, 0, isImage, live); // Initialize position (center). - std::tr1::shared_ptr media = std::tr1::static_pointer_cast(mappingManager->getPaintById(mediaId)); + QSharedPointer media = qSharedPointerCast(mappingManager->getPaintById(mediaId)); Q_CHECK_PTR(media); if (_isPlaying) @@ -1961,7 +2031,7 @@ bool MainWindow::addColorPaint(const QColor& color) uint colorId = createColorPaint(NULL_UID, color); // Initialize position (center). - std::tr1::shared_ptr colorPaint = std::tr1::static_pointer_cast(mappingManager->getPaintById(colorId)); + QSharedPointer colorPaint = qSharedPointerCast(mappingManager->getPaintById(colorId)); Q_CHECK_PTR(colorPaint); // Does not do anything... @@ -2005,8 +2075,8 @@ void MainWindow::addPaintItem(uid paintId, const QIcon& icon, const QString& nam // connect(paintGui.get(), SIGNAL(valueChanged()), // this, SLOT(updateCanvases())); - connect(paintGui.get(), SIGNAL(valueChanged(Paint::ptr)), - this, SLOT(handlePaintChanged(Paint::ptr))); + connect(paintGui.data(), SIGNAL(valueChanged(Paint::ptr)), + this, SLOT(handlePaintChanged(Paint::ptr))); // Add paint item to paintList widget. QListWidgetItem* item = new QListWidgetItem(icon, name); @@ -2051,10 +2121,10 @@ void MainWindow::addMappingItem(uid mappingId) // Add mapper. // XXX hardcoded for textures - std::tr1::shared_ptr textureMapping; + QSharedPointer textureMapping; if (paintType == "media" || paintType == "image") { - textureMapping = std::tr1::static_pointer_cast(mapping); + textureMapping = qSharedPointerCast(mapping); Q_CHECK_PTR(textureMapping); } @@ -2107,18 +2177,15 @@ void MainWindow::addMappingItem(uid mappingId) mappingPropertyPanel->setEnabled(true); // When mapper value is changed, update canvases. - connect(mapper.get(), SIGNAL(valueChanged()), - this, SLOT(updateCanvases())); + connect(mapper.data(), SIGNAL(valueChanged()), + this, SLOT(updateCanvases())); - connect(sourceCanvas, SIGNAL(shapeChanged(MShape*)), - mapper.get(), SLOT(updateShape(MShape*))); + connect(sourceCanvas, SIGNAL(shapeChanged(MShape*)), + mapper.data(), SLOT(updateShape(MShape*))); connect(destinationCanvas, SIGNAL(shapeChanged(MShape*)), - mapper.get(), SLOT(updateShape(MShape*))); + mapper.data(), SLOT(updateShape(MShape*))); - connect(this, SIGNAL(paintChanged()), - mapper.get(), SLOT(updatePaint())); - // Switch to mapping tab. contentTab->setCurrentWidget(mappingSplitter); @@ -2137,9 +2204,9 @@ void MainWindow::addMappingItem(uid mappingId) // Add items to scenes. if (mapper->getInputGraphicsItem()) - sourceCanvas->scene()->addItem(mapper->getInputGraphicsItem()); + sourceCanvas->scene()->addItem(mapper->getInputGraphicsItem().data()); if (mapper->getGraphicsItem()) - destinationCanvas->scene()->addItem(mapper->getGraphicsItem()); + destinationCanvas->scene()->addItem(mapper->getGraphicsItem().data()); // Window was modified. windowModified(); @@ -2264,7 +2331,15 @@ void MainWindow::showMappingContextMenu(const QPoint &point) QWidget *objectSender = dynamic_cast(sender()); if (objectSender != NULL && mappingList->count() > 0) - contextMenu->exec(objectSender->mapToGlobal(point)); + mappingContextMenu->exec(objectSender->mapToGlobal(point)); +} + +void MainWindow::showPaintContextMenu(const QPoint &point) +{ + QWidget *objectSender = dynamic_cast(sender()); + + if (objectSender != NULL && paintList->count() > 0) + paintContextMenu->exec(objectSender->mapToGlobal(point)); } QString MainWindow::strippedName(const QString &fullFileName) @@ -2535,7 +2610,7 @@ bool MainWindow::setTextureUri(int texture_id, const std::string &uri) bool success = false; Paint::ptr paint = this->mappingManager->getPaintById(texture_id); - if (paint.get() == NULL) + if (paint.isNull()) { std::cout << "No such texture paint id " << texture_id << std::endl; success = false; @@ -2544,14 +2619,14 @@ bool MainWindow::setTextureUri(int texture_id, const std::string &uri) { if (paint->getType() == "media") { - Media *media = (Media *) paint.get(); // FIXME: use sharedptr cast + Media *media = static_cast(paint.data()); // FIXME: use sharedptr cast videoTimer->stop(); success = media->setUri(QString(uri.c_str())); videoTimer->start(); } else if (paint->getType() == "image") { - Image *media = (Image*) paint.get(); // FIXME: use sharedptr cast + Image *media = (Image*) paint.data(); // FIXME: use sharedptr cast videoTimer->stop(); success = media->setUri(QString(uri.c_str())); videoTimer->start(); @@ -2568,7 +2643,7 @@ bool MainWindow::setTextureUri(int texture_id, const std::string &uri) bool MainWindow::setTextureRate(int texture_id, double rate) { Paint::ptr paint = this->mappingManager->getPaintById(texture_id); - if (paint.get() == NULL) + if (paint.isNull()) { std::cout << "No such texture paint id " << texture_id << std::endl; return false; @@ -2577,7 +2652,7 @@ bool MainWindow::setTextureRate(int texture_id, double rate) { if (paint->getType() == "media") { - Media *media = (Media *) paint.get(); // FIXME: use sharedptr cast + Media *media = static_cast(paint.data()); // FIXME: use sharedptr cast videoTimer->stop(); media->setRate(rate); videoTimer->start(); @@ -2591,8 +2666,3 @@ bool MainWindow::setTextureRate(int texture_id, double rate) return true; } -void MainWindow::quitMapMap() -{ - close(); -} - diff --git a/MainWindow.h b/MainWindow.h index 1346dc2..171f612 100644 --- a/MainWindow.h +++ b/MainWindow.h @@ -71,9 +71,6 @@ protected: void closeEvent(QCloseEvent *event); bool eventFilter(QObject *obj, QEvent *event); -signals: - void paintChanged(); - // Slots //////////////////////////////////////////////////////////////////////////////////////////////////// private slots: @@ -94,8 +91,11 @@ private slots: void openRecentVideo(); // Edit menu. void deleteItem(); + // Context menu. void cloneItem(); - void renameItem(); + void renameMappingItem(); + void deletePaintItem(); + void renamePaintItem(); // Widget callbacks. void handlePaintItemSelectionChanged(); @@ -188,8 +188,10 @@ public slots: void enableStickyVertices(bool display); void enableTestSignal(bool enable); - // Show Context Menu + // Show Mapping Context Menu void showMappingContextMenu(const QPoint &point); + // Show Paint Context Menu + void showPaintContextMenu(const QPoint &point); public: bool setTextureUri(int texture_id, const std::string &uri); @@ -202,7 +204,8 @@ private: void createLayout(); void createActions(); void createMenus(); - void createContextMenu(); + void createMappingContextMenu(); + void createPaintContextMenu(); void createToolBars(); void createStatusBar(); void updateRecentFileActions(); @@ -262,7 +265,8 @@ private: QMenu *helpMenu; QMenu *recentFileMenu; QMenu *recentVideoMenu; - QMenu *contextMenu; + QMenu *mappingContextMenu; + QMenu *paintContextMenu; // Toolbar. QToolBar *mainToolBar; @@ -281,8 +285,10 @@ private: QAction *undoAction; QAction *redoAction; QAction *cloneAction; - QAction *deleteAction; - QAction *renameAction; + QAction *deleteMappingAction; + QAction *renameMappingAction; + QAction *deletePaintAction; + QAction *renamePaintAction; QAction *preferencesAction; QAction *aboutAction; QAction *clearRecentFileActions; @@ -319,6 +325,8 @@ private: QListWidget* mappingList; QStackedWidget* mappingPropertyPanel; + QUndoView* undoView; + SourceGLCanvas* sourceCanvas; DestinationGLCanvas* destinationCanvas; OutputGLWindow* outputWindow; @@ -420,7 +428,6 @@ public: bool setOscPort(int portNumber); int getOscPort() const; void setOutputWindowFullScreen(bool enable); - void quitMapMap(); public: // Constants. /////////////////////////////////////////////////////////////////////////////////////// static const int DEFAULT_WIDTH = 1600; diff --git a/Mapper.cpp b/Mapper.cpp index 529025c..b1abb08 100644 --- a/Mapper.cpp +++ b/Mapper.cpp @@ -30,7 +30,7 @@ MShape::ptr ShapeControlPainter::getShape() const { return _shapeItem->getShape( void ShapeControlPainter::paint(QPainter *painter, const QList& selectedVertices) { _paintShape(painter); - _paintVertices(painter); + _paintVertices(painter, selectedVertices); } void ShapeControlPainter::_paintVertices(QPainter *painter, const QList& selectedVertices) @@ -45,7 +45,7 @@ void ShapeControlPainter::_paintVertices(QPainter *painter, const QList& se void PolygonControlPainter::_paintShape(QPainter *painter) { - Polygon* poly = static_cast(getShape().get()); + Polygon* poly = static_cast(getShape().data()); Q_ASSERT(poly); // Init colors and stroke. @@ -58,7 +58,7 @@ void PolygonControlPainter::_paintShape(QPainter *painter) void EllipseControlPainter::_paintShape(QPainter *painter) { - Ellipse* ellipse = static_cast(getShape().get()); + Ellipse* ellipse = static_cast(getShape().data()); Q_ASSERT(ellipse); // Init colors and stroke. @@ -76,7 +76,7 @@ void EllipseControlPainter::_paintShape(QPainter *painter) void MeshControlPainter::_paintShape(QPainter *painter) { - Mesh* mesh = static_cast(getShape().get()); + Mesh* mesh = static_cast(getShape().data()); Q_ASSERT(mesh); // Init colors and stroke. @@ -97,7 +97,7 @@ void MeshControlPainter::_paintShape(QPainter *painter) ShapeGraphicsItem::ShapeGraphicsItem(Mapping::ptr mapping, bool output) : _mapping(mapping), _output(output) { - _shape = output ? _mapping->getShape() : _mapping->getInputShape(); + _shape = output ? getMapping()->getShape() : getMapping()->getInputShape(); } MapperGLCanvas* ShapeGraphicsItem::getCanvas() const @@ -106,7 +106,9 @@ MapperGLCanvas* ShapeGraphicsItem::getCanvas() const return isOutput() ? win->getDestinationCanvas() : win->getSourceCanvas(); } -bool ShapeGraphicsItem::isMappingCurrent() const { return MainWindow::instance()->getCurrentMappingId() == _mapping->getId(); } +bool ShapeGraphicsItem::isMappingCurrent() const { + return MainWindow::instance()->getCurrentMappingId() == getMapping()->getId(); +} void ShapeGraphicsItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) @@ -115,7 +117,7 @@ void ShapeGraphicsItem::paint(QPainter *painter, // Sync depth of figure with that of mapping (for layered output). if (isOutput()) - setZValue(_mapping->getDepth()); + setZValue(getMapping()->getDepth()); // Paint if visible. if (isMappingVisible()) @@ -207,21 +209,21 @@ QPen ShapeGraphicsItem::_getRescaledShapeStroke(bool innerStroke) void ColorGraphicsItem::_prePaint(QPainter *painter, const QStyleOptionGraphicsItem *option) { - Color* color = static_cast(_mapping->getPaint().get()); + Color* color = static_cast(getMapping()->getPaint().data()); Q_ASSERT(color); painter->setPen(Qt::NoPen); // Set brush. QColor col = color->getColor(); - col.setAlphaF(_mapping->getOpacity()); + col.setAlphaF(getMapping()->getOpacity()); painter->setBrush(col); } QPainterPath PolygonColorGraphicsItem::shape() const { QPainterPath path; - Polygon* poly = static_cast(_shape.get()); + Polygon* poly = static_cast(_shape.data()); Q_ASSERT(poly); path.addPolygon(poly->toPolygon()); return mapFromScene(path); @@ -231,7 +233,7 @@ void PolygonColorGraphicsItem::_doPaint(QPainter *painter, const QStyleOptionGraphicsItem *option) { Q_UNUSED(option); - Polygon* poly = static_cast(_shape.get()); + Polygon* poly = static_cast(_shape.data()); Q_ASSERT(poly); painter->drawPolygon(mapFromScene(poly->toPolygon())); } @@ -240,7 +242,7 @@ void PolygonColorGraphicsItem::_doPaintControls(QPainter* painter, const QStyleO { Q_UNUSED(option); painter->setPen(_getRescaledShapeStroke()); - Polygon* poly = static_cast(_shape.get()); + Polygon* poly = static_cast(_shape.data()); Q_ASSERT(poly); painter->drawPolygon(mapFromScene(poly->toPolygon())); } @@ -249,7 +251,7 @@ QPainterPath EllipseColorGraphicsItem::shape() const { // Create path for ellipse. QPainterPath path; - Ellipse* ellipse = static_cast(_shape.get()); + Ellipse* ellipse = static_cast(_shape.data()); Q_ASSERT(ellipse); QTransform transform; transform.translate(ellipse->getCenter().x(), ellipse->getCenter().y()); @@ -269,13 +271,13 @@ void EllipseColorGraphicsItem::_doPaint(QPainter* painter, TextureGraphicsItem::TextureGraphicsItem(Mapping::ptr mapping, bool output) : ShapeGraphicsItem(mapping, output) { - _textureMapping = std::tr1::static_pointer_cast(mapping); + _textureMapping = qSharedPointerCast(mapping); Q_CHECK_PTR(_textureMapping); - _texture = std::tr1::static_pointer_cast(_textureMapping->getPaint()); + _texture = qSharedPointerCast(_textureMapping.toStrongRef()->getPaint()); Q_CHECK_PTR(_texture); - _inputShape = std::tr1::static_pointer_cast(_textureMapping->getInputShape()); + _inputShape = qSharedPointerCast(_textureMapping.toStrongRef()->getInputShape()); Q_CHECK_PTR(_inputShape); } @@ -298,7 +300,7 @@ void TextureGraphicsItem::_doDrawInput(QPainter* painter) // FIXME: Does this draw the quad counterclockwise? glBegin (GL_QUADS); { - QRectF rect = mapFromScene(_texture->getRect()).boundingRect(); + QRectF rect = mapFromScene(_texture.toStrongRef()->getRect()).boundingRect(); Util::correctGlTexCoord(0, 0); glVertex3f (rect.x(), rect.y(), 0); @@ -322,12 +324,14 @@ void TextureGraphicsItem::_prePaint(QPainter* painter, Q_UNUSED(option); painter->beginNativePainting(); + QSharedPointer texture = _texture.toStrongRef(); + // Only works for similar shapes. // TODO:remettre //Q_ASSERT( _inputShape->nVertices() == outputShape->nVertices()); // Project source texture and sent it to destination. - _texture->update(); + texture->update(); // Allow alpha blending. glEnable (GL_BLEND); @@ -335,17 +339,17 @@ void TextureGraphicsItem::_prePaint(QPainter* painter, // Get texture. glEnable (GL_TEXTURE_2D); - glBindTexture(GL_TEXTURE_2D, _texture->getTextureId()); + glBindTexture(GL_TEXTURE_2D, texture->getTextureId()); // Copy bits to texture iff necessary. - _texture->lockMutex(); - if (_texture->bitsHaveChanged()) + texture->lockMutex(); + if (texture->bitsHaveChanged()) { glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, - _texture->getWidth(), _texture->getHeight(), 0, GL_RGBA, - GL_UNSIGNED_BYTE, _texture->getBits()); + texture->getWidth(), texture->getHeight(), 0, GL_RGBA, + GL_UNSIGNED_BYTE, texture->getBits()); } - _texture->unlockMutex(); + texture->unlockMutex(); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER); @@ -353,7 +357,8 @@ void TextureGraphicsItem::_prePaint(QPainter* painter, glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); // Set texture color (apply opacity). - glColor4f(1.0f, 1.0f, 1.0f, isOutput() ? _mapping->getOpacity() : _mapping->getPaint()->getOpacity()); + glColor4f(1.0f, 1.0f, 1.0f, + isOutput() ? getMapping()->getOpacity() : getMapping()->getPaint()->getOpacity()); } void TextureGraphicsItem::_postPaint(QPainter* painter, @@ -369,7 +374,7 @@ void TextureGraphicsItem::_postPaint(QPainter* painter, QPainterPath PolygonTextureGraphicsItem::shape() const { QPainterPath path; - Polygon* poly = static_cast(_shape.get()); + Polygon* poly = static_cast(_shape.data()); Q_ASSERT(poly); path.addPolygon(poly->toPolygon()); return mapFromScene(path); @@ -384,11 +389,12 @@ void TriangleTextureGraphicsItem::_doDrawOutput(QPainter* painter) Q_UNUSED(painter); if (isOutput()) { + MShape::ptr inputShape = _inputShape.toStrongRef(); glBegin(GL_TRIANGLES); { - for (int i=0; i<_inputShape->nVertices(); i++) + for (int i=0; inVertices(); i++) { - Util::setGlTexPoint(*_texture, _inputShape->getVertex(i), mapFromScene(_shape->getVertex(i))); + Util::setGlTexPoint(*_texture.toStrongRef(), inputShape->getVertex(i), mapFromScene(getShape()->getVertex(i))); } } glEnd(); @@ -399,7 +405,7 @@ void PolygonTextureGraphicsItem::_doPaintControls(QPainter* painter, const QStyl { Q_UNUSED(option); painter->setPen(_getRescaledShapeStroke()); - Polygon* poly = static_cast(_shape.get()); + Polygon* poly = static_cast(_shape.data()); Q_ASSERT(poly); painter->drawPolygon(mapFromScene(poly->toPolygon())); } @@ -409,8 +415,8 @@ void MeshTextureGraphicsItem::_doDrawOutput(QPainter* painter) Q_UNUSED(painter); if (isOutput()) { - std::tr1::shared_ptr outputMesh = std::tr1::static_pointer_cast(_shape); - std::tr1::shared_ptr inputMesh = std::tr1::static_pointer_cast(_inputShape); + QSharedPointer outputMesh = qSharedPointerCast(_shape); + QSharedPointer inputMesh = qSharedPointerCast(_inputShape); QVector > outputQuads = outputMesh->getQuads2d(); QVector > inputQuads = inputMesh->getQuads2d(); for (int x = 0; x < outputMesh->nHorizontalQuads(); x++) @@ -419,7 +425,7 @@ void MeshTextureGraphicsItem::_doDrawOutput(QPainter* painter) { QSizeF size = mapFromScene(outputQuads[x][y].toPolygon()).boundingRect().size(); float area = size.width() * size.height(); - _drawQuad(*_texture, inputQuads[x][y], outputQuads[x][y], area); + _drawQuad(*_texture.toStrongRef(), inputQuads[x][y], outputQuads[x][y], area); } } } @@ -430,7 +436,7 @@ void MeshTextureGraphicsItem::_doPaintControls(QPainter* painter, const QStyleOp { Q_UNUSED(option); - Mesh* mesh = static_cast(_shape.get()); + Mesh* mesh = static_cast(_shape.data()); Q_ASSERT(mesh); // Init colors and stroke. @@ -526,7 +532,7 @@ QPainterPath EllipseTextureGraphicsItem::shape() const { // Create path for ellipse. QPainterPath path; - Ellipse* ellipse = static_cast(_shape.get()); + Ellipse* ellipse = static_cast(_shape.data()); Q_ASSERT(ellipse); QTransform transform; transform.translate(ellipse->getCenter().x(), ellipse->getCenter().y()); @@ -544,8 +550,9 @@ void EllipseTextureGraphicsItem::_doDrawOutput(QPainter* painter) { Q_UNUSED(painter); // Get input and output ellipses. - std::tr1::shared_ptr inputEllipse = std::tr1::static_pointer_cast(_inputShape); - std::tr1::shared_ptr outputEllipse = std::tr1::static_pointer_cast(_shape); + QSharedPointer inputEllipse = qSharedPointerCast(_inputShape); + QSharedPointer outputEllipse = qSharedPointerCast(_shape); + QSharedPointer texture = _texture.toStrongRef(); // Start / end angle. //const float startAngle = 0; @@ -588,9 +595,9 @@ void EllipseTextureGraphicsItem::_doDrawOutput(QPainter* painter) { // Draw triangle. glBegin(GL_TRIANGLES); - Util::setGlTexPoint(*_texture, inputControlCenter, outputControlCenter); - Util::setGlTexPoint(*_texture, prevInputPoint, prevOutputPoint); - Util::setGlTexPoint(*_texture, currentInputPoint, currentOutputPoint); + Util::setGlTexPoint(*texture, inputControlCenter, outputControlCenter); + Util::setGlTexPoint(*texture, prevInputPoint, prevOutputPoint); + Util::setGlTexPoint(*texture, currentInputPoint, currentOutputPoint); glEnd(); } @@ -622,7 +629,7 @@ Mapper::Mapper(Mapping::ptr mapping) Q_CHECK_PTR(outputShape); // Create editor. - _propertyBrowser = new QtTreePropertyBrowser; + _propertyBrowser.reset(new QtTreePropertyBrowser); _variantManager = new VariantManager; _variantFactory = new VariantFactory; @@ -645,7 +652,7 @@ Mapper::Mapper(Mapping::ptr mapping) _outputItem = _variantManager->addProperty(QtVariantPropertyManager::groupTypeId(), QObject::tr("Output shape")); - _buildShapeProperty(_outputItem, mapping->getShape().get()); + _buildShapeProperty(_outputItem, mapping->getShape().data()); _topItem->addSubProperty(_outputItem); // Collapse output shape. @@ -656,18 +663,6 @@ Mapper::Mapper(Mapping::ptr mapping) //qDebug() << "Creating mapper" << endl; } -Mapper::~Mapper() -{ - if (_propertyBrowser) - delete _propertyBrowser; - if (_graphicsItem) - delete _graphicsItem; -} - -QWidget* Mapper::getPropertiesEditor() -{ - return _propertyBrowser; -} void Mapper::setValue(QtProperty* property, const QVariant& value) { @@ -697,6 +692,14 @@ void Mapper::setValue(QtProperty* property, const QVariant& value) } } +void Mapper::updateShape(MShape* shape) +{ + if (shape == _mapping->getShape().data()) + { + _updateShapeProperty(_outputItem, shape); + } +} + void Mapper::_buildShapeProperty(QtProperty* shapeItem, MShape* shape) { for (int i=0; inVertices(); i++) @@ -732,16 +735,10 @@ void Mapper::_updateShapeProperty(QtProperty* shapeItem, MShape* shape) ColorMapper::ColorMapper(Mapping::ptr mapping) : Mapper(mapping) { - color = std::tr1::static_pointer_cast(_mapping->getPaint()); + color = qSharedPointerCast(_mapping->getPaint()); Q_CHECK_PTR(color); } -void ColorMapper::updatePaint() -{ - color.reset(); - color = std::tr1::static_pointer_cast(_mapping->getPaint()); - Q_CHECK_PTR(color); -} //MeshColorMapper::MeshColorMapper(Mapping::ptr mapping) // : ColorMapper(mapping) { @@ -757,7 +754,7 @@ void ColorMapper::updatePaint() // painter->setPen(Qt::NoPen); // painter->setBrush(color->getColor()); // -// std::tr1::shared_ptr outputMesh = std::tr1::static_pointer_cast(outputShape); +// QSharedPointer outputMesh = qSharedPointerCast(outputShape); // QVector > outputQuads = outputMesh->getQuads2d(); // for (int x = 0; x < outputMesh->nHorizontalQuads(); x++) // { @@ -771,7 +768,7 @@ void ColorMapper::updatePaint() // //void MeshColorMapper::drawControls(QPainter* painter, const QList* selectedVertices) //{ -// std::tr1::shared_ptr outputMesh = std::tr1::static_pointer_cast(outputShape); +// QSharedPointer outputMesh = qSharedPointerCast(outputShape); // Util::drawControlsMesh(painter, selectedVertices, *outputMesh); //} // @@ -792,24 +789,24 @@ void ColorMapper::updatePaint() // ColorMapper::setValue(property, value); //} -TextureMapper::TextureMapper(std::tr1::shared_ptr mapping) +TextureMapper::TextureMapper(QSharedPointer mapping) : Mapper(mapping), _meshItem(NULL) { // Assign members pointers. - textureMapping = std::tr1::static_pointer_cast(_mapping); + textureMapping = qSharedPointerCast(_mapping); Q_CHECK_PTR(textureMapping); - texture = std::tr1::static_pointer_cast(textureMapping->getPaint()); + texture = qSharedPointerCast(_mapping->getPaint()); Q_CHECK_PTR(texture); - inputShape = std::tr1::static_pointer_cast(textureMapping->getInputShape()); + inputShape = textureMapping.toStrongRef()->getInputShape(); Q_CHECK_PTR(inputShape); // Input shape. _inputItem = _variantManager->addProperty(QtVariantPropertyManager::groupTypeId(), QObject::tr("Input shape")); - _buildShapeProperty(_inputItem, textureMapping->getInputShape().get()); + _buildShapeProperty(_inputItem, inputShape.data()); _topItem->insertSubProperty(_inputItem, _opacityItem); // insert // Collapse input shape. @@ -844,14 +841,14 @@ TextureMapper::TextureMapper(std::tr1::shared_ptr mapping) void TextureMapper::updateShape(MShape* shape) { - std::tr1::shared_ptr textureMapping = std::tr1::static_pointer_cast(_mapping); + QSharedPointer textureMapping = qSharedPointerCast(_mapping); Q_CHECK_PTR(textureMapping); - std::tr1::shared_ptr texture = std::tr1::static_pointer_cast(textureMapping->getPaint()); + QSharedPointer texture = qSharedPointerCast(textureMapping->getPaint()); Q_CHECK_PTR(texture); - MShape* inputShape = textureMapping->getInputShape().get(); - MShape* outputShape = textureMapping->getShape().get(); + MShape* inputShape = textureMapping->getInputShape().data(); + MShape* outputShape = textureMapping->getShape().data(); if (shape == inputShape) { _updateShapeProperty(_inputItem, inputShape); @@ -863,12 +860,6 @@ void TextureMapper::updateShape(MShape* shape) } -void TextureMapper::updatePaint() -{ - texture.reset(); - texture = std::tr1::static_pointer_cast(textureMapping->getPaint()); - Q_CHECK_PTR(texture); -} // //void TextureMapper::_preDraw(QPainter* painter) //{ @@ -910,21 +901,21 @@ void TextureMapper::updatePaint() // //void PolygonTextureMapper::drawControls(QPainter* painter, const QList* selectedVertices) //{ -// std::tr1::shared_ptr outputPoly = std::tr1::static_pointer_cast(outputShape); +// QSharedPointer outputPoly = qSharedPointerCast(outputShape); // Util::drawControlsPolygon(painter, selectedVertices, *outputPoly); //} // //void PolygonTextureMapper::drawInputControls(QPainter* painter, const QList* selectedVertices) //{ -// std::tr1::shared_ptr inputPoly = std::tr1::static_pointer_cast(inputShape); +// QSharedPointer inputPoly = qSharedPointerCast(inputShape); // Util::drawControlsPolygon(painter, selectedVertices, *inputPoly); //} -TriangleTextureMapper::TriangleTextureMapper(std::tr1::shared_ptr mapping) +TriangleTextureMapper::TriangleTextureMapper(QSharedPointer mapping) : PolygonTextureMapper(mapping) { - _graphicsItem = new TriangleTextureGraphicsItem(_mapping, true); - _inputGraphicsItem = new TriangleTextureGraphicsItem(_mapping, false); + _graphicsItem.reset(new TriangleTextureGraphicsItem(_mapping, true)); + _inputGraphicsItem.reset(new TriangleTextureGraphicsItem(_mapping, false)); } // //void TriangleTextureMapper::_doDraw(QPainter* painter) @@ -941,14 +932,14 @@ TriangleTextureMapper::TriangleTextureMapper(std::tr1::shared_ptr mapping) +MeshTextureMapper::MeshTextureMapper(QSharedPointer mapping) : PolygonTextureMapper(mapping) { - _graphicsItem = new MeshTextureGraphicsItem(_mapping, true); - _inputGraphicsItem = new MeshTextureGraphicsItem(_mapping, false); + _graphicsItem.reset(new MeshTextureGraphicsItem(_mapping, true)); + _inputGraphicsItem.reset(new MeshTextureGraphicsItem(_mapping, false)); // Add mesh sub property. - Mesh* mesh = (Mesh*)textureMapping->getShape().get(); + QSharedPointer mesh = qSharedPointerCast(_mapping->getShape()); _meshItem = _variantManager->addProperty(QVariant::Size, QObject::tr("Dimensions")); _meshItem->setValue(QSize(mesh->nColumns(), mesh->nRows())); _meshItem->setAttribute("minimum", QSize(2,2)); @@ -959,11 +950,8 @@ void MeshTextureMapper::setValue(QtProperty* property, const QVariant& value) { if (property == _meshItem) { - std::tr1::shared_ptr textureMapping = std::tr1::static_pointer_cast(_mapping); - Q_CHECK_PTR(textureMapping); - - Mesh* outputMesh = static_cast(textureMapping->getShape().get()); - Mesh* inputMesh = static_cast(textureMapping->getInputShape().get()); + QSharedPointer outputMesh = qSharedPointerCast(_mapping->getShape()); + QSharedPointer inputMesh = qSharedPointerCast(textureMapping.toStrongRef()->getInputShape()); QSize size = (static_cast(property))->value().toSize(); if (outputMesh->nColumns() != size.width() || outputMesh->nRows() != size.height() || inputMesh->nColumns() != size.width() || inputMesh->nRows() != size.height()) @@ -983,10 +971,10 @@ void MeshTextureMapper::setValue(QtProperty* property, const QVariant& value) TextureMapper::setValue(property, value); } -EllipseTextureMapper::EllipseTextureMapper(std::tr1::shared_ptr mapping) +EllipseTextureMapper::EllipseTextureMapper(QSharedPointer mapping) : PolygonTextureMapper(mapping) { - _graphicsItem = new EllipseTextureGraphicsItem(_mapping, true); - _inputGraphicsItem = new EllipseTextureGraphicsItem(_mapping, false); + _graphicsItem.reset(new EllipseTextureGraphicsItem(_mapping, true)); + _inputGraphicsItem.reset(new EllipseTextureGraphicsItem(_mapping, false)); } diff --git a/Mapper.h b/Mapper.h index 374510c..65d7abe 100644 --- a/Mapper.h +++ b/Mapper.h @@ -30,8 +30,6 @@ #include #endif -#include - #include #include @@ -58,7 +56,7 @@ class ShapeGraphicsItem; class ShapeControlPainter { public: - typedef std::tr1::shared_ptr ptr; + typedef QSharedPointer ptr; ShapeControlPainter(ShapeGraphicsItem* shapeItem); virtual ~ShapeControlPainter() {} @@ -107,6 +105,8 @@ protected: class ShapeGraphicsItem : public QGraphicsItem { Q_DECLARE_TR_FUNCTIONS(ShapeGraphicsItem) +public: + typedef QSharedPointer ptr; protected: ShapeGraphicsItem(Mapping::ptr mapping, bool output=true); @@ -116,9 +116,9 @@ public: public: // TODO: dangereux: confusion possible entre shape() et getShape()... - MShape::ptr getShape() const { return _shape; } + MShape::ptr getShape() const { return _shape.toStrongRef(); } - Mapping::ptr getMapping() const { return _mapping; } + Mapping::ptr getMapping() const { return _mapping.toStrongRef(); } ShapeControlPainter::ptr getControlPainter() { return _controlPainter; } @@ -126,7 +126,7 @@ public: MapperGLCanvas* getCanvas() const; bool isMappingCurrent() const; - bool isMappingVisible() const { return _mapping->isVisible(); } + bool isMappingVisible() const { return getMapping()->isVisible(); } virtual QRectF boundingRect() const { return shape().boundingRect(); } // virtual QPainterPath shape() const; @@ -152,8 +152,8 @@ public: // invariant to the zoom level (to be used in _doPaintControls() method). QPen _getRescaledShapeStroke(bool innerStroke=false); protected: - Mapping::ptr _mapping; - MShape::ptr _shape; + QWeakPointer _mapping; + QWeakPointer _shape; ShapeControlPainter::ptr _controlPainter; bool _output; }; @@ -224,9 +224,9 @@ protected: virtual void _doDrawInput(QPainter* painter); protected: - std::tr1::shared_ptr _textureMapping; - std::tr1::shared_ptr _texture; - std::tr1::shared_ptr _inputShape; + QWeakPointer _textureMapping; + QWeakPointer _texture; + QWeakPointer _inputShape; }; /// Graphics item for textured polygons (eg. triangles). @@ -306,28 +306,25 @@ class Mapper : public QObject Q_OBJECT public: - typedef std::tr1::shared_ptr ptr; + typedef QSharedPointer ptr; protected: /// Constructor. A mapper applies to a mapping. Mapper(Mapping::ptr mapping); - virtual ~Mapper(); + +public: + virtual ~Mapper() {} public: /// Returns a pointer to the properties editor for that mapper. - virtual QWidget* getPropertiesEditor(); + virtual QWidget* getPropertiesEditor() { return _propertyBrowser.data(); } - virtual ShapeGraphicsItem* getGraphicsItem() { - return _graphicsItem; - } - virtual ShapeGraphicsItem* getInputGraphicsItem() { - return _inputGraphicsItem; - } + virtual ShapeGraphicsItem::ptr getGraphicsItem() const { return _graphicsItem; } + virtual ShapeGraphicsItem::ptr getInputGraphicsItem() { return _inputGraphicsItem; } public slots: virtual void setValue(QtProperty* property, const QVariant& value); - virtual void updateShape(MShape* shape) { Q_UNUSED(shape); } - virtual void updatePaint() {} + virtual void updateShape(MShape* shape); signals: void valueChanged(); @@ -335,7 +332,7 @@ signals: protected: Mapping::ptr _mapping; - QtTreePropertyBrowser* _propertyBrowser; + QSharedPointer _propertyBrowser; QtVariantEditorFactory* _variantFactory; QtVariantPropertyManager* _variantManager; @@ -345,8 +342,8 @@ protected: std::map > _propertyToVertex; - ShapeGraphicsItem* _graphicsItem; - ShapeGraphicsItem* _inputGraphicsItem; + ShapeGraphicsItem::ptr _graphicsItem; + ShapeGraphicsItem::ptr _inputGraphicsItem; // FIXME: use typedefs, member of the class for type names that are too long to type: MShape::ptr outputShape; @@ -362,15 +359,12 @@ class ColorMapper : public Mapper { Q_OBJECT -public slots: - virtual void updatePaint(); - protected: ColorMapper(Mapping::ptr mapping); virtual ~ColorMapper() {} protected: - std::tr1::shared_ptr color; + QSharedPointer color; }; class PolygonColorMapper : public ColorMapper @@ -379,7 +373,7 @@ class PolygonColorMapper : public ColorMapper public: PolygonColorMapper(Mapping::ptr mapping) : ColorMapper(mapping) { - _graphicsItem = new PolygonColorGraphicsItem(mapping, true); + _graphicsItem.reset(new PolygonColorGraphicsItem(mapping, true)); } virtual ~PolygonColorMapper() {} }; @@ -408,7 +402,7 @@ class EllipseColorMapper : public ColorMapper public: EllipseColorMapper(Mapping::ptr mapping) : ColorMapper(mapping) { - _graphicsItem = new EllipseColorGraphicsItem(mapping, true); + _graphicsItem.reset(new EllipseColorGraphicsItem(mapping, true)); } virtual ~EllipseColorMapper() {} @@ -422,7 +416,7 @@ class TextureMapper : public Mapper Q_OBJECT public: - TextureMapper(std::tr1::shared_ptr mapping); + TextureMapper(QSharedPointer mapping); virtual ~TextureMapper() {} // /** @@ -437,7 +431,6 @@ public: public slots: virtual void updateShape(MShape* shape); - virtual void updatePaint(); //protected: // virtual void _doDraw(QPainter* painter) = 0; @@ -449,9 +442,9 @@ protected: QtVariantProperty* _meshItem; // FIXME: use typedefs, member of the class for type names that are too long to type: - std::tr1::shared_ptr textureMapping; - std::tr1::shared_ptr texture; - std::tr1::shared_ptr inputShape; + QWeakPointer textureMapping; + QWeakPointer texture; + QWeakPointer inputShape; }; class PolygonTextureMapper : public TextureMapper @@ -459,7 +452,7 @@ class PolygonTextureMapper : public TextureMapper Q_OBJECT public: - PolygonTextureMapper(std::tr1::shared_ptr mapping) : TextureMapper(mapping) {} + PolygonTextureMapper(QSharedPointer mapping) : TextureMapper(mapping) {} virtual ~PolygonTextureMapper() {} }; @@ -468,7 +461,7 @@ class TriangleTextureMapper : public PolygonTextureMapper Q_OBJECT public: - TriangleTextureMapper(std::tr1::shared_ptr mapping); + TriangleTextureMapper(QSharedPointer mapping); virtual ~TriangleTextureMapper() {} }; @@ -477,7 +470,7 @@ class MeshTextureMapper : public PolygonTextureMapper Q_OBJECT public: - MeshTextureMapper(std::tr1::shared_ptr mapping); + MeshTextureMapper(QSharedPointer mapping); virtual ~MeshTextureMapper() {} public slots: @@ -491,7 +484,7 @@ class EllipseTextureMapper : public PolygonTextureMapper { Q_OBJECT public: - EllipseTextureMapper(std::tr1::shared_ptr mapping); + EllipseTextureMapper(QSharedPointer mapping); virtual ~EllipseTextureMapper() {} protected: diff --git a/MapperGLCanvas.cpp b/MapperGLCanvas.cpp index a6bf567..b48eaa5 100644 --- a/MapperGLCanvas.cpp +++ b/MapperGLCanvas.cpp @@ -26,7 +26,7 @@ MapperGLCanvas::MapperGLCanvas(MainWindow* mainWindow, QWidget* parent, const QGLWidget * shareWidget, QGraphicsScene* scene) : QGraphicsView(parent), _mainWindow(mainWindow), - _mousePressedOnVertex(false), + _vertexGrabbed(false), _activeVertex(NO_VERTEX), _shapeGrabbed(false), // comment out? _shapeFirstGrab(false), // comment out? @@ -61,12 +61,12 @@ MapperGLCanvas::MapperGLCanvas(MainWindow* mainWindow, QWidget* parent, const QG this->scene()->setBackgroundBrush(Qt::black); } -MShape* MapperGLCanvas::getCurrentShape() +MShape::ptr MapperGLCanvas::getCurrentShape() { return getShapeFromMappingId(MainWindow::instance()->getCurrentMappingId()); } -ShapeGraphicsItem* MapperGLCanvas::getCurrentShapeGraphicsItem() +QSharedPointer MapperGLCanvas::getCurrentShapeGraphicsItem() { return getShapeGraphicsItemFromMappingId(MainWindow::instance()->getCurrentMappingId()); } @@ -80,13 +80,25 @@ void MapperGLCanvas::drawForeground(QPainter *painter , const QRectF &rect) uid mid = _mainWindow->getCurrentMappingId(); if (mid != NULL_UID) { - ShapeGraphicsItem* item = getCurrentShapeGraphicsItem(); + // Use current shape graphics item to draw controls. + ShapeGraphicsItem::ptr item = getCurrentShapeGraphicsItem(); if (item) - item->getControlPainter()->paint(painter); + { + QList selected; + if (hasActiveVertex()) + selected.push_back(getActiveVertexIndex()); + item->getControlPainter()->paint(painter, selected); + } } } } +void MapperGLCanvas::currentShapeWasChanged() +{ + emit shapeChanged(getCurrentShape().data()); +} + + // void MapperGLCanvas::mousePressEvent(QMouseEvent* event) { @@ -112,7 +124,7 @@ void MapperGLCanvas::mousePressEvent(QMouseEvent* event) // Check for vertex selection first. else if (event->buttons() & Qt::LeftButton) { - MShape* shape = getCurrentShape(); + MShape::ptr shape = getCurrentShape(); if (shape) { // Note: we compare with the square value for fastest computation of the distance @@ -127,10 +139,10 @@ void MapperGLCanvas::mousePressEvent(QMouseEvent* event) _activeVertex = i; minDistance = dist; - _mousePressedOnVertex = true; + _vertexGrabbed = true; mousePressedOnSomething = true; - _grabbedObjectStartPosition = shape->getVertex(i); + _grabbedObjectStartScenePosition = shape->getVertex(i); } } } @@ -142,14 +154,14 @@ void MapperGLCanvas::mousePressEvent(QMouseEvent* event) // Check for shape selection. if (event->buttons() & (Qt::LeftButton | Qt::RightButton)) // Add Right click for context menu { - MShape* selectedShape = getCurrentShape(); + MShape::ptr selectedShape = getCurrentShape(); // Possibility of changing shape in output by clicking on it. MappingManager manager = getMainWindow()->getMappingManager(); QVector mappings = manager.getVisibleMappings(); for (QVector::const_iterator it = mappings.end() - 1; it >= mappings.begin(); --it) { - MShape *shape = getShapeFromMappingId((*it)->getId()); + MShape::ptr shape = getShapeFromMappingId((*it)->getId()); // Check if mouse was pressed on that shape. if (shape && shape->includesPoint(pos)) @@ -181,7 +193,7 @@ void MapperGLCanvas::mousePressEvent(QMouseEvent* event) _shapeGrabbed = true; _shapeFirstGrab = true; - _grabbedObjectStartPosition = pos; + _grabbedObjectStartScenePosition = pos; } } } @@ -210,14 +222,22 @@ void MapperGLCanvas::mouseReleaseEvent(QMouseEvent* event) // if ((event->buttons() & Qt::LeftButton) && _mousePressedOnVertex) // { // } - if (_mousePressedOnVertex) + if (_vertexGrabbed) { + // TODO : code repetition here!!! + QPointF p = mapToScene(event->pos()); + + // Stick to vertices. + if (_mainWindow->stickyVertices()) + _glueVertex(&p); + + undoStack->push(new MoveVertexCommand(this, TransformShapeCommand::RELEASE, _activeVertex, p)); } else if (_shapeGrabbed) { - + undoStack->push(new TranslateShapeCommand(this, TransformShapeCommand::RELEASE, QPointF())); } - _mousePressedOnVertex = false; + _vertexGrabbed = false; _shapeGrabbed = false; } @@ -225,30 +245,30 @@ void MapperGLCanvas::mouseMoveEvent(QMouseEvent* event) { static QPoint lastMousePos; - QPointF pos = mapToScene(event->pos()); + QPointF scenePos = mapToScene(event->pos()); // Prepare to store commands undoStack = getMainWindow()->getUndoStack(); // Vertex grab. - if (_mousePressedOnVertex) + if (_vertexGrabbed) { // std::cout << "Move event " << std::endl; - MShape* shape = getCurrentShape(); - if (shape && _activeVertex != NO_VERTEX) + MShape::ptr shape = getCurrentShape(); + if (shape && hasActiveVertex()) { // QPointF p = shape->getVertex(_activeVertex); // // Set point to mouse coordinates. // p.setX(pos.x()); // p.setY(pos.y()); - QPointF p = pos; + QPointF p = scenePos; // Stick to vertices. if (_mainWindow->stickyVertices()) _glueVertex(&p); - shape->setVertex(_activeVertex, p); + undoStack->push(new MoveVertexCommand(this, TransformShapeCommand::FREE, _activeVertex, p)); } } @@ -256,7 +276,7 @@ void MapperGLCanvas::mouseMoveEvent(QMouseEvent* event) else if (_shapeGrabbed) { // std::cout << "Move event " << std::endl; - MShape* shape = getCurrentShape(); + MShape::ptr shape = getCurrentShape(); if (shape) { if (_shapeFirstGrab) @@ -266,8 +286,8 @@ void MapperGLCanvas::mouseMoveEvent(QMouseEvent* event) } } - QPointF diff = pos - mapToScene(lastMousePos); - shape->translate(diff.x(), diff.y()); + QPointF diff = scenePos - mapToScene(lastMousePos); + undoStack->push(new TranslateShapeCommand(this, TransformShapeCommand::FREE, diff)); } // Window translation action @@ -279,108 +299,114 @@ void MapperGLCanvas::mouseMoveEvent(QMouseEvent* event) // view->update(); } + // Reset last mouse position. lastMousePos = event->pos(); } -// -//void MapperGLCanvas::keyPressEvent(QKeyEvent* event) -//{ -// // Prepare to store commands -// undoStack = getMainWindow()->getUndoStack(); -// -// // Checks if the key has been handled by this function or needs to be deferred to superclass. -// bool handledKey = false; -// -// // Active vertex selected. -// if (hasActiveVertex()) -// { -// Shape* shape = getCurrentShape(); -// QPointF p = shape->getVertex(_activeVertex); -// handledKey = true; -// switch (event->key()) { -// // TODO: key tab should switch to next vertex: not working because somehow caught at a higher level -// // to switch between frames of the layout -//// case Qt::Key_Tab: -//// if (shape) -//// _activeVertex = (_activeVertex + 1) % shape->nVertices(); -//// p = shape->getVertex(_activeVertex); // reset to new vertex -//// qDebug() << "New active vertex : " << _activeVertex << endl; -//// break; -// // Handle pixel-wise adjustments of vertex. -// case Qt::Key_Up: -// p.ry()--; -// break; -// case Qt::Key_Down: -// p.ry()++; -// break; -// case Qt::Key_Right: -// p.rx()++; -// break; -// case Qt::Key_Left: -// p.rx()--; -// break; -// default: -// if (event->matches(QKeySequence::Undo)) -// undoStack->undo(); -// -// else if (event->matches(QKeySequence::Redo)) -// undoStack->redo(); -// else -// handledKey = false; + +void MapperGLCanvas::keyPressEvent(QKeyEvent* event) +{ + // Prepare to store commands. + undoStack = getMainWindow()->getUndoStack(); + + // Checks if the key has been handled by this function or needs to be deferred to superclass. + bool handledKey = false; + + // Active vertex selected. + if (hasActiveVertex()) + { + MShape::ptr shape = getCurrentShape(); + QPoint pos = mapFromScene(shape->getVertex(_activeVertex)); + handledKey = true; + + switch (event->key()) { + // TODO: key tab should switch to next vertex: not working because somehow caught at a higher level + // to switch between frames of the layout +// case Qt::Key_Tab: +// if (shape) +// _activeVertex = (_activeVertex + 1) % shape->nVertices(); +// p = shape->getVertex(_activeVertex); // reset to new vertex +// qDebug() << "New active vertex : " << _activeVertex << endl; // break; + // Handle pixel-wise adjustments of vertex. + case Qt::Key_Up: + pos.ry()--; + break; + case Qt::Key_Down: + pos.ry()++; + break; + case Qt::Key_Right: + pos.rx()++; + break; + case Qt::Key_Left: + pos.rx()--; + break; + default: + if (event->matches(QKeySequence::Undo)) + undoStack->undo(); + + else if (event->matches(QKeySequence::Redo)) + undoStack->redo(); + else + handledKey = false; + break; + } + + // Remap window position to scene. + QPointF scenePos = mapToScene(pos); + + // TODO: this will always be called even if no arrow key has been pressed (small performance issue). + // Enable to Undo and Redo when arrow keys move the position of vertices + undoStack->push(new MoveVertexCommand(this, TransformShapeCommand::STEP, _activeVertex, scenePos)); + } + + // Defer unhandled keys to parent. + if (!handledKey) + { + QWidget::keyPressEvent(event); + } + +// std::cout << "Key pressed" << std::endl; +// int xMove = 0; +// int yMove = 0; +// switch (event->key()) { +// case Qt::Key_Tab: +// if (event->modifiers() & Qt::ControlModifier) +// switchImage( (Common::getCurrentSourceId() + 1) % Common::nImages()); +// else +// { +// Quad& quad = getQuad(); +// _active_vertex = (_active_vertex + 1 ) % 4; // } -// // TODO: this will always be called even if no arrow key has been pressed (small performance issue). -// // Enable to Undo and Redo when arrow keys move the position of vertices -// undoStack->push(new MoveVertexCommand(this, _activeVertex, p)); -// } -// -// // Defer unhandled keys to parent. -// if (!handledKey) -// { +// break; +// case Qt::Key_Up: +// yMove = -1; +// break; +// case Qt::Key_Down: +// yMove = +1; +// break; +// case Qt::Key_Left: +// xMove = -1; +// break; +// case Qt::Key_Right: +// xMove = +1; +// break; +// default: +// std::cerr << "Unhandled key" << std::endl; // QWidget::keyPressEvent(event); +// break; // } // -//// std::cout << "Key pressed" << std::endl; -//// int xMove = 0; -//// int yMove = 0; -//// switch (event->key()) { -//// case Qt::Key_Tab: -//// if (event->modifiers() & Qt::ControlModifier) -//// switchImage( (Common::getCurrentSourceId() + 1) % Common::nImages()); -//// else -//// { -//// Quad& quad = getQuad(); -//// _active_vertex = (_active_vertex + 1 ) % 4; -//// } -//// break; -//// case Qt::Key_Up: -//// yMove = -1; -//// break; -//// case Qt::Key_Down: -//// yMove = +1; -//// break; -//// case Qt::Key_Left: -//// xMove = -1; -//// break; -//// case Qt::Key_Right: -//// xMove = +1; -//// break; -//// default: -//// std::cerr << "Unhandled key" << std::endl; -//// QWidget::keyPressEvent(event); -//// break; -//// } -//// -//// Quad& quad = getQuad(); -//// Point *p = quad.getVertex(_active_vertex); -//// p->x += xMove; -//// p->y += yMove; -//// quad.setVertex(_active_vertex, p); -//// -//// update(); -//// -//// emit quadChanged(); -//} +// Quad& quad = getQuad(); +// Point *p = quad.getVertex(_active_vertex); +// p->x += xMove; +// p->y += yMove; +// quad.setVertex(_active_vertex, p); +// +// update(); +// +// emit quadChanged(); +} // //void MapperGLCanvas::paintEvent(QPaintEvent* ) //{ @@ -428,7 +454,7 @@ void MapperGLCanvas::updateCanvas() void MapperGLCanvas::deselectVertices() { _activeVertex = NO_VERTEX; - _mousePressedOnVertex = false; + _vertexGrabbed = false; } void MapperGLCanvas::deselectAll() @@ -497,7 +523,7 @@ void MapperGLCanvas::_glueVertex(QPointF* p) MappingManager manager = MainWindow::instance()->getMappingManager(); for (int i = 0; i < manager.nMappings(); i++) { - MShape *shape = manager.getMapping(i)->getShape().get(); + MShape *shape = manager.getMapping(i)->getShape().data(); if (shape && shape != getCurrentShape()) { for (int vertex = 0; vertex < shape->nVertices(); vertex++) diff --git a/MapperGLCanvas.h b/MapperGLCanvas.h index ab388fd..e25d29e 100644 --- a/MapperGLCanvas.h +++ b/MapperGLCanvas.h @@ -47,7 +47,6 @@ class ShapeGraphicsItem; class MapperGLCanvas: public QGraphicsView { Q_OBJECT - public: /// Constructor. MapperGLCanvas(MainWindow* mainWindow, QWidget* parent = 0, const QGLWidget* shareWidget = 0, QGraphicsScene* scene = 0); @@ -55,11 +54,11 @@ public: /// Returns shape associated with mapping id. virtual bool isOutput() const = 0; - virtual MShape* getShapeFromMappingId(uid mappingId) const = 0; - virtual ShapeGraphicsItem* getShapeGraphicsItemFromMappingId(uid mappingId) const = 0; + virtual MShape::ptr getShapeFromMappingId(uid mappingId) const = 0; + virtual QSharedPointer getShapeGraphicsItemFromMappingId(uid mappingId) const = 0; - MShape* getCurrentShape(); - ShapeGraphicsItem* getCurrentShapeGraphicsItem(); + MShape::ptr getCurrentShape(); + QSharedPointer getCurrentShapeGraphicsItem(); // QSize sizeHint() const; // QSize minimumSizeHint() const; @@ -86,6 +85,9 @@ public: qreal getZoomFactor() const { return qBound(qPow(MM::ZOOM_FACTOR, _zoomLevel), MM::ZOOM_MIN, MM::ZOOM_MAX); } + /// This function needs to be called after a shape inside the canvas has been changed for appropriate signals to be activated. + void currentShapeWasChanged(); + protected: // void initializeGL(); // void resizeGL(int width, int height); @@ -125,10 +127,10 @@ private: QPoint _mousePressedPosition; // Start position of last object grabbed (in scene coordinates). - QPointF _grabbedObjectStartPosition; + QPointF _grabbedObjectStartScenePosition; // Mouse currently pressed inside a vertex. - bool _mousePressedOnVertex; + bool _vertexGrabbed; // Index of currently active vertex. int _activeVertex; @@ -158,6 +160,7 @@ public slots: void mousePressEvent(QMouseEvent *event); void mouseReleaseEvent(QMouseEvent *event); void mouseMoveEvent(QMouseEvent *event); + void keyPressEvent(QKeyEvent* event); // Event Filter bool eventFilter(QObject *target, QEvent *event); diff --git a/Mapping.h b/Mapping.h index ee0a3b0..7a6d568 100644 --- a/Mapping.h +++ b/Mapping.h @@ -22,7 +22,7 @@ #define MAPPING_H_ #include -#include + #include "Shape.h" #include "Paint.h" #include "UidAllocator.h" @@ -64,7 +64,7 @@ protected: Mapping(Paint::ptr paint, MShape::ptr shape, uid id=NULL_UID); public: - typedef std::tr1::shared_ptr ptr; + typedef QSharedPointer ptr; virtual ~Mapping(); @@ -118,7 +118,6 @@ public: float getOpacity() const { return _opacity * _paint->getOpacity(); } void setPaint(Paint::ptr p) { _paint = p; } - void removePaint() { if (_paint) delete _paint.get(); } }; /** diff --git a/MediaImpl.cpp b/MediaImpl.cpp index 0620dc6..6477c6a 100644 --- a/MediaImpl.cpp +++ b/MediaImpl.cpp @@ -242,9 +242,6 @@ _uri(uri) void MediaImpl::unloadMovie() { - // Free allocated resources. - freeResources(); - // Reset variables. _terminate = false; _seekEnabled = false; @@ -252,6 +249,9 @@ void MediaImpl::unloadMovie() // Un-ready. _setMovieReady(false); setPlayState(false); + + // Free allocated resources. + freeResources(); } void MediaImpl::freeResources() @@ -462,13 +462,7 @@ bool MediaImpl::loadMovie(QString filename) g_printerr ("Could not link shmsrc, deserializer and video queue.\n"); } } - else - { - if (! gst_element_link (_uridecodebin0, _queue0)) - { - g_printerr ("Could not link uridecodebin to video queue.\n"); - } - } + // link uridecodebin -> queue will be performed by callback if (! gst_element_link_many (_queue0, _videoconvert0, capsfilter0, videoscale0, _appsink0, NULL)) { @@ -487,12 +481,14 @@ bool MediaImpl::loadMovie(QString filename) // Process URI. QByteArray ba = filename.toLocal8Bit(); - gchar* uri = (gchar*) filename.toUtf8().constData(); + gchar *filename_tmp = g_strdup((gchar*) filename.toUtf8().constData()); + gchar* uri = NULL; // (gchar*) filename.toUtf8().constData(); if (! _isSharedMemorySource && ! gst_uri_is_valid(uri)) { // Try to convert filename to URI. GError* error = NULL; - uri = gst_filename_to_uri(uri, &error); + qDebug() << "Calling gst_filename_to_uri : " << uri; + uri = gst_filename_to_uri(filename_tmp, &error); if (error) { qDebug() << "Filename to URI error: " << error->message; @@ -502,6 +498,7 @@ bool MediaImpl::loadMovie(QString filename) return false; } } + g_free(filename_tmp); if (_isSharedMemorySource) { @@ -515,8 +512,8 @@ bool MediaImpl::loadMovie(QString filename) // Connect to the pad-added signal if (! _isSharedMemorySource) { - g_object_set (_uridecodebin0, "uri", uri, NULL); g_signal_connect (_uridecodebin0, "pad-added", G_CALLBACK (MediaImpl::gstPadAddedCallback), &_padHandlerData); + g_object_set (_uridecodebin0, "uri", uri, NULL); } else { @@ -525,6 +522,7 @@ bool MediaImpl::loadMovie(QString filename) g_object_set (_shmsrc0, "is-live", TRUE, NULL); _padHandlerData.videoIsConnected = true; } + g_free(uri); // Configure audio appsink. // TODO: change from mono to stereo diff --git a/MediaImpl.h b/MediaImpl.h index d7c8a6b..1e77083 100644 --- a/MediaImpl.h +++ b/MediaImpl.h @@ -37,7 +37,6 @@ #else #include #endif -#include /** * Private declaration of the video player. diff --git a/NEWS b/NEWS index 0b20402..1bc880d 100644 --- a/NEWS +++ b/NEWS @@ -1,6 +1,12 @@ Release notes for MapMap ======================== +2015-10-30 - MapMap 0.3.1 +------------------------- +* Fix #138: splash screen does not show when installed +* Fix #139: Stylesheet is not applied when the app is installed on Linux +* Fix #135: Video playback is broken + 2015-07-17 - MapMap 0.3.0 ------------------------- * Add zoom and scroll/drag in editor windows diff --git a/OscInterface.cpp b/OscInterface.cpp index 1ce270a..a4319a2 100644 --- a/OscInterface.cpp +++ b/OscInterface.cpp @@ -240,7 +240,7 @@ void OscInterface::applyOscCommand(MainWindow &main_window, QVariantList & comma } else if (path == "/mapmap/quit") { - main_window.quitMapMap(); + main_window.close(); } else { diff --git a/OscInterface.h b/OscInterface.h index 6aa0a7a..f708cd9 100644 --- a/OscInterface.h +++ b/OscInterface.h @@ -24,10 +24,10 @@ #define OSC_INTERFACE_H_ #ifdef HAVE_OSC -#include +#include + #include "concurrentqueue.h" #include "OscReceiver.h" -#include class MainWindow; // forward decl @@ -37,7 +37,7 @@ class MainWindow; // forward decl class OscInterface { public: - typedef std::tr1::shared_ptr ptr; + typedef QSharedPointer ptr; OscInterface( //MainWindow* owner, const std::string &listen_port); diff --git a/OutputGLWindow.cpp b/OutputGLWindow.cpp index 630789d..728487e 100644 --- a/OutputGLWindow.cpp +++ b/OutputGLWindow.cpp @@ -23,7 +23,7 @@ #include "MainWindow.h" -OutputGLWindow:: OutputGLWindow(const DestinationGLCanvas* canvas_) +OutputGLWindow:: OutputGLWindow(QWidget* parent, const DestinationGLCanvas* canvas_) : QDialog(parent) { resize(MainWindow::OUTPUT_WINDOW_MINIMUM_WIDTH, MainWindow::OUTPUT_WINDOW_MINIMUM_HEIGHT); diff --git a/OutputGLWindow.h b/OutputGLWindow.h index c646d9f..fc90fc8 100644 --- a/OutputGLWindow.h +++ b/OutputGLWindow.h @@ -34,7 +34,7 @@ class OutputGLWindow : public QDialog Q_OBJECT public: - OutputGLWindow(const DestinationGLCanvas* canvas_); + OutputGLWindow(QWidget* parent, const DestinationGLCanvas* canvas_); //OutputGLWindow(MainWindow* mainWindow, QWidget* parent = 0, const QGLWidget * shareWidget = 0); public slots: diff --git a/Paint.h b/Paint.h index c415e52..de5b8c3 100644 --- a/Paint.h +++ b/Paint.h @@ -34,8 +34,6 @@ #include #endif -#include - #include "UidAllocator.h" /** @@ -56,7 +54,7 @@ protected: Paint(uid id=NULL_UID); public: - typedef std::tr1::shared_ptr ptr; + typedef QSharedPointer ptr; virtual ~Paint(); diff --git a/PaintGui.cpp b/PaintGui.cpp index c884ca9..88fb6fe 100644 --- a/PaintGui.cpp +++ b/PaintGui.cpp @@ -73,7 +73,7 @@ void PaintGui::setValue(QtProperty* property, const QVariant& value) ColorGui::ColorGui(Paint::ptr paint) : PaintGui(paint) { - color = std::tr1::static_pointer_cast(paint); + color = qSharedPointerCast(paint); Q_CHECK_PTR(color); _colorItem = _variantManager->addProperty(QVariant::Color, @@ -99,7 +99,7 @@ TextureGui::TextureGui(Paint::ptr paint) : PaintGui(paint) { ImageGui::ImageGui(Paint::ptr paint) : TextureGui(paint) { - image = std::tr1::static_pointer_cast(paint); + image = qSharedPointerCast(paint); Q_CHECK_PTR(image); _imageFileItem = _variantManager->addProperty(VariantManager::filePathTypeId(), @@ -123,7 +123,7 @@ void ImageGui::setValue(QtProperty* property, const QVariant& value) { MediaGui::MediaGui(Paint::ptr paint) : TextureGui(paint) { - media = std::tr1::static_pointer_cast(paint); + media = qSharedPointerCast(paint); Q_CHECK_PTR(media); _mediaFileItem = _variantManager->addProperty(VariantManager::filePathTypeId(), diff --git a/PaintGui.h b/PaintGui.h index f2b648d..7cc4aaf 100644 --- a/PaintGui.h +++ b/PaintGui.h @@ -29,8 +29,6 @@ #include #endif -#include - #include "MM.h" #include "Paint.h" @@ -48,7 +46,7 @@ class PaintGui : public QObject { Q_OBJECT public: - typedef std::tr1::shared_ptr ptr; + typedef QSharedPointer ptr; public: // TODO: should be protected @@ -86,7 +84,7 @@ public slots: virtual void setValue(QtProperty* property, const QVariant& value); protected: - std::tr1::shared_ptr color; + QSharedPointer color; QtVariantProperty* _colorItem; }; @@ -112,7 +110,7 @@ public slots: virtual void setValue(QtProperty* property, const QVariant& value); protected: - std::tr1::shared_ptr image; + QSharedPointer image; QtVariantProperty* _imageFileItem; }; @@ -127,7 +125,7 @@ public slots: virtual void setValue(QtProperty* property, const QVariant& value); protected: - std::tr1::shared_ptr media; + QSharedPointer media; QtVariantProperty* _mediaFileItem; QtVariantProperty* _mediaRateItem; QtVariantProperty* _mediaVolumeItem; diff --git a/ProjectWriter.cpp b/ProjectWriter.cpp index b3a06ab..851e372 100644 --- a/ProjectWriter.cpp +++ b/ProjectWriter.cpp @@ -37,12 +37,12 @@ bool ProjectWriter::writeFile(QIODevice *device) _xml.writeStartElement("paints"); for (int i = 0; i < _manager->nPaints(); i++) - writeItem(_manager->getPaint(i).get()); + writeItem(_manager->getPaint(i).data()); _xml.writeEndElement(); _xml.writeStartElement("mappings"); for (int i = 0; i < _manager->nMappings(); i++) - writeItem(_manager->getMapping(i).get()); + writeItem(_manager->getMapping(i).data()); _xml.writeEndElement(); _xml.writeEndElement(); @@ -150,7 +150,7 @@ void ProjectWriter::writeItem(Mapping *item) _xml.writeAttribute("solo", QString::number((int) item->isSolo() ? 1 : 0)); _xml.writeAttribute("visible", QString::number((int) item->isVisible() ? 1 : 0)); - MShape *shape = item->getShape().get(); + MShape *shape = item->getShape().data(); _xml.writeStartElement("destination"); _xml.writeAttribute("shape", shape->getType()); writeShapeVertices(shape); @@ -159,7 +159,7 @@ void ProjectWriter::writeItem(Mapping *item) if (item->getType().endsWith("_texture")) { TextureMapping *tex = (TextureMapping *) item; - shape = tex->getInputShape().get(); + shape = tex->getInputShape().data(); _xml.writeStartElement("source"); _xml.writeAttribute("shape", shape->getType()); diff --git a/Shape.cpp b/Shape.cpp index 70a0431..1dfc06c 100644 --- a/Shape.cpp +++ b/Shape.cpp @@ -19,14 +19,23 @@ #include "Shape.h" -void MShape::translate(int x, int y) +void MShape::copyFrom(const MShape& shape) { - for (QVector::iterator it = vertices.begin() ; - it != vertices.end(); ++it) - { - it->setX(it->x() + x); - it->setY(it->y() + y); - } + // Just copy vertices. + vertices = shape.vertices; +} + +MShape* MShape::clone() const { + MShape* copyShape = _create(); + copyShape->copyFrom(*this); + return copyShape; +} + +void MShape::translate(const QPointF& offset) +{ + // We can feel free to translate every vertex without check by default. + for (QVector::iterator it = vertices.begin(); it != vertices.end(); ++it) + *it += offset; } void Polygon::setVertex(int i, const QPointF& v) @@ -402,8 +411,11 @@ void Mesh::removeColumn(int columnId) vertices = newVertices; _vertices2d = newVertices2d; - // Increment number of columns. + // Decrement number of columns. _nColumns--; + + // Reorder. + _reorderVertices(); } void Mesh::removeRow(int rowId) @@ -459,8 +471,11 @@ void Mesh::removeRow(int rowId) vertices = newVertices; _vertices2d = newVertices2d; - // Increment number of columns. + // Decrement number of rows. _nRows--; + + // Reorder. + _reorderVertices(); } diff --git a/Shape.h b/Shape.h index f1fe591..e1d7343 100644 --- a/Shape.h +++ b/Shape.h @@ -20,7 +20,6 @@ #ifndef SHAPE_H_ #define SHAPE_H_ -#include #include #include @@ -45,7 +44,7 @@ class MShape { public: - typedef std::tr1::shared_ptr ptr; + typedef QSharedPointer ptr; MShape() {} MShape(QVector vertices_) : @@ -85,7 +84,11 @@ public: virtual bool includesPoint(const QPointF& p) = 0; /// Translate all vertices of shape by the vector (x,y). - virtual void translate(int x, int y); + virtual void translate(const QPointF& offset); + + virtual void copyFrom(const MShape& shape); + + virtual MShape* clone() const; protected: QVector vertices; @@ -100,6 +103,8 @@ protected: vertices[i] = v; } + /// Returns a new MShape (using default constructor). + virtual MShape* _create() const = 0; }; /** @@ -148,6 +153,10 @@ public: virtual ~Quad() {} virtual QString getType() const { return "quad"; } + +protected: + /// Returns a new MShape (using default constructor). + virtual MShape* _create() const { return new Quad(); } }; /** @@ -165,6 +174,10 @@ public: } virtual ~Triangle() {} virtual QString getType() const { return "triangle"; } + +protected: + /// Returns a new MShape (using default constructor). + virtual MShape* _create() const { return new Triangle(); } }; class Mesh : public Quad @@ -246,6 +259,9 @@ protected: * 8----9---10----11 */ void _reorderVertices(); + + /// Returns a new MShape (using default constructor). + virtual MShape* _create() const { return new Mesh(); } }; class Ellipse : public MShape { @@ -379,6 +395,10 @@ public: // Override the parent, checking to make sure the vertices are displaced correctly. virtual void setVertex(int i, const QPointF& v); +protected: + /// Returns a new MShape (using default constructor). + virtual MShape* _create() const { return new Ellipse(); } + //protected: // virtual void _vertexChanged(int i, Point* p=NULL) { // // Get horizontal and vertical axis length. diff --git a/SourceGLCanvas.cpp b/SourceGLCanvas.cpp index 7236b7f..5af3f0a 100644 --- a/SourceGLCanvas.cpp +++ b/SourceGLCanvas.cpp @@ -28,23 +28,23 @@ SourceGLCanvas::SourceGLCanvas(MainWindow* mainWindow, QWidget* parent) { } -MShape* SourceGLCanvas::getShapeFromMappingId(uid mappingId) const +MShape::ptr SourceGLCanvas::getShapeFromMappingId(uid mappingId) const { if (mappingId == NULL_UID) - return NULL; + return MShape::ptr(); else { Mapping::ptr mapping = getMainWindow()->getMappingManager().getMappingById(mappingId); Q_CHECK_PTR(mapping); - return mapping->getInputShape().get(); + return mapping->getInputShape(); } } -ShapeGraphicsItem* SourceGLCanvas::getShapeGraphicsItemFromMappingId(uid mappingId) const +QSharedPointer SourceGLCanvas::getShapeGraphicsItemFromMappingId(uid mappingId) const { if (mappingId == NULL_UID) - return NULL; + return QSharedPointer(); else { diff --git a/SourceGLCanvas.h b/SourceGLCanvas.h index 09c581c..c0f0119 100644 --- a/SourceGLCanvas.h +++ b/SourceGLCanvas.h @@ -36,8 +36,8 @@ public: virtual ~SourceGLCanvas() {} virtual bool isOutput() const { return false; } - virtual MShape* getShapeFromMappingId(uid mappingId) const; - virtual ShapeGraphicsItem* getShapeGraphicsItemFromMappingId(uid mappingId) const; + virtual MShape::ptr getShapeFromMappingId(uid mappingId) const; + virtual QSharedPointer getShapeGraphicsItemFromMappingId(uid mappingId) const; private: // virtual void doDraw(QPainter* painter); diff --git a/TODO b/TODO index e140000..8e7ef91 100644 --- a/TODO +++ b/TODO @@ -92,3 +92,59 @@ You should make sure to block all incoming messages on that port if you don't wa /mapmap/output/size ,ii /mapmap/output/position ,ii + +Roadmap (to do) +--------------- +* Change default OSC port. (currently 12345) +* Allow to change the default OSC port via the GUI. +* Reorder layers. +* MIDI support. +* Art-Net support. +* Make output window fullscreen. +* Port to Microsoft Windows 8. +* Port to iOS. +* Port to Android. +* Support multiple output windows. +* Chroma-key effect. +* Luma-key effect. +* More control via OSC. +* Live video capture. (camera) +* Syphon support on Apple OS X. +* Shared memory support on all operating systems. +* Transition between video clips. +* Anti-aliasing. +* Multiple cues for video files playback in a project. +* Multiple layouts in a project. +* Reorder mappings. +* Sample OSC clients: Python, bash, Pure Data, Processing. +* Allow to start the software with no GUI. +* Support OSC via TCP. +* Implement a JSON REST interface. +* Bézier curves. +* Pause and resume media files. +* Support RTSP URI. +* Support audio. + + + + + + +Fiche technique +=========== + + + + + + + + + + + + + + + + diff --git a/VERSION.txt b/VERSION.txt index 0d91a54..9e11b32 100644 --- a/VERSION.txt +++ b/VERSION.txt @@ -1 +1 @@ -0.3.0 +0.3.1 diff --git a/docs/datasheet.rst b/docs/datasheet.rst index b6cf180..8830420 100644 --- a/docs/datasheet.rst +++ b/docs/datasheet.rst @@ -3,15 +3,18 @@ Datasheet User Interface -------------- -* Create and destroy an unlimited amount of video texture sources paints. Textures can be video or image files. +MapMap allows its users to: + +* Create and destroy an unlimited amount of texture sources paints. Textures can be video or image files. * Create and destroy an unlimited amount of mappings. Each mapping is a shape on which a source paint is drawn. * Color paints can be used as masks. * Move layers. * Save the project to a human-readable XML file. * Load the project from a human-readable XML file. -* OpenSoundControl (OSC) support. * Turn any quad into a mesh. -* Properties inspector. +* Inspect properties. + +MapMap doesn't currently play sound from video files. Supported codecs and file formats --------------------------------- @@ -32,21 +35,21 @@ Video containers Recommended video codecs ~~~~~~~~~~~~~~~~~~~~~~~~ * Motion-JPEG. -* Vorbis. +* OGG Theora. * MPEG4. * H.264. Supported Operating Systems --------------------------- -* Apple OS X 10.9.2 and up. +* Apple OS X 10.9. (it doesn't currently work on OS X 10.10) * Ubuntu GNU/Linux 12.04 and up. * Fedora GNU/Linux 19 and up. Recommended hardware configuration ---------------------------------- -* Dual-core 1.0 GHz processor, or better. +* Dual-core 1.0 GHz processor AMD64, or better. * At least 1 Gb of RAM. -* Video card with 3D acceleration, OpenGL 2.0 support and at least 64 Mb or VRAM. +* Video card with 3D acceleration, OpenGL 2.0 support and at least 512 Mb of VRAM. Using the OSC interface ----------------------- @@ -54,58 +57,5 @@ You can control MapMap via a set of OSC messages. OpenSoundControl allows users MapMap listens for incoming OSC messages on the default port 12345. -Roadmap (to do) ---------------- -* Change default OSC port. (currently 12345) -* Allow to change the default OSC port via the GUI. -* Reorder layers. -* MIDI support. -* Art-Net support. -* Make output window fullscreen. -* Port to Microsoft Windows 8. -* Port to iOS. -* Port to Android. -* Support multiple output windows. -* Chroma-key effect. -* Luma-key effect. -* More control via OSC. -* Live video capture. (camera) -* Syphon support on Apple OS X. -* Shared memory support on all operating systems. -* Transition between video clips. -* Anti-aliasing. -* Multiple cues for video files playback in a project. -* Multiple layouts in a project. -* Reorder mappings. -* Sample OSC clients: Python, bash, Pure Data, Processing. -* Allow to start the software with no GUI. -* Support OSC via TCP. -* Implement a JSON REST interface. -* Bézier curves. -* Pause and resume media files. -* Support RTSP URI. -* Support audio. - - - - - - -Fiche technique -=========== - - - - - - - - - - - - - - - +There is a Processing bridge to MapMap as well as a Toonloop to MapMap. diff --git a/main.cpp b/main.cpp index ae25309..fe8eeef 100644 --- a/main.cpp +++ b/main.cpp @@ -18,9 +18,9 @@ static void set_env_vars_if_needed() { #ifdef __MACOSX_CORE__ - std::cout << "OS X detected. Set environment for GStreamer-SDK support." << std::endl; + std::cout << "OS X detected. Set environment for GStreamer support." << std::endl; if (0 == setenv("GST_PLUGIN_PATH", "/Library/Frameworks/GStreamer.framework/Libraries", 1)) - std::cout << " * GST_PLUGIN_PATH=Library/Frameworks/GStreamer.framework/Libraries" << std::endl; + std::cout << " * GST_PLUGIN_PATH=/Library/Frameworks/GStreamer.framework/Libraries" << std::endl; if (0 == setenv("GST_DEBUG", "2", 1)) std::cout << " * GST_DEBUG=2" << std::endl; //setenv("LANG", "C", 1); @@ -92,10 +92,13 @@ int main(int argc, char *argv[]) #endif // USING_QT_5 if (! QGLFormat::hasOpenGL()) + { qFatal("This system has no OpenGL support."); + return 1; + } // Create splash screen. - QPixmap pixmap("splash.png"); + QPixmap pixmap(":/mapmap-splash"); QSplashScreen splash(pixmap); // Show splash. @@ -106,11 +109,6 @@ int main(int argc, char *argv[]) bool FORCE_FRENCH_LANG = false; // set_language_to_french(app); - if (FORCE_FRENCH_LANG) // XXX FIXME this if seems wrong - { - std::cerr << "This system has no OpenGL support" << std::endl; - return 1; - } // Let splash for at least one second. I::sleep(1); @@ -123,7 +121,7 @@ int main(int argc, char *argv[]) app.setFont(QFont(":/base-font", 10, QFont::Bold)); // Load stylesheet. - QFile stylesheet("mapmap.qss"); + QFile stylesheet(":/stylesheet"); stylesheet.open(QFile::ReadOnly); app.setStyleSheet(QLatin1String(stylesheet.readAll())); diff --git a/mapmap.pro b/mapmap.pro index 33c07e5..ae044e9 100644 --- a/mapmap.pro +++ b/mapmap.pro @@ -1,6 +1,6 @@ CONFIG += qt debug TEMPLATE = app -VERSION = 0.3.0 +VERSION = 0.3.1 TARGET = mapmap QT += gui opengl xml greaterThan(QT_MAJOR_VERSION, 4): QT += widgets @@ -72,10 +72,11 @@ QMAKE_EXTRA_TARGETS += docs unix:!mac { DEFINES += UNIX CONFIG += link_pkgconfig + INCLUDE_PATH += PKGCONFIG += \ gstreamer-1.0 gstreamer-base-1.0 gstreamer-app-1.0 \ liblo \ - gl x11 + gl x11 QMAKE_CXXFLAGS += -Wno-unused-result -Wfatal-errors QMAKE_CXXFLAGS += -DHAVE_OSC mapmapfile.files = mapmap @@ -121,6 +122,14 @@ mac { # This tells qmake not to put the executable inside a bundle. # just for reference. Do not uncomment. # CONFIG-=app_bundle + + # For OSC support: (if pkg-config was installed) + # CONFIG += link_pkgconfig + # PKGCONFIG += lo + + LIBS += -L/usr/local/lib -llo + INCLUDEPATH += /usr/local/include + QMAKE_CXXFLAGS += -DHAVE_OSC } # Windows-specific: diff --git a/mapmap.qrc b/mapmap.qrc index 6f2ad09..561c045 100644 --- a/mapmap.qrc +++ b/mapmap.qrc @@ -39,12 +39,15 @@ resources/images/logo/logomapmap.png resources/images/logo/logo_m_big_mapmap.png + resources/images/logo/splash.png resources/fonts/HelveticaNeueLTPro-Bd.otf resources/fonts/HelveticaNeueLTPro-Bd.otf resources/images/test-signal/test-signal.svg + + resources/qss/mapmap.qss diff --git a/splash.png b/resources/images/logo/splash.png similarity index 100% rename from splash.png rename to resources/images/logo/splash.png diff --git a/mapmap.qss b/resources/qss/mapmap.qss similarity index 100% rename from mapmap.qss rename to resources/qss/mapmap.qss