view edtimeline.cpp @ 510:43ea59887c69

Start work on making C64 formats encoding possible by changing DMDecodeOps to DMEncDecOps and adding fields and op enums for custom encode functions, renaming, etc. Split generic op sanity checking into a separate function in preparation for its use in generic encoding function.
author Matti Hamalainen <ccr@tnsp.org>
date Mon, 19 Nov 2012 15:06:01 +0200
parents d34922e6a244
children a4666c9e1336
line wrap: on
line source

#include <QtGui>
#include "edtimeline.h"


QEDTimelineTrackDisplay::QEDTimelineTrackDisplay(QWidget *parent) : QWidget(parent)
{
    track = NULL;
    time = offs = 0;
    scale = 1.0f;
    
    setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Minimum);
}


QSize QEDTimelineTrackDisplay::minimumSizeHint() const
{
    return QSize(100, 60);
}


QSize QEDTimelineTrackDisplay::sizeHint() const
{
    return QSize(600, 60);
}


void QEDTimelineTrackDisplay::setTrack(DMTimelineTrack *mtrack)
{
    track = mtrack;
}


void QEDTimelineTrackDisplay::setTime(const int mtime)
{
    time = mtime;
}


void QEDTimelineTrackDisplay::setOffset(const int moffs)
{
    offs = moffs;
}


void QEDTimelineTrackDisplay::setScale(const float mscale)
{
    if (mscale > 0.05)
        scale = mscale;
}


float QEDTimelineTrackDisplay::getTimeScale(float value)
{
    return value * scale;
}


float QEDTimelineTrackDisplay::getTimeFromCoord(float value)
{
    return value * scale * 1000.0f;
}


void QEDTimelineTrackDisplay::paintEvent(QPaintEvent *)
{
    if (track == NULL)
        return;

    QColor eventColor(150, 150, 150);
    QColor invalidEventColor(250, 150, 150);
    QColor eventBorder(200, 250, 200);
    QColor eventParam(200, 150, 100);
    QColor eventText(255, 255, 255);
    QColor markerColor(255,255,255);

    QFont fantti;
    fantti.setFamily("Arial");
    fantti.setPointSizeF(8.0f);
    fantti.setStyleHint(QFont::SansSerif);

    QPainter painter(this);
    painter.setRenderHint(QPainter::Antialiasing);


    painter.save();
    painter.scale(scale, 1);

    float wd = getTimeScale(width());
    for (int event = 0; event < track->nevents; event++)
    {
        DMTimelineEvent *ev = track->events[event];

        float x0 = getTimeScale(ev->start - offs),
              x1 = getTimeScale(ev->start + ev->duration - offs);

        if ((x0 >= 0 && x0 < wd) || (x0 < 0 && x1 >= 0))
        {
            painter.setFont(fantti);
            painter.setBrush(ev->effect != NULL ? eventColor : invalidEventColor);
            painter.setPen(eventBorder);
            x0 = ev->start - offs;
            x1 = ev->duration;
            painter.fillRect(x0, 0, x1, height(), eventColor);

            painter.setBrush(eventText);
            if (ev->effect != NULL)
            {
                QString name(ev->effect->name);
                painter.drawText(QPointF(x0 + 2, 10), name);
            }
            else
            {
                painter.drawText(QPointF(x0 + 2, 10), "INVALID");
            }
        }

    }

    painter.restore();

    if (time >= offs * scale && time - offs <= width() * scale)
    {
        int xc = time - offs;
        painter.save();
        painter.scale(scale, 1);
        painter.setPen(markerColor);
        painter.drawLine(xc, 0, xc, height());
        painter.restore();
    }
}


void QEDTimelineTrackDisplay::mousePressEvent(QMouseEvent *ev)
{
/*
    if (ev->button() == Qt::LeftButton)
    {
        lastPoint = ev->pos();
        scribbling = true;
    }
*/
}


void QEDTimelineTrackDisplay::mouseMoveEvent(QMouseEvent *ev)
{
/*
    if ((ev->buttons() & Qt::LeftButton) && scribbling)
        drawLineTo(ev->pos());
*/
}


void QEDTimelineTrackDisplay::mouseReleaseEvent(QMouseEvent *ev)
{
/*
    if (ev->button() == Qt::LeftButton && scribbling)
    {
        drawLineTo(ev->pos());
        scribbling = false;
    }
*/
}


