From c375cd3ee72e248a279271b4b21740b72efde06a Mon Sep 17 00:00:00 2001 From: itsmattkc Date: Thu, 19 Jul 2018 13:02:35 +0100 Subject: [PATCH] many fixes and improvements --- dialogs/newsequencedialog.cpp | 24 +-- io/media.cpp | 4 +- io/media.h | 2 +- mainwindow.cpp | 6 +- panels/project.cpp | 9 +- panels/timeline.cpp | 38 ++--- panels/viewer.cpp | 92 ++++++------ panels/viewer.h | 4 +- project/undo.cpp | 12 +- ui/timelinewidget.cpp | 276 +++++++++++++++++----------------- 10 files changed, 239 insertions(+), 228 deletions(-) diff --git a/dialogs/newsequencedialog.cpp b/dialogs/newsequencedialog.cpp index 80513d8a3..aaf619119 100644 --- a/dialogs/newsequencedialog.cpp +++ b/dialogs/newsequencedialog.cpp @@ -19,17 +19,17 @@ NewSequenceDialog::NewSequenceDialog(QWidget *parent) : { ui->setupUi(this); - ui->frame_rate_combobox->addItem("10 FPS", 10.0f); - ui->frame_rate_combobox->addItem("12.5 FPS", 12.5f); - ui->frame_rate_combobox->addItem("15 FPS", 15.0f); - ui->frame_rate_combobox->addItem("23.976 FPS", 23.976f); - ui->frame_rate_combobox->addItem("24 FPS", 24.0f); - ui->frame_rate_combobox->addItem("25 FPS", 25.0f); - ui->frame_rate_combobox->addItem("29.97 FPS", 29.97f); - ui->frame_rate_combobox->addItem("30 FPS", (float) 30.0f); - ui->frame_rate_combobox->addItem("50 FPS", (float) 50.0f); - ui->frame_rate_combobox->addItem("59.94 FPS", (float) 59.94f); - ui->frame_rate_combobox->addItem("60 FPS", (float) 60.0f); + ui->frame_rate_combobox->addItem("10 FPS", 10.0); + ui->frame_rate_combobox->addItem("12.5 FPS", 12.5); + ui->frame_rate_combobox->addItem("15 FPS", 15.0); + ui->frame_rate_combobox->addItem("23.976 FPS", 23.976); + ui->frame_rate_combobox->addItem("24 FPS", 24.0); + ui->frame_rate_combobox->addItem("25 FPS", 25.0); + ui->frame_rate_combobox->addItem("29.97 FPS", 29.97); + ui->frame_rate_combobox->addItem("30 FPS", 30.0); + ui->frame_rate_combobox->addItem("50 FPS", 50.0); + ui->frame_rate_combobox->addItem("59.94 FPS", 59.94); + ui->frame_rate_combobox->addItem("60 FPS", 60.0); ui->frame_rate_combobox->setCurrentIndex(6); ui->audio_frequency_combobox->addItem("22050 Hz", 22050); @@ -58,7 +58,7 @@ void NewSequenceDialog::on_buttonBox_accepted() s->name = ui->lineEdit->text(); s->width = ui->width_numeric->value(); s->height = ui->height_numeric->value(); - s->frame_rate = ui->frame_rate_combobox->currentData().toFloat(); + s->frame_rate = ui->frame_rate_combobox->currentData().toDouble(); s->audio_frequency = ui->audio_frequency_combobox->currentData().toInt(); s->audio_layout = AV_CH_LAYOUT_STEREO; diff --git a/io/media.cpp b/io/media.cpp index 880ac10f0..d44dcc782 100644 --- a/io/media.cpp +++ b/io/media.cpp @@ -19,8 +19,8 @@ Media::~Media() { audio_tracks.clear(); } -long Media::get_length_in_frames(float frame_rate) { - return ceil((float) length / (float) AV_TIME_BASE * frame_rate); +long Media::get_length_in_frames(double frame_rate) { + return ceil(((double) length / (double) AV_TIME_BASE) * frame_rate); } MediaStream* Media::get_stream_from_file_index(int index) { diff --git a/io/media.h b/io/media.h index dd9a585be..e4c0d6d30 100644 --- a/io/media.h +++ b/io/media.h @@ -38,7 +38,7 @@ struct Media QVector audio_tracks; int save_id; bool ready; - long get_length_in_frames(float frame_rate); + long get_length_in_frames(double frame_rate); MediaStream* get_stream_from_file_index(int index); }; diff --git a/mainwindow.cpp b/mainwindow.cpp index 0957eaacb..8409c9076 100644 --- a/mainwindow.cpp +++ b/mainwindow.cpp @@ -512,7 +512,7 @@ void MainWindow::on_actionFrames_triggered() { panel_viewer->timecode_view = TIMECODE_FRAMES; if (sequence != NULL) { - panel_viewer->update_playhead_timecode(); + panel_viewer->update_playhead_timecode(panel_timeline->playhead); panel_viewer->update_end_timecode(); } } @@ -521,7 +521,7 @@ void MainWindow::on_actionDrop_Frame_triggered() { panel_viewer->timecode_view = TIMECODE_DROP; if (sequence != NULL) { - panel_viewer->update_playhead_timecode(); + panel_viewer->update_playhead_timecode(panel_timeline->playhead); panel_viewer->update_end_timecode(); } } @@ -530,7 +530,7 @@ void MainWindow::on_actionNon_Drop_Frame_triggered() { panel_viewer->timecode_view = TIMECODE_NONDROP; if (sequence != NULL) { - panel_viewer->update_playhead_timecode(); + panel_viewer->update_playhead_timecode(panel_timeline->playhead); panel_viewer->update_end_timecode(); } } diff --git a/panels/project.cpp b/panels/project.cpp index 457fe4cdc..4c9574a9d 100644 --- a/panels/project.cpp +++ b/panels/project.cpp @@ -275,11 +275,10 @@ void Project::delete_selected_media() { } for (int i=0;idelete_media(items.at(i)); } undo_stack.push(ta); @@ -288,6 +287,8 @@ void Project::delete_selected_media() { if (redraw) { panel_timeline->redraw_all_clips(true); } + + project_changed = true; } else { delete ta; } diff --git a/panels/timeline.cpp b/panels/timeline.cpp index 28a7245b5..ad2ab4d23 100644 --- a/panels/timeline.cpp +++ b/panels/timeline.cpp @@ -121,12 +121,14 @@ void Timeline::next_cut() { void Timeline::reset_all_audio() { // reset all clip audio - for (int i=0;iclip_count();i++) { - Clip* c = sequence->get_clip(i); - if (c != NULL) { - c->reset_audio = true; - c->frame_sample_index = 0; - c->audio_buffer_write = 0; + if (sequence != NULL) { + for (int i=0;iclip_count();i++) { + Clip* c = sequence->get_clip(i); + if (c != NULL) { + c->reset_audio = true; + c->frame_sample_index = 0; + c->audio_buffer_write = 0; + } } } ui->audio_monitor->reset(); @@ -247,23 +249,21 @@ void Timeline::repaint_timeline() { ui->audio_monitor->update(); last_frame = playhead; } - panel_viewer->update_playhead_timecode(); + panel_viewer->update_playhead_timecode(playhead); } void Timeline::redraw_all_clips(bool changed) { - if (sequence != NULL) { - if (changed) { - project_changed = true; - if (!playing) reset_all_audio(); - panel_viewer->viewer_widget->update(); - } - - ui->video_area->redraw_clips(); - ui->audio_area->redraw_clips(); - ui->headers->update(); - - panel_viewer->update_end_timecode(); + if (changed) { + project_changed = true; + if (!playing) reset_all_audio(); + panel_viewer->viewer_widget->update(); } + + ui->video_area->redraw_clips(); + ui->audio_area->redraw_clips(); + ui->headers->update(); + + panel_viewer->update_end_timecode(); } void Timeline::select_all() { diff --git a/panels/viewer.cpp b/panels/viewer.cpp index 9ba2a36af..25556dd6a 100644 --- a/panels/viewer.cpp +++ b/panels/viewer.cpp @@ -24,6 +24,9 @@ Viewer::Viewer(QWidget *parent) : viewer_widget = ui->openGLWidget; timecode_view = TIMECODE_DROP; update_sequence(); + + update_playhead_timecode(0); + update_end_timecode(); } Viewer::~Viewer() @@ -32,8 +35,8 @@ Viewer::~Viewer() delete ui; } -QString Viewer::frame_to_timecode(long f) { - if (timecode_view == TIMECODE_FRAMES) { +QString Viewer::frame_to_timecode(long f, int view, double frame_rate) { + if (view == TIMECODE_FRAMES) { return QString::number(f); } @@ -44,49 +47,47 @@ QString Viewer::frame_to_timecode(long f) { int frames = 0; QString token = ":"; - if (sequence != NULL) { - if (timecode_view == TIMECODE_DROP && frame_rate_is_droppable(sequence->frame_rate)) { - //CONVERT A FRAME NUMBER TO DROP FRAME TIMECODE - //Code by David Heidelberger, adapted from Andrew Duncan, further adapted for Olive by Olive Team - //Given an int called framenumber and a double called framerate - //Framerate should be 29.97, 59.94, or 23.976, otherwise the calculations will be off. + if (view == TIMECODE_DROP && frame_rate_is_droppable(frame_rate)) { + //CONVERT A FRAME NUMBER TO DROP FRAME TIMECODE + //Code by David Heidelberger, adapted from Andrew Duncan, further adapted for Olive by Olive Team + //Given an int called framenumber and a double called framerate + //Framerate should be 29.97, 59.94, or 23.976, otherwise the calculations will be off. - int d; - int m; + int d; + int m; - int dropFrames = round(sequence->frame_rate * .066666); //Number of frames to drop on the minute marks is the nearest integer to 6% of the framerate - int framesPerHour = round(sequence->frame_rate*60*60); //Number of frames in an hour - int framesPer24Hours = framesPerHour*24; //Number of frames in a day - timecode rolls over after 24 hours - int framesPer10Minutes = round(sequence->frame_rate * 60 * 10); //Number of frames per ten minutes - int framesPerMinute = (round(sequence->frame_rate)*60)- dropFrames; //Number of frames per minute is the round of the framerate * 60 minus the number of dropped frames + int dropFrames = round(frame_rate * .066666); //Number of frames to drop on the minute marks is the nearest integer to 6% of the framerate + int framesPerHour = round(frame_rate*60*60); //Number of frames in an hour + int framesPer24Hours = framesPerHour*24; //Number of frames in a day - timecode rolls over after 24 hours + int framesPer10Minutes = round(frame_rate * 60 * 10); //Number of frames per ten minutes + int framesPerMinute = (round(frame_rate)*60)- dropFrames; //Number of frames per minute is the round of the framerate * 60 minus the number of dropped frames - //If framenumber is greater than 24 hrs, next operation will rollover clock - f = f % framesPer24Hours; //% is the modulus operator, which returns a remainder. a % b = the remainder of a/b + //If framenumber is greater than 24 hrs, next operation will rollover clock + f = f % framesPer24Hours; //% is the modulus operator, which returns a remainder. a % b = the remainder of a/b - d = f / framesPer10Minutes; // \ means integer division, which is a/b without a remainder. Some languages you could use floor(a/b) - m = f % framesPer10Minutes; + d = f / framesPer10Minutes; // \ means integer division, which is a/b without a remainder. Some languages you could use floor(a/b) + m = f % framesPer10Minutes; - //In the original post, the next line read m>1, which only worked for 29.97. Jean-Baptiste Mardelle correctly pointed out that m should be compared to dropFrames. - if (m > dropFrames) { - f = f + (dropFrames*9*d) + dropFrames * ((m - dropFrames) / framesPerMinute); - } else { - f = f + dropFrames*9*d; - } - - int frRound = round(sequence->frame_rate); - frames = f % frRound; - secs = (f / frRound) % 60; - mins = ((f / frRound) / 60) % 60; - hours = (((f / frRound) / 60) / 60); - - token = ";"; + //In the original post, the next line read m>1, which only worked for 29.97. Jean-Baptiste Mardelle correctly pointed out that m should be compared to dropFrames. + if (m > dropFrames) { + f = f + (dropFrames*9*d) + dropFrames * ((m - dropFrames) / framesPerMinute); } else { - int int_fps = qRound(sequence->frame_rate); - hours = f/ (3600 * int_fps); - mins = f / (60*int_fps) % 60; - secs = f/int_fps % 60; - frames = f%int_fps; + f = f + dropFrames*9*d; } + + int frRound = round(frame_rate); + frames = f % frRound; + secs = (f / frRound) % 60; + mins = ((f / frRound) / 60) % 60; + hours = (((f / frRound) / 60) / 60); + + token = ";"; + } else { + int int_fps = qRound(frame_rate); + hours = f/ (3600 * int_fps); + mins = f / (60*int_fps) % 60; + secs = f/int_fps % 60; + frames = f%int_fps; } return QString(QString::number(hours).rightJustified(2, '0') + ":" + QString::number(mins).rightJustified(2, '0') + @@ -99,12 +100,16 @@ bool frame_rate_is_droppable(float rate) { return (rate == 23.976f || rate == 29.97f || rate == 59.94f); } -void Viewer::update_playhead_timecode() { - ui->currentTimecode->setText(frame_to_timecode(panel_timeline->playhead)); +void Viewer::update_playhead_timecode(long p) { + ui->currentTimecode->setText(frame_to_timecode(p, timecode_view, (sequence != NULL) ? sequence->frame_rate : 30)); } void Viewer::update_end_timecode() { - ui->endTimecode->setText(frame_to_timecode(sequence->getEndFrame())); + if (sequence == NULL) { + ui->endTimecode->setText(frame_to_timecode(0, timecode_view, 30)); + } else { + ui->endTimecode->setText(frame_to_timecode(sequence->getEndFrame(), timecode_view, sequence->frame_rate)); + } } void Viewer::update_sequence() { @@ -127,11 +132,14 @@ void Viewer::update_sequence() { timecode_view = TIMECODE_NONDROP; } - update_playhead_timecode(); + update_playhead_timecode(panel_timeline->playhead); update_end_timecode(); ui->glViewerPane->aspect_ratio = (float) sequence->width / (float) sequence->height; ui->glViewerPane->adjust(); + } else { + update_playhead_timecode(0); + update_end_timecode(); } update(); diff --git a/panels/viewer.h b/panels/viewer.h index 2f30bed66..13835a77e 100644 --- a/panels/viewer.h +++ b/panels/viewer.h @@ -28,7 +28,7 @@ public: void compose(); void set_playpause_icon(bool play); int timecode_view; - void update_playhead_timecode(); + void update_playhead_timecode(long p); void update_end_timecode(); ViewerWidget* viewer_widget; @@ -46,7 +46,7 @@ private slots: void on_pushButton_3_clicked(); private: - QString frame_to_timecode(long f); + QString frame_to_timecode(long f, int view, double frame_rate); }; #endif // VIEWER_H diff --git a/project/undo.cpp b/project/undo.cpp index 5d5a950c9..1e67ff26f 100644 --- a/project/undo.cpp +++ b/project/undo.cpp @@ -323,12 +323,12 @@ void TimelineAction::redo() { deleted_media_parents.append(item->parent()); // if we're deleting the open sequence, close it - if (panel_project->get_type_from_tree(item) == MEDIA_TYPE_SEQUENCE) { - if (panel_project->get_sequence_from_tree(item) == sequence && !change_seq) { - old_seq = sequence; - new_seq = NULL; - change_seq = true; - } + if (panel_project->get_type_from_tree(item) == MEDIA_TYPE_SEQUENCE && + panel_project->get_sequence_from_tree(item) == sequence && + !change_seq) { + old_seq = sequence; + new_seq = NULL; + change_seq = true; } if (item->parent() == NULL) { diff --git a/ui/timelinewidget.cpp b/ui/timelinewidget.cpp index 8b2736efa..202c58ac8 100644 --- a/ui/timelinewidget.cpp +++ b/ui/timelinewidget.cpp @@ -1230,161 +1230,163 @@ int color_brightness(int r, int g, int b) { void TimelineWidget::redraw_clips() { // Draw clips - int panel_width = panel_timeline->getScreenPointFromFrame(sequence->getEndFrame()) + 100; + if (sequence != NULL) { + int panel_width = panel_timeline->getScreenPointFromFrame(sequence->getEndFrame()) + 100; - if (minimumWidth() != panel_width || clip_pixmap.height() != height()) { - setMinimumWidth(panel_width); - clip_pixmap = QPixmap(panel_width, height()); - } + if (minimumWidth() != panel_width || clip_pixmap.height() != height()) { + setMinimumWidth(panel_width); + clip_pixmap = QPixmap(qMax(width(), panel_width), height()); + } - clip_pixmap.fill(Qt::transparent); - QPainter clip_painter(&clip_pixmap); - int video_track_limit = 0; - int audio_track_limit = 0; - QColor transition_color(255, 0, 0, 16); - for (int i=0;iclip_count();i++) { - Clip* clip = sequence->get_clip(i); - if (clip != NULL && is_track_visible(clip->track)) { - if (clip->track < 0 && clip->track < video_track_limit) { // video clip - video_track_limit = clip->track; - } else if (clip->track > audio_track_limit) { - audio_track_limit = clip->track; - } - - QRect clip_rect(panel_timeline->getScreenPointFromFrame(clip->timeline_in), getScreenPointFromTrack(clip->track), clip->getLength() * panel_timeline->zoom, panel_timeline->calculate_track_height(clip->track, -1)); - clip_painter.fillRect(clip_rect, QColor(clip->color_r, clip->color_g, clip->color_b)); - - int thumb_x = clip_rect.x() + 1; - - QRect text_rect(clip_rect.left() + CLIP_TEXT_PADDING, clip_rect.top() + CLIP_TEXT_PADDING, clip_rect.width() - CLIP_TEXT_PADDING - 1, clip_rect.height() - CLIP_TEXT_PADDING - 1); - - // draw clip transitions - for (char i=0;i<2;i++) { - Transition* t; - if (i == 0) { - t = clip->opening_transition; - } else { - t = clip->closing_transition; + clip_pixmap.fill(Qt::transparent); + QPainter clip_painter(&clip_pixmap); + int video_track_limit = 0; + int audio_track_limit = 0; + QColor transition_color(255, 0, 0, 16); + for (int i=0;iclip_count();i++) { + Clip* clip = sequence->get_clip(i); + if (clip != NULL && is_track_visible(clip->track)) { + if (clip->track < 0 && clip->track < video_track_limit) { // video clip + video_track_limit = clip->track; + } else if (clip->track > audio_track_limit) { + audio_track_limit = clip->track; } - if (t != NULL) { - int transition_width = panel_timeline->getScreenPointFromFrame(t->length); - int transition_height = clip_rect.height() * 0.6; - if (transition_height <= TRACK_MIN_HEIGHT) { - transition_height = clip_rect.height(); - } - int tr_y = clip_rect.y() + ((clip_rect.height()-transition_height)/2); - int tr_x = 0; + + QRect clip_rect(panel_timeline->getScreenPointFromFrame(clip->timeline_in), getScreenPointFromTrack(clip->track), clip->getLength() * panel_timeline->zoom, panel_timeline->calculate_track_height(clip->track, -1)); + clip_painter.fillRect(clip_rect, QColor(clip->color_r, clip->color_g, clip->color_b)); + + int thumb_x = clip_rect.x() + 1; + + QRect text_rect(clip_rect.left() + CLIP_TEXT_PADDING, clip_rect.top() + CLIP_TEXT_PADDING, clip_rect.width() - CLIP_TEXT_PADDING - 1, clip_rect.height() - CLIP_TEXT_PADDING - 1); + + // draw clip transitions + for (char i=0;i<2;i++) { + Transition* t; if (i == 0) { - tr_x = clip_rect.x(); - text_rect.setX(text_rect.x()+transition_width); - thumb_x += transition_width; + t = clip->opening_transition; } else { - tr_x = clip_rect.right()-transition_width; - text_rect.setWidth(text_rect.width()-transition_width); + t = clip->closing_transition; } - QRect transition_rect = QRect(tr_x, tr_y, transition_width, transition_height); - clip_painter.fillRect(transition_rect, transition_color); - QRect transition_text_rect(transition_rect.x() + CLIP_TEXT_PADDING, transition_rect.y() + CLIP_TEXT_PADDING, transition_rect.width() - CLIP_TEXT_PADDING, transition_rect.height() - CLIP_TEXT_PADDING); - if (transition_text_rect.width() > MAX_TEXT_WIDTH) { - clip_painter.setPen(QColor(0, 0, 0, 96)); - if (i == 0) { - clip_painter.drawLine(transition_rect.bottomLeft(), transition_rect.topRight()); - } else { - clip_painter.drawLine(transition_rect.topLeft(), transition_rect.bottomRight()); + if (t != NULL) { + int transition_width = panel_timeline->getScreenPointFromFrame(t->length); + int transition_height = clip_rect.height() * 0.6; + if (transition_height <= TRACK_MIN_HEIGHT) { + transition_height = clip_rect.height(); } - - clip_painter.setPen(Qt::white); - clip_painter.drawText(transition_text_rect, 0, t->name, &transition_text_rect); - } - clip_painter.setPen(Qt::black); - clip_painter.drawRect(transition_rect); - } - } - - // draw thumbnail/waveform - if (clip->media_stream->preview_done) { - if (clip->track < 0) { - int thumb_y = clip_painter.fontMetrics().height()+CLIP_TEXT_PADDING+CLIP_TEXT_PADDING; - int thumb_height = clip_rect.height()-thumb_y; - int thumb_width = (thumb_height*((float)clip->media_stream->video_preview.width()/(float)clip->media_stream->video_preview.height())); - if (thumb_height > thumb_y && text_rect.width() + CLIP_TEXT_PADDING > thumb_width) { // at small clip heights, don't even draw it - QRect thumb_rect(thumb_x, clip_rect.y()+thumb_y, thumb_width, thumb_height); - clip_painter.drawImage(thumb_rect, clip->media_stream->video_preview); - } - } else if (clip_rect.height() > TRACK_MIN_HEIGHT) { - int divider = clip->media_stream->audio_channels*2; - - clip_painter.setPen(QColor(80, 80, 80)); - int channel_height = clip_rect.height()/clip->media_stream->audio_channels; - long media_length = clip->media->get_length_in_frames(clip->sequence->frame_rate); - for (int i=0;iclip_in + ((float) i/panel_timeline->zoom))/media_length) * clip->media_stream->audio_preview.size())/divider)*divider; - - for (int j=0;jmedia_stream->audio_channels;j++) { - int mid = clip_rect.top()+channel_height*j+(channel_height/2); - int offset = waveform_index+(j*2); - - if (offset >= 0 && offset < clip->media_stream->audio_preview.size()) { - qint8 min = (double)clip->media_stream->audio_preview.at(offset) / 128.0 * (channel_height/2); - qint8 max = (double)clip->media_stream->audio_preview.at(offset+1) / 128.0 * (channel_height/2); - clip_painter.drawLine(clip_rect.left()+i, mid+min, clip_rect.left()+i, mid+max); + int tr_y = clip_rect.y() + ((clip_rect.height()-transition_height)/2); + int tr_x = 0; + if (i == 0) { + tr_x = clip_rect.x(); + text_rect.setX(text_rect.x()+transition_width); + thumb_x += transition_width; + } else { + tr_x = clip_rect.right()-transition_width; + text_rect.setWidth(text_rect.width()-transition_width); + } + QRect transition_rect = QRect(tr_x, tr_y, transition_width, transition_height); + clip_painter.fillRect(transition_rect, transition_color); + QRect transition_text_rect(transition_rect.x() + CLIP_TEXT_PADDING, transition_rect.y() + CLIP_TEXT_PADDING, transition_rect.width() - CLIP_TEXT_PADDING, transition_rect.height() - CLIP_TEXT_PADDING); + if (transition_text_rect.width() > MAX_TEXT_WIDTH) { + clip_painter.setPen(QColor(0, 0, 0, 96)); + if (i == 0) { + clip_painter.drawLine(transition_rect.bottomLeft(), transition_rect.topRight()); } else { - QMessageBox::critical(this, "AAAAAAAAAAAAA", "Here's that terrible, no-good bug again!!! I've stepped around it but plz report the following to Matt:\n\n" + QString::number(offset) + " vs " + QString::number(clip->media_stream->audio_preview.size()), QMessageBox::Ok); - break; + clip_painter.drawLine(transition_rect.topLeft(), transition_rect.bottomRight()); + } + + clip_painter.setPen(Qt::white); + clip_painter.drawText(transition_text_rect, 0, t->name, &transition_text_rect); + } + clip_painter.setPen(Qt::black); + clip_painter.drawRect(transition_rect); + } + } + + // draw thumbnail/waveform + if (clip->media_stream->preview_done) { + if (clip->track < 0) { + int thumb_y = clip_painter.fontMetrics().height()+CLIP_TEXT_PADDING+CLIP_TEXT_PADDING; + int thumb_height = clip_rect.height()-thumb_y; + int thumb_width = (thumb_height*((float)clip->media_stream->video_preview.width()/(float)clip->media_stream->video_preview.height())); + if (thumb_height > thumb_y && text_rect.width() + CLIP_TEXT_PADDING > thumb_width) { // at small clip heights, don't even draw it + QRect thumb_rect(thumb_x, clip_rect.y()+thumb_y, thumb_width, thumb_height); + clip_painter.drawImage(thumb_rect, clip->media_stream->video_preview); + } + } else if (clip_rect.height() > TRACK_MIN_HEIGHT) { + int divider = clip->media_stream->audio_channels*2; + + clip_painter.setPen(QColor(80, 80, 80)); + int channel_height = clip_rect.height()/clip->media_stream->audio_channels; + long media_length = clip->media->get_length_in_frames(clip->sequence->frame_rate); + for (int i=0;iclip_in + ((float) i/panel_timeline->zoom))/media_length) * clip->media_stream->audio_preview.size())/divider)*divider; + + for (int j=0;jmedia_stream->audio_channels;j++) { + int mid = clip_rect.top()+channel_height*j+(channel_height/2); + int offset = waveform_index+(j*2); + + if (offset >= 0 && offset < clip->media_stream->audio_preview.size()) { + qint8 min = (double)clip->media_stream->audio_preview.at(offset) / 128.0 * (channel_height/2); + qint8 max = (double)clip->media_stream->audio_preview.at(offset+1) / 128.0 * (channel_height/2); + clip_painter.drawLine(clip_rect.left()+i, mid+min, clip_rect.left()+i, mid+max); + } else { + QMessageBox::critical(this, "AAAAAAAAAAAAA", "Here's that terrible, no-good bug again!!! I've stepped around it but plz report the following to Matt:\n\n" + QString::number(offset) + " vs " + QString::number(clip->media_stream->audio_preview.size()), QMessageBox::Ok); + break; + } } } } } - } - // top left bevel - clip_painter.setPen(Qt::white); - clip_painter.drawLine(clip_rect.bottomLeft(), clip_rect.topLeft()); - clip_painter.drawLine(clip_rect.topLeft(), clip_rect.topRight()); + // top left bevel + clip_painter.setPen(Qt::white); + clip_painter.drawLine(clip_rect.bottomLeft(), clip_rect.topLeft()); + clip_painter.drawLine(clip_rect.topLeft(), clip_rect.topRight()); - // draw text - if (text_rect.width() > MAX_TEXT_WIDTH) { - if (color_brightness(clip->color_r, clip->color_g, clip->color_b) > 160) { - // set to black if color is bright - clip_painter.setPen(Qt::black); + // draw text + if (text_rect.width() > MAX_TEXT_WIDTH) { + if (color_brightness(clip->color_r, clip->color_g, clip->color_b) > 160) { + // set to black if color is bright + clip_painter.setPen(Qt::black); + } + if (clip->linked.size() > 0) { + int underline_y = CLIP_TEXT_PADDING + clip_painter.fontMetrics().height() + clip_rect.top(); + int underline_width = qMin(text_rect.width() - 1, clip_painter.fontMetrics().width(clip->name)); + clip_painter.drawLine(text_rect.x(), underline_y, text_rect.x() + underline_width, underline_y); + } + clip_painter.drawText(text_rect, 0, clip->name, &text_rect); } - if (clip->linked.size() > 0) { - int underline_y = CLIP_TEXT_PADDING + clip_painter.fontMetrics().height() + clip_rect.top(); - int underline_width = qMin(text_rect.width() - 1, clip_painter.fontMetrics().width(clip->name)); - clip_painter.drawLine(text_rect.x(), underline_y, text_rect.x() + underline_width, underline_y); - } - clip_painter.drawText(text_rect, 0, clip->name, &text_rect); - } - // bottom right gray - clip_painter.setPen(QColor(0, 0, 0, 128)); - clip_painter.drawLine(clip_rect.bottomLeft(), clip_rect.bottomRight()); - clip_painter.drawLine(clip_rect.bottomRight(), clip_rect.topRight()); + // bottom right gray + clip_painter.setPen(QColor(0, 0, 0, 128)); + clip_painter.drawLine(clip_rect.bottomLeft(), clip_rect.bottomRight()); + clip_painter.drawLine(clip_rect.bottomRight(), clip_rect.topRight()); + } + } + + // Draw track lines + if (show_track_lines) { + clip_painter.setPen(QColor(0, 0, 0, 96)); + audio_track_limit++; + if (video_track_limit == 0) video_track_limit--; + + if (bottom_align) { + // only draw lines for video tracks + for (int i=video_track_limit;i<0;i++) { + int line_y = getScreenPointFromTrack(i) - 1; + clip_painter.drawLine(0, line_y, rect().width(), line_y); + } + } else { + // only draw lines for audio tracks + for (int i=0;icalculate_track_height(i, -1); + clip_painter.drawLine(0, line_y, rect().width(), line_y); + } + } } } - // Draw track lines - if (show_track_lines) { - clip_painter.setPen(QColor(0, 0, 0, 96)); - audio_track_limit++; - if (video_track_limit == 0) video_track_limit--; - - if (bottom_align) { - // only draw lines for video tracks - for (int i=video_track_limit;i<0;i++) { - int line_y = getScreenPointFromTrack(i) - 1; - clip_painter.drawLine(0, line_y, rect().width(), line_y); - } - } else { - // only draw lines for audio tracks - for (int i=0;icalculate_track_height(i, -1); - clip_painter.drawLine(0, line_y, rect().width(), line_y); - } - } - } - update(); } @@ -1392,7 +1394,7 @@ void TimelineWidget::paintEvent(QPaintEvent*) { if (sequence != NULL) { QPainter p(this); - p.drawPixmap(0, 0, minimumWidth(), height(), clip_pixmap); + p.drawPixmap(0, 0, clip_pixmap.width(), height(), clip_pixmap); // Draw selections for (int i=0;iselections.size();i++) {