Mercurial > hg > dmlib
changeset 376:40e33ad0d153
Work towards a working editor .. some day.
author | Matti Hamalainen <ccr@tnsp.org> |
---|---|
date | Wed, 17 Oct 2012 02:27:55 +0300 |
parents | e024ef14f35b |
children | a41d0db5fa36 |
files | Makefile.gen eddemoobj.cpp eddemoobj.h edgui.cpp edmain.cpp edmain.h edtimeline.cpp edwaveform.cpp edwaveform.h |
diffstat | 9 files changed, 1077 insertions(+), 26 deletions(-) [+] |
line wrap: on
line diff
--- a/Makefile.gen Wed Oct 17 01:47:49 2012 +0300 +++ b/Makefile.gen Wed Oct 17 02:27:55 2012 +0300 @@ -362,7 +362,7 @@ @echo " LINK $+" @$(CC) -o $@ $(filter %.o %.a,$+) $(DM_LDFLAGS) $(SDL_LDFLAGS) -$(BINPATH)$(DEMO_BIN)$(EXEEXT): $(OBJPATH)$(DEMO_BIN).o $(addprefix $(OBJPATH),$(DEMO_OBJS)) $(DMLIB_A) +$(BINPATH)$(DEMO_BIN)$(EXEEXT): $(addprefix $(OBJPATH),$(DEMO_OBJS)) $(DMLIB_A) @echo " LINK $+" @$(CC) -o $@ $(filter %.o %.a,$+) $(DM_LDFLAGS) $(SDL_LDFLAGS) @@ -372,7 +372,7 @@ $(EDITOR_PRO): $(DMLIB)Makefile.gen config.mak $(addprefix $(DMLIB),$(EDITOR_SOURCES)) $(addprefix $(OBJPATH),$(DEMO_OBJS)) $(DMLIB_A) @echo " CREATE $@" @echo > $@ - @echo "POST_TARGETDEPS = $(filter %.o %.a,$+)" >> $@ + @echo "QMAKE_LIBS += $(filter-out %dmsimple.o,$(filter %.o %.a,$+))" >> $@ @echo "QMAKE_CXXFLAGS += $(DM_CFLAGS) $(SDL_CFLAGS)" >> $@ @echo "QMAKE_LIBS += $(DM_LDFLAGS) $(SDL_LDFLAGS)" >> $@ @echo "MAKEFILE = $(EDITOR_MAKEFILE)" >> $@
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eddemoobj.cpp Wed Oct 17 02:27:55 2012 +0300 @@ -0,0 +1,58 @@ +// +// Map Mask Designer -- Map object and map region classes +// (C) Copyright 2012 Matti 'ccr' Hämäläinen <ccr@tnsp.org> +// +#include "eddemoobj.h" +#include "dmres.h" +#include <QFileInfo> + +////////////////////////////////////////////////////////////////////////////// + +DemoObject::DemoObject() +{ + lastError = QFile::NoError; + changed = 0; +} + + +// Create a copy of the given mapobject +DemoObject::DemoObject(DemoObject *obj) +{ + lastError = QFile::NoError; + changed = 0; + + filename = obj->filename; +} + + +DemoObject::~DemoObject() +{ +} + +int DemoObject::load(QString mfilename) +{ + QByteArray fnba = mfilename.toUtf8(); + DMResource *res; + if ((res = dmf_create_stdio(fnba.data(), "rb")) == NULL) + return DMERR_FOPEN; + + int err = dmLoadTimeline(res, &data.tl); + + dmf_close(res); + filename = mfilename; + return err; +} + + +int DemoObject::save(QString mfilename) +{ + QByteArray fnba = mfilename.toUtf8(); + DMResource *res; + if ((res = dmf_create_stdio(fnba.data(), "wb")) == NULL) + return DMERR_FOPEN; + + int err = dmSaveTimeline(res, data.tl); + + dmf_close(res); + return err; +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eddemoobj.h Wed Oct 17 02:27:55 2012 +0300 @@ -0,0 +1,30 @@ +// +// Demo Editor -- Demo state object +// (C) Copyright 2012 Matti 'ccr' Hämäläinen <ccr@tnsp.org> +// +#ifndef DEMOOBJECT_H +#define DEMOOBJECT_H + +#include "dmengine.h" +#include <QFile> + +class DemoObject +{ +public: + // Last file I/O status + QFile::FileError lastError; + QString state; + int changed; + DMEngineData data; + QString filename; + + DemoObject(); + DemoObject(DemoObject *); + ~DemoObject(); + + int load(QString filename); + int save(QString filename); +}; + + +#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/edgui.cpp Wed Oct 17 02:27:55 2012 +0300 @@ -0,0 +1,446 @@ +// +// 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 <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 (!demo || demo->filename.isEmpty()) + name = DOC_DEF_FILENAME; + else + name = demo->filename; + + if (changed) + name = "*" + name; + + setWindowTitle(name + " - " + QCoreApplication::applicationName()); + + // Enable menu items based on states +#if 0 + menuActValidate->setEnabled(demo->get); + menuActSave->setEnabled(demo->changed || changed); + menuActSaveAs->setEnabled(demo->changed || changed); +#else + menuActSave->setEnabled(false); + menuActSaveAs->setEnabled(false); +#endif + + // 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, QFile::FileError err) +{ +/* + QString msg; + + QMessageBox::error(this, + "A non-critical error occured", + operation +*/ +} + + +void DemoEditor::actionFileNew() +{ + bool okToCreate = true; + + if (changed) + { + okToCreate = false; + switch (showDocumentModifiedDialog()) + { + case QMessageBox::Discard: + okToCreate = true; + break; + + case QMessageBox::Save: + actionFileSave(); + if (!changed) + { + QMessageBox::information(this, + "Document saved", + "The document was saved as " + demo->filename); + + okToCreate = true; + } + break; + + default: + break; + } + } + + if (okToCreate) + createNewFile(); +} + + +void DemoEditor::actionFileOpen() +{ + bool okToOpen = true; + + if (changed) + { + okToOpen = false; + + switch (showDocumentModifiedDialog()) + { + case QMessageBox::Discard: + okToOpen = true; + break; + + case QMessageBox::Save: + actionFileSave(); + if (!changed) + { + QMessageBox::information(this, + "Document saved", + "The document was saved as " + demo->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 (!demo) + { + qDebug() << "DemoEditor::actionFileSaveAs(): demo == 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(demo->filename.isEmpty() ? demo->filename : DOC_DEF_FILENAME); + + if (fdialog.exec()) + saveToFile(fdialog.selectedFiles()[0]); +} + + +void DemoEditor::actionFileSave() +{ + if (!demo) + { + qDebug() << "DemoEditor::actionFileSave(): demo == null"; + return; + } + + // If filename has been set, save .. otherwise go to save as + if (!demo->filename.isEmpty()) + saveToFile(demo->filename); + else + actionFileSaveAs(); +} + + +void DemoEditor::closeEvent(QCloseEvent *event) +{ + bool okToClose = true; + + if (changed) + { + okToClose = false; + switch (showDocumentModifiedDialog()) + { + case QMessageBox::Discard: + okToClose = true; + break; + + case QMessageBox::Save: + actionFileSave(); + if (!changed) + okToClose = true; + break; + + default: + break; + } + } + + if (okToClose) + event->accept(); +} + + +// +// Various menu actions +// + + +// +// 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()); + + + qDebug() << "- Constructing toolbars"; + + // + // 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); + +// view = new MapView(); + + QWidget *holder = new QWidget(); + QHBoxLayout *viewSplitter = new QHBoxLayout(holder); + + viewSplitter->addWidget(sideVBoxContainer); +// viewSplitter->addWidget(view); + + setCentralWidget(holder); +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/edmain.cpp Wed Oct 17 02:27:55 2012 +0300 @@ -0,0 +1,436 @@ +// +// Demo Editor -- Main program +// (C) Copyright 2012 Matti 'ccr' Hämäläinen <ccr@tnsp.org> +// +#include <SDL.h> +#include "dmengine.h" +#include "edmain.h" +#include "eddemoobj.h" +#include <QSettings> +#include <QGLWidget> + + +int main(int argc, char *argv[]) +{ + dmVerbosity = 5; + + QApplication app(argc, argv); + + app.setOrganizationName("TNSP"); + app.setOrganizationDomain("tnsp.org"); + app.setApplicationName(PROGRAM_NAME); + app.setApplicationVersion(PROGRAM_VERSION); + + DemoEditor mainWin; + + mainWin.show(); + + return app.exec(); +} + + +void engineAudioCallback(void *userdata, Uint8 * stream, int len) +{ + DMEngineData *engine = (DMEngineData *) userdata; + + if (engine->paused) + { + memset(stream, 0, len); + } + else +#ifdef DM_USE_JSS + { + if (engine->dev != NULL) + jvmRenderAudio(engine->dev, stream, + len / jvmGetSampleSize(engine->dev)); + } +#endif +#ifdef DM_USE_TREMOR + if (engine->audioPos + len >= engine->audioRes->rdataSize) + { + engine->exitFlag = true; + } + else + { + memcpy(stream, (Uint8 *) engine->audioRes->rdata + engine->audioPos, len); + engine->audioPos += len; + } +#endif +} + + +int DemoEditor::reopenResources() +{ + int err; + + if ((err = dmres_init(&engine.resources, engine.optPackFilename, engine.optDataPath, + engine.optResFlags, engineClassifier)) != DMERR_OK) + { + dmError("Could not initialize resource manager: %d, %s.\n", + err, dmErrorStr(err)); + } + return err; +} + + +int DemoEditor::loadResources() +{ + int err, loaded, total; + err = dmres_preload(engine.resources, true, &loaded, &total); + + while ((err = dmres_preload(engine.resources, false, &loaded, &total)) == DMERR_PROGRESS) + { + // Show a nice progress bar while loading + if (total > 0 && (loaded % 2) == 0) + { +/* + if ((err = engineShowProgress(loaded, total)) != DMERR_OK) + return err; +*/ + } + } + return DMERR_OK; +} + + +DemoEditor::DemoEditor() +{ + int err; + initSDL = FALSE; + + resize(1024, 768); + setWindowTitle(QCoreApplication::applicationName()); + + memset(&engine, 0, sizeof(engine)); + + // Pre-initialization + if ((err = demoPreInit(&engine)) != DMERR_OK) + goto error_exit; + + // Initialize resource subsystem + dmPrint(1, "Initializing resources subsystem.\n"); + if ((err = reopenResources()) != DMERR_OK) + goto error_exit; + + // Initialize SDL components + dmPrint(1, "Initializing libSDL.\n"); + if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_AUDIO | SDL_INIT_TIMER) != 0) + { + dmError("Could not initialize SDL: %s\n", SDL_GetError()); + goto error_exit; + } + initSDL = true; + + // Initialize audio parts + if (engine.optAfmt.freq == 0 && engine.optAfmt.channels == 0) + { + // Defaults, if none seem to be set + engine.optAfmt.freq = 44100; + engine.optAfmt.format = AUDIO_S16SYS; + engine.optAfmt.channels = 2; + engine.optAfmt.samples = engine.optAfmt.freq / 16; + } + +#ifdef DM_USE_JSS + jssInit(); + + switch (engine.optAfmt.format) + { + case AUDIO_S16SYS: + engine.jss_format = JSS_AUDIO_S16; + break; + case AUDIO_U16SYS: + engine.jss_format = JSS_AUDIO_U16; + break; + case AUDIO_S8: + engine.jss_format = JSS_AUDIO_S8; + break; + case AUDIO_U8: + engine.jss_format = JSS_AUDIO_U8; + break; + } + + dmPrint(1, "Initializing miniJSS mixer with fmt=%d, chn=%d, freq=%d\n", + engine.jss_format, engine.optAfmt.channels, engine.optAfmt.freq); + + if ((engine.dev = + jvmInit(engine.jss_format, engine.optAfmt.channels, + engine.optAfmt.freq, JMIX_AUTO)) == NULL) + { + dmError("jvmInit() returned NULL, voi perkele.\n"); + goto error_exit; + } + + if ((engine.plr = jmpInit(engine.dev)) == NULL) + { + dmError("jmpInit() returned NULL\n"); + goto error_exit; + } +#endif + + // Initialize SDL audio + dmPrint(1, "Trying to init SDL audio with: fmt=%d, chn=%d, freq=%d\n", + engine.optAfmt.format, engine.optAfmt.channels, + engine.optAfmt.freq); + + engine.optAfmt.callback = engineAudioCallback; + + if (SDL_OpenAudio(&engine.optAfmt, NULL) < 0) + { + dmError("Couldn't open SDL audio: %s\n", SDL_GetError()); + goto error_exit; + } + + // Initialize SDL video + if (engine.demoInitPreVideo != NULL && + (err = engine.demoInitPreVideo(&engine)) != DMERR_OK) + { + dmError("demoInitPreVideo() failed, %d: %s\n", err, dmErrorStr(err)); + goto error_exit; + } + + dmPrint(1, "Initializing SDL video %d x %d x %dbpp, flags=0x%08x\n", + engine.optScrWidth, engine.optScrHeight, engine.optBitDepth, engine.optVFlags); + + engine.screen = SDL_CreateRGBSurface(SDL_SWSURFACE, engine.optScrWidth, engine.optScrHeight, engine.optBitDepth, 0, 0, 0, 0); + if (engine.screen == NULL) + { + dmError("Could not allocate video backbuffer surface.\n"); + goto error_exit; + } + + if (engine.demoInitPostVideo != NULL && + (err = engine.demoInitPostVideo(&engine)) != DMERR_OK) + { + dmError("demoInitPostVideo() failed, %d: %s\n", err, dmErrorStr(err)); + goto error_exit; + } + + // Load resources + dmPrint(1, "Loading resources, please wait...\n"); + if ((err = loadResources()) != DMERR_OK) + { + dmError("Error loading resources, %d: %s.\n", err, dmErrorStr(err)); + goto error_exit; + } + + dmPrint(1, "Initializing effects, etc.\n"); + + // Final initializations + if ((err = engine.demoInit(&engine)) != DMERR_OK) + { + dmError("Failure in demoInit(), %d: %s\n", + err, dmErrorStr(err)); + goto error_exit; + } + + // Initialize effects + if ((err = engineInitializeEffects(&engine)) != DMERR_OK) + { + dmError("Effects initialization failed, %d: %s\n", + err, dmErrorStr(err)); + goto error_exit; + } + +error_exit: + + // Setup GUI elements + demo = NULL; + createMainGUI(); + createNewFile(); + + // Finalize init + settingsRestore(); + +// view->setViewport(new QGLWidget(QGLFormat(QGL::SampleBuffers))); + + updateMenuStates(); + statusMsg("Application started."); +} + + +DemoEditor::~DemoEditor() +{ + dmPrint(1, "Shutting down.\n"); + + settingsSave(); +// delete view; + delete demo; + historyReset(); + + if (engine.screen) + SDL_FreeSurface(engine.screen); + + SDL_LockAudio(); + SDL_PauseAudio(1); +#ifdef DM_USE_JSS + jmpClose(engine.plr); + jvmClose(engine.dev); + jssClose(); +#endif + SDL_UnlockAudio(); + + dmFreeTimeline(engine.tl); + dmFreePreparedTimelineData(engine.ptl); + engineShutdownEffects(&engine); + dmres_close(engine.resources); + + if (engine.demoShutdown != NULL) + engine.demoShutdown(&engine); + + if (initSDL) + SDL_Quit(); + + if (engine.demoQuit != NULL) + engine.demoQuit(&engine); +} + + +void DemoEditor::rehashFile() +{ +// view->setDemoObject(demo); + update(); + historyReset(); + changed = false; + updateMenuStates(); +} + + +void DemoEditor::createNewFile() +{ + delete demo; + demo = new DemoObject(); + rehashFile(); +} + + +void DemoEditor::readFromFile(QString filename) +{ + DemoObject *tmp = new DemoObject(); + int ret = tmp->load(filename); + if (ret != DMERR_OK) + { + showFileErrorDialog("Loading demo blob file "+ filename, ret, tmp->lastError); + delete tmp; + } + else + { + delete demo; + demo = tmp; + rehashFile(); + } +} + + +void DemoEditor::saveToFile(QString filename) +{ + int ret = demo->save(filename); + if (ret != DMERR_OK) + { + showFileErrorDialog("Saving demo blob file "+ filename, ret, demo->lastError); + } + + updateMenuStates(); +} + + +void DemoEditor::settingsRestore() +{ + QSettings s; + + restoreGeometry(s.value("windowGeometry").toByteArray()); + restoreState(s.value("windowState").toByteArray()); + +} + + +void DemoEditor::settingsSave() +{ + QSettings s; + + s.setValue("windowGeometry", saveGeometry()); + s.setValue("windowState", saveState()); + +} + + +// +// Edit history functionality +// +void DemoEditor::historyReset() +{ + changed = false; + undoHistoryPos = -1; + undoHistoryMax = DOC_UNDO_MAX; + undoHistory.clear(); +} + + +void DemoEditor::historyPush(QString description) +{ + if (!undoHistory.isEmpty() && undoHistory.last()->state == "-") + { + delete undoHistory.takeLast(); + } + + while (undoHistory.size() >= undoHistoryMax) + { + delete undoHistory.takeFirst(); + } + + DemoObject *copy = new DemoObject(demo); + copy->state = description; + undoHistory.append(copy); +} + + +void DemoEditor::historyTop() +{ + DemoObject *copy = new DemoObject(demo); + copy->state = "-"; + undoHistory.append(copy); + + undoHistoryPos = undoHistory.size() - 1; + changed = true; + updateMenuStates(); + update(); +} + + +void DemoEditor::historyPop() +{ + if (!undoHistory.isEmpty()) + { + delete undoHistory.takeLast(); + } +} + + +void DemoEditor::performRedo() +{ + if (undoHistoryPos >= 0 && undoHistoryPos < undoHistory.size() - 1) + { + undoHistoryPos++; + delete demo; + demo = new DemoObject(undoHistory.at(undoHistoryPos)); + changed = true; + + updateMenuStates(); + update(); + } +} + + +void DemoEditor::performUndo() +{ + if (undoHistoryPos > 0 && undoHistory.size() > 1) + { + undoHistoryPos--; + delete demo; + demo = new DemoObject(undoHistory.at(undoHistoryPos)); + changed = true; + + updateMenuStates(); + update(); + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/edmain.h Wed Oct 17 02:27:55 2012 +0300 @@ -0,0 +1,98 @@ +#ifndef EDMAIN_H +#define EDMAIN_H + +// Program name etc +#define PROGRAM_NAME "DMPE Editor" +#define PROGRAM_VERSION "0.1" + +// Defaults +#define DOC_DEF_FILENAME "Untitled" +#define DOC_UNDO_MAX 30 + +#include "eddemoobj.h" + +#include <QDebug> +#include <QFile> +#include <QApplication> +#include <QMainWindow> +#include <QTableView> +#include <QAction> +#include <QActionGroup> +#include <QSlider> +#include <QMessageBox> +#include <QCheckBox> + + +class DemoEditor : public QMainWindow +{ + Q_OBJECT + +public: + DemoEditor(); + ~DemoEditor(); + + void settingsRestore(); + void settingsSave(); + + +private slots: + void actionFileNew(); + void actionFileOpen(); + void actionFileSave(); + void actionFileSaveAs(); + + void actionAboutBox(); + + //void actionCut(); + //void actionCopy(); + //void actionPaste(); + //void actionDelete(); + + void performUndo(); + void performRedo(); + +private: + bool changed, initSDL; + DemoObject *demo; + DMEngineData engine; + + + QTableView *list; + QAction *menuActUndo, *menuActRedo, *menuActOpen, *menuActSave, *menuActSaveAs; +// QAction *menuActCut, *menuActCopy, *menuActPaste, *menuActDelete; + + QAction * createToolButton(QActionGroup *group, QString name, QIcon icon, QString statustip, QVariant data); + QAction * createMenuAction(QString name, const QKeySequence &shortcut, QString tooltip); + QAction * createMenuGroupAction(QMenu *, QActionGroup *, QString name, const QKeySequence &shortcut, QString tooltip, QVariant data); + void setActionGroupChecked(QActionGroup *group, QVariant data); + + + void showFileErrorDialog(QString operation, int code, QFile::FileError err); + QMessageBox::StandardButton showDocumentModifiedDialog(); + void statusMsg(QString message); + void closeEvent(QCloseEvent *event); + void createMainGUI(); + void updateMenuStates(); + + int reopenResources(); + int loadResources(); + bool initializeVideo(); + + + void rehashFile(); + void createNewFile(); + void readFromFile(QString filename); + void saveToFile(QString filename); + + + QList<DemoObject *> undoHistory; + int undoHistoryPos, undoHistoryMax; + + void historyReset(); + void historyPush(QString description); + void historyTop(); + void historyPop(); +}; + + +#endif // EDMAIN_H
--- a/edtimeline.cpp Wed Oct 17 01:47:49 2012 +0300 +++ b/edtimeline.cpp Wed Oct 17 02:27:55 2012 +0300 @@ -59,18 +59,6 @@ for (int event = 0; event < track->nevents; event++) { DMTimelineEvent *ev = track->events[event]; - - if (ev->startTime >= offs && ev->startTime < twidth || - ev->startTime + ev->duration >= offs) - { - int ex0 = x0 + (ev->startTime - offs) * scale, - ew = ex0 + ev->duration * scale, - ex1 = ex0 + ew <= x1 ? ex0 + ew : x1; - - painter.setPen(waveColor); - dmFillRect(screen, ex0, y0, ex1, y1, eventColor); - //dmDrawTTFText(screen, font, fontcol, ex0, y0, "'%s'", ev->effect->name); - } } if (time >= offs * scale && time - offs <= width() * scale)
--- a/edwaveform.cpp Wed Oct 17 01:47:49 2012 +0300 +++ b/edwaveform.cpp Wed Oct 17 02:27:55 2012 +0300 @@ -4,25 +4,20 @@ WaveformView::WaveformView(QWidget *parent) : QWidget(parent) { - track = NULL; - time = offs = 0; + data = NULL; + len = time = offs = 0; scale = 1.0f; } -void WaveformView::setTrack(DMWaveform *mtrack) +void WaveformView::setWaveform(qint16 *mdata, int mlen) { - track = mtrack; + data = mdata; + len = mlen; update(); } -DMWaveform * WaveformView::getTrack() -{ - return track; -} - - void WaveformView::setTime(const int mtime) { time = mtime; @@ -61,7 +56,7 @@ int prevY = 0, prevX = 0; for (int xc = 0; xc < width(); xc++) { - qint16 value = data[(offs + xc) * scale]; + qint16 value = data[(int) ((offs + xc) * scale)]; painter.drawLine(prevX, prevY, xc, value); prevY = value; prevX = xc; }
--- a/edwaveform.h Wed Oct 17 01:47:49 2012 +0300 +++ b/edwaveform.h Wed Oct 17 02:27:55 2012 +0300 @@ -10,7 +10,7 @@ public: WaveformView(QWidget *parent = 0); - void setWaveform(qint16 *mdata, int len); + void setWaveform(qint16 *mdata, int mlen); void setTime(const int mtime); void setOffset(const int moffs);