Mercurial > hg > dmlib
diff editor/edgui.cpp @ 651:e2ac08228a0f
Move files to various subdirectories.
author | Matti Hamalainen <ccr@tnsp.org> |
---|---|
date | Tue, 16 Apr 2013 06:01:42 +0300 |
parents | edgui.cpp@d34922e6a244 |
children |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/editor/edgui.cpp Tue Apr 16 06:01:42 2013 +0300 @@ -0,0 +1,522 @@ +// +// Demo Editor -- Qt GUI setup parts and callbacks +// (C) Copyright 2012 Matti 'ccr' Hämäläinen <ccr@tnsp.org> +// +#include "edmain.h" + +#include <QCloseEvent> +#include <QToolBar> +#include <QMenuBar> +#include <QStatusBar> +#include <QMenu> +#include <QProgressBar> +#include <QFileDialog> +#include <QHBoxLayout> +#include <QVBoxLayout> + + + +void DemoEditor::updateMenuStates() +{ + // Set window title based on document filename and changed status + QString name; + + if (!currTimeline || currTimeline->filename.isEmpty()) + name = DOC_DEF_FILENAME; + else + name = currTimeline->filename; + + if (currTimeline != NULL) + { + if (currTimeline->tl != NULL && currTimeline->tl->name != NULL) + name += " (" + QString(currTimeline->tl->name) + ")"; + + if (currTimeline->touched()) + name = "*" + name; + } + + setWindowTitle(name + " - " + QCoreApplication::applicationName()); + + // Enable menu items based on states + menuActSave->setEnabled(currTimeline != NULL&& currTimeline->touched()); + menuActSaveAs->setEnabled(currTimeline != NULL); + + // Enable undo/redo items and set their texts based on history status + int historyLevels = undoHistory.size(); + QString itemText; + bool itemEnabled; + + if (undoHistoryPos >= 0 && undoHistoryPos < historyLevels) + { + itemText = " " + undoHistory.at(undoHistoryPos)->state(); + itemEnabled = true; + } + else + { + itemText = ""; + itemEnabled = false; + } + + menuActRedo->setEnabled(itemEnabled); + menuActRedo->setText("&Redo" + itemText); + + if (undoHistoryPos > 0 && historyLevels > 0) + { + itemText = " " + undoHistory.at(undoHistoryPos - 1)->state(); + itemEnabled = true; + } + else + { + itemText = ""; + itemEnabled = false; + } + + menuActUndo->setEnabled(itemEnabled); + menuActUndo->setText("&Undo" + itemText); + + update(); +} + + +// +// Show about dialog +// +void DemoEditor::actionAboutBox() +{ + QMessageBox::about(this, + "About "+ QCoreApplication::applicationName(), + "<h1>" + QCoreApplication::applicationName() + + " v"+ QCoreApplication::applicationVersion() +"</h1><br>\n" + "(C) Copyright 2012 Matti 'ccr' Hämäläinen<br>\n" + "<br>\n" + "<b>A demo editor TNSP dmlib engine.</b><br>\n"); +} + + +// +// Show a dialog inquiring the user whether to save the current +// document if it has been modified since last save/load. +// +QMessageBox::StandardButton DemoEditor::showDocumentModifiedDialog() +{ + return QMessageBox::question(this, + "The document has been modified.", + "Do you want to save your changes?", + QMessageBox::Discard | QMessageBox::Cancel | QMessageBox::Save, + QMessageBox::Save); +} + + +// +// Generic error/warning dialog +// +void DemoEditor::showFileErrorDialog(QString operation, int code) +{ +/* + QString msg; + + QMessageBox::error(this, + "A non-critical error occured", + operation +*/ +} + + +void DemoEditor::actionFileNew() +{ + bool okToCreate = true; + + if (currTimeline != NULL && currTimeline->touched()) + { + okToCreate = false; + switch (showDocumentModifiedDialog()) + { + case QMessageBox::Discard: + okToCreate = true; + break; + + case QMessageBox::Save: + actionFileSave(); + if (!currTimeline->touched()) + { + QMessageBox::information(this, + "Document saved", + "The document was saved as " + currTimeline->filename); + + okToCreate = true; + } + break; + + default: + break; + } + } + + if (okToCreate) + createNewFile(); +} + + +void DemoEditor::actionFileOpen() +{ + bool okToOpen = true; + + if (currTimeline != NULL && currTimeline->touched()) + { + okToOpen = false; + + switch (showDocumentModifiedDialog()) + { + case QMessageBox::Discard: + okToOpen = true; + break; + + case QMessageBox::Save: + actionFileSave(); + if (!currTimeline->touched()) + { + QMessageBox::information(this, + "Document saved", + "The document was saved as " + currTimeline->filename); + + okToOpen = true; + } + break; + + default: + break; + } + } + + if (okToOpen) + { + QFileDialog fdialog(this); + + fdialog.setAcceptMode(QFileDialog::AcceptOpen); + fdialog.setFileMode(QFileDialog::ExistingFile); + fdialog.setNameFilter("Demo timeline files (*.demo)"); + fdialog.setDefaultSuffix("demo"); + + if (fdialog.exec()) + readFromFile(fdialog.selectedFiles()[0]); + } +} + + +void DemoEditor::actionFileSaveAs() +{ + if (!currTimeline) + { + qDebug() << "DemoEditor::actionFileSaveAs(): currTimeline == null"; + return; + } + + QFileDialog fdialog(this); + + fdialog.setAcceptMode(QFileDialog::AcceptSave); + fdialog.setFileMode(QFileDialog::AnyFile); + fdialog.setNameFilter("Demo files (*.demo)"); + fdialog.setDefaultSuffix("demo"); + fdialog.setConfirmOverwrite(true); + + fdialog.selectFile(currTimeline->filename.isEmpty() ? currTimeline->filename : DOC_DEF_FILENAME); + + if (fdialog.exec()) + saveToFile(fdialog.selectedFiles()[0]); +} + + +void DemoEditor::actionFileSave() +{ + if (!currTimeline) + { + qDebug() << "DemoEditor::actionFileSave(): currTimeline == null"; + return; + } + + // If filename has been set, save .. otherwise go to save as + if (!currTimeline->filename.isEmpty()) + saveToFile(currTimeline->filename); + else + actionFileSaveAs(); +} + + +void DemoEditor::closeEvent(QCloseEvent *event) +{ + bool okToClose = true; + + if (currTimeline && currTimeline->touched()) + { + okToClose = false; + switch (showDocumentModifiedDialog()) + { + case QMessageBox::Discard: + okToClose = true; + break; + + case QMessageBox::Save: + actionFileSave(); + if (!currTimeline->touched()) + okToClose = true; + break; + + default: + break; + } + } + + if (okToClose) + event->accept(); +} + + +// +// Various menu actions +// +void DemoEditor::actionControlChanged(QAction *act) +{ +// demoView->setToolMode(act->data().toInt()); +} + + +// +// Update statusbar message text +// +void DemoEditor::statusMsg(QString message) +{ + statusBar()->showMessage(message, 0); +} + + +// +// Set active element of an action group based on matching the data +// +void DemoEditor::setActionGroupChecked(QActionGroup *group, QVariant data) +{ + QList<QAction *> items = group->actions(); + + for (int i = 0; i < items.size(); i++) + { + QAction *act = items.at(i); + if (act->data() == data) + { + act->setChecked(true); + return; + } + } +} + + +// +// Helper functions for creating GUI elements +// +QAction * DemoEditor::createToolButton(QActionGroup *group, QString name, QIcon icon, QString statustip, QVariant data) +{ + QAction *action = new QAction(icon, name, group); + + action->setStatusTip(statustip + "."); + action->setCheckable(true); + action->setData(data); + + return action; +} + + +QAction * DemoEditor::createMenuAction(QString name, const QKeySequence &shortcut, QString tooltip) +{ + QAction *action = new QAction(name, this); + + if (shortcut != QKeySequence(QKeySequence::UnknownKey)) + action->setShortcut(shortcut); + + if (!tooltip.isNull()) + action->setStatusTip(tooltip + "."); + + return action; +} + + +QAction * DemoEditor::createMenuGroupAction(QMenu *menu, QActionGroup *group, QString name, const QKeySequence &shortcut, QString tooltip, QVariant data) +{ + QAction *action = createMenuAction(name, shortcut, tooltip); + + action->setCheckable(true); + action->setData(data); + + menu->addAction(action); + group->addAction(action); + + return action; +} + + +#define MCONNECT(menu, act, slot) do { connect(act, SIGNAL(triggered()), this, SLOT(slot)); menu->addAction(act); } while(0) + + +// +// Create GUI elements +// +void DemoEditor::createMainGUI() +{ + QAction *act; + QMenu *fileMenu, *editMenu, *viewMenu, *helpMenu; + + qDebug() << "- Constructing menus"; + + // + // File menu + // + fileMenu = menuBar()->addMenu("&File"); + + act = createMenuAction("&New", QKeySequence::New, "Create a new demo timeline"); + MCONNECT(fileMenu, act, actionFileNew()); + + menuActOpen = createMenuAction("&Open", QKeySequence::Open, "Open a demo timeline file"); + MCONNECT(fileMenu, menuActOpen, actionFileOpen()); + + menuActSave = createMenuAction("&Save", QKeySequence::Save, "Save demo timeline"); + MCONNECT(fileMenu, menuActSave, actionFileSave()); + + menuActSaveAs = createMenuAction("Save &as", QKeySequence::SaveAs, "Save demo timeline as a new file"); + MCONNECT(fileMenu, menuActSaveAs, actionFileSaveAs()); + + fileMenu->addSeparator(); + + QKeySequence qseq(Qt::CTRL + Qt::Key_Q); + act = createMenuAction("&Quit", qseq, "Exit application"); + MCONNECT(fileMenu, act, close()); + + + // + // Edit menu + // + editMenu = menuBar()->addMenu("&Edit"); + + menuActUndo = createMenuAction("&Undo", QKeySequence::Undo, "Undo last change"); + MCONNECT(editMenu, menuActUndo, performUndo()); + + menuActRedo = createMenuAction("&Redo", QKeySequence::Redo, "Redo last change"); + MCONNECT(editMenu, menuActRedo, performRedo()); + +#if 0 + editMenu->addSeparator(); + + menuActCut = createMenuAction("Cu&t", QKeySequence::Cut, "Cut object"); + MCONNECT(editMenu, menuActCut, actionCut()); + + menuActCopy = createMenuAction("&Copy", QKeySequence::Copy, "Copy object"); + MCONNECT(editMenu, menuActCopy, actionCopy()); + + menuActPaste = createMenuAction("&Paste", QKeySequence::Paste, "Paste object"); + MCONNECT(editMenu, menuActPaste, actionPaste()); + + menuActDelete = createMenuAction("&Delete", QKeySequence::Delete, "Delete object"); + MCONNECT(editMenu, menuActDelete, actionDelete()); +#endif + + // + // Help menu + // + helpMenu = menuBar()->addMenu("&Help"); + act = createMenuAction("About", 0, "Show information about application"); + MCONNECT(helpMenu, act, actionAboutBox()); + + + + // + // Controls toolbar + // + qDebug() << "- Constructing toolbars"; + + actGroupControls = new QActionGroup(this); + actGroupControls->setExclusive(true); + connect(actGroupControls, SIGNAL(triggered(QAction*)), this, SLOT(actionControlChanged(QAction *))); + + createToolButton(actGroupControls, "Rewind", QIcon("rewind.png"), + "Rewind to start of the timeline", CTRL_REWIND); + + createToolButton(actGroupControls, "Play start", QIcon("play1.png"), + "Play from start", CTRL_PLAY_START); + + createToolButton(actGroupControls, "Play current", QIcon("play2.png"), + "Play from current position", CTRL_PLAY_CURRENT); + + createToolButton(actGroupControls, "Pause", QIcon("pause.png"), + "Pause", CTRL_PAUSE); + + + QToolBar *controlButtons = new QToolBar("Player controls", this); + controlButtons->setMovable(false); + controlButtons->setFloatable(false); + controlButtons->setIconSize(QSize(CTRL_ICON_SIZE, CTRL_ICON_SIZE)); + controlButtons->setToolButtonStyle(Qt::ToolButtonIconOnly); + controlButtons->addActions(actGroupControls->actions()); + + + // + // Effect resource view + // + qDebug() << "- Constructing effects resource view"; + + resourceView = new QTableView(this); + resourceView->setHorizontalScrollBarPolicy(Qt::ScrollBarAsNeeded); + resourceView->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOn); + resourceView->setSelectionMode(QAbstractItemView::SingleSelection); + resourceView->setSelectionBehavior(QAbstractItemView::SelectRows); + resourceModel = new QEDResourceModel(this); + resourceView->setModel(resourceModel); + + // + // Construct the main screen + // + qDebug() << "- Constructing main screen layout"; + + QWidget *sideVBoxContainer = new QWidget(); + QSizePolicy sideVBoxPolicy(QSizePolicy::Fixed, QSizePolicy::Ignored); + sideVBoxPolicy.setHeightForWidth(sideVBoxContainer->sizePolicy().hasHeightForWidth()); + sideVBoxContainer->setSizePolicy(sideVBoxPolicy); + + QVBoxLayout *sideVBox = new QVBoxLayout(sideVBoxContainer); + sideVBox->setSpacing(0); + sideVBox->setContentsMargins(0, 0, 0, 0); + sideVBox->addWidget(resourceView); + sideVBox->addWidget(controlButtons); + + + QWidget *holder = new QWidget(); + QVBoxLayout *verticalSplitter = new QVBoxLayout(holder); + QHBoxLayout *horizSplitter = new QHBoxLayout(); + + + timelineScrollBar = new QScrollBar(Qt::Horizontal); + connect(timelineScrollBar, SIGNAL(valueChanged(int)), this, SLOT(actionTimelineScrollChanged(int))); + + timelineAudioTrack = new QEDWaveTrackView(); + connect(timelineAudioTrack, SIGNAL(offsetChanged(float)), this, SLOT(actionOffsetChanged(float))); + connect(timelineAudioTrack, SIGNAL(timeChanged(float)), this, SLOT(actionTimeChanged(float))); + + timelineView = new QEDTimelineView(); + connect(timelineView, SIGNAL(timelineChanged()), this, SLOT(actionTimelineChanged())); + + QScrollArea *scrollArea = new QScrollArea(); + scrollArea->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Maximum); + scrollArea->setWidget(timelineView); + scrollArea->setWidgetResizable(true); + + + demoView = new QEDSWDemoView(this); + + verticalSplitter->addLayout(horizSplitter); + verticalSplitter->addWidget(scrollArea); + verticalSplitter->addWidget(timelineAudioTrack); + verticalSplitter->addWidget(timelineScrollBar); + + horizSplitter->addWidget(sideVBoxContainer); + horizSplitter->addWidget(demoView); + + + updateTimelineView(); + + setCentralWidget(holder); +}