From 1aace8a57809d081422ca295695e4609f6e15ac6 Mon Sep 17 00:00:00 2001 From: Vasilis Liaskovitis Date: Thu, 22 May 2014 11:30:25 +0200 Subject: [PATCH] Change the uri of existing media or color paint with double-click When double-clicking a paint QListWidgetItem, the uri of that paint can be altered. A new signal is sent to ColorMapper and TextureMapper objects so that they can update heir color and texture paints respectively. Mappings of the old paint are transferred to the new paint. TODO: the active mapping may be lost in some cases, needs some more testing. --- MainWindow.cpp | 98 +++++++++++++++++++++++++++++++++++----------- MainWindow.h | 18 +++++---- Mapper.cpp | 14 +++++++ Mapper.h | 7 ++++ MapperGLCanvas.cpp | 1 - Mapping.h | 2 + MappingManager.cpp | 19 +++++++++ MappingManager.h | 1 + ProjectReader.cpp | 5 ++- 9 files changed, 133 insertions(+), 32 deletions(-) diff --git a/MainWindow.cpp b/MainWindow.cpp index e38d9df..f1b7151 100644 --- a/MainWindow.cpp +++ b/MainWindow.cpp @@ -158,6 +158,37 @@ void MainWindow::handleItemSelected(QListWidgetItem* item) currentSelectedItem = item; } +void MainWindow::handleItemDoubleClicked(QListWidgetItem* item) +{ + // Change currently selected item. + Paint::ptr paint = mappingManager->getPaintById(getItemId(*item)); + uid curMappingId = getCurrentMappingId(); + removeCurrentMapping(); + removeCurrentPaint(); + + //qDebug() << "DOUBLE CLICK! " << endl; + videoTimer->stop(); + if (paint->getType() == "media") { + QString fileName = QFileDialog::getOpenFileName(this, + tr("Import media source file"), "."); + // Restart video playback. XXX Hack + videoTimer->start(); + if (!fileName.isEmpty()) + importMediaFile(fileName, paint); + } + else if (paint->getType() == "color") { + // Pop-up color-choosing dialog to choose color paint. + QColor initialColor; + QColor color = QColorDialog::getColor(initialColor, this); + videoTimer->start(); + if (color.isValid()) + addColorPaint(color, paint); + } + + if (curMappingId != NULL_UID) + setCurrentMapping(curMappingId); +} + void MainWindow::closeEvent(QCloseEvent *event) { // Stop video playback to avoid lags. XXX Hack @@ -272,7 +303,7 @@ void MainWindow::import() videoTimer->start(); if (!fileName.isEmpty()) - importMediaFile(fileName); + importMediaFile(fileName, std::tr1::shared_ptr(static_cast(0))); } void MainWindow::addColor() @@ -284,7 +315,7 @@ void MainWindow::addColor() QColor initialColor; QColor color = QColorDialog::getColor(initialColor, this); if (color.isValid()) - addColorPaint(color); + addColorPaint(color, std::tr1::shared_ptr(static_cast(0))); // Restart video playback. XXX Hack videoTimer->start(); @@ -297,7 +328,7 @@ void MainWindow::addMesh() return; // Retrieve current paint (as texture). - Paint::ptr paint = getMappingManager().getPaint(getCurrentPaintId()); + Paint::ptr paint = getMappingManager().getPaintById(getCurrentPaintId()); Q_CHECK_PTR(paint); // Create input and output quads. @@ -330,7 +361,7 @@ void MainWindow::addTriangle() return; // Retrieve current paint (as texture). - Paint::ptr paint = getMappingManager().getPaint(getCurrentPaintId()); + Paint::ptr paint = getMappingManager().getPaintById(getCurrentPaintId()); Q_CHECK_PTR(paint); // Create input and output quads. @@ -363,7 +394,7 @@ void MainWindow::addEllipse() return; // Retrieve current paint (as texture). - Paint::ptr paint = getMappingManager().getPaint(getCurrentPaintId()); + Paint::ptr paint = getMappingManager().getPaintById(getCurrentPaintId()); Q_CHECK_PTR(paint); // Create input and output ellipses. @@ -442,7 +473,7 @@ void MainWindow::deleteItem() else if (currentSelectedItem->listWidget() == paintList) { // Delete paint. - deletePaint( getItemId(*paintList->currentItem()) ); + deletePaint( getItemId(*paintList->currentItem()), false ); //currentSelectedItem = NULL; } else @@ -489,7 +520,7 @@ bool MainWindow::clearProject() return true; } -uid MainWindow::createMediaPaint(uid paintId, QString uri, float x, float y) +uid MainWindow::createMediaPaint(uid paintId, QString uri, float x, float y, Paint::ptr oldPaint) { // Cannot create image with already existing id. if (Paint::getUidAllocator().exists(paintId)) @@ -509,14 +540,20 @@ uid MainWindow::createMediaPaint(uid paintId, QString uri, float x, float y) // Add paint to model and return its uid. uid id = mappingManager->addPaint(paint); + // If replacing existing paint, extra work needs to be done + if (oldPaint.get()) { + mappingManager->replacePaintMappings(oldPaint, paint); + deletePaint(oldPaint->getId(), true); + emit paintChanged(); + } + // Add paint widget item. addPaintItem(id, QIcon(uri), strippedName(uri)); - return id; } } -uid MainWindow::createColorPaint(uid paintId, QColor color) +uid MainWindow::createColorPaint(uid paintId, QColor color, Paint::ptr oldPaint) { // Cannot create image with already existing id. if (Paint::getUidAllocator().exists(paintId)) @@ -532,6 +569,13 @@ uid MainWindow::createColorPaint(uid paintId, QColor color) // Add paint to model and return its uid. uid id = mappingManager->addPaint(paint); + // If replacing existing paint, extra work needs to be done + if (oldPaint.get()) { + mappingManager->replacePaintMappings(oldPaint, paint); + deletePaint(oldPaint->getId(), true); + emit paintChanged(); + } + // Create a small icon with the color. QPixmap pixmap(100,100); pixmap.fill(color); @@ -733,18 +777,22 @@ void MainWindow::deleteMapping(uid mappingId) } /// Deletes/removes a paint and all associated mappigns. -void MainWindow::deletePaint(uid paintId) +void MainWindow::deletePaint(uid paintId, bool replace) { // Cannot delete unexisting paint. if (Paint::getUidAllocator().exists(paintId)) { - int r = QMessageBox::warning(this, tr("MapMap"), - tr("Remove this paint and all its associated mappings?"), - QMessageBox::Ok | QMessageBox::Cancel); - if (r == QMessageBox::Ok) - { - removePaintItem(paintId); + if (replace == false) { + int r = QMessageBox::warning(this, tr("MapMap"), + tr("Remove this paint and all its associated mappings?"), + QMessageBox::Ok | QMessageBox::Cancel); + if (r == QMessageBox::Ok) + { + removePaintItem(paintId); + } } + else + removePaintItem(paintId); } } @@ -1208,7 +1256,7 @@ void MainWindow::setCurrentFile(const QString &fileName) // { // } -bool MainWindow::importMediaFile(const QString &fileName) +bool MainWindow::importMediaFile(const QString &fileName, Paint::ptr oldPaint) { QFile file(fileName); if (!file.open(QIODevice::ReadOnly)) { @@ -1222,7 +1270,7 @@ bool MainWindow::importMediaFile(const QString &fileName) QApplication::setOverrideCursor(Qt::WaitCursor); // Add media file to model. - uint mediaId = createMediaPaint(NULL_UID, fileName, 0, 0); + uint mediaId = createMediaPaint(NULL_UID, fileName, 0, 0, oldPaint); // Initialize position (center). std::tr1::shared_ptr media = std::tr1::static_pointer_cast(mappingManager->getPaintById(mediaId)); @@ -1238,12 +1286,12 @@ bool MainWindow::importMediaFile(const QString &fileName) return true; } -bool MainWindow::addColorPaint(const QColor& color) +bool MainWindow::addColorPaint(const QColor& color, Paint::ptr oldPaint) { QApplication::setOverrideCursor(Qt::WaitCursor); // Add color to model. - uint colorId = createColorPaint(NULL_UID, color); + uint colorId = createColorPaint(NULL_UID, color, oldPaint); // Initialize position (center). std::tr1::shared_ptr colorPaint = std::tr1::static_pointer_cast(mappingManager->getPaintById(colorId)); @@ -1354,6 +1402,9 @@ void MainWindow::addMappingItem(uid mappingId) connect(destinationCanvas, SIGNAL(shapeChanged(Shape*)), mapper.get(), SLOT(updateShape(Shape*))); + + connect(this, SIGNAL(paintChanged()), + mapper.get(), SLOT(updatePaint())); // Add item to layerList widget. QListWidgetItem* item = new QListWidgetItem(label); @@ -1407,9 +1458,9 @@ void MainWindow::removePaintItem(uid paintId) // Remove all mappings associated with paint. QMap paintMappings = mappingManager->getPaintMappings(paint); for (QMap::const_iterator it = paintMappings.constBegin(); - it != paintMappings.constEnd(); ++it) + it != paintMappings.constEnd(); ++it) { removeMappingItem(it.key()); - + } // Remove paint from model. Q_ASSERT( mappingManager->removePaint(paintId) ); @@ -1461,6 +1512,9 @@ void MainWindow::connectProjectWidgets() connect(paintList, SIGNAL(itemPressed(QListWidgetItem*)), this, SLOT(handleItemSelected(QListWidgetItem*))); + connect(paintList, SIGNAL(itemDoubleClicked(QListWidgetItem*)), + this, SLOT(handleItemDoubleClicked(QListWidgetItem*))); + connect(paintList, SIGNAL(itemActivated(QListWidgetItem*)), this, SLOT(handleItemSelected(QListWidgetItem*))); diff --git a/MainWindow.h b/MainWindow.h index affa5df..0e81e98 100644 --- a/MainWindow.h +++ b/MainWindow.h @@ -67,6 +67,9 @@ protected: // Events /////////////////////////////////////////////////////////////////////////////////////////////////// void closeEvent(QCloseEvent *event); +signals: + void paintChanged(); + // Slots //////////////////////////////////////////////////////////////////////////////////////////////////// private slots: @@ -85,6 +88,7 @@ private slots: // Widget callbacks. void handlePaintItemSelectionChanged(); + void handleItemDoubleClicked(QListWidgetItem* item); void handleMappingItemSelectionChanged(); void handleMappingItemChanged(QListWidgetItem* item); void handleMappingIndexesMoved(); @@ -104,11 +108,11 @@ public slots: /// Clears all mappings and paints. bool clearProject(); - /// Create an image paint. - uid createMediaPaint(uid paintId, QString uri, float x, float y); + /// Create or replace an image paint. + uid createMediaPaint(uid paintId, QString uri, float x, float y, Paint::ptr oldPaint); - /// Create a color paint. - uid createColorPaint(uid paintId, QColor color); + /// Create or replace a color paint. + uid createColorPaint(uid paintId, QColor color, Paint::ptr oldPaint); /// Creates a textured mesh. uid createMeshTextureMapping(uid mappingId, @@ -145,7 +149,7 @@ public slots: void deleteMapping(uid mappingId); /// Deletes/removes a paint and all associated mappigns. - void deletePaint(uid paintId); + void deletePaint(uid paintId, bool replace); /// Updates all canvases. void updateCanvases(); @@ -178,8 +182,8 @@ public: bool loadFile(const QString &fileName); bool saveFile(const QString &fileName); void setCurrentFile(const QString &fileName); - bool importMediaFile(const QString &fileName); - bool addColorPaint(const QColor& color); + bool importMediaFile(const QString &fileName, Paint::ptr oldPaint); + bool addColorPaint(const QColor& color, Paint::ptr oldPaint); void addMappingItem(uid mappingId); void removeMappingItem(uid mappingId); void addPaintItem(uid paintId, const QIcon& icon, const QString& name); diff --git a/Mapper.cpp b/Mapper.cpp index e8bd170..ef89c21 100644 --- a/Mapper.cpp +++ b/Mapper.cpp @@ -84,6 +84,13 @@ TextureMapper::TextureMapper(std::tr1::shared_ptr mapping) _topItem->insertSubProperty(_inputItem, 0); // insert before output item } +void TextureMapper::updatePaint() +{ + texture.reset(); + texture = std::tr1::static_pointer_cast(textureMapping->getPaint()); + Q_CHECK_PTR(texture); +} + void Mapper::setValue(QtProperty* property, const QVariant& value) { std::map >::iterator it = _propertyToVertex.find(property); @@ -139,6 +146,13 @@ ColorMapper::ColorMapper(Mapping::ptr mapping) Q_CHECK_PTR(color); } +void ColorMapper::updatePaint() +{ + color.reset(); + color = std::tr1::static_pointer_cast(_mapping->getPaint()); + Q_CHECK_PTR(color); +} + void PolygonColorMapper::draw(QPainter* painter) { painter->setRenderHint(QPainter::Antialiasing); diff --git a/Mapper.h b/Mapper.h index 167a2bd..7bc6f1b 100644 --- a/Mapper.h +++ b/Mapper.h @@ -85,6 +85,9 @@ public slots: { Q_UNUSED(shape); } + virtual void updatePaint() + { + } signals: void valueChanged(); @@ -112,6 +115,9 @@ class ColorMapper : public Mapper { Q_OBJECT +public slots: + virtual void updatePaint(); + protected: ColorMapper(Mapping::ptr mapping); virtual ~ColorMapper() {} @@ -181,6 +187,7 @@ public: public slots: virtual void updateShape(Shape* shape); + virtual void updatePaint(); protected: virtual void _doDraw(QPainter* painter) = 0; diff --git a/MapperGLCanvas.cpp b/MapperGLCanvas.cpp index 2b366e7..c51f409 100644 --- a/MapperGLCanvas.cpp +++ b/MapperGLCanvas.cpp @@ -166,7 +166,6 @@ void MapperGLCanvas::mouseMoveEvent(QMouseEvent* event) else _shapefirstgrab = false; } - // Update previous mouse position. prevMousePosition.setX( event->x() ); prevMousePosition.setY( event->y() ); diff --git a/Mapping.h b/Mapping.h index 4421c1a..12db844 100644 --- a/Mapping.h +++ b/Mapping.h @@ -94,6 +94,8 @@ public: Q_ASSERT(0.0f <= opacity && opacity <= 1.0f); _opacity = opacity; } + void setPaint(Paint::ptr p) { _paint = p; } + void removePaint() { if (_paint) delete _paint.get(); } void toggleLocked() { _isLocked = !_isLocked; } void toggleSolo() { _isSolo = !_isSolo; } diff --git a/MappingManager.cpp b/MappingManager.cpp index c0b18c1..0879848 100644 --- a/MappingManager.cpp +++ b/MappingManager.cpp @@ -71,6 +71,25 @@ bool MappingManager::removePaint(uid paintId) return true; } + + + return false; +} + +bool MappingManager::replacePaintMappings(Paint::ptr oldpaint, Paint::ptr newpaint) +{ + // Make sure the paint to which this paint refers to exists in the manager. + if (oldpaint && newpaint) + { + QMap paintMappings = getPaintMappings(oldpaint); + for (QMap::const_iterator it = paintMappings.constBegin(); + it != paintMappings.constEnd(); ++it) { + Mapping::ptr mapping = it.value(); + mapping->setPaint(newpaint); + } + return true; + } + return false; } diff --git a/MappingManager.h b/MappingManager.h index 7d20595..95eb8a9 100644 --- a/MappingManager.h +++ b/MappingManager.h @@ -50,6 +50,7 @@ public: uid addPaint(Paint::ptr paint); bool removePaint(uid paintId); + bool replacePaintMappings(Paint::ptr oldpaint, Paint::ptr newpaint); int nPaints() const { return paintVector.size(); } Paint::ptr getPaint(int i) { return paintVector[i]; } Paint::ptr getPaintById(uid id) { return paintMap[id]; } diff --git a/ProjectReader.cpp b/ProjectReader.cpp index cd5d982..5a8ce40 100644 --- a/ProjectReader.cpp +++ b/ProjectReader.cpp @@ -96,7 +96,8 @@ void ProjectReader::parsePaint(const QDomElement& paint) QString x = paint.firstChildElement("x").text(); QString y = paint.firstChildElement("y").text(); - uid id = _window->createMediaPaint(paintAttrId.toInt(), uri, x.toFloat(), y.toFloat()); + uid id = _window->createMediaPaint(paintAttrId.toInt(), uri, x.toFloat(), y.toFloat(), + std::tr1::shared_ptr(static_cast(0))); if (id == NULL_UID) _xml.raiseError(QObject::tr("Cannot create media with uri %1.").arg(uri)); } @@ -105,7 +106,7 @@ void ProjectReader::parsePaint(const QDomElement& paint) QString rgb = paint.firstChildElement("rgb").text(); QColor color(rgb); - uid id = _window->createColorPaint(paintAttrId.toInt(), color); + uid id = _window->createColorPaint(paintAttrId.toInt(), color, std::tr1::shared_ptr(static_cast(0))); if (id == NULL_UID) _xml.raiseError(QObject::tr("Cannot create color with RGB hex code %1.").arg(rgb));