Mercurial > hg > dmlib
view editor/edgui.cpp @ 1707:a0986cfd6f9d
More consistently use DMGrowBuf in the lib64gfx APIs, and implement
"backwards" RLE decoding and encoding (optionally regards input/output).
Not tested very much yet, there may be bugs.
author | Matti Hamalainen <ccr@tnsp.org> |
---|---|
date | Tue, 05 Jun 2018 21:58:10 +0300 |
parents | e2ac08228a0f |
children |
line wrap: on
line source
// // 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); }