X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=src%2Fkeyframehelper.cpp;h=b0bbb391d4329f3d7b51096cdc88e9a33f59326b;hb=c3302003093710ee247ad84c0fe2ef3c579d417f;hp=b880f0e39651ca19d39173cd0bb5c45582270418;hpb=89a0d2304f3e3de29843e92f6e644b44352ea5d6;p=kdenlive diff --git a/src/keyframehelper.cpp b/src/keyframehelper.cpp index b880f0e3..b0bbb391 100644 --- a/src/keyframehelper.cpp +++ b/src/keyframehelper.cpp @@ -17,75 +17,223 @@ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * ***************************************************************************/ -#include -#include + +#include "keyframehelper.h" +#include "kdenlivesettings.h" +#include "definitions.h" #include -#include -#include #include +#include -#include "keyframehelper.h" +#include +#include +#include -#include "definitions.h" +const int margin = 5; +const int cursorWidth = 6; +#define SEEK_INACTIVE (-1) -KeyframeHelper::KeyframeHelper(QWidget *parent) - : QWidget(parent), m_geom(NULL) { +KeyframeHelper::KeyframeHelper(QWidget *parent) : + QWidget(parent) + , frameLength(1) + , m_geom(NULL) + , m_position(0) + , m_scale(0) + , m_movingKeyframe(false) + , m_movingItem() + , m_lineHeight(9) + , m_drag(false) + , m_hoverKeyframe(-1) + , m_seekPosition(SEEK_INACTIVE) +{ setFont(KGlobalSettings::toolBarFont()); - + setMouseTracking(true); + QPalette p = palette(); + KColorScheme scheme(p.currentColorGroup(), KColorScheme::Window, KSharedConfig::openConfig(KdenliveSettings::colortheme())); + m_selected = scheme.decoration(KColorScheme::HoverColor).color(); + m_keyframe = scheme.foreground(KColorScheme::LinkText).color(); + m_keyframebg = scheme.shade(KColorScheme::MidShade); } // virtual -void KeyframeHelper::mousePressEvent(QMouseEvent * event) { - /* if (event->button() == Qt::RightButton) { - m_contextMenu->exec(event->globalPos()); - return; +void KeyframeHelper::mousePressEvent(QMouseEvent * event) +{ + m_hoverKeyframe = -1; + if (event->button() != Qt::LeftButton) { + QWidget::mousePressEvent(event); + return; + } + int xPos = event->x() - margin; + if (m_geom != NULL && (event->y() < m_lineHeight)) { + // check if we want to move a keyframe + int mousePos = qMax((int)(xPos / m_scale), 0); + Mlt::GeometryItem item; + if (m_geom->next_key(&item, mousePos) == 0) { + if (qAbs(item.frame() * m_scale - xPos) < 4) { + m_drag = true; + m_movingItem.x(item.x()); + m_movingItem.y(item.y()); + m_movingItem.w(item.w()); + m_movingItem.h(item.h()); + m_movingItem.mix(item.mix()); + m_movingItem.frame(item.frame()); + + while (!m_extraMovingItems.isEmpty()) { + Mlt::GeometryItem *gitem = m_extraMovingItems.takeFirst(); + if (gitem) delete gitem; + } + for (int i = 0; i < m_extraGeometries.count(); ++i) { + if (m_extraGeometries.at(i)->next_key(item, mousePos) == 0) { + Mlt::GeometryItem *item2 = new Mlt::GeometryItem(); + item2->x(item.x()); + item2->frame(item.frame()); + m_extraMovingItems.append(item2); + } else { + m_extraMovingItems.append(NULL); + } + } + + m_dragStart = event->pos(); + m_movingKeyframe = true; + return; + } } - m_view->activateMonitor(); - int pos = (int)((event->x() + offset())); - m_moveCursor = RULER_CURSOR; - if (event->y() > 10) { - if (qAbs(pos - m_zoneStart * m_factor) < 4) m_moveCursor = RULER_START; - else if (qAbs(pos - (m_zoneStart + (m_zoneEnd - m_zoneStart) / 2) * m_factor) < 4) m_moveCursor = RULER_MIDDLE; - else if (qAbs(pos - m_zoneEnd * m_factor) < 4) m_moveCursor = RULER_END; + } + if (event->y() >= m_lineHeight && event->y() < height()) { + int seekRequest = xPos / m_scale; + m_drag = true; + if (seekRequest != m_position) { + m_seekPosition = seekRequest; + emit requestSeek(m_seekPosition); + update(); } - if (m_moveCursor == RULER_CURSOR) - m_view->setCursorPos((int) pos / m_factor); - */ + } +} + +void KeyframeHelper::leaveEvent( QEvent * event ) +{ + Q_UNUSED(event); + if (m_hoverKeyframe != -1) { + m_hoverKeyframe = -1; + update(); + } } // virtual -void KeyframeHelper::mouseMoveEvent(QMouseEvent * event) { - /* if (event->buttons() == Qt::LeftButton) { - int pos = (int)((event->x() + offset()) / m_factor); - if (pos < 0) pos = 0; - if (m_moveCursor == RULER_CURSOR) { - m_view->setCursorPos(pos); - return; - } else if (m_moveCursor == RULER_START) m_zoneStart = pos; - else if (m_moveCursor == RULER_END) m_zoneEnd = pos; - else if (m_moveCursor == RULER_MIDDLE) { - int move = pos - (m_zoneStart + (m_zoneEnd - m_zoneStart) / 2); - m_zoneStart += move; - m_zoneEnd += move; +void KeyframeHelper::mouseMoveEvent(QMouseEvent * event) +{ + int xPos = event->x() - margin; + if (!m_drag) { + int mousePos = qMax((int)(xPos / m_scale), 0); + if (qAbs(m_position * m_scale - xPos) < cursorWidth && event->y() >= m_lineHeight) { + // Mouse over time cursor + if (m_hoverKeyframe != -2) { + m_hoverKeyframe = -2; + update(); + } + event->accept(); + return; + } + if (m_geom != NULL && (event->y() < m_lineHeight)) { + // check if we want to move a keyframe + Mlt::GeometryItem item; + if (m_geom->next_key(&item, mousePos) == 0) { + if (qAbs(item.frame() * m_scale - xPos) < 4) { + if (m_hoverKeyframe == item.frame()) return; + m_hoverKeyframe = item.frame(); + setCursor(Qt::PointingHandCursor); + update(); + event->accept(); + return; + } } - m_view->setDocumentModified(); + } + if (m_hoverKeyframe != -1) { + m_hoverKeyframe = -1; + setCursor(Qt::ArrowCursor); update(); - } else { - int pos = (int)((event->x() + offset())); - if (event->y() <= 10) setCursor(Qt::ArrowCursor); - else if (qAbs(pos - m_zoneStart * m_factor) < 4) setCursor(KCursor("left_side", Qt::SizeHorCursor)); - else if (qAbs(pos - m_zoneEnd * m_factor) < 4) setCursor(KCursor("right_side", Qt::SizeHorCursor)); - else if (qAbs(pos - (m_zoneStart + (m_zoneEnd - m_zoneStart) / 2) * m_factor) < 4) setCursor(Qt::SizeHorCursor); - else setCursor(Qt::ArrowCursor); } - */ + event->accept(); + return; + } + if (m_movingKeyframe) { + if (!m_dragStart.isNull()) { + if ((QPoint(xPos, event->y()) - m_dragStart).manhattanLength() < QApplication::startDragDistance()) return; + m_dragStart = QPoint(); + m_geom->remove(m_movingItem.frame()); + for (int i = 0; i < m_extraGeometries.count(); ++i) + m_extraGeometries[i]->remove(m_movingItem.frame()); + } + int pos = qBound(0, (int)(xPos / m_scale), frameLength); + if (KdenliveSettings::snaptopoints() && qAbs(pos - m_position) < 5) + pos = m_position; + m_movingItem.frame(pos); + for (int i = 0; i < m_extraMovingItems.count(); ++i) { + if (m_extraMovingItems.at(i)) + m_extraMovingItems[i]->frame(pos); + } + update(); + return; + } + m_seekPosition = (int) (xPos / m_scale); + m_seekPosition = qMax(0, m_seekPosition); + m_seekPosition = qMin(frameLength, m_seekPosition); + m_hoverKeyframe = -2; + emit requestSeek(m_seekPosition); + update(); } +void KeyframeHelper::mouseDoubleClickEvent(QMouseEvent * event) +{ + if (m_geom != NULL && event->button() == Qt::LeftButton) { + // check if we want to move a keyframe + int xPos = event->x() - margin; + int mousePos = qMax((int)(xPos / m_scale - 5), 0); + Mlt::GeometryItem item; + if (m_geom->next_key(&item, mousePos) == 0 && item.frame() - mousePos < 10) { + // There is already a keyframe close to mouse click + emit removeKeyframe(item.frame()); + return; + } + // add new keyframe + emit addKeyframe((int)(xPos / m_scale)); + } +} + +// virtual +void KeyframeHelper::mouseReleaseEvent(QMouseEvent * event) +{ + m_drag = false; + setCursor(Qt::ArrowCursor); + m_hoverKeyframe = -1; + if (m_movingKeyframe) { + m_geom->insert(m_movingItem); + m_movingKeyframe = false; + + for (int i = 0; i < m_extraGeometries.count(); ++i) { + if (m_extraMovingItems.at(i)) + m_extraGeometries[i]->insert(m_extraMovingItems.at(i)); + } + + emit keyframeMoved(m_position); + return; + } + QWidget::mouseReleaseEvent(event); +} // virtual -void KeyframeHelper::wheelEvent(QWheelEvent * e) { +void KeyframeHelper::wheelEvent(QWheelEvent * e) +{ + if (e->delta() < 0) + --m_position; + else + ++m_position; + m_position = qMax(0, m_position); + m_position = qMin(frameLength, m_position); + emit requestSeek(m_position); + update(); /* int delta = 1; if (e->modifiers() == Qt::ControlModifier) delta = m_timecode.fps(); if (e->delta() < 0) delta = 0 - delta; @@ -94,29 +242,103 @@ void KeyframeHelper::wheelEvent(QWheelEvent * e) { } // virtual -void KeyframeHelper::paintEvent(QPaintEvent *e) { +void KeyframeHelper::paintEvent(QPaintEvent *e) +{ QStylePainter p(this); - p.setClipRect(e->rect()); - + const QRectF clipRect = e->rect(); + p.setClipRect(clipRect); + m_scale = (double) (width() - 2 * margin) / frameLength; if (m_geom != NULL) { int pos = 0; + p.setPen(m_keyframe); + p.setBrush(m_keyframebg); Mlt::GeometryItem item; - for (int i = 0; i < m_geom->length(); i++) { - m_geom->next_key(&item, pos); + while (true) { + if (m_geom->next_key(&item, pos) == 1) break; pos = item.frame(); - kDebug() << "++ PAINTING POS: " << pos; - int scaledPos = pos * width() / m_length; - p.fillRect(QRect(scaledPos - 1, 0, 2, 15), QBrush(QColor(255, 20, 20))); + if (pos == m_hoverKeyframe) { + p.setBrush(m_selected); + } + int scaledPos = margin + pos * m_scale; + // draw keyframes + p.drawLine(scaledPos, 9, scaledPos, 15); + // draw pointer + QPolygon pa(4); + pa.setPoints(4, + scaledPos, 0, + scaledPos - 4, 4, + scaledPos, 8, + scaledPos + 4, 4); + p.drawPolygon(pa); + //p.drawEllipse(scaledPos - 4, 0, 8, 8); + if (pos == m_hoverKeyframe) { + p.setBrush(m_keyframebg); + } + //p.fillRect(QRect(scaledPos - 1, 0, 2, 15), QBrush(QColor(255, 20, 20))); pos++; } + + if (m_movingKeyframe) { + p.setBrush(m_selected); + int scaledPos = margin + (int)(m_movingItem.frame() * m_scale); + // draw keyframes + p.drawLine(scaledPos, 9, scaledPos, 15); + // draw pointer + QPolygon pa(5); + pa.setPoints(4, + scaledPos, 0, + scaledPos - 4, 4, + scaledPos, 8, + scaledPos + 4, 4); + p.drawPolygon(pa); + p.setBrush(m_keyframe); + } + } + p.setPen(palette().dark().color()); + p.drawLine(margin, m_lineHeight, width() - margin - 1, m_lineHeight); + p.drawLine(margin, m_lineHeight - 3, margin, m_lineHeight + 3); + p.drawLine(width() - margin, m_lineHeight - 3, width() - margin, m_lineHeight + 3); + + // draw pointer + if (m_seekPosition != SEEK_INACTIVE) { + p.fillRect(margin + m_seekPosition * m_scale - 1, 0, 3, height(), palette().dark()); } + QPolygon pa(3); + const int cursor = margin + m_position * m_scale; + pa.setPoints(3, cursor - cursorWidth, 16, cursor + cursorWidth, 16, cursor, 10); + if (m_hoverKeyframe == -2) + p.setBrush(palette().highlight()); + else + p.setBrush(palette().dark().color()); + p.drawPolygon(pa); } -void KeyframeHelper::setKeyGeometry(Mlt::Geometry *geom, const int length) { +int KeyframeHelper::value() const +{ + return m_position; +} + +void KeyframeHelper::setValue(const int pos) +{ + if (pos == m_position || m_geom == NULL) + return; + if (pos == m_seekPosition) { + m_seekPosition = SEEK_INACTIVE; + } + m_position = pos; + update(); +} + +void KeyframeHelper::setKeyGeometry(Mlt::Geometry *geom, const int length) +{ m_geom = geom; - m_length = length; - kDebug() << "KEYFRAMES: " << m_geom->length() << ", TRANS SOZE: " << m_length; + frameLength = qMax(1, length); update(); } +void KeyframeHelper::addGeometry(Mlt::Geometry *geom) +{ + m_extraGeometries.append(geom); +} + #include "keyframehelper.moc"