Sélectionner une révision Git
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;
}