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));