diff --git a/MM.cpp b/MM.cpp index caa99ef..020c8b7 100644 --- a/MM.cpp +++ b/MM.cpp @@ -33,8 +33,11 @@ const QColor MM::BLUE_GRAY("#323541"); const QColor MM::DARK_GRAY("#272a36"); const QColor MM::CONTROL_COLOR(WHITE); +const QColor MM::CONTROL_LOCKED_COLOR("#FF0000"); const QBrush MM::VERTEX_BACKGROUND(QColor(CONTROL_COLOR.red(), CONTROL_COLOR.green(), CONTROL_COLOR.blue(), 63)); const QBrush MM::VERTEX_SELECTED_BACKGROUND(QColor(CONTROL_COLOR.red(), CONTROL_COLOR.green(), CONTROL_COLOR.blue(), 127)); +//const QBrush MM::VERTEX_LOCKED_BACKGROUND(QColor(CONTROL_LOCKED_COLOR.red(), CONTROL_LOCKED_COLOR.green(), CONTROL_LOCKED_COLOR.blue(), 63)); +const QBrush MM::VERTEX_LOCKED_BACKGROUND(CONTROL_LOCKED_COLOR); const qreal MM::SHAPE_STROKE_WIDTH = 1.5; const qreal MM::SHAPE_INNER_STROKE_WIDTH = 0.5; @@ -43,6 +46,7 @@ const QPen MM::SHAPE_INNER_STROKE(QBrush(CONTROL_COLOR), SHAPE_INNER_STROKE_WIDT const qreal MM::VERTEX_STICK_RADIUS = 10; const qreal MM::VERTEX_SELECT_RADIUS = 10; +const qreal MM::VERTEX_LOCKED_RADIUS = 6; const qreal MM::VERTEX_SELECT_STROKE_WIDTH = 1; // Time. diff --git a/MM.h b/MM.h index d6bf1da..0816a9d 100644 --- a/MM.h +++ b/MM.h @@ -56,8 +56,10 @@ public: static const QColor DARK_GRAY; static const QColor CONTROL_COLOR; + static const QColor CONTROL_LOCKED_COLOR; static const QBrush VERTEX_BACKGROUND; static const QBrush VERTEX_SELECTED_BACKGROUND; + static const QBrush VERTEX_LOCKED_BACKGROUND; static const qreal SHAPE_STROKE_WIDTH; static const qreal SHAPE_INNER_STROKE_WIDTH; @@ -67,6 +69,7 @@ public: // Control. static const qreal VERTEX_STICK_RADIUS; static const qreal VERTEX_SELECT_RADIUS; + static const qreal VERTEX_LOCKED_RADIUS; static const qreal VERTEX_SELECT_STROKE_WIDTH; // Time. diff --git a/MainWindow.cpp b/MainWindow.cpp index e0b2aad..459e78b 100644 --- a/MainWindow.cpp +++ b/MainWindow.cpp @@ -764,6 +764,21 @@ void MainWindow::renameMappingItem() contentTab->setCurrentWidget(mappingSplitter); } +void MainWindow::setMappingitemLocked(bool locked) +{ + setMappingLocked(getItemId(*mappingList->currentItem()), locked); +} + +void MainWindow::setMappingitemVisible(bool visible) +{ + setMappingVisible(getItemId(*mappingList->currentItem()), !visible); +} + +void MainWindow::setMappingItemSolo(bool solo) +{ + setMappingSolo(getItemId(*mappingList->currentItem()), solo); +} + void MainWindow::renameMapping(uid mappingId, const QString &name) { Mapping::ptr mapping = mappingManager->getMappingById(mappingId); @@ -1135,14 +1150,27 @@ void MainWindow::setMappingVisible(uid mappingId, bool visible) void MainWindow::setMappingSolo(uid mappingId, bool solo) { - Q_UNUSED(mappingId); - Q_UNUSED(solo); + Mapping::ptr mapping = mappingManager->getMappingById(mappingId); + if (!mapping.isNull()) { + // Turn this mapping into solo mode + mapping->setSolo(solo); + // Update canvases + updateCanvases(); + } } void MainWindow::setMappingLocked(uid mappingId, bool locked) { - Q_UNUSED(mappingId); - Q_UNUSED(locked); + Mapping::ptr mapping = mappingManager->getMappingById(mappingId); + + if (!mapping.isNull()) { + // Lock position of mapping + mapping->setLocked(locked); + // Lock shape too. + mapping->getShape()->setLocked(locked); + // Update canvases + updateCanvases(); + } } void MainWindow::deleteMapping(uid mappingId) @@ -1482,6 +1510,33 @@ void MainWindow::createActions() addAction(renameMappingAction); connect(renameMappingAction, SIGNAL(triggered()), this, SLOT(renameMappingItem())); + // Lock mapping. + mappingLockedAction = new QAction(tr("Lock mapping"), this); + mappingLockedAction->setToolTip(tr("Lock mapping item")); + mappingLockedAction->setIconVisibleInMenu(false); + mappingLockedAction->setCheckable(true); + mappingLockedAction->setChecked(false); + addAction(mappingLockedAction); + connect(mappingLockedAction, SIGNAL(triggered(bool)), this, SLOT(setMappingitemLocked(bool))); + + // Mute mapping. + mappingMuteAction = new QAction(tr("Mute mapping"), this); + mappingMuteAction->setToolTip(tr("Mute mapping item")); + mappingMuteAction->setIconVisibleInMenu(false); + mappingMuteAction->setCheckable(true); + mappingMuteAction->setChecked(false); + addAction(mappingMuteAction); + connect(mappingMuteAction, SIGNAL(triggered(bool)), this, SLOT(setMappingitemVisible(bool))); + + // Solo mapping. + mappingSoloAction = new QAction(tr("Solo mapping"), this); + mappingSoloAction->setToolTip(tr("solo mapping item")); + mappingSoloAction->setIconVisibleInMenu(false); + mappingSoloAction->setCheckable(true); + mappingSoloAction->setChecked(false); + addAction(mappingSoloAction); + connect(mappingSoloAction, SIGNAL(triggered(bool)), this, SLOT(setMappingItemSolo(bool))); + // Delete paint. deletePaintAction = new QAction(tr("Delete paint"), this); //deletePaintAction->setShortcut(tr("CTRL+DEL")); @@ -1759,6 +1814,9 @@ void MainWindow::createMappingContextMenu() mappingContextMenu->addAction(cloneMappingAction); mappingContextMenu->addAction(deleteMappingAction); mappingContextMenu->addAction(renameMappingAction); + mappingContextMenu->addAction(mappingLockedAction); + mappingContextMenu->addAction(mappingMuteAction); + mappingContextMenu->addAction(mappingSoloAction); // Set context menu policy mappingList->setContextMenuPolicy(Qt::CustomContextMenu); @@ -1767,8 +1825,8 @@ void MainWindow::createMappingContextMenu() // Context Menu Connexions connect(mappingList, SIGNAL(customContextMenuRequested(const QPoint&)), this, SLOT(showMappingContextMenu(const QPoint&))); - connect(destinationCanvas, SIGNAL(customContextMenuRequested(const QPoint&)), this, SLOT(showMappingContextMenu(const QPoint&))); - connect(outputWindow, SIGNAL(customContextMenuRequested(const QPoint&)), this, SLOT(showMappingContextMenu(const QPoint&))); + connect(destinationCanvas, SIGNAL(shapeContextMenuRequested(const QPoint&)), this, SLOT(showMappingContextMenu(const QPoint&))); + connect(outputWindow->getCanvas(), SIGNAL(shapeContextMenuRequested(const QPoint&)), this, SLOT(showMappingContextMenu(const QPoint&))); } void MainWindow::createPaintContextMenu() @@ -1786,7 +1844,7 @@ void MainWindow::createPaintContextMenu() // Connexions connect(paintList, SIGNAL(customContextMenuRequested(const QPoint&)), this, SLOT(showPaintContextMenu(const QPoint&))); - connect(sourceCanvas, SIGNAL(customContextMenuRequested(const QPoint&)), this, SLOT(showPaintContextMenu(const QPoint&))); + connect(sourceCanvas, SIGNAL(shapeContextMenuRequested(const QPoint&)), this, SLOT(showPaintContextMenu(const QPoint&))); } void MainWindow::createToolBars() @@ -2529,6 +2587,13 @@ void MainWindow::enableStickyVertices(bool value) void MainWindow::showMappingContextMenu(const QPoint &point) { QWidget *objectSender = dynamic_cast(sender()); + uid mappingId = getItemId(*mappingList->currentItem()); + Mapping::ptr mapping = mappingManager->getMappingById(mappingId); + + // Switch to right action check state + mappingLockedAction->setChecked(mapping->isLocked()); + mappingMuteAction->setChecked(!mapping->isVisible()); + mappingSoloAction->setChecked(mapping->isSolo()); if (objectSender != NULL && mappingList->count() > 0) mappingContextMenu->exec(objectSender->mapToGlobal(point)); diff --git a/MainWindow.h b/MainWindow.h index c8cf18a..aca49e8 100644 --- a/MainWindow.h +++ b/MainWindow.h @@ -98,6 +98,9 @@ private slots: void duplicateMappingItem(); void deleteMappingItem(); void renameMappingItem(); + void setMappingitemLocked(bool locked); + void setMappingitemVisible(bool visible); + void setMappingItemSolo(bool solo); void mappingListEditEnd(QWidget* editor); // Context menu for paints void deletePaintItem(); @@ -305,9 +308,14 @@ private: QAction *exitAction; QAction *undoAction; QAction *redoAction; + // Mappings context menu actions QAction *cloneMappingAction; QAction *deleteMappingAction; QAction *renameMappingAction; + QAction *mappingSoloAction; + QAction *mappingLockedAction; + QAction *mappingMuteAction; + // Paints context menu action QAction *deletePaintAction; QAction *renamePaintAction; QAction *preferencesAction; diff --git a/MapperGLCanvas.cpp b/MapperGLCanvas.cpp index c01e9f9..b6fc26d 100644 --- a/MapperGLCanvas.cpp +++ b/MapperGLCanvas.cpp @@ -236,7 +236,8 @@ void MapperGLCanvas::mousePressEvent(QMouseEvent* event) _activeVertex = i; minDistance = dist; - _vertexGrabbed = true; + // Vertex can be grabbed only if the mapping is not locked + _vertexGrabbed = shape->isLocked() ? false : true; mousePressedOnSomething = true; _grabbedObjectStartScenePosition = shape->getVertex(i); @@ -287,12 +288,21 @@ void MapperGLCanvas::mousePressEvent(QMouseEvent* event) { if (selectedShape && selectedShape->includesPoint(pos)) { - _shapeGrabbed = true; + // Shape can be grabbed only if it is not locked + _shapeGrabbed = selectedShape->isLocked() ? false : true; _shapeFirstGrab = true; _grabbedObjectStartScenePosition = pos; } } + // Show the shape/mapping context menu + if (event->button() & Qt::RightButton) + { + if (selectedShape && selectedShape->includesPoint(pos)) + { + emit shapeContextMenuRequested(event->pos()); + } + } } if (mousePressedOnSomething) diff --git a/MapperGLCanvas.h b/MapperGLCanvas.h index 80c7e73..83c5176 100644 --- a/MapperGLCanvas.h +++ b/MapperGLCanvas.h @@ -178,6 +178,7 @@ private: signals: void shapeChanged(MShape*); void imageChanged(); + void shapeContextMenuRequested(const QPoint &pos); public slots: void updateCanvas(); diff --git a/Shape.h b/Shape.h index bf7515e..f8f3349 100644 --- a/Shape.h +++ b/Shape.h @@ -46,7 +46,7 @@ class MShape public: typedef QSharedPointer ptr; - MShape() {} + MShape() : _isLocked(false) {} MShape(QVector vertices_) : vertices(vertices_) {} @@ -89,6 +89,9 @@ public: virtual void copyFrom(const MShape& shape); virtual MShape* clone() const; + // Handle shape lock + bool isLocked() const { return _isLocked; } + void setLocked(bool locked) { _isLocked = locked; } protected: QVector vertices; @@ -105,6 +108,10 @@ protected: /// Returns a new MShape (using default constructor). virtual MShape* _create() const = 0; + +private: + // Shape lock state + bool _isLocked; }; /** diff --git a/ShapeControlPainter.cpp b/ShapeControlPainter.cpp index 1528830..64e290e 100644 --- a/ShapeControlPainter.cpp +++ b/ShapeControlPainter.cpp @@ -36,16 +36,17 @@ void ShapeControlPainter::paint(QPainter *painter, MapperGLCanvas* canvas, const void ShapeControlPainter::_paintVertices(QPainter *painter, MapperGLCanvas* canvas, const QList& selectedVertices) { qreal zoomFactor = canvas->getZoomFactor(); - qreal selectRadius = MM::VERTEX_SELECT_RADIUS / zoomFactor; + qreal selectRadius = (getShape()->isLocked() ? MM::VERTEX_LOCKED_RADIUS : MM::VERTEX_SELECT_RADIUS) / zoomFactor; qreal strokeWidth = MM::VERTEX_SELECT_STROKE_WIDTH / zoomFactor; for (int i=0; inVertices(); i++) - Util::drawControlsVertex(painter, getShape()->getVertex(i), selectedVertices.contains(i), selectRadius, strokeWidth); + Util::drawControlsVertex(painter, getShape()->getVertex(i), selectedVertices.contains(i), getShape()->isLocked(), selectRadius, strokeWidth); } QPen ShapeControlPainter::getRescaledShapeStroke(MapperGLCanvas* canvas, bool innerStroke) { - return QPen(QBrush(MM::CONTROL_COLOR), (innerStroke ? MM::SHAPE_INNER_STROKE_WIDTH : MM::SHAPE_STROKE_WIDTH) / canvas->getZoomFactor()); + return QPen(getShape()->isLocked() ? QBrush(MM::CONTROL_LOCKED_COLOR) : QBrush(MM::CONTROL_COLOR), + (innerStroke ? MM::SHAPE_INNER_STROKE_WIDTH : MM::SHAPE_STROKE_WIDTH) / canvas->getZoomFactor()); } void PolygonControlPainter::_paintShape(QPainter *painter, MapperGLCanvas* canvas) diff --git a/Util.cpp b/Util.cpp index 516157d..7cf9035 100644 --- a/Util.cpp +++ b/Util.cpp @@ -150,11 +150,15 @@ Ellipse* createEllipseForColor(int frameWidth, int frameHeight) ); } -void drawControlsVertex(QPainter* painter, const QPointF& vertex, bool selected, qreal radius, qreal strokeWidth) +void drawControlsVertex(QPainter* painter, const QPointF& vertex, bool selected, bool locked, qreal radius, qreal strokeWidth) { // Init colors and stroke. - painter->setBrush(selected ? MM::VERTEX_SELECTED_BACKGROUND : MM::VERTEX_BACKGROUND); - painter->setPen(QPen(MM::CONTROL_COLOR, strokeWidth)); + if (locked) + painter->setBrush(MM::VERTEX_LOCKED_BACKGROUND); + else + painter->setBrush(selected ? MM::VERTEX_SELECTED_BACKGROUND : MM::VERTEX_BACKGROUND); + + painter->setPen(locked ? QPen(MM::CONTROL_LOCKED_COLOR) : QPen(MM::CONTROL_COLOR, strokeWidth)); // Draw ellipse. painter->drawEllipse(vertex, radius, radius); @@ -169,10 +173,10 @@ void drawControlsVertices(QPainter* painter, const QList* selectedVertices, { if (!selectedVertices) for (int i=0; icontains(i)); + drawControlsVertex(painter, shape.getVertex(i), selectedVertices->contains(i), shape.isLocked()); } void drawControlsEllipse(QPainter* painter, const QList* selectedVertices, const Ellipse& ellipse) diff --git a/Util.h b/Util.h index 5dc8412..a55f4c5 100644 --- a/Util.h +++ b/Util.h @@ -57,7 +57,7 @@ Quad* createQuadForColor(int frameWidth, int frameHeight); Triangle* createTriangleForColor(int frameWidth, int frameHeight); Ellipse* createEllipseForColor(int frameWidth, int frameHeight); -void drawControlsVertex(QPainter* painter, const QPointF& vertex, bool selected, qreal radius = MM::VERTEX_SELECT_RADIUS, qreal strokeWidth = MM::VERTEX_SELECT_STROKE_WIDTH); +void drawControlsVertex(QPainter* painter, const QPointF& vertex, bool selected, bool locked, qreal radius = MM::VERTEX_SELECT_RADIUS, qreal strokeWidth = MM::VERTEX_SELECT_STROKE_WIDTH); void drawControlsVertices(QPainter* painter, const QList* selectedVertices, const MShape& shape); void drawControlsEllipse(QPainter* painter, const QList* selectedVertices, const Ellipse& ellipse);