Skip to content
Extraits de code Groupes Projets
Sélectionner une révision Git
  • 3efde45b7daf0ae3f4c3da6423f47e4b058b4ec7
  • master par défaut
  • script
  • new-devel
  • devel
  • timingView-edit
  • fix-mpv
7 résultats

TimingLine.cc

Blame
  • TimingLine.cc 5,43 Kio
    #include "TimingLine.hh"
    
    #include <QPainter>
    #include <QGraphicsScene>
    
    #include "TimingUtils.hh"
    
    using namespace Vivy;
    
    #define CONNECT_SEP(sep)                                                                           \
        connect(sep, &TimingSeparator::positionChanged, this, &TimingLine::timingSeparatorHasChanged); \
        connect(sep, &TimingSeparator::enterPress, this, &TimingLine::sepEnterPress);                  \
        connect(sep, &TimingSeparator::exitPress, this, &TimingLine::sepExitPress);
    
    TimingLine::TimingLine(Ass::Line *lineptr, int index, QGraphicsItem *parent)
        : QGraphicsObject(parent)
        , line(*lineptr)
        , lineIndex(index)
    {
        setPos(TimingUtils::posFromMs(int(line.getStart()) * 10), TimingUtils::axisHeight());
        int currentTime = 0;
        int endSyl      = 0;
        int i;
    
        setZValue(Z_LINE_BACKGROUND);
    
        TimingSeparator *timingSeparatorStart =
            new TimingSeparator(currentTime, 0, TimingSeparator::SeparatorStyle::Start, this);
        seps.append(timingSeparatorStart);
        CONNECT_SEP(timingSeparatorStart);
    
        QVector<Ass::Syl> syls = line.getContent();
        for (i = 0; i < syls.size(); ++i) {
            endSyl = currentTime + 10 * int(syls.at(i).getDuration());
    
            TimingSyl *timingSyl = new TimingSyl(syls.at(i), currentTime, this);
            timingSyls.append(timingSyl);
    
            if (i != 0) {
                TimingSeparator *timingSeparator =
                    new TimingSeparator(currentTime, i, TimingSeparator::SeparatorStyle::Middle, this);
                seps.append(timingSeparator);
                CONNECT_SEP(timingSeparator);
            }
    
            currentTime = endSyl;
        }
    
        TimingSeparator *timingSeparatorEnd =
            new TimingSeparator(currentTime, i, TimingSeparator::SeparatorStyle::End, this);
        seps.append(timingSeparatorEnd);
        CONNECT_SEP(timingSeparatorEnd);
    }
    #undef CONNECT_SEP
    
    QRectF
    TimingLine::boundingRect() const
    {
        return QRectF(tempOffset, 0,
                      TimingUtils::posFromMs(int(10 * (line.getEnd() - line.getStart()))),
                      TimingUtils::audioHeight());
    }
    
    void
    TimingLine::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
    {
        painter->fillRect(QRectF(tempOffset, 0,
                                 TimingUtils::posFromMs(int(10 * (line.getEnd() - line.getStart()))),
                                 TimingUtils::audioHeight()),
                          QColor(0, 255, 255, 50));
    }
    
    void
    TimingLine::timingSeparatorHasChanged(int sylIndex, qreal x)
    {
    }
    
    void
    TimingLine::sepEnterPress(int sepIndex)
    {
    }
    
    void
    TimingLine::sepExitPress(int sepIndex)
    {
        if (tempOffset) {
            prepareGeometryChange();
            if (sepIndex == 0) {
                moveBy(tempOffset, 0);
    
                timingSyls[sepIndex]->setPos(0, 0);
                seps[sepIndex]->silentlySetPos(0, 0);
    
                for (int i = 1; i < timingSyls.size(); i++) {
                    timingSyls[i]->moveBy(-tempOffset, 0);
                }
                for (int i = 1; i < seps.size(); i++) {
                    seps[i]->silentlyMoveBy(-tempOffset, 0);
                }
    
                line.setStart(quint64(TimingUtils::msFromPos(mapToScene(0, 0).x()) / 10));
            }
        }
    
        tempOffset = 0;
    }
    
    qreal
    TimingLine::requestMove(int sepIndex, qreal x)
    {
        QRectF sceneRect       = mapRectFromScene(scene()->sceneRect());
        QVector<Ass::Syl> syls = line.getContent();
    
        qreal given = x;
        qreal mini, maxi;
    
        if (sepIndex <= 0) {
            prepareGeometryChange();
    
            mini = sceneRect.left();
            maxi = sepIndex < syls.size() - 1 ? timingSyls[sepIndex + 1]->pos().x()
                                              : TimingUtils::posFromMs(int(line.getDuration()) * 10);
    
            given      = qBound(mini, given, maxi);
            tempOffset = given;
    
            quint64 dur1 = quint64(TimingUtils::msFromPos(int(seps[1]->pos().x() - given)) / 10);
            syls[0].setDuration(dur1);
            timingSyls[0]->setLen(dur1);
            timingSyls[0]->setPos(given, 0);
            line.setStart(quint64(TimingUtils::msFromPos(mapToScene(seps[0]->pos().x(), 0).x()) / 10));
        }
    
        else if (sepIndex >= syls.size()) {
            prepareGeometryChange();
    
            mini  = timingSyls[sepIndex - 1]->pos().x();
            maxi  = sceneRect.right();
            given = qBound(mini, given, maxi);
    
            quint64 dur2 =
                quint64(TimingUtils::msFromPos(int(given - timingSyls[sepIndex - 1]->pos().x())) / 10);
            syls[sepIndex - 1].setDuration(dur2);
            timingSyls[sepIndex - 1]->setLen(dur2);
            line.setEnd(line.getStart() + quint64(TimingUtils::msFromPos(int(given)) / 10));
        }
    
        else {
            mini  = timingSyls[sepIndex - 1]->pos().x();
            maxi  = sepIndex < syls.size() - 1 ? timingSyls[sepIndex + 1]->pos().x()
                                               : TimingUtils::posFromMs(int(line.getDuration() * 10));
            given = qBound(mini, given, maxi);
    
            quint64 sumDur = syls[sepIndex].getDuration() + syls[sepIndex - 1].getDuration();
            quint64 dur1   = quint64(
                  TimingUtils::msFromPos(int(given) - int(timingSyls[sepIndex - 1]->pos().x())) / 10);
            dur1         = qMin(dur1, sumDur);
            quint64 dur2 = sumDur - dur1;
    
            syls[sepIndex - 1].setDuration(dur1);
            syls[sepIndex].setDuration(dur2);
    
            timingSyls[sepIndex - 1]->setLen(dur1);
            timingSyls[sepIndex]->setPos(given, 0);
            timingSyls[sepIndex]->setLen(dur2);
        }
    
        line.setContent(syls);
    
        if (given) {
            emit lineChanged(lineIndex, std::make_shared<Ass::Line>(line));
        }
    
        return given;
    }