QEDTimelineTrackView::QEDTimelineTrackView(QWidget *parent) : QWidget(parent)
{
    QHBoxLayout *mainLayout = new QHBoxLayout(this);
    mainLayout->setMargin(0);
    track = new QEDTimelineTrackDisplay(this);

    QFrame *infoLayoutContainer = new QFrame(this);
    infoLayoutContainer->setFrameStyle(QFrame::StyledPanel | QFrame::Plain);
    infoLayoutContainer->setLineWidth(2);
    infoLayoutContainer->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Minimum);
    infoLayoutContainer->setFixedWidth(200);

    QVBoxLayout *infoLayout = new QVBoxLayout(infoLayoutContainer);
    infoLayout->setMargin(0);
//    QVBoxLayout *infoLayout = new QVBoxLayout();
    infoName = new QLineEdit();
    infoName->setFrame(false);
    infoName->setMaxLength(DT_MAX_NAME_LENGTH);
    infoName->setStyleSheet("QLineEdit { background-color: black; color: white; padding: 2px; }");
    connect(infoName, SIGNAL(textEdited(const QString&)), this, SLOT(slotTrackNameChanged(const QString&)));
    infoLayout->addWidget(infoName);


    enabledCheck = new QCheckBox("Enabled");
    infoLayout->addWidget(enabledCheck);
    connect(enabledCheck, SIGNAL(toggled(bool)), this, SLOT(slotTrackEnabledChanged(bool)));
    
    infoData = new QLabel();
    infoData->setStyleSheet("QLabel { padding: 2px; }");
    infoLayout->addWidget(infoData);

    mainLayout->addWidget(infoLayoutContainer);
//    mainLayout->addLayout(infoLayout);
    mainLayout->addWidget(track);
}


void QEDTimelineTrackView::update()
{
    if (track != NULL && track->track)
    {
        infoName->setText(QString(track->track->name));
        enabledCheck->setChecked(track->track->enabled);
        infoData->setText(QString("<b>%1</b> events").arg(track->track->nevents));
    }
    else
    {
        infoName->setText("");
        infoData->setText("-");
        enabledCheck->setChecked(false);
    }

    QWidget::update();
}


void QEDTimelineTrackView::setTrack(DMTimelineTrack *mtrack)
{
    track->setTrack(mtrack);
    update();
}


void QEDTimelineTrackView::slotTrackEnabledChanged(bool value)
{
    track->track->enabled = value;
    emit trackChanged();
}


void QEDTimelineTrackView::slotTrackNameChanged(const QString & text)
{
    QByteArray ba = text.toUtf8();
    track->track->name = dm_strdup(ba.constData());
    emit trackChanged();
}



QEDTimelineView::QEDTimelineView(QWidget *parent) : QWidget(parent)
{
    layout = new QVBoxLayout(this);
    tl = NULL;
}


void QEDTimelineView::setTimeline(EDTimelineObject *mtl)
{
    tl = mtl;

    delete layout;
    layout = new QVBoxLayout(this);
    layout->setMargin(0);
    
    tracks.clear();

    if (tl != NULL && tl->tl != NULL)
    {
        for (int track = 0; track < tl->tl->ntracks; track++)
        {
            QEDTimelineTrackView *vtr = new QEDTimelineTrackView(this);
            vtr->setTrack(tl->tl->tracks[track]);
            tracks.append(vtr);
            layout->addWidget(vtr);
            connect(vtr, SIGNAL(trackChanged()), this, SLOT(slotTimelineChanged()));
        }
    }
    update();
}


void QEDTimelineView::slotTimelineChanged()
{
    if (tl != NULL)
    {
        tl->touch();
        emit timelineChanged();
    }
}


void QEDTimelineView::setTime(const int mtime)
{
    if (tl != NULL && tl->tl != NULL)
    {
        QList<QEDTimelineTrackView *>::iterator track;
        for (track = tracks.begin(); track != tracks.end(); track++)
        {
            (*track)->track->setTime(mtime);
        }
        update();
    }
}


void QEDTimelineView::setOffset(const int moffs)
{
    if (tl != NULL && tl->tl != NULL)
    {
        QList<QEDTimelineTrackView *>::iterator track;
        for (track = tracks.begin(); track != tracks.end(); track++)
        {
            (*track)->track->setOffset(moffs);
        }
        update();
    }
}


void QEDTimelineView::setScale(const float mscale)
{
    if (tl != NULL && tl->tl != NULL)
    {
        QList<QEDTimelineTrackView *>::iterator track;
        for (track = tracks.begin(); track != tracks.end(); track++)
        {
            (*track)->track->setScale(mscale);
        }
        update();
    }
}