(event);
@@ -290,60 +309,48 @@ bool MainWindow::eventFilter(QObject *obj, QEvent *event)
// Menubar shortcut
if (keyEvent->modifiers() == Qt::CTRL)
{
- 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();
- break;
- case Qt::Key_O:
- open();
- break;
- case Qt::Key_S:
- save();
- break;
- case Qt::Key_Q:
- close();
- break;
- case Qt::Key_Delete:
- deleteItem();
- break;
- case Qt::Key_M:
- addMesh();
- break;
- case Qt::Key_T:
- addTriangle();
- break;
- case Qt::Key_E:
- addEllipse();
- break;
- case Qt::Key_W:
- outputWindow->setVisible(true);
- break;
- case Qt::Key_R:
- rewind();
- break;
- case Qt::Key_Z:
- undoStack->undo();
- break;
- }
+ switch (keyEvent->key()) {
+ case Qt::Key_N:
+ newFile();
+ break;
+ case Qt::Key_O:
+ open();
+ break;
+ case Qt::Key_S:
+ save();
+ break;
+ case Qt::Key_Q:
+ close();
+ break;
+ case Qt::Key_Delete:
+ deleteItem();
+ break;
+ case Qt::Key_M:
+ addMesh();
+ break;
+ case Qt::Key_T:
+ addTriangle();
+ break;
+ case Qt::Key_E:
+ addEllipse();
+ break;
+ case Qt::Key_W:
+ outputWindow->setVisible(true);
+ break;
+ case Qt::Key_R:
+ rewind();
+ break;
+ case Qt::Key_Z:
+ undoStack->undo();
+ break;
+ }
}
else if (keyEvent->matches(QKeySequence::Redo))
{
undoStack->redo();
}
else if (keyEvent->key() == Qt::Key_Escape)
- {
- outputWindow->setFullScreen(false);
- outputWindowFullScreenAction->setChecked(false);
- outputWindowFullScreenAction->setEnabled(false);
- }
+ outputWindow->close();
else if (keyEvent->key() == Qt::Key_Space)
{
if (_isPlaying)
@@ -366,11 +373,35 @@ bool MainWindow::eventFilter(QObject *obj, QEvent *event)
}
}
+void MainWindow::keyPressEvent(QKeyEvent *event)
+{
+#ifdef Q_OS_OSX // On Mac OS X
+ // Do nothing
+#endif
+
+#ifdef Q_OS_LINUX // On Linux
+ if (event->modifiers() & Qt::AltModifier) {
+ QString currentDesktop = QString(getenv("XDG_CURRENT_DESKTOP")).toLower();
+ if (currentDesktop != "unity" && !_showMenuBar) {
+ menuBar()->setHidden(!menuBar()->isHidden());
+ menuBar()->setFocus(Qt::MenuBarFocusReason);
+ }
+ }
+#endif
+#ifdef Q_OS_WIN
+ if (event->modifiers() & Qt::AltModifier) {
+ if (!_showMenuBar) {
+ menuBar()->setHidden(!menuBar()->isHidden());
+ menuBar()->setFocus(Qt::MenuBarFocusReason);
+ }
+ }
+#endif
+}
+
void MainWindow::setOutputWindowFullScreen(bool enable)
{
- outputWindow->setFullScreen(false);
+ outputWindow->setFullScreen(enable);
// setCheckState
- outputWindowFullScreenAction->setChecked(enable);
displayControlsAction->setChecked(enable);
}
@@ -400,9 +431,9 @@ void MainWindow::open()
if (okToContinue())
{
QString fileName = QFileDialog::getOpenFileName(this,
- tr("Open project"),
- settings.value("defaultProjectDir").toString(),
- tr("MapMap files (*.%1)").arg(MM::FILE_EXTENSION));
+ tr("Open project"),
+ settings.value("defaultProjectDir").toString(),
+ tr("MapMap files (*.%1)").arg(MM::FILE_EXTENSION));
if (! fileName.isEmpty())
loadFile(fileName);
}
@@ -436,8 +467,8 @@ bool MainWindow::saveAs()
// Popul file dialog to choose filename.
QString fileName = QFileDialog::getSaveFileName(this,
- tr("Save project"), settings.value("defaultProjectDir").toString(),
- tr("MapMap files (*.%1)").arg(MM::FILE_EXTENSION));
+ tr("Save project"), settings.value("defaultProjectDir").toString(),
+ tr("MapMap files (*.%1)").arg(MM::FILE_EXTENSION));
// Restart video playback. XXX Hack
videoTimer->start();
@@ -448,31 +479,16 @@ bool MainWindow::saveAs()
if (! fileName.endsWith(MM::FILE_EXTENSION))
{
std::cout << "filename doesn't end with expected extension: " <<
- fileName.toStdString() << std::endl;
- fileName.append(".");
- fileName.append(MM::FILE_EXTENSION);
+ fileName.toStdString() << std::endl;
+ fileName.append(".");
+ fileName.append(MM::FILE_EXTENSION);
}
// Save to filename.
return saveFile(fileName);
}
-void MainWindow::importVideo()
-{
- // Stop video playback to avoid lags. XXX Hack
- videoTimer->stop();
-
- // Pop-up file-choosing dialog to choose media file.
- // TODO: restrict the type of files that can be imported
- QString fileName = QFileDialog::getOpenFileName(this, tr("Import media source file"), settings.value("defaultVideoDir").toString(), tr("Video files (%1);;All files (*)").arg(MM::VIDEO_FILES_FILTER));
- // Restart video playback. XXX Hack
- videoTimer->start();
-
- if (!fileName.isEmpty())
- importMediaFile(fileName, false);
-}
-
-void MainWindow::importImage()
+void MainWindow::importMedia()
{
// Stop video playback to avoid lags. XXX Hack
videoTimer->stop();
@@ -480,13 +496,22 @@ void MainWindow::importImage()
// Pop-up file-choosing dialog to choose media file.
// TODO: restrict the type of files that can be imported
QString fileName = QFileDialog::getOpenFileName(this,
- tr("Import media source file"), settings.value("defaultImageDir").toString(), tr("Image files (%1);;All files (*)").arg(MM::IMAGE_FILES_FILTER));
-
+ tr("Import media source file"),
+ settings.value("defaultVideoDir").toString(),
+ tr("Media files (%1 %2);;All files (*)")
+ .arg(MM::VIDEO_FILES_FILTER)
+ .arg(MM::IMAGE_FILES_FILTER));
// Restart video playback. XXX Hack
videoTimer->start();
- if (!fileName.isEmpty())
- importMediaFile(fileName, true);
+ // Check if file is image or not
+ // according to file extension
+ if (!fileName.isEmpty()) {
+ if (MM::IMAGE_FILES_FILTER.contains(QFileInfo(fileName).suffix(), Qt::CaseInsensitive))
+ importMediaFile(fileName, true);
+ else
+ importMediaFile(fileName, false);
+ }
}
void MainWindow::addColor()
@@ -499,8 +524,8 @@ void MainWindow::addColor()
// it should rather be a member of this class, or so.
static QColor color = QColor(0, 255, 0, 255);
color = QColorDialog::getColor(color, this, tr("Select Color"),
- // QColorDialog::DontUseNativeDialog |
- QColorDialog::ShowAlphaChannel);
+ // QColorDialog::DontUseNativeDialog |
+ QColorDialog::ShowAlphaChannel);
if (color.isValid())
{
addColorPaint(color);
@@ -656,25 +681,25 @@ void MainWindow::about()
// Pop-up about dialog.
QMessageBox::about(this, tr("About MapMap"),
- tr("
%1
"
- "Copyright © 2013 %2.
"
- "MapMap is a free software for video mapping.
"
- "Projection mapping, also known as video mapping and spatial augmented reality, "
- "is a projection technology used to turn objects, often irregularly shaped, into "
- "a display surface for video projection. These objects may be complex industrial "
- "landscapes, such as buildings. By using specialized software, a two or three "
- "dimensional object is spatially mapped on the virtual program which mimics the "
- "real environment it is to be projected on. The software can interact with a "
- "projector to fit any desired image onto the surface of that object. This "
- "technique is used by artists and advertisers alike who can add extra dimensions, "
- "optical illusions, and notions of movement onto previously static objects. The "
- "video is commonly combined with, or triggered by, audio to create an "
- "audio-visual narrative."
- "This project was made possible by the support of the International Organization of "
- "La Francophonie.
"
- "http://mapmap.info
"
- "http://www.francophonie.org
"
- ).arg(MM::VERSION, MM::COPYRIGHT_OWNERS));
+ tr("
%1
"
+ "Copyright © 2013 %2.
"
+ "MapMap is a free software for video mapping.
"
+ "Projection mapping, also known as video mapping and spatial augmented reality, "
+ "is a projection technology used to turn objects, often irregularly shaped, into "
+ "a display surface for video projection. These objects may be complex industrial "
+ "landscapes, such as buildings. By using specialized software, a two or three "
+ "dimensional object is spatially mapped on the virtual program which mimics the "
+ "real environment it is to be projected on. The software can interact with a "
+ "projector to fit any desired image onto the surface of that object. This "
+ "technique is used by artists and advertisers alike who can add extra dimensions, "
+ "optical illusions, and notions of movement onto previously static objects. The "
+ "video is commonly combined with, or triggered by, audio to create an "
+ "audio-visual narrative."
+ "This project was made possible by the support of the International Organization of "
+ "La Francophonie.
"
+ "http://mapmap.info
"
+ "http://www.francophonie.org
"
+ ).arg(MM::VERSION, MM::COPYRIGHT_OWNERS));
// Restart video playback. XXX Hack
videoTimer->start();
@@ -682,14 +707,37 @@ void MainWindow::about()
void MainWindow::updateStatusBar()
{
- // Nothing to do for now.
-// locationLabel->setText(spreadsheet->currentLocation());
-// formulaLabel->setText(spreadsheet->currentFormula());
+ QPointF mousePos = destinationCanvas->mapToScene(destinationCanvas->mapFromGlobal(destinationCanvas->cursor().pos()));
+ if (currentSelectedItem) // Show mouse coordinate only if mappingList is not empty
+ mousePosLabel->setText("Mouse coordinate: X " + QString::number(mousePos.x()) + " Y " + QString::number(mousePos.y()));
+ else
+ mousePosLabel->setText(""); // Otherwise set empty text.
+ currentMessageLabel->setText(statusBar()->currentMessage());
+ sourceZoomLabel->setText("Source: " + QString::number(int(sourceCanvas->getZoomFactor() * 100)).append(QChar('%')));
+ destinationZoomLabel->setText("Destination: " + QString::number(int(destinationCanvas->getZoomFactor() * 100)).append(QChar('%')));
+ undoLabel->setText(undoStack->text(undoStack->count() - 1));
+}
+
+void MainWindow::showMenuBar(bool shown)
+{
+ _showMenuBar = shown;
+
+#ifdef Q_OS_OSX // On Mac OS X
+ // Do nothing
+#endif
+#ifdef Q_OS_LINUX // On Linux
+ QString currentDesktop = QString(getenv("XDG_CURRENT_DESKTOP")).toLower();
+ if (currentDesktop != "unity")
+ menuBar()->setVisible(shown);
+#endif
+#ifdef Q_OS_WIN // On Windows
+ menuBar()->setVisible(shown);
+#endif
}
/**
* Called when the user wants to delete an item.
- *
+ *
* Deletes either a Paint or a Mapping.
*/
void MainWindow::deleteItem()
@@ -715,14 +763,14 @@ void MainWindow::deleteItem()
{
qCritical() << "Selected item neither a mapping nor a paint." << endl;
}
- }
+ }
}
-void MainWindow::cloneItem()
+void MainWindow::duplicateMappingItem()
{
if (currentSelectedItem)
{
- cloneMappingItem(getItemId(*mappingList->currentItem()));
+ duplicateMapping(getItemId(*mappingList->currentItem()));
}
else
{
@@ -747,17 +795,42 @@ void MainWindow::renameMappingItem()
// Set current item editable and rename it
QListWidgetItem* item = mappingList->currentItem();
item->setFlags(item->flags() | Qt::ItemIsEditable);
+ // Used by context menu
mappingList->editItem(item);
+ // Switch to mapping tab.
contentTab->setCurrentWidget(mappingSplitter);
}
-void MainWindow::renameMappingItem(uid mappingId, QString name)
+void MainWindow::setMappingitemLocked(bool locked)
{
- if (mappingList->count() > 0) {
- mappingList->item(mappingId)->setText(name);
+ 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);
+ if (!mapping.isNull()) {
+ getItemFromId(*mappingList, mappingId)->setText(name);
+ mapping->setName(name);
}
}
+void MainWindow::mappingListEditEnd(QWidget *editor)
+{
+ QString name = reinterpret_cast(editor)->text();
+ renameMapping(getItemId(*mappingList->currentItem()), name);
+}
+
void MainWindow::deletePaintItem()
{
if(currentSelectedItem)
@@ -775,29 +848,39 @@ void MainWindow::renamePaintItem()
// Set current item editable and rename it
QListWidgetItem* item = paintList->currentItem();
item->setFlags(item->flags() | Qt::ItemIsEditable);
+ // Used by context menu
paintList->editItem(item);
+ // Switch to paint tab
contentTab->setCurrentWidget(paintSplitter);
}
-void MainWindow::renamePaintItem(uid paintId, QString name)
+void MainWindow::renamePaint(uid paintId, const QString &name)
{
- if (paintList->count() > 0) {
- paintList->item(paintId)->setText(name);
+ Paint::ptr paint = mappingManager->getPaintById(paintId);
+ if (!paint.isNull()) {
+ getItemFromId(*paintList, paintId)->setText(name);
+ paint->setName(name);
}
}
+void MainWindow::paintListEditEnd(QWidget *editor)
+{
+ QString name = reinterpret_cast(editor)->text();
+ renamePaint(getItemId(*paintList->currentItem()), name);
+}
+
void MainWindow::openRecentFile()
{
- QAction *action = qobject_cast(sender());
- if (action)
- loadFile(action->data().toString());
+ QAction *action = qobject_cast(sender());
+ if (action)
+ loadFile(action->data().toString());
}
void MainWindow::openRecentVideo()
{
- QAction *action = qobject_cast(sender());
- if (action)
- importMediaFile(action->data().toString(),false);
+ QAction *action = qobject_cast(sender());
+ if (action)
+ importMediaFile(action->data().toString(),false);
}
bool MainWindow::clearProject()
@@ -853,7 +936,7 @@ uid MainWindow::createMediaPaint(uid paintId, QString uri, float x, float y,
{
// Check if file exists before
if (! fileExists(uri))
- uri = locateMediaFile(uri, isImage);
+ uri = locateMediaFile(uri, isImage);
Texture* tex = 0;
if (isImage)
@@ -1104,14 +1187,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)
@@ -1120,10 +1216,10 @@ void MainWindow::deleteMapping(uid mappingId)
if (Mapping::getUidAllocator().exists(mappingId))
{
removeMappingItem(mappingId);
- }
+ }
}
-void MainWindow::cloneMappingItem(uid mappingId)
+void MainWindow::duplicateMapping(uid mappingId)
{
// Current Mapping
Mapping::ptr mappingPtr = mappingManager->getMappingById(mappingId);
@@ -1143,14 +1239,14 @@ void MainWindow::cloneMappingItem(uid mappingId)
{
if (shapeType == "quad")
shapePtr = MShape::ptr(new Quad(shape->getVertex(0), shape->getVertex(1),
- shape->getVertex(2), shape->getVertex(3)));
+ shape->getVertex(2), shape->getVertex(3)));
if (shapeType == "triangle")
shapePtr = MShape::ptr(new Triangle(shape->getVertex(0), shape->getVertex(1), shape->getVertex(2)));
if (shapeType == "ellipse")
shapePtr = MShape::ptr(new Ellipse(shape->getVertex(0), shape->getVertex(1), shape->getVertex(2),
- shape->getVertex(3)));
+ shape->getVertex(3)));
mapping = new ColorMapping(paint, shapePtr);
}
@@ -1160,14 +1256,14 @@ void MainWindow::cloneMappingItem(uid mappingId)
if (shapeType == "mesh")
shapePtr = MShape::ptr(new Mesh(shape->getVertex(0), shape->getVertex(1),
- shape->getVertex(3), shape->getVertex(2)));
+ shape->getVertex(3), shape->getVertex(2)));
if (shapeType == "triangle")
shapePtr = MShape::ptr(new Triangle(shape->getVertex(0), shape->getVertex(1), shape->getVertex(2)));
if (shapeType == "ellipse")
shapePtr = MShape::ptr(new Ellipse(shape->getVertex(0), shape->getVertex(1), shape->getVertex(2),
- shape->getVertex(3), shape->getVertex(4)));
+ shape->getVertex(3), shape->getVertex(4)));
mapping = new TextureMapping(paint, shapePtr, inputShape);
}
@@ -1192,8 +1288,8 @@ void MainWindow::deletePaint(uid paintId, bool replace)
{
if (replace == false) {
int r = QMessageBox::warning(this, tr("MapMap"),
- tr("Remove this paint and all its associated mappings?"),
- QMessageBox::Ok | QMessageBox::Cancel);
+ tr("Remove this paint and all its associated mappings?"),
+ QMessageBox::Ok | QMessageBox::Cancel);
if (r == QMessageBox::Ok)
{
removePaintItem(paintId);
@@ -1239,9 +1335,6 @@ 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);
@@ -1254,7 +1347,6 @@ void MainWindow::createLayout()
destinationCanvas->setMinimumSize(CANVAS_MINIMUM_WIDTH, CANVAS_MINIMUM_HEIGHT);
outputWindow = new OutputGLWindow(this, destinationCanvas);
- outputWindow->setVisible(true);
outputWindow->installEventFilter(destinationCanvas);
outputWindow->installEventFilter(this);
@@ -1268,8 +1360,12 @@ void MainWindow::createLayout()
// Output changed -> change destinatioin
// XXX si je decommente cette ligne alors quand je clique sur ajouter media ca gele...
-// connect(outputWindow->getCanvas()->scene(), SIGNAL(changed(const QList&)),
-// destinationCanvas, SLOT(updateCanvas()));
+ // connect(outputWindow->getCanvas()->scene(), SIGNAL(changed(const QList&)),
+ // destinationCanvas, SLOT(updateCanvas()));
+
+ // Create console logging output
+ consoleWindow = ConsoleWindow::getInstance();
+ consoleWindow->setVisible(false);
// Create layout.
paintSplitter = new QSplitter(Qt::Vertical);
@@ -1321,49 +1417,53 @@ void MainWindow::createActions()
newAction = new QAction(tr("&New"), this);
newAction->setIcon(QIcon(":/new"));
newAction->setShortcut(QKeySequence::New);
- newAction->setStatusTip(tr("Create a new project"));
+ newAction->setToolTip(tr("Create a new project"));
newAction->setIconVisibleInMenu(false);
+ addAction(newAction);
connect(newAction, SIGNAL(triggered()), this, SLOT(newFile()));
// Open.
openAction = new QAction(tr("&Open..."), this);
openAction->setIcon(QIcon(":/open"));
openAction->setShortcut(QKeySequence::Open);
- openAction->setStatusTip(tr("Open an existing project"));
+ openAction->setToolTip(tr("Open an existing project"));
openAction->setIconVisibleInMenu(false);
+ addAction(openAction);
connect(openAction, SIGNAL(triggered()), this, SLOT(open()));
// Save.
saveAction = new QAction(tr("&Save"), this);
saveAction->setIcon(QIcon(":/save"));
saveAction->setShortcut(QKeySequence::Save);
- saveAction->setStatusTip(tr("Save the project"));
+ saveAction->setToolTip(tr("Save the project"));
saveAction->setIconVisibleInMenu(false);
+ addAction(saveAction);
connect(saveAction, SIGNAL(triggered()), this, SLOT(save()));
// 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->setShortcut(QKeySequence::SaveAs);
+ saveAsAction->setToolTip(tr("Save the project as..."));
saveAsAction->setIconVisibleInMenu(false);
+ addAction(saveAsAction);
connect(saveAsAction, SIGNAL(triggered()), this, SLOT(saveAs()));
// Recents file
for (int i = 0; i < MaxRecentFiles; i++)
{
- recentFileActions[i] = new QAction(this);
- recentFileActions[i]->setVisible(false);
- connect(recentFileActions[i], SIGNAL(triggered()),
- this, SLOT(openRecentFile()));
+ recentFileActions[i] = new QAction(this);
+ recentFileActions[i]->setVisible(false);
+ connect(recentFileActions[i], SIGNAL(triggered()),
+ this, SLOT(openRecentFile()));
}
// Recent video
for (int i = 0; i < MaxRecentVideo; i++)
{
- recentVideoActions[i] = new QAction(this);
- recentVideoActions[i]->setVisible(false);
- connect(recentVideoActions[i], SIGNAL(triggered()), this, SLOT(openRecentVideo()));
+ recentVideoActions[i] = new QAction(this);
+ recentVideoActions[i]->setVisible(false);
+ connect(recentVideoActions[i], SIGNAL(triggered()), this, SLOT(openRecentVideo()));
}
// Clear recent video list action
@@ -1376,35 +1476,30 @@ void MainWindow::createActions()
emptyRecentVideos->setEnabled(false);
- // Import video.
- importVideoAction = new QAction(tr("&Import Video File..."), this);
- importVideoAction->setShortcut(tr("Ctrl+I"));
- importVideoAction->setIcon(QIcon(":/add-video"));
- 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 Image File..."), this);
- importImageAction->setShortcut(tr("Ctrl+Shift+I"));
- importImageAction->setIcon(QIcon(":/add-image"));
- importImageAction->setStatusTip(tr("Import a image source file..."));
- importImageAction->setIconVisibleInMenu(false);
- connect(importImageAction, SIGNAL(triggered()), this, SLOT(importImage()));
+ // Import Media.
+ importMediaAction = new QAction(tr("&Import Media File..."), this);
+ importMediaAction->setShortcut(tr("Ctrl+I"));
+ importMediaAction->setIcon(QIcon(":/add-video"));
+ importMediaAction->setToolTip(tr("Import a video or image file..."));
+ importMediaAction->setIconVisibleInMenu(false);
+ addAction(importMediaAction);
+ connect(importMediaAction, SIGNAL(triggered()), this, SLOT(importMedia()));
// Add color.
addColorAction = new QAction(tr("Add &Color Paint..."), this);
addColorAction->setShortcut(tr("Ctrl+Shift+A"));
addColorAction->setIcon(QIcon(":/add-color"));
- addColorAction->setStatusTip(tr("Add a color paint..."));
+ addColorAction->setToolTip(tr("Add a color paint..."));
addColorAction->setIconVisibleInMenu(false);
+ addAction(addColorAction);
connect(addColorAction, SIGNAL(triggered()), this, SLOT(addColor()));
// Exit/quit.
exitAction = new QAction(tr("E&xit"), this);
- exitAction->setShortcut(tr("Ctrl+Q"));
- exitAction->setStatusTip(tr("Exit the application"));
+ exitAction->setShortcut(QKeySequence::Quit);
+ exitAction->setToolTip(tr("Exit the application"));
exitAction->setIconVisibleInMenu(false);
+ addAction(exitAction);
connect(exitAction, SIGNAL(triggered()), this, SLOT(close()));
// Undo action
@@ -1412,68 +1507,104 @@ void MainWindow::createActions()
undoAction->setShortcut(QKeySequence::Undo);
undoAction->setIconVisibleInMenu(false);
undoAction->setShortcutContext(Qt::ApplicationShortcut);
+ addAction(undoAction);
//Redo action
redoAction = undoStack->createRedoAction(this, tr("&Redo"));
redoAction->setShortcut(QKeySequence::Redo);
redoAction->setIconVisibleInMenu(false);
redoAction->setShortcutContext(Qt::ApplicationShortcut);
+ addAction(redoAction);
// About.
aboutAction = new QAction(tr("&About"), this);
- aboutAction->setStatusTip(tr("Show the application's About box"));
+ aboutAction->setToolTip(tr("Show the application's About box"));
aboutAction->setIconVisibleInMenu(false);
+ addAction(aboutAction);
connect(aboutAction, SIGNAL(triggered()), this, SLOT(about()));
// Duplicate.
- cloneAction = new QAction(tr("Duplicate"), this);
- cloneAction->setShortcut(tr("Ctrl+D"));
- cloneAction->setStatusTip(tr("Duplicate item"));
- cloneAction->setIconVisibleInMenu(false);
- connect(cloneAction, SIGNAL(triggered()), this, SLOT(cloneItem()));
+ cloneMappingAction = new QAction(tr("Duplicate"), this);
+ cloneMappingAction->setShortcut(Qt::CTRL + Qt::Key_D);
+ cloneMappingAction->setToolTip(tr("Duplicate item"));
+ cloneMappingAction->setIconVisibleInMenu(false);
+ addAction(cloneMappingAction);
+ connect(cloneMappingAction, SIGNAL(triggered()), this, SLOT(duplicateMappingItem()));
// Delete mapping.
- deleteMappingAction = new QAction(tr("Delete"), this);
- deleteMappingAction->setShortcut(tr("CTRL+DEL"));
- deleteMappingAction->setStatusTip(tr("Delete item"));
+ deleteMappingAction = new QAction(tr("Delete mapping"), this);
+ deleteMappingAction->setShortcut(QKeySequence::Delete);
+ deleteMappingAction->setToolTip(tr("Delete item"));
deleteMappingAction->setIconVisibleInMenu(false);
+ addAction(deleteMappingAction);
connect(deleteMappingAction, SIGNAL(triggered()), this, SLOT(deleteMappingItem()));
// Rename mapping.
renameMappingAction = new QAction(tr("Rename"), this);
renameMappingAction->setShortcut(Qt::Key_F2);
- renameMappingAction->setStatusTip(tr("Rename item"));
+ renameMappingAction->setToolTip(tr("Rename item"));
renameMappingAction->setIconVisibleInMenu(false);
+ 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"), this);
+ deletePaintAction = new QAction(tr("Delete paint"), this);
//deletePaintAction->setShortcut(tr("CTRL+DEL"));
- deletePaintAction->setStatusTip(tr("Delete item"));
+ deletePaintAction->setToolTip(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->setToolTip(tr("Rename item"));
renamePaintAction->setIconVisibleInMenu(false);
+ addAction(renamePaintAction);
connect(renamePaintAction, SIGNAL(triggered()), this, SLOT(renamePaintItem()));
// Preferences...
preferencesAction = new QAction(tr("&Preferences..."), this);
//preferencesAction->setIcon(QIcon(":/preferences"));
- preferencesAction->setShortcut(tr("CTRL+,"));
- preferencesAction->setStatusTip(tr("Configure preferences..."));
+ preferencesAction->setShortcut(Qt::CTRL + Qt::Key_Comma);
+ preferencesAction->setToolTip(tr("Configure preferences..."));
//preferencesAction->setIconVisibleInMenu(false);
+ addAction(preferencesAction);
connect(preferencesAction, SIGNAL(triggered()), this, SLOT(preferences()));
// Add quad/mesh.
addMeshAction = new QAction(tr("Add Quad/&Mesh"), this);
addMeshAction->setShortcut(tr("CTRL+M"));
addMeshAction->setIcon(QIcon(":/add-mesh"));
- addMeshAction->setStatusTip(tr("Add quad/mesh"));
+ addMeshAction->setToolTip(tr("Add quad/mesh"));
addMeshAction->setIconVisibleInMenu(false);
+ addAction(addMeshAction);
connect(addMeshAction, SIGNAL(triggered()), this, SLOT(addMesh()));
addMeshAction->setEnabled(false);
@@ -1481,8 +1612,9 @@ void MainWindow::createActions()
addTriangleAction = new QAction(tr("Add &Triangle"), this);
addTriangleAction->setShortcut(tr("CTRL+T"));
addTriangleAction->setIcon(QIcon(":/add-triangle"));
- addTriangleAction->setStatusTip(tr("Add triangle"));
+ addTriangleAction->setToolTip(tr("Add triangle"));
addTriangleAction->setIconVisibleInMenu(false);
+ addAction(addTriangleAction);
connect(addTriangleAction, SIGNAL(triggered()), this, SLOT(addTriangle()));
addTriangleAction->setEnabled(false);
@@ -1490,8 +1622,9 @@ void MainWindow::createActions()
addEllipseAction = new QAction(tr("Add &Ellipse"), this);
addEllipseAction->setShortcut(tr("CTRL+E"));
addEllipseAction->setIcon(QIcon(":/add-ellipse"));
- addEllipseAction->setStatusTip(tr("Add ellipse"));
+ addEllipseAction->setToolTip(tr("Add ellipse"));
addEllipseAction->setIconVisibleInMenu(false);
+ addAction(addEllipseAction);
connect(addEllipseAction, SIGNAL(triggered()), this, SLOT(addEllipse()));
addEllipseAction->setEnabled(false);
@@ -1499,8 +1632,9 @@ void MainWindow::createActions()
playAction = new QAction(tr("Play"), this);
playAction->setShortcut(Qt::Key_Space);
playAction->setIcon(QIcon(":/play"));
- playAction->setStatusTip(tr("Play"));
+ playAction->setToolTip(tr("Play"));
playAction->setIconVisibleInMenu(false);
+ addAction(playAction);
connect(playAction, SIGNAL(triggered()), this, SLOT(play()));
playAction->setVisible(true);
@@ -1508,86 +1642,104 @@ void MainWindow::createActions()
pauseAction = new QAction(tr("Pause"), this);
pauseAction->setShortcut(Qt::Key_Space);
pauseAction->setIcon(QIcon(":/pause"));
- pauseAction->setStatusTip(tr("Pause"));
+ pauseAction->setToolTip(tr("Pause"));
pauseAction->setIconVisibleInMenu(false);
+ addAction(pauseAction);
connect(pauseAction, SIGNAL(triggered()), this, SLOT(pause()));
pauseAction->setVisible(false);
- // Pause.
+ // Rewind.
rewindAction = new QAction(tr("Rewind"), this);
rewindAction->setShortcut(tr("CTRL+R"));
rewindAction->setIcon(QIcon(":/rewind"));
- rewindAction->setStatusTip(tr("Rewind"));
+ rewindAction->setToolTip(tr("Rewind"));
rewindAction->setIconVisibleInMenu(false);
+ addAction(rewindAction);
connect(rewindAction, SIGNAL(triggered()), this, SLOT(rewind()));
// Toggle display of output window.
- 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);
- displayOutputWindowAction->setCheckable(true);
- displayOutputWindowAction->setChecked(true);
- // Manage show/hide of GL output window.
- connect(displayOutputWindowAction, SIGNAL(toggled(bool)), outputWindow, SLOT(setVisible(bool)));
- // When closing the GL output window, uncheck the action in menu.
- connect(outputWindow, SIGNAL(closed()), displayOutputWindowAction, SLOT(toggle()));
-
- // Toggle display of output window.
- outputWindowFullScreenAction = new QAction(tr("&Fullscreen"), this);
- outputWindowFullScreenAction->setIcon(QIcon(":/fullscreen"));
- outputWindowFullScreenAction->setShortcut(tr("Ctrl+F"));
- outputWindowFullScreenAction->setStatusTip(tr("Full screen"));
- outputWindowFullScreenAction->setIconVisibleInMenu(false);
- outputWindowFullScreenAction->setCheckable(true);
- outputWindowFullScreenAction->setChecked(false);
- // Manage fullscreen mode for output window.
- connect(outputWindowFullScreenAction, SIGNAL(toggled(bool)), outputWindow, SLOT(setFullScreen(bool)));
- // When fullscreen is toggled by the output window (eg. when pressing ESC), change the action checkbox.
- connect(outputWindow, SIGNAL(fullScreenToggled(bool)), outputWindowFullScreenAction, SLOT(setChecked(bool)));
- // Output window should be displayed for full screen option to be available.
- connect(displayOutputWindowAction, SIGNAL(toggled(bool)), outputWindowFullScreenAction, SLOT(setEnabled(bool)));
+ outputFullScreenAction = new QAction(tr("&Full Screen"), this);
+ outputFullScreenAction->setShortcut(Qt::CTRL + Qt::Key_F);
+ outputFullScreenAction->setIcon(QIcon(":/fullscreen"));
+ outputFullScreenAction->setToolTip(tr("Full screen mode"));
+ outputFullScreenAction->setIconVisibleInMenu(false);
+ outputFullScreenAction->setCheckable(true);
+ // Don't be displayed by default
+ outputFullScreenAction->setChecked(false);
+ addAction(outputFullScreenAction);
+ // Manage fullscreen/modal show of GL output window.
+ connect(outputFullScreenAction, SIGNAL(toggled(bool)), outputWindow, SLOT(setFullScreen(bool)));
+ // When closing the GL output window or hit ESC key, uncheck the action in menu.
+ connect(outputWindow, SIGNAL(closed()), outputFullScreenAction, SLOT(toggle()));
// Toggle display of canvas controls.
displayControlsAction = new QAction(tr("&Display Canvas Controls"), this);
- displayControlsAction->setShortcut(tr("Alt+D"));
+ displayControlsAction->setShortcut(Qt::ALT + Qt::Key_C);
displayControlsAction->setIcon(QIcon(":/control-points"));
- displayControlsAction->setStatusTip(tr("Display canvas controls"));
+ displayControlsAction->setToolTip(tr("Display canvas controls"));
displayControlsAction->setIconVisibleInMenu(false);
displayControlsAction->setCheckable(true);
displayControlsAction->setChecked(_displayControls);
+ addAction(displayControlsAction);
// Manage show/hide of canvas controls.
connect(displayControlsAction, SIGNAL(toggled(bool)), this, SLOT(enableDisplayControls(bool)));
// Toggle sticky vertices
stickyVerticesAction = new QAction(tr("&Sticky Vertices"), this);
- stickyVerticesAction->setShortcut(tr("Alt+S"));
+ stickyVerticesAction->setShortcut(Qt::ALT + Qt::Key_S);
stickyVerticesAction->setIcon(QIcon(":/control-points"));
- stickyVerticesAction->setStatusTip(tr("Enable sticky vertices"));
+ stickyVerticesAction->setToolTip(tr("Enable sticky vertices"));
stickyVerticesAction->setIconVisibleInMenu(false);
stickyVerticesAction->setCheckable(true);
stickyVerticesAction->setChecked(_stickyVertices);
+ addAction(stickyVerticesAction);
// Manage sticky vertices
connect(stickyVerticesAction, SIGNAL(toggled(bool)), this, SLOT(enableStickyVertices(bool)));
displayTestSignalAction = new QAction(tr("&Display Test Signal"), this);
- displayTestSignalAction->setShortcut(tr("Alt+T"));
+ displayTestSignalAction->setShortcut(Qt::ALT + Qt::Key_T);
displayTestSignalAction->setIcon(QIcon(":/control-points"));
- displayTestSignalAction->setStatusTip(tr("Display test signal"));
+ displayTestSignalAction->setToolTip(tr("Display test signal"));
displayTestSignalAction->setIconVisibleInMenu(false);
displayTestSignalAction->setCheckable(true);
displayTestSignalAction->setChecked(_displayTestSignal);
+ addAction(displayTestSignalAction);
// Manage show/hide of test signal
connect(displayTestSignalAction, SIGNAL(toggled(bool)), this, SLOT(enableTestSignal(bool)));
// Toggle display of Undo Stack
displayUndoStackAction = new QAction(tr("Display &Undo Stack"), this);
- displayUndoStackAction->setShortcut(tr("Ctrl+U"));
+ displayUndoStackAction->setShortcut(Qt::ALT + Qt::Key_U);
displayUndoStackAction->setCheckable(true);
displayUndoStackAction->setChecked(_displayUndoStack);
+ addAction(displayUndoStackAction);
// Manage show/hide of Undo Stack
connect(displayUndoStackAction, SIGNAL(toggled(bool)), this, SLOT(displayUndoStack(bool)));
+
+ // Toggle display of Console output
+ openConsoleAction = new QAction(tr("Open Conso&le"), this);
+ openConsoleAction->setShortcut(Qt::ALT + Qt::Key_L);
+ openConsoleAction->setCheckable(true);
+ openConsoleAction->setChecked(false);
+ addAction(openConsoleAction);
+ connect(openConsoleAction, SIGNAL(toggled(bool)), consoleWindow, SLOT(setVisible(bool)));
+ // uncheck action when window is closed
+ connect(consoleWindow, SIGNAL(windowClosed()), openConsoleAction, SLOT(toggle()));
+
+ // Toggle display of zoom tool buttons
+ displayZoomToolAction = new QAction(tr("Display &Zoom Toolbar"), this);
+ displayZoomToolAction->setShortcut(Qt::ALT + Qt::Key_Z);
+ displayZoomToolAction->setCheckable(true);
+ displayZoomToolAction->setChecked(true);
+ addAction(displayZoomToolAction);
+ connect(displayZoomToolAction, SIGNAL(toggled(bool)), sourceCanvas, SLOT(showZoomToolBar(bool)));
+ connect(displayZoomToolAction, SIGNAL(toggled(bool)), destinationCanvas, SLOT(showZoomToolBar(bool)));
+
+ // Toggle show/hide menuBar
+ showMenuBarAction = new QAction(tr("&Menu Bar"), this);
+ showMenuBarAction->setCheckable(true);
+ showMenuBarAction->setChecked(_showMenuBar);
+ connect(showMenuBarAction, SIGNAL(toggled(bool)), this, SLOT(showMenuBar(bool)));
}
void MainWindow::startFullScreen()
@@ -1595,9 +1747,7 @@ void MainWindow::startFullScreen()
// Remove canvas controls.
displayControlsAction->setChecked(false);
// Display output window.
- displayOutputWindowAction->setChecked(true);
- // Send fullscreen.
- outputWindowFullScreenAction->setChecked(true);
+ outputFullScreenAction->setChecked(true);
}
void MainWindow::createMenus()
@@ -1618,22 +1768,21 @@ void MainWindow::createMenus()
fileMenu->addAction(saveAction);
fileMenu->addAction(saveAsAction);
fileMenu->addSeparator();
- fileMenu->addAction(importVideoAction);
- fileMenu->addAction(importImageAction);
+ fileMenu->addAction(importMediaAction);
fileMenu->addAction(addColorAction);
// Recent file separator
separatorAction = fileMenu->addSeparator();
recentFileMenu = fileMenu->addMenu(tr("Open Recents Projects"));
for (int i = 0; i < MaxRecentFiles; ++i)
- recentFileMenu->addAction(recentFileActions[i]);
+ recentFileMenu->addAction(recentFileActions[i]);
recentFileMenu->addAction(clearRecentFileActions);
// Recent import video
recentVideoMenu = fileMenu->addMenu(tr("Open Recents Videos"));
recentVideoMenu->addAction(emptyRecentVideos);
for (int i = 0; i < MaxRecentVideo; ++i)
- recentVideoMenu->addAction(recentVideoActions[i]);
+ recentVideoMenu->addAction(recentVideoActions[i]);
// Exit
fileMenu->addSeparator();
@@ -1642,31 +1791,60 @@ void MainWindow::createMenus()
// Edit.
editMenu = menuBar->addMenu(tr("&Edit"));
+ // Undo & Redo menu
editMenu->addAction(undoAction);
editMenu->addAction(redoAction);
- editMenu->addAction(deleteMappingAction);
+ editMenu->addSeparator();
+ // Source canvas menu
+ sourceMenu = editMenu->addMenu(tr("Source"));
+ sourceMenu->setEnabled(false);
+ sourceMenu->addAction(deletePaintAction);
+ sourceMenu->addAction(renamePaintAction);
+ // Destination canvas menu
+ destinationMenu = editMenu->addMenu(tr("Destination"));
+ destinationMenu->setEnabled(false);
+ destinationMenu->addAction(cloneMappingAction);
+ destinationMenu->addAction(deleteMappingAction);
+ destinationMenu->addAction(renameMappingAction);
+ editMenu->addSeparator();
+ // Preferences
editMenu->addAction(preferencesAction);
// View.
viewMenu = menuBar->addMenu(tr("&View"));
- viewMenu->addAction(displayOutputWindowAction);
- viewMenu->addAction(outputWindowFullScreenAction);
+ // Toolbars menu
+ toolBarsMenu = viewMenu->addMenu(tr("Toolbars"));
+#ifdef Q_OS_LINUX
+ if (QString(getenv("XDG_CURRENT_DESKTOP")).toLower() != "unity")
+ toolBarsMenu->addAction(showMenuBarAction);
+#endif
+#ifdef Q_OS_WIN
+ toolBarsMenu->addAction(showMenuBarAction);
+#endif
+ viewMenu->addSeparator();
viewMenu->addAction(displayControlsAction);
viewMenu->addAction(stickyVerticesAction);
viewMenu->addAction(displayTestSignalAction);
viewMenu->addSeparator();
viewMenu->addAction(displayUndoStackAction);
+ viewMenu->addAction(displayZoomToolAction);
+ viewMenu->addSeparator();
+ viewMenu->addAction(outputFullScreenAction);
// Run.
- runMenu = menuBar->addMenu(tr("&Run"));
- runMenu->addAction(playAction);
- runMenu->addAction(pauseAction);
- runMenu->addAction(rewindAction);
+ playbackMenu = menuBar->addMenu(tr("&Playback"));
+ playbackMenu->addAction(playAction);
+ playbackMenu->addAction(pauseAction);
+ playbackMenu->addAction(rewindAction);
+
+ // Tools
+ toolsMenu = menuBar->addMenu(tr("&Tools"));
+ toolsMenu->addAction(openConsoleAction);
// Help.
helpMenu = menuBar->addMenu(tr("&Help"));
helpMenu->addAction(aboutAction);
-// helpMenu->addAction(aboutQtAction);
+ // helpMenu->addAction(aboutQtAction);
}
@@ -1676,9 +1854,12 @@ void MainWindow::createMappingContextMenu()
mappingContextMenu = new QMenu(this);
// Add different Action
- mappingContextMenu->addAction(cloneAction);
+ 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);
@@ -1687,8 +1868,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()
@@ -1706,20 +1887,16 @@ 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()
{
- mainToolBar = addToolBar(tr("&File"));
+ mainToolBar = addToolBar(tr("&Toolbar"));
mainToolBar->setIconSize(QSize(MM::TOP_TOOLBAR_ICON_SIZE, MM::TOP_TOOLBAR_ICON_SIZE));
mainToolBar->setMovable(false);
- mainToolBar->addAction(importVideoAction);
- mainToolBar->addAction(importImageAction);
+ mainToolBar->addAction(importMediaAction);
mainToolBar->addAction(addColorAction);
- mainToolBar->addAction(newAction);
- mainToolBar->addAction(openAction);
- mainToolBar->addAction(saveAction);
mainToolBar->addSeparator();
@@ -1729,52 +1906,59 @@ void MainWindow::createToolBars()
mainToolBar->addSeparator();
- mainToolBar->addAction(displayOutputWindowAction);
- mainToolBar->addAction(outputWindowFullScreenAction);
- mainToolBar->addAction(displayControlsAction);
- mainToolBar->addAction(stickyVerticesAction);
+ mainToolBar->addAction(outputFullScreenAction);
mainToolBar->addAction(displayTestSignalAction);
- runToolBar = addToolBar(tr("&Run"));
- runToolBar->setIconSize(QSize(MM::TOP_TOOLBAR_ICON_SIZE, MM::TOP_TOOLBAR_ICON_SIZE));
- runToolBar->setMovable(false);
// XXX: style hack: dummy expanding widget allows the placement of toolbar at the top right
// From: http://www.qtcentre.org/threads/9102-QToolbar-setContentsMargins
- QWidget* spacer = new QWidget(runToolBar);
+ QWidget* spacer = new QWidget(mainToolBar);
spacer->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
- runToolBar->addWidget(spacer);
- runToolBar->addAction(playAction);
- runToolBar->addAction(pauseAction);
- runToolBar->addAction(rewindAction);
+ mainToolBar->addWidget(spacer);
+ mainToolBar->addAction(playAction);
+ mainToolBar->addAction(pauseAction);
+ mainToolBar->addAction(rewindAction);
+
+ // Disable toolbar context menu
+ mainToolBar->setContextMenuPolicy(Qt::PreventContextMenu);
+
+ // Toggle show/hide of toolbar
+ showToolBarAction = mainToolBar->toggleViewAction();
+ toolBarsMenu->addAction(showToolBarAction);
// Add toolbars.
addToolBar(Qt::TopToolBarArea, mainToolBar);
- addToolBar(Qt::TopToolBarArea, runToolBar);
-
-// editToolBar = addToolBar(tr("&Edit"));
-// editToolBar->addAction(cloneAction);
-// editToolBar->addAction(deleteAction);
-// editToolBar->addSeparator();
-// editToolBar->addAction(findAction);
-// editToolBar->addAction(goToCellAction);
}
void MainWindow::createStatusBar()
{
-// locationLabel = new QLabel(" W999 ");
-// locationLabel->setAlignment(Qt::AlignHCenter);
-// locationLabel->setMinimumSize(locationLabel->sizeHint());
-//
-// formulaLabel = new QLabel;
-// formulaLabel->setIndent(3);
-//
-// statusBar()->addWidget(locationLabel);
-// statusBar()->addWidget(formulaLabel, 1);
-//
-// connect(spreadsheet, SIGNAL(currentCellChanged(int, int, int, int)), this,
-// SLOT(updateStatusBar()));
-// connect(spreadsheet, SIGNAL(modified()), this, SLOT(spreadsheetModified()));
+ // Create canvases zoom level statut
+ destinationZoomLabel = new QLabel(statusBar());
+ destinationZoomLabel->setFrameStyle(QFrame::Panel | QFrame::Sunken);
+ destinationZoomLabel->setContentsMargins(2, 0, 0, 0);
+ sourceZoomLabel = new QLabel(statusBar());
+ sourceZoomLabel->setFrameStyle(QFrame::Panel | QFrame::Sunken);
+ sourceZoomLabel->setContentsMargins(2, 0, 0, 0);
+ // Undoview statut
+ undoLabel = new QLabel(statusBar());
+ undoLabel->setFrameStyle(QFrame::Panel | QFrame::Sunken);
+ undoLabel->setContentsMargins(2, 0, 0, 0);
+ // Standard message
+ currentMessageLabel = new QLabel(statusBar());
+ currentMessageLabel->setFrameStyle(QFrame::Panel | QFrame::Sunken);
+ currentMessageLabel->setContentsMargins(0, 0, 0, 0);
+ // Current location of the mouse
+ mousePosLabel = new QLabel(statusBar());
+ mousePosLabel->setFrameStyle(QFrame::Panel | QFrame::Sunken);
+ mousePosLabel->setContentsMargins(2, 0, 0, 0);
+ // Add permanently into the statut bar
+ statusBar()->addPermanentWidget(currentMessageLabel, 5);
+ statusBar()->addPermanentWidget(undoLabel, 4);
+ statusBar()->addPermanentWidget(mousePosLabel, 3);
+ statusBar()->addPermanentWidget(sourceZoomLabel, 1);
+ statusBar()->addPermanentWidget(destinationZoomLabel, 1);
+
+ // Update the status bar
updateStatusBar();
}
@@ -1795,15 +1979,11 @@ void MainWindow::readSettings()
// new in 0.1.2:
if (settings.contains("displayOutputWindow"))
{
- displayOutputWindowAction->setChecked(settings.value("displayOutputWindow").toBool());
- }
- if (settings.contains("outputWindowFullScreen"))
- {
- outputWindowFullScreenAction->setChecked(settings.value("outputWindowFullScreen").toBool());
+ outputFullScreenAction->setChecked(settings.value("displayOutputWindow").toBool());
}
if (settings.contains("displayTestSignal"))
{
- displayOutputWindowAction->setChecked(settings.value("displayTestSignal").toBool());
+ outputFullScreenAction->setChecked(settings.value("displayTestSignal").toBool());
}
config_osc_receive_port = settings.value("osc_receive_port", 12345).toInt();
@@ -1814,6 +1994,10 @@ void MainWindow::readSettings()
// new in 0.3.2
if (settings.contains("displayUndoStack"))
displayUndoStackAction->setChecked(settings.value("displayUndoStack").toBool());
+ if (settings.contains("zoomToolBar"))
+ displayZoomToolAction->setChecked(settings.value("zoomToolBar").toBool());
+ if (settings.contains("showMenuBar"))
+ showMenuBarAction->setChecked(settings.value("showMenuBar").toBool());
}
void MainWindow::writeSettings()
@@ -1826,11 +2010,12 @@ void MainWindow::writeSettings()
settings.setValue("mappingSplitter", mappingSplitter->saveState());
settings.setValue("canvasSplitter", canvasSplitter->saveState());
settings.setValue("outputWindow", outputWindow->saveGeometry());
- settings.setValue("displayOutputWindow", displayOutputWindowAction->isChecked());
- settings.setValue("outputWindowFullScreen", outputWindowFullScreenAction->isChecked());
+ settings.setValue("displayOutputWindow", outputFullScreenAction->isChecked());
settings.setValue("displayTestSignal", displayTestSignalAction->isChecked());
settings.setValue("osc_receive_port", config_osc_receive_port);
settings.setValue("displayUndoStack", displayUndoStackAction->isChecked());
+ settings.setValue("zoomToolBar", displayZoomToolAction->isChecked());
+ settings.setValue("showMenuBar", showMenuBarAction->isChecked());
}
bool MainWindow::okToContinue()
@@ -1838,9 +2023,9 @@ bool MainWindow::okToContinue()
if (isWindowModified())
{
int r = QMessageBox::warning(this, tr("MapMap"),
- tr("The document has been modified.\n"
- "Do you want to save your changes?"),
- QMessageBox::Yes | QMessageBox::No | QMessageBox::Cancel);
+ tr("The document has been modified.\n"
+ "Do you want to save your changes?"),
+ QMessageBox::Yes | QMessageBox::No | QMessageBox::Cancel);
if (r == QMessageBox::Yes)
{
return save();
@@ -1861,10 +2046,10 @@ bool MainWindow::loadFile(const QString &fileName)
if (! file.open(QFile::ReadOnly | QFile::Text))
{
QMessageBox::warning(this, tr("Error reading mapping project file"),
- tr("Cannot read file %1:\n%2.")
- .arg(fileName)
- .arg(file.errorString()));
- return false;
+ tr("Cannot read file %1:\n%2.")
+ .arg(fileName)
+ .arg(file.errorString()));
+ return false;
}
// Clear current project.
@@ -1875,9 +2060,9 @@ bool MainWindow::loadFile(const QString &fileName)
if (! reader.readFile(&file))
{
QMessageBox::warning(this, tr("Error reading mapping project file"),
- tr("Parse error in file %1:\n\n%2")
- .arg(fileName)
- .arg(reader.errorString()));
+ tr("Parse error in file %1:\n\n%2")
+ .arg(fileName)
+ .arg(reader.errorString()));
}
else
{
@@ -1895,9 +2080,9 @@ bool MainWindow::saveFile(const QString &fileName)
if (! file.open(QFile::WriteOnly | QFile::Text))
{
QMessageBox::warning(this, tr("Error saving mapping project"),
- tr("Cannot write file %1:\n%2.")
- .arg(fileName)
- .arg(file.errorString()));
+ tr("Cannot write file %1:\n%2.")
+ .arg(fileName)
+ .arg(file.errorString()));
return false;
}
@@ -1937,15 +2122,15 @@ void MainWindow::setCurrentFile(const QString &fileName)
void MainWindow::setCurrentVideo(const QString &fileName)
{
- curVideo = fileName;
+ curVideo = fileName;
- recentVideos = settings.value("recentVideos").toStringList();
- recentVideos.removeAll(curVideo);
- recentVideos.prepend(curVideo);
- while (recentVideos.size() > MaxRecentVideo)
- recentVideos.removeLast();
- settings.setValue("recentVideos", recentVideos);
- updateRecentVideoActions();
+ recentVideos = settings.value("recentVideos").toStringList();
+ recentVideos.removeAll(curVideo);
+ recentVideos.prepend(curVideo);
+ while (recentVideos.size() > MaxRecentVideo)
+ recentVideos.removeLast();
+ settings.setValue("recentVideos", recentVideos);
+ updateRecentVideoActions();
}
void MainWindow::updateRecentFileActions()
@@ -1956,14 +2141,14 @@ void MainWindow::updateRecentFileActions()
for (int j = 0; j < numRecentFiles; ++j)
{
QString text = tr("&%1 %2")
- .arg(j + 1)
- .arg(strippedName(recentFiles[j]));
+ .arg(j + 1)
+ .arg(strippedName(recentFiles[j]));
recentFileActions[j]->setText(text);
recentFileActions[j]->setData(recentFiles[j]);
recentFileActions[j]->setVisible(true);
clearRecentFileActions->setVisible(true);
}
-
+
for (int i = numRecentFiles; i < MaxRecentFiles; ++i)
{
recentFileActions[i]->setVisible(false);
@@ -1982,37 +2167,37 @@ void MainWindow::updateRecentFileActions()
void MainWindow::updateRecentVideoActions()
{
- recentVideos = settings.value("recentVideos").toStringList();
- int numRecentVideos = qMin(recentVideos.size(), int(MaxRecentVideo));
+ recentVideos = settings.value("recentVideos").toStringList();
+ int numRecentVideos = qMin(recentVideos.size(), int(MaxRecentVideo));
- for (int i = 0; i < numRecentVideos; ++i)
- {
- QString text = tr("&%1 %2")
- .arg(i + 1)
- .arg(strippedName(recentVideos[i]));
- recentVideoActions[i]->setText(text);
- recentVideoActions[i]->setData(recentVideos[i]);
- recentVideoActions[i]->setVisible(true);
- }
+ for (int i = 0; i < numRecentVideos; ++i)
+ {
+ QString text = tr("&%1 %2")
+ .arg(i + 1)
+ .arg(strippedName(recentVideos[i]));
+ recentVideoActions[i]->setText(text);
+ recentVideoActions[i]->setData(recentVideos[i]);
+ recentVideoActions[i]->setVisible(true);
+ }
- for (int j = numRecentVideos; j < MaxRecentVideo; ++j)
- recentVideoActions[j]->setVisible(false);
+ for (int j = numRecentVideos; j < MaxRecentVideo; ++j)
+ recentVideoActions[j]->setVisible(false);
- if (numRecentVideos > 0)
- {
- emptyRecentVideos->setVisible(false);
- }
+ if (numRecentVideos > 0)
+ {
+ emptyRecentVideos->setVisible(false);
+ }
}
void MainWindow::clearRecentFileList()
{
- recentFiles = settings.value("recentFiles").toStringList();
+ recentFiles = settings.value("recentFiles").toStringList();
- while (recentFiles.size() > 0)
- recentFiles.clear();
+ while (recentFiles.size() > 0)
+ recentFiles.clear();
- settings.setValue("recentFiles", recentFiles);
- updateRecentFileActions();
+ settings.setValue("recentFiles", recentFiles);
+ updateRecentFileActions();
}
// TODO
@@ -2025,6 +2210,9 @@ bool MainWindow::importMediaFile(const QString &fileName, bool isImage)
QFile file(fileName);
QDir currentDir;
+ if (!fileSupported(fileName, isImage))
+ return false;
+
bool live = false;
if (!file.open(QIODevice::ReadOnly)) {
if (file.isSequential())
@@ -2121,8 +2309,8 @@ void MainWindow::addPaintItem(uid paintId, const QIcon& icon, const QString& nam
paintPropertyPanel->setEnabled(true);
// When paint value is changed, update canvases.
-// connect(paintGui.get(), SIGNAL(valueChanged()),
-// this, SLOT(updateCanvases()));
+ // connect(paintGui.get(), SIGNAL(valueChanged()),
+ // this, SLOT(updateCanvases()));
connect(paintGui.data(), SIGNAL(valueChanged(Paint::ptr)),
this, SLOT(handlePaintChanged(Paint::ptr)));
@@ -2234,7 +2422,7 @@ void MainWindow::addMappingItem(uid mappingId)
connect(destinationCanvas, SIGNAL(shapeChanged(MShape*)),
mapper.data(), SLOT(updateShape(MShape*)));
-
+
// Switch to mapping tab.
contentTab->setCurrentWidget(mappingSplitter);
@@ -2337,7 +2525,7 @@ void MainWindow::clearWindow()
clearProject();
}
-bool MainWindow::fileExists(const QString file)
+bool MainWindow::fileExists(const QString &file)
{
QFileInfo checkFile(file);
@@ -2347,6 +2535,25 @@ bool MainWindow::fileExists(const QString file)
return false;
}
+bool MainWindow::fileSupported(const QString &file, bool isImage)
+{
+ QFileInfo fileInfo(file);
+ QString fileExtension = fileInfo.suffix();
+
+ if (isImage) {
+ if (MM::IMAGE_FILES_FILTER.contains(fileExtension, Qt::CaseInsensitive))
+ return true;
+ } else {
+ if (MM::VIDEO_FILES_FILTER.contains(fileExtension, Qt::CaseInsensitive))
+ return true;
+ }
+
+ QMessageBox::warning(this, tr("Warning"),
+ tr("The following file is not supported: %1")
+ .arg(fileInfo.fileName()));
+ return false;
+}
+
QString MainWindow::locateMediaFile(const QString &uri, bool isImage)
{
// Get more info about url
@@ -2363,18 +2570,18 @@ QString MainWindow::locateMediaFile(const QString &uri, bool isImage)
// Show a warning and offer to locate the file
QMessageBox::warning(this,
- tr("Cannot load movie"),
- tr("Unable to use the file « %1 » \n"
- "The original file is not found. Will you locate?")
- .arg(filename));
+ tr("Cannot load movie"),
+ tr("Unable to use the file « %1 » \n"
+ "The original file is not found. Will you locate?")
+ .arg(filename));
// Set the new uri
url = QFileDialog::getOpenFileName(this,
- tr("Locate file « %1 »").arg(filename),
- directory,
- tr("%1 files (%2)")
- .arg(mediaType)
- .arg(mediaFilter));
+ tr("Locate file « %1 »").arg(filename),
+ directory,
+ tr("%1 files (%2)")
+ .arg(mediaType)
+ .arg(mediaFilter));
return url;
}
@@ -2397,8 +2604,14 @@ void MainWindow::updateCanvases()
sourceCanvas->update();
destinationCanvas->update();
outputWindow->getCanvas()->update();
-}
+ // Update position of zoom toolbar
+ sourceCanvas->updateZoomToolbar();
+ destinationCanvas->updateZoomToolbar();
+
+ // Update statut bar
+ updateStatusBar();
+}
void MainWindow::enableDisplayControls(bool display)
{
@@ -2416,10 +2629,13 @@ void MainWindow::displayUndoStack(bool display)
{
_displayUndoStack = display;
+ // Create undo view.
+ undoView = new QUndoView(getUndoStack(), this);
+
if (display) {
contentTab->addTab(undoView, tr("Undo stack"));
} else {
- contentTab->removeTab(contentTab->indexOf(undoView));
+ contentTab->removeTab(2);
}
}
@@ -2431,6 +2647,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));
@@ -2457,11 +2680,17 @@ void MainWindow::connectProjectWidgets()
connect(paintList, SIGNAL(itemPressed(QListWidgetItem*)),
this, SLOT(handleItemSelected(QListWidgetItem*)));
-// connect(paintList, SIGNAL(itemDoubleClicked(QListWidgetItem*)),
-// this, SLOT(handleItemDoubleClicked(QListWidgetItem*)));
+ // connect(paintList, SIGNAL(itemDoubleClicked(QListWidgetItem*)),
+ // this, SLOT(handleItemDoubleClicked(QListWidgetItem*)));
connect(paintList, SIGNAL(itemActivated(QListWidgetItem*)),
this, SLOT(handleItemSelected(QListWidgetItem*)));
+ // Rename Paint with double click
+ connect(paintList, SIGNAL(itemDoubleClicked(QListWidgetItem*)),
+ this, SLOT(renamePaintItem()));
+ // When finish to edit mapping item
+ connect(paintList->itemDelegate(), SIGNAL(commitData(QWidget*)),
+ this, SLOT(paintListEditEnd(QWidget*)));
connect(mappingList, SIGNAL(itemSelectionChanged()),
this, SLOT(handleMappingItemSelectionChanged()));
@@ -2480,12 +2709,12 @@ void MainWindow::connectProjectWidgets()
connect(mappingList->model(), SIGNAL(rowsMoved(const QModelIndex&, int, int, const QModelIndex &, int)),
this, SLOT(handleMappingIndexesMoved()));
- // Rename mapping with double click
- connect(mappingList, SIGNAL(itemDoubleClicked(QListWidgetItem*)),
- this, SLOT(renameMappingItem()));
- // Rename Paint with double click
- connect(paintList, SIGNAL(itemDoubleClicked(QListWidgetItem*)),
- this, SLOT(renamePaintItem()));
+ // Rename mapping with double click
+ connect(mappingList, SIGNAL(itemDoubleClicked(QListWidgetItem*)),
+ this, SLOT(renameMappingItem()));
+ // When finish to edit mapping item
+ connect(mappingList->itemDelegate(), SIGNAL(commitData(QWidget*)),
+ this, SLOT(mappingListEditEnd(QWidget*)));
}
void MainWindow::disconnectProjectWidgets()
@@ -2563,7 +2792,7 @@ QIcon MainWindow::createImageIcon(const QString& filename) {
void MainWindow::setCurrentPaint(int uid)
{
if (uid == NULL_UID)
- removeCurrentPaint();
+ removeCurrentPaint();
else {
if (currentPaintId != uid) {
currentPaintId = uid;
@@ -2606,7 +2835,11 @@ void MainWindow::startOscReceiver()
int port = config_osc_receive_port;
std::ostringstream os;
os << port;
- std::cout << "OSC port: " << port << std::endl;
+#if QT_VERSION >= 0x050500
+ QMessageLogger(__FILE__, __LINE__, 0).info() << "OSC port: " << port ;
+#else
+ QMessageLogger(__FILE__, __LINE__, 0).debug() << "OSC port: " << port ;
+#endif
osc_interface.reset(new OscInterface(os.str()));
if (port != 0)
{
@@ -2684,7 +2917,7 @@ void MainWindow::pollOscInterface()
// std::cout << std::endl;
// std::cout.flush();
// }
-//
+//
// if (command.size() < 2)
// return;
// if (command.at(0).type() != QVariant::String)
@@ -2693,7 +2926,7 @@ void MainWindow::pollOscInterface()
// return;
// std::string path = command.at(0).toString().toStdString();
// std::string typetags = command.at(1).toString().toStdString();
-//
+//
// // Handle all OSC messages here
// if (path == "/image/uri" && typetags == "s")
// {
@@ -2714,38 +2947,38 @@ void MainWindow::pollOscInterface()
bool MainWindow::setTextureUri(int texture_id, const std::string &uri)
{
- // TODO: const QString &
+ // TODO: const QString &
- bool success = false;
- Paint::ptr paint = this->mappingManager->getPaintById(texture_id);
- if (paint.isNull())
+ bool success = false;
+ Paint::ptr paint = this->mappingManager->getPaintById(texture_id);
+ if (paint.isNull())
+ {
+ std::cout << "No such texture paint id " << texture_id << std::endl;
+ success = false;
+ }
+ else
+ {
+ if (paint->getType() == "media")
{
- std::cout << "No such texture paint id " << texture_id << std::endl;
- success = false;
+ 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.data(); // FIXME: use sharedptr cast
+ videoTimer->stop();
+ success = media->setUri(QString(uri.c_str()));
+ videoTimer->start();
}
else
{
- if (paint->getType() == "media")
- {
- 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.data(); // FIXME: use sharedptr cast
- videoTimer->stop();
- success = media->setUri(QString(uri.c_str()));
- videoTimer->start();
- }
- else
- {
- std::cout << "Paint id " << texture_id << " is not a media texture." << std::endl;
- return false;
- }
+ std::cout << "Paint id " << texture_id << " is not a media texture." << std::endl;
+ return false;
}
- return success;
+ }
+ return success;
}
bool MainWindow::setTextureRate(int texture_id, double rate)
@@ -2753,23 +2986,23 @@ bool MainWindow::setTextureRate(int texture_id, double rate)
Paint::ptr paint = this->mappingManager->getPaintById(texture_id);
if (paint.isNull())
{
- std::cout << "No such texture paint id " << texture_id << std::endl;
- return false;
+ std::cout << "No such texture paint id " << texture_id << std::endl;
+ return false;
}
else
{
- if (paint->getType() == "media")
- {
- Media *media = static_cast(paint.data()); // FIXME: use sharedptr cast
- videoTimer->stop();
- media->setRate(rate);
- videoTimer->start();
- }
- else
- {
- std::cout << "Paint id " << texture_id << " is not a media texture." << std::endl;
- return false;
- }
+ if (paint->getType() == "media")
+ {
+ Media *media = static_cast(paint.data()); // FIXME: use sharedptr cast
+ videoTimer->stop();
+ media->setRate(rate);
+ videoTimer->start();
+ }
+ else
+ {
+ std::cout << "Paint id " << texture_id << " is not a media texture." << std::endl;
+ return false;
+ }
}
return true;
}
@@ -2786,15 +3019,15 @@ bool MainWindow::setTextureVolume(int texture_id, double volume)
{
if (paint->getType() == "media")
{
- Media *media = static_cast(paint.data()); // FIXME: use sharedptr cast
- videoTimer->stop();
- media->setVolume(volume);
- videoTimer->start();
+ Media *media = static_cast(paint.data()); // FIXME: use sharedptr cast
+ videoTimer->stop();
+ media->setVolume(volume);
+ videoTimer->start();
}
else
{
- std::cout << "Paint id " << texture_id << " is not a media texture." << std::endl;
- return false;
+ std::cout << "Paint id " << texture_id << " is not a media texture." << std::endl;
+ return false;
}
}
return true;
diff --git a/MainWindow.h b/MainWindow.h
index 537fa63..7dbda87 100644
--- a/MainWindow.h
+++ b/MainWindow.h
@@ -28,6 +28,7 @@
#include
#include
#include
+#include
#include "MM.h"
@@ -39,6 +40,7 @@
#include "OutputGLWindow.h"
#include "PreferencesDialog.h"
+#include "ConsoleWindow.h"
#include "MappingManager.h"
@@ -70,6 +72,7 @@ protected:
// Events ///////////////////////////////////////////////////////////////////////////////////////////////////
void closeEvent(QCloseEvent *event);
bool eventFilter(QObject *obj, QEvent *event);
+ void keyPressEvent(QKeyEvent *event);
// Slots ////////////////////////////////////////////////////////////////////////////////////////////////////
private slots:
@@ -81,11 +84,11 @@ private slots:
void preferences();
bool save();
bool saveAs();
- void importVideo();
- void importImage();
+ void importMedia();
void addColor();
void about();
void updateStatusBar();
+ void showMenuBar(bool shown);
void openRecentFile();
void clearRecentFileList();
void openRecentVideo();
@@ -93,12 +96,17 @@ private slots:
// Edit menu.
void deleteItem();
// Context menu for mappings.
- void cloneItem();
+ 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();
void renamePaintItem();
+ void paintListEditEnd(QWidget* editor);
// Widget callbacks.
void handlePaintItemSelectionChanged();
@@ -179,7 +187,7 @@ public slots:
void deleteMapping(uid mappingId);
/// Clone/duplicate a mapping
- void cloneMappingItem(uid mappingId);
+ void duplicateMapping(uid mappingId);
/// Deletes/removes a paint and all associated mappigns.
void deletePaint(uid paintId, bool replace);
@@ -240,11 +248,13 @@ public:
void addPaintItem(uid paintId, const QIcon& icon, const QString& name);
void updatePaintItem(uid paintId, const QIcon& icon, const QString& name);
void removePaintItem(uid paintId);
- void renameMappingItem(uid mappingId, QString name);
- void renamePaintItem(uid paintId, QString name);
+ void renameMapping(uid mappingId, const QString& name);
+ void renamePaint(uid paintId, const QString& name);
void clearWindow();
// Check if the file exists
- bool fileExists(const QString file);
+ bool fileExists(const QString& file);
+ // Check if the file is supported
+ bool fileSupported(const QString& file, bool isImage);
// Locate the file not found
QString locateMediaFile(const QString& uri, bool isImage);
@@ -273,32 +283,40 @@ private:
QMenu *fileMenu;
QMenu *editMenu;
QMenu *viewMenu;
- QMenu *runMenu;
+ QMenu *toolsMenu;
+ QMenu *playbackMenu;
QMenu *helpMenu;
QMenu *recentFileMenu;
QMenu *recentVideoMenu;
QMenu *mappingContextMenu;
QMenu *paintContextMenu;
+ // Some menus when need to be separated
+ QMenu *sourceMenu;
+ QMenu *destinationMenu;
+ QMenu *toolBarsMenu;
// Toolbar.
QToolBar *mainToolBar;
- QToolBar *runToolBar;
// Actions.
QAction *separatorAction;
QAction *newAction;
QAction *openAction;
- QAction *importVideoAction;
- QAction *importImageAction;
+ QAction *importMediaAction;
QAction *addColorAction;
QAction *saveAction;
QAction *saveAsAction;
QAction *exitAction;
QAction *undoAction;
QAction *redoAction;
- QAction *cloneAction;
+ // 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;
@@ -314,13 +332,15 @@ private:
QAction *pauseAction;
QAction *rewindAction;
- QAction *displayOutputWindowAction;
- //QAction *outputWindowHasCursor;
- QAction *outputWindowFullScreenAction;
+ QAction *outputFullScreenAction;
QAction *displayControlsAction;
QAction *displayTestSignalAction;
QAction *stickyVerticesAction;
QAction *displayUndoStackAction;
+ QAction *displayZoomToolAction;
+ QAction *openConsoleAction;
+ QAction *showMenuBarAction;
+ QAction *showToolBarAction;
enum { MaxRecentFiles = 10 };
enum { MaxRecentVideo = 5 };
@@ -343,6 +363,7 @@ private:
SourceGLCanvas* sourceCanvas;
DestinationGLCanvas* destinationCanvas;
OutputGLWindow* outputWindow;
+ ConsoleWindow* consoleWindow;
QSplitter* mainSplitter;
QSplitter* canvasSplitter;
@@ -398,6 +419,9 @@ private:
bool _displayUndoStack;
+ // Menu bar hidden state
+ bool _showMenuBar;
+
// Keeps track of the current selected item, wether it's a paint or mapping.
QListWidgetItem* currentSelectedItem;
QTimer *videoTimer;
@@ -407,6 +431,12 @@ private:
// UndoStack
QUndoStack *undoStack;
+ // Labels for status bar
+ QLabel *destinationZoomLabel;
+ QLabel *sourceZoomLabel;
+ QLabel *undoLabel;
+ QLabel *currentMessageLabel;
+ QLabel *mousePosLabel;
public:
@@ -415,6 +445,8 @@ public:
MappingGui::ptr getMappingGuiByMappingId(uint id) const { return mappers[id]; }
uid getCurrentPaintId() const { return currentPaintId; }
uid getCurrentMappingId() const { return currentMappingId; }
+ Mapping::ptr getCurrentMapping() const { return mappingManager->getMappingById(currentMappingId); }
+ Paint::ptr getCurrentPaint() const { return mappingManager->getPaintById(currentPaintId); }
OutputGLWindow* getOutputWindow() const { return outputWindow; }
bool hasCurrentPaint() const { return _hasCurrentPaint; }
bool hasCurrentMapping() const { return _hasCurrentMapping; }
diff --git a/MapperGLCanvas.cpp b/MapperGLCanvas.cpp
index b72f899..2a41d7e 100644
--- a/MapperGLCanvas.cpp
+++ b/MapperGLCanvas.cpp
@@ -30,7 +30,8 @@ MapperGLCanvas::MapperGLCanvas(MainWindow* mainWindow, QWidget* parent, const QG
_activeVertex(NO_VERTEX),
_shapeGrabbed(false), // comment out?
_shapeFirstGrab(false), // comment out?
- _zoomLevel(0)
+ _zoomLevel(0),
+ _shapeIsAdapted(false)
{
// For now clicking on the window doesn't do anything.
setDragMode(QGraphicsView::NoDrag);
@@ -54,6 +55,11 @@ MapperGLCanvas::MapperGLCanvas(MainWindow* mainWindow, QWidget* parent, const QG
setViewport(new QGLWidget(QGLFormat(QGL::SampleBuffers), this, shareWidget));
setViewportUpdateMode(QGraphicsView::FullViewportUpdate);
+ // Create zoom tools layout
+ createZoomToolsLayout();
+ // Disable zoom tool buttons
+ enableZoomToolBar(false);
+
// TODO: do we need to delete scene (or call new QGraphicsScene(this)?)
setScene(scene ? scene : new QGraphicsScene);
@@ -63,12 +69,12 @@ MapperGLCanvas::MapperGLCanvas(MainWindow* mainWindow, QWidget* parent, const QG
MShape::ptr MapperGLCanvas::getCurrentShape()
{
- return getShapeFromMappingId(MainWindow::instance()->getCurrentMappingId());
+ return getShapeFromMapping(MainWindow::instance()->getCurrentMapping());
}
QSharedPointer MapperGLCanvas::getCurrentShapeGraphicsItem()
{
- return getShapeGraphicsItemFromMappingId(MainWindow::instance()->getCurrentMappingId());
+ return getShapeGraphicsItemFromMapping(MainWindow::instance()->getCurrentMapping());
}
// Draws foreground (displays crosshair if needed).
@@ -98,6 +104,97 @@ void MapperGLCanvas::currentShapeWasChanged()
emit shapeChanged(getCurrentShape().data());
}
+void MapperGLCanvas::applyZoomToView()
+{
+ // Re-bound zoom (for consistency).
+ qreal zoomFactor = getZoomFactor();
+ // Get first of the list of all the views
+ QGraphicsView* view = this->scene()->views().first();
+ // Resets the view transformation matrix
+ view->resetMatrix();
+ // Scale the current view
+ view->scale(zoomFactor, zoomFactor);
+ // And update
+ view->update();
+ // Update dropdown menu
+ updateDropdownMenu();
+}
+
+void MapperGLCanvas::createZoomToolsLayout()
+{
+ // Create zoom tool bar
+ _zoomToolBar = new QWidget(this);
+ _zoomToolBar->setObjectName("zoom-toolbox");
+
+ // Create vertical layout for widgets
+ QHBoxLayout* buttonsLayout = new QHBoxLayout;
+ buttonsLayout->setContentsMargins(0, 0, 5, 0);
+ // Create buttons
+ // Zoom In button
+ _zoomInButton = new QPushButton;
+ _zoomInButton->setIcon(QIcon(":/zoom-in"));
+ _zoomInButton->setIconSize(QSize(MM::ZOOM_TOOLBAR_ICON_SIZE, MM::ZOOM_TOOLBAR_ICON_SIZE));
+ _zoomInButton->setToolTip(tr("Enlarge the shape"));
+ _zoomInButton->setFixedSize(MM::ZOOM_TOOLBAR_BUTTON_SIZE, MM::ZOOM_TOOLBAR_BUTTON_SIZE);
+ _zoomInButton->setObjectName("zoom-in");
+ connect(_zoomInButton, SIGNAL(clicked()), this, SLOT(increaseZoomLevel()));
+ // Zoom Out button
+ _zoomOutButton = new QPushButton;
+ _zoomOutButton->setIcon(QIcon(":/zoom-out"));
+ _zoomOutButton->setIconSize(QSize(MM::ZOOM_TOOLBAR_ICON_SIZE, MM::ZOOM_TOOLBAR_ICON_SIZE));
+ _zoomOutButton->setToolTip(tr("Shrink the shape"));
+ _zoomOutButton->setFixedSize(MM::ZOOM_TOOLBAR_BUTTON_SIZE, MM::ZOOM_TOOLBAR_BUTTON_SIZE);
+ _zoomOutButton->setObjectName("zoom-out");
+ connect(_zoomOutButton, SIGNAL(clicked()), this, SLOT(decreaseZoomLevel()));
+ // Reset to normal size button.
+ _resetZoomButton = new QPushButton;
+ _resetZoomButton->setIcon(QIcon(":/reset-zoom"));
+ _resetZoomButton->setIconSize(QSize(MM::ZOOM_TOOLBAR_ICON_SIZE, MM::ZOOM_TOOLBAR_ICON_SIZE));
+ _resetZoomButton->setToolTip(tr("Reset the shape to the normal size"));
+ _resetZoomButton->setFixedSize(MM::ZOOM_TOOLBAR_BUTTON_SIZE, MM::ZOOM_TOOLBAR_BUTTON_SIZE);
+ _resetZoomButton->setObjectName("reset-zoom");
+ connect(_resetZoomButton, SIGNAL(clicked()), this, SLOT(resetZoomLevel()));
+ // Fit to view button
+ _fitToViewButton = new QPushButton;
+ _fitToViewButton->setIcon(QIcon(":/zoom-fit"));
+ _fitToViewButton->setIconSize(QSize(MM::ZOOM_TOOLBAR_ICON_SIZE, MM::ZOOM_TOOLBAR_ICON_SIZE));
+ _fitToViewButton->setToolTip(tr("Fit the shape to content view"));
+ _fitToViewButton->setFixedSize(MM::ZOOM_TOOLBAR_BUTTON_SIZE, MM::ZOOM_TOOLBAR_BUTTON_SIZE);
+ _fitToViewButton->setObjectName("zoom-fit");
+ connect(_fitToViewButton, SIGNAL(clicked()), this, SLOT(fitShapeInView()));
+
+ // Create separator
+ QFrame *separator = new QFrame(_zoomToolBar);
+ separator->setFixedSize(5, 30);
+ separator->setFrameShape(QFrame::VLine);
+
+ // Create the dropdowm menu
+ _dropdownMenu = new QComboBox;
+ // make some settings
+ _dropdownMenu->setObjectName("dropdown-menu");
+ // Create if empty or update list
+ updateDropdownMenu();
+ // And listen
+ connect(_dropdownMenu, SIGNAL(activated(QString)), this, SLOT(setZoomFromMenu(QString)));
+
+ // Add widgets into layout
+ buttonsLayout->addWidget(_zoomInButton);
+ buttonsLayout->addWidget(_zoomOutButton);
+ buttonsLayout->addWidget(_resetZoomButton);
+ buttonsLayout->addWidget(_fitToViewButton);
+ buttonsLayout->addWidget(separator);
+ buttonsLayout->addWidget(_dropdownMenu);
+
+ // Insert layout in widget
+ _zoomToolBar->setLayout(buttonsLayout);
+}
+
+void MapperGLCanvas::updateZoomToolbar()
+{
+ _zoomToolBar->move(this->viewport()->width() - _zoomToolBar->width(),
+ this->viewport()->height() - _zoomToolBar->height());
+}
+
//
void MapperGLCanvas::mousePressEvent(QMouseEvent* event)
@@ -139,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);
@@ -161,7 +259,7 @@ void MapperGLCanvas::mousePressEvent(QMouseEvent* event)
QVector mappings = manager.getVisibleMappings();
for (QVector::const_iterator it = mappings.end() - 1; it >= mappings.begin(); --it)
{
- MShape::ptr shape = getShapeFromMappingId((*it)->getId());
+ MShape::ptr shape = getShapeFromMapping(*it);
// Check if mouse was pressed on that shape.
if (shape && shape->includesPoint(pos))
@@ -190,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)
@@ -317,47 +424,95 @@ void MapperGLCanvas::keyPressEvent(QKeyEvent* event)
{
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();
+ if (event->modifiers() & Qt::ShiftModifier) {
+
+ // SHIFT + directional keys allow move with large steps
+ if (event->key() == Qt::Key_Up)
+ pos.ry() -= MM::VERTEX_MOVES_STEP;
+ else if (event->key() == Qt::Key_Down)
+ pos.ry() += MM::VERTEX_MOVES_STEP;
+ else if (event->key() == Qt::Key_Right)
+ pos.rx() += MM::VERTEX_MOVES_STEP;
+ else if (event->key() == Qt::Key_Left)
+ pos.rx() -= MM::VERTEX_MOVES_STEP;
+
+ // SHIFT+Space to switch between vertex
+ else if (event->key() == Qt::Key_Space) {
+ if (shape)
+ _activeVertex = (_activeVertex + 1) % shape->nVertices();
+ pos = shape->getVertex(_activeVertex).toPoint(); // reset to new vertex
+ }
- else if (event->matches(QKeySequence::Redo))
- undoStack->redo();
else
handledKey = false;
- break;
+ }
+ else
+ {
+ switch (event->key()) {
+ 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:
+ handledKey = false;
+ break;
+ }
}
- // Remap window position to scene.
- QPointF scenePos = mapToScene(pos);
+ if (handledKey)
+ // Enable to Undo and Redo when arrow keys move the position of vertices
+ undoStack->push(new MoveVertexCommand(this, TransformShapeCommand::STEP, _activeVertex, 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));
+ else {
+ // Take scroll bar current coordinate
+ int scrollX = this->horizontalScrollBar()->value();
+ int scrollY = this->verticalScrollBar()->value();
+
+ handledKey = true;
+ if (event->matches(QKeySequence::Undo))
+ undoStack->undo();
+ else if (event->matches(QKeySequence::Redo))
+ undoStack->redo();
+ // Case 1: zoom in with CTRL++
+ else if (event->matches(QKeySequence::ZoomIn))
+ increaseZoomLevel();
+ else if (event->matches(QKeySequence::ZoomOut))
+ decreaseZoomLevel();
+ else if (event->modifiers() & Qt::ControlModifier) {
+ if(event->key() == Qt::Key_0)
+ resetZoomLevel();
+ // Case 2: zoom in with CTRL+=
+ else if (event->key() == Qt::Key_Equal ||
+ // Case 3: zoom in with CTRL+SHIFT++
+ (event->modifiers() & Qt::ShiftModifier && event->key() == Qt::Key_Plus))
+ increaseZoomLevel();
+ }
+ else if(event->key() == Qt::Key_Up)
+ scrollY -= 50;
+ else if(event->key() == Qt::Key_Down)
+ scrollY += 50;
+ else if(event->key() == Qt::Key_Right)
+ scrollX += 50;
+ else if(event->key() == Qt::Key_Left)
+ scrollX -= 50;
+ else
+ handledKey = false;
+
+ // Set scroll bar new value
+ this->verticalScrollBar()->setValue(scrollY);
+ this->horizontalScrollBar()->setValue(scrollX);
}
// Defer unhandled keys to parent.
@@ -365,60 +520,7 @@ void MapperGLCanvas::keyPressEvent(QKeyEvent* event)
{
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;
-// }
-// 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();
}
-//
-//void MapperGLCanvas::paintEvent(QPaintEvent* )
-//{
-// makeCurrent();
-//
-// QPainter painter(this);
-// painter.setRenderHint(QPainter::Antialiasing);
-//
-// draw(&painter);
-//
-// painter.end();
-//}
void MapperGLCanvas::updateCanvas()
{
@@ -426,31 +528,6 @@ void MapperGLCanvas::updateCanvas()
scene()->update();
}
-///* Stick vertex p of Shape orig to another Shape's vertex, if the 2 vertices are
-// * close enough. The distance per coordinate is currently set in dist_stick
-// * variable. Perhaps the sticky-sensitivity should be configurable through GUI */
-//void MapperGLCanvas::glueVertex(MShape *orig, QPointF *p)
-//{
-// MappingManager manager = getMainWindow()->getMappingManager();
-// for (int i = 0; i < manager.nMappings(); i++)
-// {
-// MShape *shape = getShapeFromMappingId(manager.getMapping(i)->getId());
-// if (shape && shape != orig)
-// {
-// for (int vertex = 0; vertex < shape->nVertices(); vertex++)
-// {
-// const QPointF& v = shape->getVertex(vertex);
-// if (distIsInside(v, *p, MM::VERTEX_STICK_RADIUS))
-// {
-// p->setX(v.x());
-// p->setY(v.y());
-// }
-// }
-// }
-// }
-//}
-
-
void MapperGLCanvas::deselectVertices()
{
_activeVertex = NO_VERTEX;
@@ -466,38 +543,25 @@ void MapperGLCanvas::deselectAll()
void MapperGLCanvas::wheelEvent(QWheelEvent *event)
{
+ // [-120]-----[-1]|[1]++++++[120]
+ // See: http://doc.qt.io/qt-5/qwheelevent.html#angleDelta
+#if QT_VERSION >= 0x050500
+ int deltaLevel = event->angleDelta().y() / 120;
+#else
int deltaLevel = event->delta() / 120;
- qreal zoomFactor = qPow(MM::ZOOM_FACTOR, _zoomLevel);
+#endif
+
if (deltaLevel > 0)
{
- // First check if we're already at max.
- while (deltaLevel && zoomFactor < MM::ZOOM_MAX) {
- _zoomLevel++;
- deltaLevel--;
- zoomFactor = qPow(MM::ZOOM_FACTOR, _zoomLevel);
- }
- zoomFactor = qMin(zoomFactor, MM::ZOOM_MAX);
+ // Increase zoom level
+ increaseZoomLevel(deltaLevel);
}
else
{
- // First check if we're already at min.
- while (deltaLevel && zoomFactor > MM::ZOOM_MIN) {
- _zoomLevel--;
- deltaLevel++;
- zoomFactor = qPow(MM::ZOOM_FACTOR, _zoomLevel);
- }
- zoomFactor = qMax(zoomFactor, MM::ZOOM_MIN);
+ // Decrease zoom level
+ decreaseZoomLevel(-deltaLevel);
}
- // Re-bound zoom (for consistency).
- zoomFactor = getZoomFactor();
-
- // Apply zoom to view.
- QGraphicsView* view = scene()->views().first();
- view->resetMatrix();
- view->scale(zoomFactor, zoomFactor);
- view->update();
-
// Accept wheel scrolling event.
event->accept();
}
@@ -517,6 +581,121 @@ bool MapperGLCanvas::eventFilter(QObject *target, QEvent *event)
}
}
+void MapperGLCanvas::increaseZoomLevel(int steps)
+{
+ qreal zoomFactor = qPow(MM::ZOOM_FACTOR, _zoomLevel);
+
+ while (steps > 0 && zoomFactor < MM::ZOOM_MAX) {
+ _zoomLevel++;
+ zoomFactor = qPow(MM::ZOOM_FACTOR, _zoomLevel);
+ steps--;
+ }
+ zoomFactor = qMin(zoomFactor, MM::ZOOM_MAX);
+
+ // Reset adaptation
+ _shapeIsAdapted = false;
+
+ // Apply to view
+ applyZoomToView();
+}
+
+void MapperGLCanvas::decreaseZoomLevel(int steps)
+{
+ qreal zoomFactor = qPow(MM::ZOOM_FACTOR, _zoomLevel);
+
+ while (steps > 0 && zoomFactor > MM::ZOOM_MIN) {
+ _zoomLevel--;
+ zoomFactor = qPow(MM::ZOOM_FACTOR, _zoomLevel);
+ steps--;
+ }
+ zoomFactor = qMax(zoomFactor, MM::ZOOM_MIN);
+
+ // Reset adaptation
+ _shapeIsAdapted = false;
+
+ // Apply to view
+ applyZoomToView();
+}
+
+void MapperGLCanvas::resetZoomLevel()
+{
+ // Reset zoom level to zero
+ _zoomLevel = 0;
+
+ // Reset adaptation
+ _shapeIsAdapted = false;
+
+ // Apply to view
+ applyZoomToView();
+}
+
+void MapperGLCanvas::fitShapeInView()
+{
+ // Get first of the list of all the views
+ QGraphicsView* view = scene()->views().first();
+ // Scales the view matrix
+ view->fitInView(this->scene()->itemsBoundingRect(), Qt::KeepAspectRatio);
+ // Get the horizontal scaling factor
+ _scalingFactor = view->matrix().m11();
+
+ // Adapt shape
+ _shapeIsAdapted = true;
+
+ // Update zoom menu list
+ updateDropdownMenu();
+}
+
+void MapperGLCanvas::showZoomToolBar(bool visible)
+{
+ if (visible)
+ _zoomToolBar->show();
+ else
+ _zoomToolBar->hide();
+}
+
+void MapperGLCanvas::enableZoomToolBar(bool enabled)
+{
+ // Enable/Disable all button
+ _zoomInButton->setEnabled(enabled);
+ _zoomOutButton->setEnabled(enabled);
+ _resetZoomButton->setEnabled(enabled);
+ _fitToViewButton->setEnabled(enabled);
+ _dropdownMenu->setEnabled(enabled);
+}
+
+void MapperGLCanvas::setZoomFromMenu(const QString &text)
+{
+ // Get text choosen by user and convert it to double
+ qreal zoomFactor = text.mid(0, text.length() - 1).toDouble();
+ // Set zoom factor
+ _scalingFactor = zoomFactor / 100;
+
+ // Adapt shape
+ _shapeIsAdapted = true;
+
+ // Apply to view
+ applyZoomToView();
+}
+
+void MapperGLCanvas::updateDropdownMenu()
+{
+ // Get current zoom factor percentage
+ QString zoomFactor = QString::number(int(getZoomFactor() * 100)).append(QChar('%'));
+ //Create list
+ QStringList zoomFactorList;
+ zoomFactorList << "400%" << "300%" << "200%" << "150%" << "125%" <<
+ "100%" << "75%" << "50%" << "25%" << "12.5%";
+ // Avoid duplicate
+ if (!zoomFactorList.contains(zoomFactor))
+ zoomFactorList.append(zoomFactor);
+ // Clear if is not empty
+ _dropdownMenu->clear();
+ // Add list item
+ _dropdownMenu->addItems(zoomFactorList);
+ // Select 100% by default
+ _dropdownMenu->setCurrentText(zoomFactor);
+}
+
void MapperGLCanvas::_glueVertex(QPointF* p)
{
diff --git a/MapperGLCanvas.h b/MapperGLCanvas.h
index 0124686..2738e21 100644
--- a/MapperGLCanvas.h
+++ b/MapperGLCanvas.h
@@ -54,8 +54,8 @@ public:
/// Returns shape associated with mapping id.
virtual bool isOutput() const = 0;
- virtual MShape::ptr getShapeFromMappingId(uid mappingId) const = 0;
- virtual QSharedPointer getShapeGraphicsItemFromMappingId(uid mappingId) const = 0;
+ virtual MShape::ptr getShapeFromMapping(const Mapping::ptr& mapping) const = 0;
+ virtual QSharedPointer getShapeGraphicsItemFromMapping(const Mapping::ptr& mapping) const = 0;
MShape::ptr getCurrentShape();
QSharedPointer getCurrentShapeGraphicsItem();
@@ -86,11 +86,19 @@ public:
bool shapeGrabbed() const { return _shapeGrabbed; }
bool vertexGrabbed() const { return _vertexGrabbed; }
- qreal getZoomFactor() const { return qBound(qPow(MM::ZOOM_FACTOR, _zoomLevel), MM::ZOOM_MIN, MM::ZOOM_MAX); }
+ //qreal getZoomFactor() const { return qBound(qPow(MM::ZOOM_FACTOR, _zoomLevel), MM::ZOOM_MIN, MM::ZOOM_MAX); }
+ qreal getZoomFactor() const { return _shapeIsAdapted
+ ? _scalingFactor
+ : qBound(MM::ZOOM_MIN, qPow(MM::ZOOM_FACTOR, _zoomLevel), 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();
+ // Apply zoom to view
+ void applyZoomToView();
+ // Refresh the zoom toolbar position
+ void updateZoomToolbar();
+
protected:
// void initializeGL();
// void resizeGL(int width, int height);
@@ -147,12 +155,30 @@ private:
// The zoom level (in number of steps).
int _zoomLevel;
+ // The scaling factor
+ qreal _scalingFactor;
+
+ bool _shapeIsAdapted;
+
// Pointer to MainWindow UndoStack
QUndoStack *undoStack;
+ // Buttons for toolbox layout
+ QWidget* _zoomToolBar;
+ QPushButton* _zoomInButton;
+ QPushButton* _zoomOutButton;
+ QPushButton* _resetZoomButton;
+ QPushButton* _fitToViewButton;
+ // Dropdown menu
+ QComboBox* _dropdownMenu;
+
+ // Create zoom tool buttons
+ void createZoomToolsLayout();
+
signals:
void shapeChanged(MShape*);
void imageChanged();
+ void shapeContextMenuRequested(const QPoint &pos);
public slots:
void updateCanvas();
@@ -168,6 +194,20 @@ public slots:
// Event Filter
bool eventFilter(QObject *target, QEvent *event);
+ // Zoom
+ void increaseZoomLevel(int steps=1);
+ void decreaseZoomLevel(int steps=1);
+ void resetZoomLevel();
+ void fitShapeInView();
+
+ // Show/Hide zoom tool buttons
+ void showZoomToolBar(bool visible);
+ void enableZoomToolBar(bool enabled);
+ // Set zoom factor with drowmenu data
+ void setZoomFromMenu(const QString& text);
+ // Update and feedback zoom level
+ void updateDropdownMenu();
+
protected:
// TODO: Perhaps the sticky-sensitivity should be configurable through GUI
void _glueVertex(QPointF* p);
diff --git a/Mapping.h b/Mapping.h
index 30f2904..618f0a3 100644
--- a/Mapping.h
+++ b/Mapping.h
@@ -165,6 +165,7 @@ public:
virtual QString getType() const {
return getShape()->getType() + "_color";
}
+
};
/**
diff --git a/MappingManager.cpp b/MappingManager.cpp
index b421f3f..e48a767 100644
--- a/MappingManager.cpp
+++ b/MappingManager.cpp
@@ -145,6 +145,31 @@ QVector MappingManager::getVisibleMappings() const
return visible;
}
+/// Returns true iff the mapping is visible.
+bool MappingManager::mappingIsVisible(Mapping::ptr mapping) const
+{
+ // Solo mappings are always visible.
+ if (mapping->isSolo())
+ return true;
+
+ // Non-solo invisible mappings are always invisible.
+ else if (!mapping->isVisible())
+ return false;
+
+ // Mapping is non-solo yet visible: check if another mapping is solo (which would thus make it invisible).
+ else
+ {
+ for (QVector::const_iterator it = mappingVector.begin(); it != mappingVector.end(); ++it)
+ {
+ if ((*it)->isSolo())
+ return false;
+ }
+
+ // Mapping is non-solo yet visible and there are no solo mappings.
+ return true;
+ }
+}
+
void MappingManager::reorderMappings(QVector mappingIds)
{
// Both vector needs to have the same size.
diff --git a/MappingManager.h b/MappingManager.h
index 2f2a9c0..f81158f 100644
--- a/MappingManager.h
+++ b/MappingManager.h
@@ -100,8 +100,12 @@ public:
/// Reorders the mappings according to given list of uids. QVector needs to
void reorderMappings(QVector mappingIds);
+ /// Returns the ordered list of visible mappings, using both the "visible" and "solo" properties.
QVector getVisibleMappings() const;
+ /// Returns true iff the mapping is visible.
+ bool mappingIsVisible(Mapping::ptr mapping) const;
+
void clearAll();
};
diff --git a/NEWS b/NEWS
index 2f34c26..3cba2f3 100644
--- a/NEWS
+++ b/NEWS
@@ -3,7 +3,33 @@ Release notes for MapMap
2015-??-?? - MapMap 0.3.2
-------------------------
-* (none)
+* Added zoom toolbar
+* Added console window
+* Fix #179: Paints and mappings renamings are now saved in file
+* Fix #162: Zooming in the destination canvas changes the size of controls in output window.
+* Fix #154: Problem with some video files: shape is size of single point
+* Can rename paints and mappings via OSC
+* Can rename paints and mappings with double click
+* Fix #156: White rectangle around the fullscreen window
+* Fix #152: The software frozen when we load a project and the video files are not found
+* Abled to locate the video files if is not found when load a project
+* Fix #149: Deleting a mapping actually deletes a paint when the paint tab is chosen
+* Improved Test signal
+* Enhancement #117: Ellipse conical projection
+* Performance improvements
+* OSC general bug fixes
+* OSC support on OSX
+* Done #174: Be able to rename a Paint
+* DOne #72: Be able to name paints and mappings - for OSC controls
+* Center the test signal #97 (must use all the space available)
+* Fix #159: Program just freezes when importing corrupted video file
+* Done #145: The user doesn't need to see the undo stack
+* Done #40: Ctrl-Q should quit the application
+* Done #183: Display logging output in a console and be able to turn it on and off
+* Done #203: The toolbar can be shown or hidden at will by the user
+* Done #147: Be able to delete a mapping with the delete key #147 (tested on Ubuntu)
+* Done #184: Make sure names support UTF-8 characters
+* Done #201 UX Design document: implement main toolbar improvements
2015-10-30 - MapMap 0.3.1
-------------------------
diff --git a/OscInterface.cpp b/OscInterface.cpp
index a08242d..001901c 100644
--- a/OscInterface.cpp
+++ b/OscInterface.cpp
@@ -41,7 +41,7 @@ OscInterface::OscInterface(
//if (listen_port != OSC_PORT_NONE)
receiving_enabled_ = true;
if (receiving_enabled_) {
- std::cout << "Listening osc.udp://localhost:" << listen_port << std::endl;
+ QMessageLogger(__FILE__, __LINE__, 0).debug() << "Listening osc.udp://localhost:" << listen_port.c_str();
// receiver_.addHandler("/ping", "", ping_cb, this);
// receiver_.addHandler("/pong", "", pong_cb, this);
//receiver_.addHandler("/image/path", "ss", image_path_cb, this);
@@ -60,7 +60,7 @@ int OscInterface::pong_cb(const char *path, const char * /*types*/,
lo_arg ** /*argv*/, int /*argc*/, void * /*data*/, void *user_data) {
OscInterface* context = static_cast(user_data);
if (context->is_verbose())
- std::cout << "Got " << path << std::endl;
+ QMessageLogger(__FILE__, __LINE__, 0).debug() << "Got " << path;
return 0;
}
@@ -71,7 +71,7 @@ int OscInterface::ping_cb(const char *path, const char * /*types*/,
lo_arg ** /*argv*/, int /*argc*/, void * /*data*/, void *user_data) {
OscInterface* context = static_cast(user_data);
if (context->is_verbose())
- std::cout << "Got " << path << std::endl;
+ QMessageLogger(__FILE__, __LINE__, 0).debug() << "Got " << path;
return 0;
}
diff --git a/OscInterface.h b/OscInterface.h
index dfdc121..61415aa 100644
--- a/OscInterface.h
+++ b/OscInterface.h
@@ -27,8 +27,9 @@
#ifdef HAVE_OSC
#include
+#include
-#include "concurrentqueue.h"
+#include "ConcurrentQueue.h"
#include "OscReceiver.h"
class MainWindow;
diff --git a/OutputGLCanvas.cpp b/OutputGLCanvas.cpp
index d03fd50..8bd8236 100644
--- a/OutputGLCanvas.cpp
+++ b/OutputGLCanvas.cpp
@@ -30,6 +30,7 @@ OutputGLCanvas::OutputGLCanvas(MainWindow* mainWindow, QWidget* parent, const QG
// Disable scrollbars.
setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
+ showZoomToolBar(false);
}
void OutputGLCanvas::drawForeground(QPainter *painter , const QRectF &rect)
diff --git a/OutputGLWindow.cpp b/OutputGLWindow.cpp
index 7866224..7681983 100644
--- a/OutputGLWindow.cpp
+++ b/OutputGLWindow.cpp
@@ -36,9 +36,6 @@ OutputGLWindow:: OutputGLWindow(QWidget* parent, const DestinationGLCanvas* canv
layout->addWidget(canvas);
setLayout(layout);
- // Save window geometry.
- _geometry = saveGeometry();
-
_pointerIsVisible = true;
}
@@ -87,61 +84,46 @@ void OutputGLWindow::closeEvent(QCloseEvent *event)
void OutputGLWindow::setFullScreen(bool fullscreen)
{
- setCursorVisible(!fullscreen);
- emit fullScreenToggled(fullscreen);
- // Activate crosshair in fullscreen mode.
- // should be only drawn if the controls should be shown
- canvas->setDisplayCrosshair(fullscreen && canvas->getMainWindow()->displayControls());
-
- // NOTE: The showFullScreen() method does not work well under Ubuntu Linux. The code below fixes the issue.
- // Notice that there might be problems with the fullscreen in other OS / window managers. If so, please add
- // the code to fix those issues here.
- // See: http://qt-project.org/doc/qt-4.8/qwidget.html#showFullScreen
- // Source: http://stackoverflow.com/questions/12645880/fullscreen-for-qdialog-from-within-mainwindow-only-working-sometimes
-#ifdef Q_OS_UNIX
- const QString session = QString(getenv("DESKTOP_SESSION")).toLower();
-#endif
if (fullscreen)
{
- // Save window geometry.
- _geometry = saveGeometry();
- //qDebug() << "Saving Geometry " << _geometry.toHex() << endl;
-
- // Move window to second screen before fullscreening it.
+ // Check if user is on multiple screen
if (QApplication::desktop()->screenCount() > 1)
+ {
+ // Hide cursor
+ setCursorVisible(!fullscreen);
+ // Activate crosshair in fullscreen mode.
+ // should be only drawn if the controls should be shown
+ canvas->setDisplayCrosshair(fullscreen && canvas->getMainWindow()->displayControls());
+ //Move window to second screen before fullscreening it.
setGeometry(QApplication::desktop()->screenGeometry(1));
-
-#ifdef Q_OS_UNIX
- // Special case for Unity.
- if (session == "ubuntu" || session == "cinnamon" || session == "default") {
+ //The problem related to the full screen on linux seems to be resolved
+ // with Qt 5.5 at least on Debian but define macro anyway
+#ifdef Q_OS_LINUX
setWindowFlags(Qt::Window);
setVisible(true);
setWindowState( windowState() ^ Qt::WindowFullScreen );
show();
- } else {
- showFullScreen();
- }
#else
showFullScreen();
#endif
+ }
+ else
+ {
+ show();
+ }
}
else
{
- // Restore geometry of window to what it was before full screen call.
- //restoreGeometry(_geometry);
-
-#ifdef Q_OS_UNIX
- // Special case for Unity.
- if (session == "ubuntu") {
- showNormal();
- } else {
- restoreGeometry(_geometry);
- showNormal();
+ if (QApplication::desktop()->screenCount() > 1) {
+#ifdef Q_OS_LINUX
setWindowFlags( windowFlags() & ~Qt::Window );
- }
#else
- restoreGeometry(_geometry);
showNormal();
#endif
+ }
+ else
+ {
+ hide();
+ }
}
}
diff --git a/OutputGLWindow.h b/OutputGLWindow.h
index 4d078de..50dd624 100644
--- a/OutputGLWindow.h
+++ b/OutputGLWindow.h
@@ -50,7 +50,6 @@ protected:
signals:
void closed();
- void fullScreenToggled(bool fullScreen);
public:
DestinationGLCanvas* getCanvas() const { return canvas; }
@@ -59,7 +58,6 @@ public:
private:
OutputGLCanvas* canvas;
- QByteArray _geometry;
bool _pointerIsVisible;
};
diff --git a/README b/README
index 5b7e56b..e3e1b3f 100644
--- a/README
+++ b/README
@@ -39,13 +39,14 @@ or else the menu will not show.
Authors
-------
* Sofian Audry: lead developer, user interface designer, project manager.
+* Dame Diongue: developer.
* Alexandre Quessy: release manager, developer, technical writer, project manager.
* Mike Latona: user interface designer.
-* Dame Diongue: developer.
* Vasilis Liaskovitis: developer.
Contributors
------------
+* Alex Barry: user experience design.
* Maxime Damecour: inspiration.
* Christian Ambaud: sponsor, inspiration.
* Louis Desjardins: project manager.
@@ -56,4 +57,3 @@ Contributors
More info
---------
Get more info from http://mapmap.info
-
diff --git a/Shape.cpp b/Shape.cpp
index 2947ffd..23d3647 100644
--- a/Shape.cpp
+++ b/Shape.cpp
@@ -19,7 +19,7 @@
#include "Shape.h"
-MShape::MShape(const QVector& vertices_) {
+MShape::MShape(const QVector& vertices_) : _isLocked(false) {
setVertices(vertices_);
build();
}
diff --git a/Shape.h b/Shape.h
index 889c1a3..4c42528 100644
--- a/Shape.h
+++ b/Shape.h
@@ -48,11 +48,12 @@ class MShape : public Serializable
{
Q_OBJECT
+ Q_PROPERTY(bool locked READ isLocked WRITE setLocked)
Q_PROPERTY(QVector vertices READ getVertices WRITE setVertices STORED false)
public:
typedef QSharedPointer ptr;
- MShape() {}
+ MShape() : _isLocked(false) {}
MShape(const QVector& vertices_);
virtual ~MShape() {}
@@ -98,6 +99,10 @@ public:
virtual MShape* clone() const;
+ bool isLocked() const { return _isLocked; }
+ void setLocked(bool locked) { _isLocked = locked; }
+ void toggleLocked() { _isLocked = !_isLocked; }
+
const QVector& getVertices() const { return vertices; }
virtual void setVertices(const QVector& vertices_)
{
@@ -111,6 +116,7 @@ public:
protected:
QVector vertices;
+ bool _isLocked;
void _addVertex(const QPointF& vertex)
{
diff --git a/ShapeControlPainter.cpp b/ShapeControlPainter.cpp
index e07df4b..6c50f41 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/ShapeGraphicsItem.cpp b/ShapeGraphicsItem.cpp
index be8faae..605b6d2 100644
--- a/ShapeGraphicsItem.cpp
+++ b/ShapeGraphicsItem.cpp
@@ -38,6 +38,10 @@ bool ShapeGraphicsItem::isMappingCurrent() const {
return MainWindow::instance()->getCurrentMappingId() == getMapping()->getId();
}
+bool ShapeGraphicsItem::isMappingVisible() const {
+ return MainWindow::instance()->getMappingManager().mappingIsVisible(getMapping());
+}
+
void ShapeGraphicsItem::paint(QPainter *painter,
const QStyleOptionGraphicsItem *option, QWidget *widget)
{
diff --git a/ShapeGraphicsItem.h b/ShapeGraphicsItem.h
index 9d07afc..4c0ce53 100644
--- a/ShapeGraphicsItem.h
+++ b/ShapeGraphicsItem.h
@@ -76,7 +76,7 @@ public:
bool isMappingCurrent() const;
/// Returns whether the mapping this shape is associated should be visible.
- bool isMappingVisible() const { return getMapping()->isVisible(); }
+ bool isMappingVisible() const;
/// Returns the bounding rectangle of this item.
virtual QRectF boundingRect() const { return shape().boundingRect(); }
diff --git a/SourceGLCanvas.cpp b/SourceGLCanvas.cpp
index cfddc72..3f244a6 100644
--- a/SourceGLCanvas.cpp
+++ b/SourceGLCanvas.cpp
@@ -28,28 +28,14 @@ SourceGLCanvas::SourceGLCanvas(MainWindow* mainWindow, QWidget* parent)
{
}
-MShape::ptr SourceGLCanvas::getShapeFromMappingId(uid mappingId) const
+MShape::ptr SourceGLCanvas::getShapeFromMapping(const Mapping::ptr& mapping) const
{
- if (mappingId == NULL_UID)
- return MShape::ptr();
-
- else
- {
- Mapping::ptr mapping = getMainWindow()->getMappingManager().getMappingById(mappingId);
- Q_CHECK_PTR(mapping);
- return mapping->getInputShape();
- }
+ return (mapping.isNull() ? MShape::ptr() : mapping->getInputShape());
}
-QSharedPointer SourceGLCanvas::getShapeGraphicsItemFromMappingId(uid mappingId) const
+QSharedPointer SourceGLCanvas::getShapeGraphicsItemFromMapping(const Mapping::ptr& mapping) const
{
- if (mappingId == NULL_UID)
- return QSharedPointer();
-
- else
- {
- return MainWindow::instance()->getMappingGuiByMappingId(mappingId)->getInputGraphicsItem();
- }
+ return (mapping.isNull() ? QSharedPointer() : MainWindow::instance()->getMappingGuiByMappingId(mapping->getId())->getInputGraphicsItem());
}
//
diff --git a/SourceGLCanvas.h b/SourceGLCanvas.h
index c0f0119..77a2cf0 100644
--- a/SourceGLCanvas.h
+++ b/SourceGLCanvas.h
@@ -36,8 +36,8 @@ public:
virtual ~SourceGLCanvas() {}
virtual bool isOutput() const { return false; }
- virtual MShape::ptr getShapeFromMappingId(uid mappingId) const;
- virtual QSharedPointer getShapeGraphicsItemFromMappingId(uid mappingId) const;
+ virtual MShape::ptr getShapeFromMapping(const Mapping::ptr& mapping) const;
+ virtual QSharedPointer getShapeGraphicsItemFromMapping(const Mapping::ptr& mapping) const;
private:
// virtual void doDraw(QPainter* painter);
diff --git a/Util.cpp b/Util.cpp
index 2e9f794..85d204a 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)
@@ -276,7 +280,7 @@ bool eraseSettings()
}
else
{
- std::cout << "Erase MapMap settings." << std::endl;
+ QMessageLogger(__FILE__, __LINE__, 0).debug() << "Erase MapMap settings.";
settingsFile.close();
return settingsFile.remove();
}
diff --git a/Util.h b/Util.h
index 4af1675..da6b8a2 100644
--- a/Util.h
+++ b/Util.h
@@ -58,7 +58,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);
diff --git a/main.cpp b/main.cpp
index 6c653f5..d3e91b1 100644
--- a/main.cpp
+++ b/main.cpp
@@ -65,8 +65,17 @@ void initRegistry()
registry.add();
}
+// Intercept all logging message and display it in the console
+void logMessageHandler(QtMsgType type, const QMessageLogContext &context, const QString &msg)
+{
+ ConsoleWindow::getInstance()->messageLog(type, context, msg);
+}
+
int main(int argc, char *argv[])
{
+ // Install message handler
+ qInstallMessageHandler(logMessageHandler);
+
set_env_vars_if_needed();
// Initialize meta-object registry.
@@ -141,10 +150,10 @@ int main(int argc, char *argv[])
// Create window.
MainWindow* win = MainWindow::instance();
-
- QFontDatabase db;
- Q_ASSERT( QFontDatabase::addApplicationFont(":/base-font") != -1);
- app.setFont(QFont(":/base-font", 10, QFont::Bold));
+ // Add custom font
+ int id = QFontDatabase::addApplicationFont(":/base-font");
+ QString family = QFontDatabase::applicationFontFamilies(id).at(0);
+ app.setFont(QFont(family, 11, QFont::Normal));
// Load stylesheet.
QFile stylesheet(":/stylesheet");
diff --git a/mapmap.pro b/mapmap.pro
index db3ba5b..a040b7f 100644
--- a/mapmap.pro
+++ b/mapmap.pro
@@ -3,11 +3,13 @@ TEMPLATE = app
VERSION = 0.3.2
TARGET = mapmap
QT += gui opengl xml
-greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
+greaterThan(QT_MAJOR_VERSION, 4): QT += widgets core
DEFINES += UNICODE QT_THREAD_SUPPORT QT_CORE_LIB QT_GUI_LIB
HEADERS = \
Commands.h \
+ ConcurrentQueue.h \
+ ConsoleWindow.h \
DestinationGLCanvas.h \
Element.h \
Ellipse.h \
@@ -46,6 +48,7 @@ HEADERS = \
SOURCES = \
Commands.cpp \
+ ConsoleWindow.cpp \
DestinationGLCanvas.cpp \
Element.cpp \
Ellipse.cpp \
diff --git a/mapmap.qrc b/mapmap.qrc
index 561c045..80914a8 100644
--- a/mapmap.qrc
+++ b/mapmap.qrc
@@ -1,53 +1,36 @@
-
- resources/images/icons/newdoc_w.png
- resources/images/icons/open_w.png
- resources/images/icons/save_w.png
- resources/images/icons/save_w.png
-
- resources/images/icons/fullscreen_w.png
- resources/images/icons/nofullscreen_w.png
- resources/images/icons/ctrl2_w.png
-
- resources/images/icons/add_movie_w.png
- resources/images/icons/add_img_w.png
- resources/images/icons/add_paint_w.png
-
- resources/images/shapes/add_quad.png
- resources/images/shapes/add_triangle.png
- resources/images/shapes/add_circle.png
-
-
-
- resources/images/icons/play_w.png
- resources/images/icons/pause_w.png
- resources/images/icons/rewind_w.png
-
- resources/images/shapes/add_quad.png
- resources/images/shapes/add_triangle.png
- resources/images/shapes/add_circle.png
-
- resources/images/shapes/add_circle.png
-
- 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
-
+
+ resources/images/icons/newdoc_w.png
+ resources/images/icons/open_w.png
+ resources/images/icons/save_w.png
+ resources/images/icons/save_w.png
+ resources/images/icons/fullscreen_w.png
+ resources/images/icons/nofullscreen_w.png
+ resources/images/icons/ctrl2_w.png
+ resources/images/icons/add_movie_w.png
+ resources/images/icons/add_img_w.png
+ resources/images/icons/add_paint_w.png
+ resources/images/shapes/add_quad.png
+ resources/images/shapes/add_triangle.png
+ resources/images/shapes/add_circle.png
+ resources/images/icons/play_w.png
+ resources/images/icons/pause_w.png
+ resources/images/icons/rewind_w.png
+ resources/images/shapes/add_quad.png
+ resources/images/shapes/add_triangle.png
+ resources/images/shapes/add_circle.png
+ resources/images/shapes/add_circle.png
+ resources/images/logo/logomapmap.png
+ resources/images/logo/logo_m_big_mapmap.png
+ resources/images/logo/splash.png
+ resources/fonts/DroidSans.otf
+ resources/fonts/DroidSans.otf
+ resources/images/test-signal/test-signal.svg
+ resources/qss/mapmap.qss
+ resources/images/icons/zoom_reset_w.png
+ resources/images/icons/zoom_in_w.png
+ resources/images/icons/zoom_out_w.png
+ resources/images/icons/zoom_fit_w.png
+ resources/fonts/Hack-Regular.otf
+
-
diff --git a/resources/fonts/DroidSans.otf b/resources/fonts/DroidSans.otf
new file mode 100644
index 0000000..ad1efca
Binary files /dev/null and b/resources/fonts/DroidSans.otf differ
diff --git a/resources/fonts/Hack-Regular.otf b/resources/fonts/Hack-Regular.otf
new file mode 100644
index 0000000..5f08325
Binary files /dev/null and b/resources/fonts/Hack-Regular.otf differ
diff --git a/resources/fonts/HelveticaNeueLTPro-Bd.otf b/resources/fonts/HelveticaNeueLTPro-Bd.otf
deleted file mode 100644
index 0712e4d..0000000
Binary files a/resources/fonts/HelveticaNeueLTPro-Bd.otf and /dev/null differ
diff --git a/resources/images/icons/zoom_fit.png b/resources/images/icons/zoom_fit.png
new file mode 100644
index 0000000..65e6d8e
Binary files /dev/null and b/resources/images/icons/zoom_fit.png differ
diff --git a/resources/images/icons/zoom_fit_w.png b/resources/images/icons/zoom_fit_w.png
new file mode 100644
index 0000000..55248a2
Binary files /dev/null and b/resources/images/icons/zoom_fit_w.png differ
diff --git a/resources/images/icons/zoom_in.png b/resources/images/icons/zoom_in.png
new file mode 100644
index 0000000..a42c5ec
Binary files /dev/null and b/resources/images/icons/zoom_in.png differ
diff --git a/resources/images/icons/zoom_in_w.png b/resources/images/icons/zoom_in_w.png
new file mode 100644
index 0000000..0148bd9
Binary files /dev/null and b/resources/images/icons/zoom_in_w.png differ
diff --git a/resources/images/icons/zoom_out.png b/resources/images/icons/zoom_out.png
new file mode 100644
index 0000000..1b446cb
Binary files /dev/null and b/resources/images/icons/zoom_out.png differ
diff --git a/resources/images/icons/zoom_out_w.png b/resources/images/icons/zoom_out_w.png
new file mode 100644
index 0000000..f41233e
Binary files /dev/null and b/resources/images/icons/zoom_out_w.png differ
diff --git a/resources/images/icons/zoom_reset.png b/resources/images/icons/zoom_reset.png
new file mode 100644
index 0000000..ec5a42b
Binary files /dev/null and b/resources/images/icons/zoom_reset.png differ
diff --git a/resources/images/icons/zoom_reset_w.png b/resources/images/icons/zoom_reset_w.png
new file mode 100644
index 0000000..d1f708c
Binary files /dev/null and b/resources/images/icons/zoom_reset_w.png differ
diff --git a/resources/qss/mapmap.qss b/resources/qss/mapmap.qss
index 2bcb487..dbe2406 100644
--- a/resources/qss/mapmap.qss
+++ b/resources/qss/mapmap.qss
@@ -54,10 +54,43 @@ QListView::item:selected {
background: #272a36;
}
-QGraphicsView {
+QGraphicsView,
+QPlainTextEdit {
border-style: none;
}
+QPushButton#zoom-in,
+QPushButton#zoom-out,
+QPushButton#reset-zoom,
+QPushButton#zoom-fit {
+ background-color: rgba(0, 0, 0, 0%);
+}
+
+QPushButton:hover#zoom-in, QPushButton:checked#zoom-in,
+QPushButton:hover#zoom-out, QPushButton:checked#zoom-out,
+QPushButton:hover#reset-zoom, QPushButton:checked#reset-zoom,
+QPushButton:hover#zoom-fit, QPushButton:checked#zoom-fit {
+ background-color: qlineargradient(x1: 0, y1: 0, x2: 1, y2: 1,
+ stop: 0 #0c0927, stop: 1 #191C28);
+ border-radius: 2px;
+ border: none;
+}
+
+QPushButton:pressed#zoom-in,
+QPushButton:pressed#zoom-out,
+QPushButton:pressed#reset-zoom,
+QPushButton:pressed#zoom-fit {
+ border: none;
+}
+
+QWidget#zoom-toolbox {
+ background-color: #272a36;
+}
+
+QStatusBar::item {
+ border: 0px solid black;
+}
+
/*
QListView::item:selected:!active {
background: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1,