diff --git a/mainwindow.cpp b/mainwindow.cpp index b7ac8d3f9..59ea56faa 100644 --- a/mainwindow.cpp +++ b/mainwindow.cpp @@ -1,5 +1,4 @@ #include "mainwindow.h" -#include "ui_mainwindow.h" #include "io/config.h" #include "io/path.h" @@ -43,6 +42,9 @@ #include #include #include +#include +#include +#include MainWindow* mainWindow; @@ -127,8 +129,6 @@ MainWindow::MainWindow(QWidget *parent) : updateTitle(""); - statusBar()->showMessage("Welcome to " + appName); - setDockNestingEnabled(true); layout()->invalidate(); @@ -199,6 +199,7 @@ MainWindow::MainWindow(QWidget *parent) : panel_timeline = new Timeline(this); QStatusBar* statusBar = new QStatusBar(this); + statusBar->showMessage("Welcome to " + appName); setStatusBar(statusBar); setup_menus(); @@ -220,8 +221,6 @@ MainWindow::MainWindow(QWidget *parent) : setup_layout(false); init_audio(); - - } MainWindow::~MainWindow() { diff --git a/mainwindow.h b/mainwindow.h index a14a1ea3f..1703321a4 100644 --- a/mainwindow.h +++ b/mainwindow.h @@ -8,10 +8,8 @@ class EffectControls; class Viewer; class Timeline; -class MainWindow : public QMainWindow -{ +class MainWindow : public QMainWindow { Q_OBJECT - public: explicit MainWindow(QWidget *parent = 0); void updateTitle(const QString &url); diff --git a/olive.pro b/olive.pro index 84097088f..d59e863b5 100644 --- a/olive.pro +++ b/olive.pro @@ -188,8 +188,6 @@ HEADERS += \ ui/keyframenavigator.h FORMS += \ - panels/effectcontrols.ui \ - panels/viewer.ui \ panels/timeline.ui \ dialogs/aboutdialog.ui \ dialogs/newsequencedialog.ui \ diff --git a/panels/effectcontrols.cpp b/panels/effectcontrols.cpp index 468fb43b5..123633448 100644 --- a/panels/effectcontrols.cpp +++ b/panels/effectcontrols.cpp @@ -1,10 +1,16 @@ #include "effectcontrols.h" -#include "ui_effectcontrols.h" #include #include #include #include +#include +#include +#include +#include +#include +#include +#include #include "panels/panels.h" #include "project/effect.h" @@ -18,44 +24,44 @@ #include "panels/viewer.h" #include "ui/viewerwidget.h" #include "io/clipboard.h" +#include "ui/timelineheader.h" +#include "ui/keyframeview.h" +#include "ui/resizablescrollbar.h" #include "debug.h" EffectControls::EffectControls(QWidget *parent) : QDockWidget(parent), multiple(false), - zoom(1), - ui(new Ui::EffectControls), - panel_name("Effects: "), - mode(TA_NO_TRANSITION) + zoom(1), + panel_name("Effects: "), + mode(TA_NO_TRANSITION) { - ui->setupUi(this); + setup_ui(); init_effects(); - clear_effects(false); - ui->headers->viewer = panel_sequence_viewer; - ui->headers->snapping = false; + clear_effects(false); + headers->viewer = panel_sequence_viewer; + headers->snapping = false; - ui->effects_area->parent_widget = ui->scrollArea; - ui->effects_area->keyframe_area = ui->keyframeView; - ui->effects_area->header = ui->headers; - ui->keyframeView->header = ui->headers; + effects_area->parent_widget = scrollArea; + effects_area->keyframe_area = keyframeView; + effects_area->header = headers; + keyframeView->header = headers; - ui->lblMultipleClipsSelected->setVisible(false); + lblMultipleClipsSelected->setVisible(false); - connect(ui->horizontalScrollBar, SIGNAL(valueChanged(int)), ui->headers, SLOT(set_scroll(int))); - connect(ui->horizontalScrollBar, SIGNAL(resize_move(double)), ui->keyframeView, SLOT(resize_move(double))); - connect(ui->horizontalScrollBar, SIGNAL(valueChanged(int)), ui->keyframeView, SLOT(set_x_scroll(int))); - connect(ui->verticalScrollBar, SIGNAL(valueChanged(int)), ui->keyframeView, SLOT(set_y_scroll(int))); - connect(ui->verticalScrollBar, SIGNAL(valueChanged(int)), ui->scrollArea->verticalScrollBar(), SLOT(setValue(int))); - connect(ui->scrollArea->verticalScrollBar(), SIGNAL(valueChanged(int)), ui->verticalScrollBar, SLOT(setValue(int))); + connect(horizontalScrollBar, SIGNAL(valueChanged(int)), headers, SLOT(set_scroll(int))); + connect(horizontalScrollBar, SIGNAL(resize_move(double)), keyframeView, SLOT(resize_move(double))); + connect(horizontalScrollBar, SIGNAL(valueChanged(int)), keyframeView, SLOT(set_x_scroll(int))); + connect(verticalScrollBar, SIGNAL(valueChanged(int)), keyframeView, SLOT(set_y_scroll(int))); + connect(verticalScrollBar, SIGNAL(valueChanged(int)), scrollArea->verticalScrollBar(), SLOT(setValue(int))); + connect(scrollArea->verticalScrollBar(), SIGNAL(valueChanged(int)), verticalScrollBar, SLOT(setValue(int))); } -EffectControls::~EffectControls() { - delete ui; -} +EffectControls::~EffectControls() {} bool EffectControls::keyframe_focus() { - return ui->headers->hasFocus() || ui->keyframeView->hasFocus(); + return headers->hasFocus() || keyframeView->hasFocus(); } void EffectControls::set_zoom(bool in) { @@ -64,292 +70,473 @@ void EffectControls::set_zoom(bool in) { } void EffectControls::menu_select(QAction* q) { - ComboAction* ca = new ComboAction(); - for (int i=0;iclips.at(selected_clips.at(i)); - if ((c->track < 0) == (effect_menu_subtype == EFFECT_TYPE_VIDEO)) { + ComboAction* ca = new ComboAction(); + for (int i=0;iclips.at(selected_clips.at(i)); + if ((c->track < 0) == (effect_menu_subtype == EFFECT_TYPE_VIDEO)) { const EffectMeta* meta = reinterpret_cast(q->data().value()); - if (effect_menu_type == EFFECT_TYPE_TRANSITION) { - if (c->get_opening_transition() == NULL) { - ca->append(new AddTransitionCommand(c, NULL, NULL, meta, TA_OPENING_TRANSITION, 30)); + if (effect_menu_type == EFFECT_TYPE_TRANSITION) { + if (c->get_opening_transition() == NULL) { + ca->append(new AddTransitionCommand(c, NULL, NULL, meta, TA_OPENING_TRANSITION, 30)); } - if (c->get_closing_transition() == NULL) { - ca->append(new AddTransitionCommand(c, NULL, NULL, meta, TA_CLOSING_TRANSITION, 30)); + if (c->get_closing_transition() == NULL) { + ca->append(new AddTransitionCommand(c, NULL, NULL, meta, TA_CLOSING_TRANSITION, 30)); } } else { - ca->append(new AddEffectCommand(c, NULL, meta)); + ca->append(new AddEffectCommand(c, NULL, meta)); } - } - } - undo_stack.push(ca); - if (effect_menu_type == EFFECT_TYPE_TRANSITION) { + } + } + undo_stack.push(ca); + if (effect_menu_type == EFFECT_TYPE_TRANSITION) { update_ui(true); } else { reload_clips(); panel_sequence_viewer->viewer_widget->update(); - } + } } void EffectControls::update_keyframes() { - ui->headers->update_zoom(zoom); - ui->keyframeView->update(); + headers->update_zoom(zoom); + keyframeView->update(); } void EffectControls::delete_selected_keyframes() { - ui->keyframeView->delete_selected_keyframes(); + keyframeView->delete_selected_keyframes(); } void EffectControls::copy(bool del) { - if (mode == TA_NO_TRANSITION) { - bool cleared = false; + if (mode == TA_NO_TRANSITION) { + bool cleared = false; - ComboAction* ca = new ComboAction(); - EffectDeleteCommand* del_com = (del) ? new EffectDeleteCommand() : NULL; - for (int i=0;iclips.at(selected_clips.at(i)); - for (int j=0;jeffects.size();j++) { - Effect* effect = c->effects.at(j); - if (effect->container->selected) { - if (!cleared) { - clear_clipboard(); - cleared = true; + ComboAction* ca = new ComboAction(); + EffectDeleteCommand* del_com = (del) ? new EffectDeleteCommand() : NULL; + for (int i=0;iclips.at(selected_clips.at(i)); + for (int j=0;jeffects.size();j++) { + Effect* effect = c->effects.at(j); + if (effect->container->selected) { + if (!cleared) { + clear_clipboard(); + cleared = true; clipboard_type = CLIPBOARD_TYPE_EFFECT; - } + } - clipboard.append(effect->copy(NULL)); + clipboard.append(effect->copy(NULL)); - if (del_com != NULL) { - del_com->clips.append(c); - del_com->fx.append(j); - } - } - } - } - if (del_com != NULL) { - if (del_com->clips.size() > 0) { - ca->append(del_com); - } else { - delete del_com; - } - } - undo_stack.push(ca); - } + if (del_com != NULL) { + del_com->clips.append(c); + del_com->fx.append(j); + } + } + } + } + if (del_com != NULL) { + if (del_com->clips.size() > 0) { + ca->append(del_com); + } else { + delete del_com; + } + } + undo_stack.push(ca); + } } void EffectControls::show_effect_menu(int type, int subtype) { - effect_menu_type = type; - effect_menu_subtype = subtype; + effect_menu_type = type; + effect_menu_subtype = subtype; - effects_loaded.lock(); + effects_loaded.lock(); - QMenu effects_menu(this); - for (int i=0;isetText(em.name); - action->setData(reinterpret_cast(&em)); + if (em.type == type && em.subtype == subtype) { + QAction* action = new QAction(&effects_menu); + action->setText(em.name); + action->setData(reinterpret_cast(&em)); - QMenu* parent = &effects_menu; - if (!em.category.isEmpty()) { - bool found = false; - for (int j=0;jmenu() != NULL) { - if (action->menu()->title() == em.category) { - parent = action->menu(); - found = true; - break; - } - } - } - if (!found) { - parent = new QMenu(&effects_menu); - parent->setTitle(em.category); + QMenu* parent = &effects_menu; + if (!em.category.isEmpty()) { + bool found = false; + for (int j=0;jmenu() != NULL) { + if (action->menu()->title() == em.category) { + parent = action->menu(); + found = true; + break; + } + } + } + if (!found) { + parent = new QMenu(&effects_menu); + parent->setTitle(em.category); - bool found = false; - for (int i=0;itext() > em.category) { - effects_menu.insertMenu(comp_action, parent); - found = true; - break; - } - } - if (!found) effects_menu.addMenu(parent); - } - } + bool found = false; + for (int i=0;itext() > em.category) { + effects_menu.insertMenu(comp_action, parent); + found = true; + break; + } + } + if (!found) effects_menu.addMenu(parent); + } + } - bool found = false; - for (int i=0;iactions().size();i++) { - QAction* comp_action = parent->actions().at(i); - if (comp_action->text() > action->text()) { - parent->insertAction(comp_action, action); - found = true; - break; - } - } - if (!found) parent->addAction(action); - } - } + bool found = false; + for (int i=0;iactions().size();i++) { + QAction* comp_action = parent->actions().at(i); + if (comp_action->text() > action->text()) { + parent->insertAction(comp_action, action); + found = true; + break; + } + } + if (!found) parent->addAction(action); + } + } - effects_loaded.unlock(); + effects_loaded.unlock(); - connect(&effects_menu, SIGNAL(triggered(QAction*)), this, SLOT(menu_select(QAction*))); - effects_menu.exec(QCursor::pos()); + connect(&effects_menu, SIGNAL(triggered(QAction*)), this, SLOT(menu_select(QAction*))); + effects_menu.exec(QCursor::pos()); } void EffectControls::clear_effects(bool clear_cache) { // clear existing clips deselect_all_effects(NULL); - QVBoxLayout* video_layout = static_cast(ui->video_effect_area->layout()); - QVBoxLayout* audio_layout = static_cast(ui->audio_effect_area->layout()); - QLayoutItem* item; - while ((item = video_layout->takeAt(0))) { - item->widget()->setParent(NULL); + QVBoxLayout* video_layout = static_cast(video_effect_area->layout()); + QVBoxLayout* audio_layout = static_cast(audio_effect_area->layout()); + QLayoutItem* item; + while ((item = video_layout->takeAt(0))) { + item->widget()->setParent(NULL); disconnect(static_cast(item->widget()), SIGNAL(deselect_others(QWidget*)), this, SLOT(deselect_all_effects(QWidget*))); - } - while ((item = audio_layout->takeAt(0))) { - item->widget()->setParent(NULL); - disconnect(static_cast(item->widget()), SIGNAL(deselect_others(QWidget*)), this, SLOT(deselect_all_effects(QWidget*))); - } - ui->lblMultipleClipsSelected->setVisible(false); - ui->vcontainer->setVisible(false); - ui->acontainer->setVisible(false); - ui->headers->setVisible(false); - ui->keyframeView->setEnabled(false); - if (clear_cache) selected_clips.clear(); - setWindowTitle(panel_name + "(none)"); + } + while ((item = audio_layout->takeAt(0))) { + item->widget()->setParent(NULL); + disconnect(static_cast(item->widget()), SIGNAL(deselect_others(QWidget*)), this, SLOT(deselect_all_effects(QWidget*))); + } + lblMultipleClipsSelected->setVisible(false); + vcontainer->setVisible(false); + acontainer->setVisible(false); + headers->setVisible(false); + keyframeView->setEnabled(false); + if (clear_cache) selected_clips.clear(); + setWindowTitle(panel_name + "(none)"); } void EffectControls::deselect_all_effects(QWidget* sender) { - for (int i=0;iclips.at(selected_clips.at(i)); - for (int j=0;jeffects.size();j++) { - if (c->effects.at(j)->container != sender) { - c->effects.at(j)->container->header_click(false, false); - } - } - } - panel_sequence_viewer->viewer_widget->update(); + for (int i=0;iclips.at(selected_clips.at(i)); + for (int j=0;jeffects.size();j++) { + if (c->effects.at(j)->container != sender) { + c->effects.at(j)->container->header_click(false, false); + } + } + } + panel_sequence_viewer->viewer_widget->update(); } void EffectControls::open_effect(QVBoxLayout* layout, Effect* e) { - CollapsibleWidget* container = e->container; - layout->addWidget(container); - connect(container, SIGNAL(deselect_others(QWidget*)), this, SLOT(deselect_all_effects(QWidget*))); + CollapsibleWidget* container = e->container; + layout->addWidget(container); + connect(container, SIGNAL(deselect_others(QWidget*)), this, SLOT(deselect_all_effects(QWidget*))); +} + +void EffectControls::setup_ui() { + setSizePolicy(QSizePolicy::Maximum, QSizePolicy::Maximum); + + QWidget* contents = new QWidget(); + + QHBoxLayout* layout = new QHBoxLayout(contents); + layout->setSpacing(0); + layout->setMargin(0); + + QSplitter* splitter = new QSplitter(contents); + splitter->setOrientation(Qt::Horizontal); + splitter->setChildrenCollapsible(false); + + scrollArea = new QScrollArea(splitter); + scrollArea->setSizePolicy(QSizePolicy::Maximum, QSizePolicy::Expanding); + scrollArea->setFrameShape(QFrame::NoFrame); + scrollArea->setFrameShadow(QFrame::Plain); + scrollArea->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff); + scrollArea->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOn); + scrollArea->setWidgetResizable(true); + + QWidget* scrollAreaWidgetContents = new QWidget(); + + QHBoxLayout* scrollAreaLayout = new QHBoxLayout(scrollAreaWidgetContents); + scrollAreaLayout->setSpacing(0); + scrollAreaLayout->setMargin(0); + + effects_area = new EffectsArea(scrollAreaWidgetContents); + + QVBoxLayout* effects_area_layout = new QVBoxLayout(effects_area); + effects_area_layout->setSpacing(0); + effects_area_layout->setMargin(0); + + vcontainer = new QWidget(effects_area); + QVBoxLayout* vcontainerLayout = new QVBoxLayout(vcontainer); + vcontainerLayout->setSpacing(0); + vcontainerLayout->setMargin(0); + + QWidget* veHeader = new QWidget(vcontainer); + veHeader->setObjectName(QStringLiteral("veHeader")); + veHeader->setStyleSheet(QLatin1String("#veHeader { background: rgba(0, 0, 0, 0.25); }")); + + QHBoxLayout* veHeaderLayout = new QHBoxLayout(veHeader); + veHeaderLayout->setSpacing(0); + veHeaderLayout->setMargin(0); + + QPushButton* btnAddVideoEffect = new QPushButton(veHeader); + btnAddVideoEffect->setIcon(QIcon(":/icons/add-effect.png")); + btnAddVideoEffect->setToolTip("Add Video Effect"); + veHeaderLayout->addWidget(btnAddVideoEffect); + connect(btnAddVideoEffect, SIGNAL(clicked(bool)), this, SLOT(video_effect_click())); + + veHeaderLayout->addStretch(); + + QLabel* lblVideoEffects = new QLabel(veHeader); + QFont font; + font.setPointSize(9); + lblVideoEffects->setFont(font); + lblVideoEffects->setAlignment(Qt::AlignCenter); + lblVideoEffects->setText("VIDEO EFFECTS"); + veHeaderLayout->addWidget(lblVideoEffects); + + veHeaderLayout->addStretch(); + + QPushButton* btnAddVideoTransition = new QPushButton(veHeader); + btnAddVideoTransition->setIcon(QIcon(":/icons/add-transition.png")); + btnAddVideoTransition->setToolTip("Add Video Transition"); + connect(btnAddVideoTransition, SIGNAL(clicked(bool)), this, SLOT(video_transition_click())); + + veHeaderLayout->addWidget(btnAddVideoTransition); + + vcontainerLayout->addWidget(veHeader); + + video_effect_area = new QWidget(vcontainer); + QVBoxLayout* veAreaLayout = new QVBoxLayout(video_effect_area); + veAreaLayout->setSpacing(0); + veAreaLayout->setMargin(0); + + vcontainerLayout->addWidget(video_effect_area); + + effects_area_layout->addWidget(vcontainer); + + acontainer = new QWidget(effects_area); + QVBoxLayout* acontainerLayout = new QVBoxLayout(acontainer); + acontainerLayout->setSpacing(0); + acontainerLayout->setMargin(0); + QWidget* aeHeader = new QWidget(acontainer); + aeHeader->setObjectName(QStringLiteral("aeHeader")); + aeHeader->setStyleSheet(QLatin1String("#aeHeader { background: rgba(0, 0, 0, 0.25); }")); + + QHBoxLayout* aeHeaderLayout = new QHBoxLayout(aeHeader); + aeHeaderLayout->setSpacing(0); + aeHeaderLayout->setMargin(0); + + QPushButton* btnAddAudioEffect = new QPushButton(aeHeader); + btnAddAudioEffect->setIcon(QIcon(":/icons/add-effect.png")); + btnAddAudioEffect->setToolTip("Add Audio Effect"); + connect(btnAddAudioEffect, SIGNAL(clicked(bool)), this, SLOT(audio_effect_click())); + aeHeaderLayout->addWidget(btnAddAudioEffect); + + aeHeaderLayout->addStretch(); + + QLabel* lblAudioEffects = new QLabel(aeHeader); + lblAudioEffects->setFont(font); + lblAudioEffects->setAlignment(Qt::AlignCenter); + lblAudioEffects->setText("AUDIO EFFECTS"); + aeHeaderLayout->addWidget(lblAudioEffects); + + aeHeaderLayout->addStretch(); + + QPushButton* btnAddAudioTransition = new QPushButton(aeHeader); + btnAddAudioTransition->setIcon(QIcon(":/icons/add-transition.png")); + btnAddAudioTransition->setToolTip("Add Audio Transition"); + connect(btnAddAudioTransition, SIGNAL(clicked(bool)), this, SLOT(audio_transition_click())); + aeHeaderLayout->addWidget(btnAddAudioTransition); + + acontainerLayout->addWidget(aeHeader); + + audio_effect_area = new QWidget(acontainer); + QVBoxLayout* aeAreaLayout = new QVBoxLayout(audio_effect_area); + aeAreaLayout->setSpacing(0); + aeAreaLayout->setMargin(0); + + acontainerLayout->addWidget(audio_effect_area); + + effects_area_layout->addWidget(acontainer); + + lblMultipleClipsSelected = new QLabel(effects_area); + lblMultipleClipsSelected->setAlignment(Qt::AlignCenter); + lblMultipleClipsSelected->setText("(Multiple clips selected)"); + effects_area_layout->addWidget(lblMultipleClipsSelected); + + effects_area_layout->addStretch(); + + scrollAreaLayout->addWidget(effects_area); + + scrollArea->setWidget(scrollAreaWidgetContents); + splitter->addWidget(scrollArea); + QWidget* keyframeArea = new QWidget(splitter); + QSizePolicy keyframe_sp; + keyframe_sp.setHorizontalPolicy(QSizePolicy::Minimum); + keyframe_sp.setVerticalPolicy(QSizePolicy::Preferred); + keyframe_sp.setHorizontalStretch(1); + keyframeArea->setSizePolicy(keyframe_sp); + QVBoxLayout* keyframeAreaLayout = new QVBoxLayout(keyframeArea); + keyframeAreaLayout->setSpacing(0); + keyframeAreaLayout->setMargin(0); + headers = new TimelineHeader(keyframeArea); + + keyframeAreaLayout->addWidget(headers); + + QWidget* keyframeCenterWidget = new QWidget(keyframeArea); + + QHBoxLayout* keyframeCenterLayout = new QHBoxLayout(keyframeCenterWidget); + keyframeCenterLayout->setSpacing(0); + keyframeCenterLayout->setMargin(0); + + keyframeView = new KeyframeView(keyframeCenterWidget); + + keyframeCenterLayout->addWidget(keyframeView); + + verticalScrollBar = new QScrollBar(keyframeCenterWidget); + verticalScrollBar->setOrientation(Qt::Vertical); + + keyframeCenterLayout->addWidget(verticalScrollBar); + + + keyframeAreaLayout->addWidget(keyframeCenterWidget); + + horizontalScrollBar = new ResizableScrollBar(keyframeArea); + horizontalScrollBar->setOrientation(Qt::Horizontal); + + keyframeAreaLayout->addWidget(horizontalScrollBar); + + splitter->addWidget(keyframeArea); + + layout->addWidget(splitter); + + setWidget(contents); } void EffectControls::load_effects() { - ui->lblMultipleClipsSelected->setVisible(multiple); + lblMultipleClipsSelected->setVisible(multiple); - if (!multiple) { + if (!multiple) { // load in new clips for (int i=0;iclips.at(selected_clips.at(i)); + Clip* c = sequence->clips.at(selected_clips.at(i)); QVBoxLayout* layout; if (c->track < 0) { - ui->vcontainer->setVisible(true); - layout = static_cast(ui->video_effect_area->layout()); + vcontainer->setVisible(true); + layout = static_cast(video_effect_area->layout()); } else { - ui->acontainer->setVisible(true); - layout = static_cast(ui->audio_effect_area->layout()); + acontainer->setVisible(true); + layout = static_cast(audio_effect_area->layout()); + } + if (mode == TA_NO_TRANSITION) { + for (int j=0;jeffects.size();j++) { + open_effect(layout, c->effects.at(j)); + } + } else if (mode == TA_OPENING_TRANSITION && c->get_opening_transition() != NULL) { + open_effect(layout, c->get_opening_transition()); + } else if (mode == TA_CLOSING_TRANSITION && c->get_closing_transition() != NULL) { + open_effect(layout, c->get_closing_transition()); } - if (mode == TA_NO_TRANSITION) { - for (int j=0;jeffects.size();j++) { - open_effect(layout, c->effects.at(j)); - } - } else if (mode == TA_OPENING_TRANSITION && c->get_opening_transition() != NULL) { - open_effect(layout, c->get_opening_transition()); - } else if (mode == TA_CLOSING_TRANSITION && c->get_closing_transition() != NULL) { - open_effect(layout, c->get_closing_transition()); - } } if (selected_clips.size() > 0) { - setWindowTitle(panel_name + sequence->clips.at(selected_clips.at(0))->name); - ui->verticalScrollBar->setMaximum(qMax(0, ui->effects_area->sizeHint().height() - ui->headers->height() + ui->scrollArea->horizontalScrollBar()->height()/* - ui->keyframeView->height() - ui->headers->height()*/)); - ui->keyframeView->setEnabled(true); - ui->headers->setVisible(true); - ui->keyframeView->update(); + setWindowTitle(panel_name + sequence->clips.at(selected_clips.at(0))->name); + verticalScrollBar->setMaximum(qMax(0, effects_area->sizeHint().height() - headers->height() + scrollArea->horizontalScrollBar()->height()/* - keyframeView->height() - headers->height()*/)); + keyframeView->setEnabled(true); + headers->setVisible(true); + keyframeView->update(); } } } void EffectControls::delete_effects() { - // load in new clips - if (mode == TA_NO_TRANSITION) { - EffectDeleteCommand* command = new EffectDeleteCommand(); - for (int i=0;iclips.at(selected_clips.at(i)); - for (int j=0;jeffects.size();j++) { - Effect* effect = c->effects.at(j); - if (effect->container->selected) { - command->clips.append(c); - command->fx.append(j); - } - } - } - if (command->clips.size() > 0) { - undo_stack.push(command); - panel_sequence_viewer->viewer_widget->update(); - } else { - delete command; - } - } + // load in new clips + if (mode == TA_NO_TRANSITION) { + EffectDeleteCommand* command = new EffectDeleteCommand(); + for (int i=0;iclips.at(selected_clips.at(i)); + for (int j=0;jeffects.size();j++) { + Effect* effect = c->effects.at(j); + if (effect->container->selected) { + command->clips.append(c); + command->fx.append(j); + } + } + } + if (command->clips.size() > 0) { + undo_stack.push(command); + panel_sequence_viewer->viewer_widget->update(); + } else { + delete command; + } + } } void EffectControls::reload_clips() { - clear_effects(false); - load_effects(); + clear_effects(false); + load_effects(); } void EffectControls::set_clips(QVector& clips, int m) { - clear_effects(true); + clear_effects(true); - // replace clip vector - selected_clips = clips; - mode = m; + // replace clip vector + selected_clips = clips; + mode = m; - load_effects(); + load_effects(); } -void EffectControls::on_btnAddVideoEffect_clicked() { - show_effect_menu(EFFECT_TYPE_EFFECT, EFFECT_TYPE_VIDEO); +void EffectControls::video_effect_click() { + show_effect_menu(EFFECT_TYPE_EFFECT, EFFECT_TYPE_VIDEO); } -void EffectControls::on_btnAddAudioEffect_clicked() { - show_effect_menu(EFFECT_TYPE_EFFECT, EFFECT_TYPE_AUDIO); +void EffectControls::audio_effect_click() { + show_effect_menu(EFFECT_TYPE_EFFECT, EFFECT_TYPE_AUDIO); } -void EffectControls::on_btnAddVideoTransition_clicked() { - show_effect_menu(EFFECT_TYPE_TRANSITION, EFFECT_TYPE_VIDEO); +void EffectControls::video_transition_click() { + show_effect_menu(EFFECT_TYPE_TRANSITION, EFFECT_TYPE_VIDEO); } -void EffectControls::on_btnAddAudioTransition_clicked() { - show_effect_menu(EFFECT_TYPE_TRANSITION, EFFECT_TYPE_AUDIO); +void EffectControls::audio_transition_click() { + show_effect_menu(EFFECT_TYPE_TRANSITION, EFFECT_TYPE_AUDIO); } void EffectControls::resizeEvent(QResizeEvent*) { - ui->verticalScrollBar->setMaximum(qMax(0, ui->effects_area->height() - ui->keyframeView->height() - ui->headers->height())); + verticalScrollBar->setMaximum(qMax(0, effects_area->height() - keyframeView->height() - headers->height())); } bool EffectControls::is_focused() { - if (this->hasFocus()) return true; - for (int i=0;iclips.at(selected_clips.at(i)); - if (c != NULL) { - for (int j=0;jeffects.size();j++) { - if (c->effects.at(j)->container->is_focused()) { - return true; - } - } - } else { + if (this->hasFocus()) return true; + for (int i=0;iclips.at(selected_clips.at(i)); + if (c != NULL) { + for (int j=0;jeffects.size();j++) { + if (c->effects.at(j)->container->is_focused()) { + return true; + } + } + } else { dout << "[WARNING] Tried to check focus of a NULL clip"; - } - } - return false; + } + } + return false; } EffectsArea::EffectsArea(QWidget* parent) : QWidget(parent) {} diff --git a/panels/effectcontrols.h b/panels/effectcontrols.h index 68d3e6861..564b4f0a8 100644 --- a/panels/effectcontrols.h +++ b/panels/effectcontrols.h @@ -11,6 +11,10 @@ class TimelineHeader; class QScrollArea; class KeyframeView; class QVBoxLayout; +class ResizableScrollBar; +class QLabel; +class KeyframeView; +class QScrollBar; class EffectsArea : public QWidget { public: @@ -21,10 +25,6 @@ public: TimelineHeader* header; }; -namespace Ui { -class EffectControls; -} - class EffectControls : public QDockWidget { Q_OBJECT @@ -32,45 +32,58 @@ class EffectControls : public QDockWidget public: explicit EffectControls(QWidget *parent = 0); ~EffectControls(); - void set_clips(QVector& clips, int mode); - void clear_effects(bool clear_cache); - void delete_effects(); - bool is_focused(); - void reload_clips(); + void set_clips(QVector& clips, int mode); + void clear_effects(bool clear_cache); + void delete_effects(); + bool is_focused(); + void reload_clips(); void set_zoom(bool in); bool keyframe_focus(); void delete_selected_keyframes(); - void copy(bool del); + void copy(bool del); bool multiple; QVector selected_clips; double zoom; - Ui::EffectControls *ui; + ResizableScrollBar* horizontalScrollBar; + QScrollBar* verticalScrollBar; public slots: - void update_keyframes(); + void update_keyframes(); private slots: - void menu_select(QAction* q); + void menu_select(QAction* q); - void on_btnAddVideoEffect_clicked(); - void on_btnAddAudioEffect_clicked(); - void on_btnAddVideoTransition_clicked(); - void on_btnAddAudioTransition_clicked(); + void video_effect_click(); + void audio_effect_click(); + void video_transition_click(); + void audio_transition_click(); - void deselect_all_effects(QWidget*); + void deselect_all_effects(QWidget*); protected: void resizeEvent(QResizeEvent *event); private: - void show_effect_menu(int type, int subtype); + void show_effect_menu(int type, int subtype); void load_effects(); void load_keyframes(); - void open_effect(QVBoxLayout* layout, Effect* e); + void open_effect(QVBoxLayout* layout, Effect* e); - int effect_menu_type; - int effect_menu_subtype; - QString panel_name; - int mode; + void setup_ui(); + + int effect_menu_type; + int effect_menu_subtype; + QString panel_name; + int mode; + + TimelineHeader* headers; + EffectsArea* effects_area; + QScrollArea* scrollArea; + QLabel* lblMultipleClipsSelected; + KeyframeView* keyframeView; + QWidget* video_effect_area; + QWidget* audio_effect_area; + QWidget* vcontainer; + QWidget* acontainer; }; #endif // EFFECTCONTROLS_H diff --git a/panels/effectcontrols.ui b/panels/effectcontrols.ui deleted file mode 100644 index 934fc26ef..000000000 --- a/panels/effectcontrols.ui +++ /dev/null @@ -1,554 +0,0 @@ - - - EffectControls - - - - 0 - 0 - 621 - 510 - - - - - 0 - 0 - - - - QDockWidget::AllDockWidgetFeatures - - - Effect Controls - - - - - 0 - - - 0 - - - 0 - - - 0 - - - 0 - - - - - Qt::Horizontal - - - - - 0 - 0 - - - - QFrame::NoFrame - - - QFrame::Plain - - - Qt::ScrollBarAlwaysOff - - - Qt::ScrollBarAlwaysOn - - - true - - - - - 0 - 0 - 189 - 483 - - - - - 0 - - - 0 - - - 0 - - - 0 - - - 0 - - - - - - 0 - - - 0 - - - 0 - - - 0 - - - 0 - - - - - - 0 - - - 0 - - - 0 - - - 0 - - - 0 - - - - - #veHeader { - background: rgba(0, 0, 0, 0.25); -} - - - - 0 - - - 0 - - - 0 - - - 0 - - - 0 - - - - - Add Video Effect - - - - - - - :/icons/add-effect.png - - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - 0 - 0 - - - - - 9 - - - - VIDEO EFFECTS - - - Qt::AlignCenter - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - Add Video Transition - - - - - - - :/icons/add-transition.png - - - - - - - - - - - - 0 - - - 0 - - - 0 - - - 0 - - - 0 - - - - - - - - - - - - 0 - - - 0 - - - 0 - - - 0 - - - 0 - - - - - #aeHeader { - background: rgba(0, 0, 0, 0.25); -} - - - - 0 - - - 0 - - - 0 - - - 0 - - - 0 - - - - - Add Audio Effect - - - - - - - :/icons/add-effect.png - - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - 0 - 0 - - - - - 9 - - - - AUDIO EFFECTS - - - Qt::AlignCenter - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - Add Audio Transition - - - - - - - :/icons/add-transition.png - - - - - - - - - - - - 0 - - - 0 - - - 0 - - - 0 - - - 0 - - - - - - - - - - - (Multiple clips selected) - - - Qt::AlignCenter - - - - - - - Qt::Vertical - - - - 20 - 40 - - - - - - - - - - - - - - 1 - 0 - - - - - 0 - - - 0 - - - 0 - - - 0 - - - 0 - - - - - - 0 - 0 - - - - - - - - - 0 - - - 0 - - - 0 - - - 0 - - - 0 - - - - - - - - 0 - - - 20 - - - 1826 - - - Qt::Vertical - - - - - - - - - - 0 - - - 20 - - - 1826 - - - Qt::Horizontal - - - - - - - - - - - - - KeyframeView - QWidget -
ui/keyframeview.h
- 1 -
- - TimelineHeader - QWidget -
ui/timelineheader.h
- 1 -
- - EffectsArea - QWidget -
panels/effectcontrols.h
- 1 -
- - ResizableScrollBar - QScrollBar -
ui/resizablescrollbar.h
-
-
- - -
diff --git a/panels/project.cpp b/panels/project.cpp index afaa1a127..7a3f36510 100644 --- a/panels/project.cpp +++ b/panels/project.cpp @@ -60,13 +60,7 @@ QString recent_proj_file; Project::Project(QWidget *parent) : QDockWidget(parent) { - setObjectName("Project"); - resize(504, 371); - QSizePolicy sizePolicy(QSizePolicy::Maximum, QSizePolicy::Maximum); - sizePolicy.setHorizontalStretch(0); - sizePolicy.setVerticalStretch(0); - sizePolicy.setHeightForWidth(this->sizePolicy().hasHeightForWidth()); - setSizePolicy(sizePolicy); + setSizePolicy(QSizePolicy::Maximum, QSizePolicy::Maximum); QWidget* dockWidgetContents = new QWidget(); QVBoxLayout* verticalLayout = new QVBoxLayout(dockWidgetContents); diff --git a/panels/timeline.cpp b/panels/timeline.cpp index 4e02496e9..e768f6195 100644 --- a/panels/timeline.cpp +++ b/panels/timeline.cpp @@ -12,7 +12,6 @@ #include "panels/viewer.h" #include "playback/cacher.h" #include "playback/playback.h" -#include "ui_viewer.h" #include "project/undo.h" #include "project/media.h" #include "io/config.h" @@ -45,35 +44,35 @@ void draw_selection_rectangle(QPainter& painter, const QRect& rect) { Timeline::Timeline(QWidget *parent) : QDockWidget(parent), - cursor_frame(0), - cursor_track(0), - zoom(1.0), - zoom_just_changed(false), - showing_all(false), - snapping(true), - snapped(false), - snap_point(0), - selecting(false), - rect_select_init(false), - rect_select_proc(false), - moving_init(false), - moving_proc(false), - move_insert(false), - trim_target(-1), - trim_in_point(false), - splitting(false), - importing(false), + cursor_frame(0), + cursor_track(0), + zoom(1.0), + zoom_just_changed(false), + showing_all(false), + snapping(true), + snapped(false), + snap_point(0), + selecting(false), + rect_select_init(false), + rect_select_proc(false), + moving_init(false), + moving_proc(false), + move_insert(false), + trim_target(-1), + trim_in_point(false), + splitting(false), + importing(false), importing_files(false), - creating(false), - transition_tool_init(false), - transition_tool_proc(false), - transition_tool_pre_clip(-1), - transition_tool_post_clip(-1), - hand_moving(false), - block_repaints(false), - ui(new Ui::Timeline), - last_frame(0), - scroll(0) + creating(false), + transition_tool_init(false), + transition_tool_proc(false), + transition_tool_pre_clip(-1), + transition_tool_post_clip(-1), + hand_moving(false), + block_repaints(false), + ui(new Ui::Timeline), + last_frame(0), + scroll(0) { default_track_height = (QGuiApplication::primaryScreen()->logicalDotsPerInch() / 96) * TRACK_DEFAULT_HEIGHT; @@ -81,16 +80,16 @@ Timeline::Timeline(QWidget *parent) : ui->headers->viewer = panel_sequence_viewer; - /* --- TEMPORARY --- - * I feel like the rolling edit tool is unnecessary, but just - * in case I change my mind, I'm leaving all the functionality - * intact and only hiding the UI to get to it. Still deciding - * on this one but the pointer tool literally does the same - * functionality. - */ - ui->toolRollingButton->setVisible(false); - ui->toolRollingButton->setEnabled(false); - /* --- */ + /* --- TEMPORARY --- + * I feel like the rolling edit tool is unnecessary, but just + * in case I change my mind, I'm leaving all the functionality + * intact and only hiding the UI to get to it. Still deciding + * on this one but the pointer tool literally does the same + * functionality. + */ + ui->toolRollingButton->setVisible(false); + ui->toolRollingButton->setEnabled(false); + /* --- */ ui->video_area->bottom_align = true; ui->video_area->scrollBar = ui->videoScrollbar; @@ -102,16 +101,16 @@ Timeline::Timeline(QWidget *parent) : tool_buttons.append(ui->toolRazorButton); tool_buttons.append(ui->toolSlipButton); tool_buttons.append(ui->toolRollingButton); - tool_buttons.append(ui->toolSlideButton); + tool_buttons.append(ui->toolSlideButton); tool_buttons.append(ui->toolTransitionButton); - tool_buttons.append(ui->toolHandButton); + tool_buttons.append(ui->toolHandButton); ui->toolArrowButton->click(); connect(ui->horizontalScrollBar, SIGNAL(valueChanged(int)), this, SLOT(setScroll(int))); connect(ui->videoScrollbar, SIGNAL(valueChanged(int)), ui->video_area, SLOT(setScroll(int))); connect(ui->audioScrollbar, SIGNAL(valueChanged(int)), ui->audio_area, SLOT(setScroll(int))); - connect(ui->horizontalScrollBar, SIGNAL(resize_move(double)), this, SLOT(resize_move(double))); + connect(ui->horizontalScrollBar, SIGNAL(resize_move(double)), this, SLOT(resize_move(double))); update_sequence(); } @@ -123,36 +122,36 @@ Timeline::~Timeline() void Timeline::previous_cut() { if (sequence->playhead > 0) { - long p_cut = 0; - for (int i=0;iclips.size();i++) { - Clip* c = sequence->clips.at(i); - if (c != NULL) { + long p_cut = 0; + for (int i=0;iclips.size();i++) { + Clip* c = sequence->clips.at(i); + if (c != NULL) { if (c->timeline_out > p_cut && c->timeline_out < sequence->playhead) { - p_cut = c->timeline_out; + p_cut = c->timeline_out; } else if (c->timeline_in > p_cut && c->timeline_in < sequence->playhead) { - p_cut = c->timeline_in; - } - } - } + p_cut = c->timeline_in; + } + } + } panel_sequence_viewer->seek(p_cut); - } + } } void Timeline::next_cut() { - bool seek_enabled = false; - long n_cut = LONG_MAX; - for (int i=0;iclips.size();i++) { - Clip* c = sequence->clips.at(i); - if (c != NULL) { + bool seek_enabled = false; + long n_cut = LONG_MAX; + for (int i=0;iclips.size();i++) { + Clip* c = sequence->clips.at(i); + if (c != NULL) { if (c->timeline_in < n_cut && c->timeline_in > sequence->playhead) { - n_cut = c->timeline_in; - seek_enabled = true; + n_cut = c->timeline_in; + seek_enabled = true; } else if (c->timeline_out < n_cut && c->timeline_out > sequence->playhead) { - n_cut = c->timeline_out; - seek_enabled = true; - } - } - } + n_cut = c->timeline_out; + seek_enabled = true; + } + } + } if (seek_enabled) panel_sequence_viewer->seek(n_cut); } @@ -173,28 +172,28 @@ void Timeline::create_ghosts_from_media(Sequence* seq, long entry_point, QVector for (int i=0;iget_type()) { + switch (medium->get_type()) { case MEDIA_TYPE_FOOTAGE: - m = medium->to_footage(); + m = medium->to_footage(); media = m; can_import = m->ready; if (m->using_inout) { double source_fr = 30; - if (m->video_tracks.size() > 0 && !qIsNull(m->video_tracks.at(0)->video_frame_rate)) source_fr = m->video_tracks.at(0)->video_frame_rate; + if (m->video_tracks.size() > 0 && !qIsNull(m->video_tracks.at(0)->video_frame_rate)) source_fr = m->video_tracks.at(0)->video_frame_rate; default_clip_in = refactor_frame_number(m->in, source_fr, seq->frame_rate); default_clip_out = refactor_frame_number(m->out, source_fr, seq->frame_rate); } break; case MEDIA_TYPE_SEQUENCE: - s = medium->to_sequence(); + s = medium->to_sequence(); sequence_length = s->getEndFrame(); if (seq != NULL) sequence_length = refactor_frame_number(sequence_length, s->frame_rate, seq->frame_rate); media = s; @@ -210,14 +209,14 @@ void Timeline::create_ghosts_from_media(Sequence* seq, long entry_point, QVector if (can_import) { Ghost g; - g.clip = -1; + g.clip = -1; g.trimming = false; g.old_clip_in = g.clip_in = default_clip_in; - g.media = medium; + g.media = medium; g.in = entry_point; g.transition = NULL; - switch (medium->get_type()) { + switch (medium->get_type()) { case MEDIA_TYPE_FOOTAGE: // is video source a still image? if (m->video_tracks.size() > 0 && m->video_tracks[0]->infinite_length && m->audio_tracks.size() == 0) { @@ -280,14 +279,14 @@ void Timeline::add_clips_from_ghosts(ComboAction* ca, Sequence* s) { earliest_point = qMin(earliest_point, g.in); Clip* c = new Clip(s); - c->media = g.media; + c->media = g.media; c->media_stream = g.media_stream; c->timeline_in = g.in; c->timeline_out = g.out; c->clip_in = g.clip_in; c->track = g.track; - if (c->media->get_type() == MEDIA_TYPE_FOOTAGE) { - Footage* m = c->media->to_footage(); + if (c->media->get_type() == MEDIA_TYPE_FOOTAGE) { + Footage* m = c->media->to_footage(); if (m->video_tracks.size() == 0) { // audio only (greenish) c->color_r = 128; @@ -305,13 +304,13 @@ void Timeline::add_clips_from_ghosts(ComboAction* ca, Sequence* s) { c->color_b = 192; } c->name = m->name; - } else if (c->media->get_type() == MEDIA_TYPE_SEQUENCE) { + } else if (c->media->get_type() == MEDIA_TYPE_SEQUENCE) { // sequence (red?ish?) c->color_r = 192; c->color_g = 128; c->color_b = 128; - Sequence* media = c->media->to_sequence(); + Sequence* media = c->media->to_sequence(); c->name = media->name; } c->recalculateMaxLength(); @@ -331,11 +330,11 @@ void Timeline::add_clips_from_ghosts(ComboAction* ca, Sequence* s) { if (c->track < 0) { // add default video effects - c->effects.append(create_effect(c, get_internal_meta(EFFECT_INTERNAL_TRANSFORM, EFFECT_TYPE_EFFECT))); + c->effects.append(create_effect(c, get_internal_meta(EFFECT_INTERNAL_TRANSFORM, EFFECT_TYPE_EFFECT))); } else { // add default audio effects - c->effects.append(create_effect(c, get_internal_meta(EFFECT_INTERNAL_VOLUME, EFFECT_TYPE_EFFECT))); - c->effects.append(create_effect(c, get_internal_meta(EFFECT_INTERNAL_PAN, EFFECT_TYPE_EFFECT))); + c->effects.append(create_effect(c, get_internal_meta(EFFECT_INTERNAL_VOLUME, EFFECT_TYPE_EFFECT))); + c->effects.append(create_effect(c, get_internal_meta(EFFECT_INTERNAL_PAN, EFFECT_TYPE_EFFECT))); } } if (config.enable_seek_to_import) { @@ -347,64 +346,64 @@ void Timeline::add_clips_from_ghosts(ComboAction* ca, Sequence* s) { } int Timeline::get_track_height_size(bool video) { - if (video) { - return video_track_heights.size(); - } else { - return audio_track_heights.size(); - } + if (video) { + return video_track_heights.size(); + } else { + return audio_track_heights.size(); + } } void Timeline::add_transition() { - ComboAction* ca = new ComboAction(); + ComboAction* ca = new ComboAction(); bool adding = false; - for (int i=0;iclips.size();i++) { - Clip* c = sequence->clips.at(i); - if (c != NULL && is_clip_selected(c, true)) { - if (c->get_opening_transition() == NULL) { - ca->append(new AddTransitionCommand(c, NULL, NULL, get_internal_meta(TRANSITION_INTERNAL_LINEARFADE, EFFECT_TYPE_TRANSITION), TA_OPENING_TRANSITION, 30)); + for (int i=0;iclips.size();i++) { + Clip* c = sequence->clips.at(i); + if (c != NULL && is_clip_selected(c, true)) { + if (c->get_opening_transition() == NULL) { + ca->append(new AddTransitionCommand(c, NULL, NULL, get_internal_meta(TRANSITION_INTERNAL_LINEARFADE, EFFECT_TYPE_TRANSITION), TA_OPENING_TRANSITION, 30)); adding = true; - } - if (c->get_closing_transition() == NULL) { - ca->append(new AddTransitionCommand(c, NULL, NULL, get_internal_meta(TRANSITION_INTERNAL_LINEARFADE, EFFECT_TYPE_TRANSITION), TA_OPENING_TRANSITION, 30)); + } + if (c->get_closing_transition() == NULL) { + ca->append(new AddTransitionCommand(c, NULL, NULL, get_internal_meta(TRANSITION_INTERNAL_LINEARFADE, EFFECT_TYPE_TRANSITION), TA_OPENING_TRANSITION, 30)); adding = true; - } - } - } + } + } + } if (adding) { - undo_stack.push(ca); + undo_stack.push(ca); } else { - delete ca; + delete ca; } update_ui(true); } int Timeline::calculate_track_height(int track, int value) { - int index = (track < 0) ? qAbs(track + 1) : track; - QVector& vector = (track < 0) ? video_track_heights : audio_track_heights; - while (vector.size() < index+1) { + int index = (track < 0) ? qAbs(track + 1) : track; + QVector& vector = (track < 0) ? video_track_heights : audio_track_heights; + while (vector.size() < index+1) { vector.append(default_track_height); - } - if (value > -1) { - vector[index] = value; - } - return vector.at(index); + } + if (value > -1) { + vector[index] = value; + } + return vector.at(index); } void Timeline::update_sequence() { - bool null_sequence = (sequence == NULL); + bool null_sequence = (sequence == NULL); for (int i=0;isetEnabled(!null_sequence); } - ui->snappingButton->setEnabled(!null_sequence); + ui->snappingButton->setEnabled(!null_sequence); ui->pushButton_4->setEnabled(!null_sequence); ui->pushButton_5->setEnabled(!null_sequence); ui->recordButton->setEnabled(!null_sequence); ui->addButton->setEnabled(!null_sequence); - ui->headers->setEnabled(!null_sequence); + ui->headers->setEnabled(!null_sequence); if (null_sequence) { setWindowTitle("Timeline: "); @@ -423,52 +422,52 @@ bool Timeline::focused() { } void Timeline::repaint_timeline() { - if (!block_repaints) { - bool draw = true; + if (!block_repaints) { + bool draw = true; - if (sequence != NULL - && !ui->horizontalScrollBar->isSliderDown() - && !ui->horizontalScrollBar->is_resizing() - && panel_sequence_viewer->playing - && !zoom_just_changed) { - // auto scroll - if (config.autoscroll == AUTOSCROLL_PAGE_SCROLL) { - int playhead_x = panel_timeline->getTimelineScreenPointFromFrame(sequence->playhead); - if (playhead_x < 0 || playhead_x > (ui->editAreas->width() - ui->videoScrollbar->width())) { - ui->horizontalScrollBar->setValue(getScreenPointFromFrame(zoom, sequence->playhead)); - draw = false; - } - } else if (config.autoscroll == AUTOSCROLL_SMOOTH_SCROLL) { - if (center_scroll_to_playhead(ui->horizontalScrollBar, zoom, sequence->playhead)) { - draw = false; - } - } - } + if (sequence != NULL + && !ui->horizontalScrollBar->isSliderDown() + && !ui->horizontalScrollBar->is_resizing() + && panel_sequence_viewer->playing + && !zoom_just_changed) { + // auto scroll + if (config.autoscroll == AUTOSCROLL_PAGE_SCROLL) { + int playhead_x = panel_timeline->getTimelineScreenPointFromFrame(sequence->playhead); + if (playhead_x < 0 || playhead_x > (ui->editAreas->width() - ui->videoScrollbar->width())) { + ui->horizontalScrollBar->setValue(getScreenPointFromFrame(zoom, sequence->playhead)); + draw = false; + } + } else if (config.autoscroll == AUTOSCROLL_SMOOTH_SCROLL) { + if (center_scroll_to_playhead(ui->horizontalScrollBar, zoom, sequence->playhead)) { + draw = false; + } + } + } - zoom_just_changed = false; + zoom_just_changed = false; - if (draw) { - ui->headers->update(); - ui->video_area->update(); - ui->audio_area->update(); + if (draw) { + ui->headers->update(); + ui->video_area->update(); + ui->audio_area->update(); - if (sequence != NULL) { - set_sb_max(); + if (sequence != NULL) { + set_sb_max(); - if (last_frame != sequence->playhead) { - ui->audio_monitor->update(); - last_frame = sequence->playhead; - } - } - } - } + if (last_frame != sequence->playhead) { + ui->audio_monitor->update(); + last_frame = sequence->playhead; + } + } + } + } } void Timeline::select_all() { if (sequence != NULL) { sequence->selections.clear(); - for (int i=0;iclips.size();i++) { - Clip* c = sequence->clips.at(i); + for (int i=0;iclips.size();i++) { + Clip* c = sequence->clips.at(i); if (c != NULL) { Selection s; s.in = c->timeline_in; @@ -478,39 +477,39 @@ void Timeline::select_all() { } } repaint_timeline(); - } + } } void Timeline::resizeEvent(QResizeEvent *event) { - if (sequence != NULL) set_sb_max(); + if (sequence != NULL) set_sb_max(); } void Timeline::delete_in_out(bool ripple) { - if (sequence != NULL && sequence->using_workarea) { - QVector areas; - int video_tracks = 0, audio_tracks = 0; - sequence->getTrackLimits(&video_tracks, &audio_tracks); - for (int i=video_tracks;i<=audio_tracks;i++) { - Selection s; - s.in = sequence->workarea_in; - s.out = sequence->workarea_out; - s.track = i; - areas.append(s); - } - ComboAction* ca = new ComboAction(); - delete_areas_and_relink(ca, areas); - if (ripple) ca->append(new RippleCommand(sequence, sequence->workarea_in, sequence->workarea_in - sequence->workarea_out)); - ca->append(new SetTimelineInOutCommand(sequence, false, 0, 0)); - undo_stack.push(ca); + if (sequence != NULL && sequence->using_workarea) { + QVector areas; + int video_tracks = 0, audio_tracks = 0; + sequence->getTrackLimits(&video_tracks, &audio_tracks); + for (int i=video_tracks;i<=audio_tracks;i++) { + Selection s; + s.in = sequence->workarea_in; + s.out = sequence->workarea_out; + s.track = i; + areas.append(s); + } + ComboAction* ca = new ComboAction(); + delete_areas_and_relink(ca, areas); + if (ripple) ca->append(new RippleCommand(sequence, sequence->workarea_in, sequence->workarea_in - sequence->workarea_out)); + ca->append(new SetTimelineInOutCommand(sequence, false, 0, 0)); + undo_stack.push(ca); update_ui(true); - } + } } void Timeline::delete_selection(QVector& selections, bool ripple_delete) { if (selections.size() > 0) { - panel_effect_controls->clear_effects(true); + panel_effect_controls->clear_effects(true); - ComboAction* ca = new ComboAction(); + ComboAction* ca = new ComboAction(); delete_areas_and_relink(ca, selections); @@ -518,43 +517,43 @@ void Timeline::delete_selection(QVector& selections, bool ripple_dele long ripple_point = selections.at(0).in; long ripple_length = selections.at(0).out - selections.at(0).in; - // retrieve ripple_point and ripple_length from current selection + // retrieve ripple_point and ripple_length from current selection for (int i=1;iclips.size();i++) { - Clip* c = sequence->clips.at(i); + bool can_ripple = true; + for (int i=0;iclips.size();i++) { + Clip* c = sequence->clips.at(i); if (c != NULL && c->timeline_in < ripple_point && c->timeline_out > ripple_point) { - // conflict detected, but this clip may be getting deleted so let's check - bool deleted = false; + // conflict detected, but this clip may be getting deleted so let's check + bool deleted = false; for (int j=0;jtrack - && !(c->timeline_in < s.in && c->timeline_out < s.in) - && !(c->timeline_in > s.out && c->timeline_out > s.out)) { - deleted = true; - break; - } - } - if (!deleted) { - for (int j=0;jclips.size();j++) { - Clip* cc = sequence->clips.at(j); + if (s.track == c->track + && !(c->timeline_in < s.in && c->timeline_out < s.in) + && !(c->timeline_in > s.out && c->timeline_out > s.out)) { + deleted = true; + break; + } + } + if (!deleted) { + for (int j=0;jclips.size();j++) { + Clip* cc = sequence->clips.at(j); if (cc != NULL && cc->track == c->track - && cc->timeline_in > c->timeline_out - && cc->timeline_in < c->timeline_out + ripple_length) { - ripple_length = cc->timeline_in - c->timeline_out; - } - } - } - } + && cc->timeline_in > c->timeline_out + && cc->timeline_in < c->timeline_out + ripple_length) { + ripple_length = cc->timeline_in - c->timeline_out; + } + } + } + } } if (can_ripple) { @@ -565,7 +564,7 @@ void Timeline::delete_selection(QVector& selections, bool ripple_dele selections.clear(); - undo_stack.push(ca); + undo_stack.push(ca); update_ui(true); } @@ -573,14 +572,14 @@ void Timeline::delete_selection(QVector& selections, bool ripple_dele void Timeline::set_zoom_value(double v) { zoom = v; - zoom_just_changed = true; - ui->headers->update_zoom(zoom); + zoom_just_changed = true; + ui->headers->update_zoom(zoom); - repaint_timeline(); + repaint_timeline(); - // TODO find a way to gradually move towards target_scroll instead of just centering it? - if (!ui->horizontalScrollBar->is_resizing()) - center_scroll_to_playhead(ui->horizontalScrollBar, zoom, sequence->playhead); + // TODO find a way to gradually move towards target_scroll instead of just centering it? + if (!ui->horizontalScrollBar->is_resizing()) + center_scroll_to_playhead(ui->horizontalScrollBar, zoom, sequence->playhead); } void Timeline::set_zoom(bool in) { @@ -590,34 +589,34 @@ void Timeline::set_zoom(bool in) { void Timeline::decheck_tool_buttons(QObject* sender) { for (int i=0;isetChecked(tool_buttons.at(i) == sender); + tool_buttons[i]->setChecked(tool_buttons.at(i) == sender); } } QVector Timeline::get_tracks_of_linked_clips(int i) { - QVector tracks; - Clip* clip = sequence->clips.at(i); - for (int j=0;jlinked.size();j++) { - tracks.append(sequence->clips.at(clip->linked.at(j))->track); - } - return tracks; + QVector tracks; + Clip* clip = sequence->clips.at(i); + for (int j=0;jlinked.size();j++) { + tracks.append(sequence->clips.at(clip->linked.at(j))->track); + } + return tracks; } void Timeline::on_pushButton_4_clicked() { - set_zoom(true); + set_zoom(true); } void Timeline::on_pushButton_5_clicked() { - set_zoom(false); + set_zoom(false); } bool Timeline::is_clip_selected(Clip* clip, bool containing) { for (int i=0;isequence->selections.size();i++) { const Selection& s = clip->sequence->selections.at(i); - if (clip->track == s.track && ((clip->timeline_in >= s.in && clip->timeline_out <= s.out && containing) || - (!containing && !(clip->timeline_in < s.in && clip->timeline_out < s.in) && !(clip->timeline_in > s.in && clip->timeline_out > s.in)))) { + if (clip->track == s.track && ((clip->timeline_in >= s.in && clip->timeline_out <= s.out && containing) || + (!containing && !(clip->timeline_in < s.in && clip->timeline_out < s.in) && !(clip->timeline_in > s.in && clip->timeline_out > s.in)))) { return true; } } @@ -629,425 +628,425 @@ void Timeline::on_snappingButton_toggled(bool checked) { } Clip* Timeline::split_clip(ComboAction* ca, int p, long frame) { - return split_clip(ca, p, frame, frame); + return split_clip(ca, p, frame, frame); } Clip* Timeline::split_clip(ComboAction* ca, int p, long frame, long post_in) { - Clip* pre = sequence->clips.at(p); - if (pre != NULL && pre->timeline_in < frame && pre->timeline_out > frame) { // guard against attempts to split at in/out points - Clip* post = pre->copy(sequence); + Clip* pre = sequence->clips.at(p); + if (pre != NULL && pre->timeline_in < frame && pre->timeline_out > frame) { // guard against attempts to split at in/out points + Clip* post = pre->copy(sequence); long new_clip_length = frame - pre->timeline_in; post->timeline_in = post_in; post->clip_in = pre->clip_in + (post->timeline_in - pre->timeline_in); - move_clip(ca, pre, pre->timeline_in, frame, pre->clip_in, pre->track); + move_clip(ca, pre, pre->timeline_in, frame, pre->clip_in, pre->track); - if (pre->get_opening_transition() != NULL) { - /*if (frame < pre->timeline_in + pre->get_opening_transition()->length && pre->get_opening_transition()->secondary_clip != NULL) { - // separate shared transition - ca->append(new SetPointer((void**) &pre->get_opening_transition()->secondary_clip, NULL)); - pre->get_opening_transition()->secondary_clip->closing_transition = pre->get_opening_transition()->copy(pre->get_opening_transition()->secondary_clip, NULL); - }*/ + if (pre->get_opening_transition() != NULL) { + /*if (frame < pre->timeline_in + pre->get_opening_transition()->length && pre->get_opening_transition()->secondary_clip != NULL) { + // separate shared transition + ca->append(new SetPointer((void**) &pre->get_opening_transition()->secondary_clip, NULL)); + pre->get_opening_transition()->secondary_clip->closing_transition = pre->get_opening_transition()->copy(pre->get_opening_transition()->secondary_clip, NULL); + }*/ - if (pre->get_opening_transition()->get_true_length() > new_clip_length) { - ca->append(new ModifyTransitionCommand(pre, TA_OPENING_TRANSITION, new_clip_length)); + if (pre->get_opening_transition()->get_true_length() > new_clip_length) { + ca->append(new ModifyTransitionCommand(pre, TA_OPENING_TRANSITION, new_clip_length)); } - post->sequence->hard_delete_transition(post, TA_OPENING_TRANSITION); + post->sequence->hard_delete_transition(post, TA_OPENING_TRANSITION); } - if (pre->get_closing_transition() != NULL) { - ca->append(new DeleteTransitionCommand(pre->sequence, pre->closing_transition)); - if (pre->get_closing_transition()->secondary_clip == NULL) post->get_closing_transition()->set_length(qMin((long) post->get_closing_transition()->get_true_length(), post->getLength())); + if (pre->get_closing_transition() != NULL) { + ca->append(new DeleteTransitionCommand(pre->sequence, pre->closing_transition)); + if (pre->get_closing_transition()->secondary_clip == NULL) post->get_closing_transition()->set_length(qMin((long) post->get_closing_transition()->get_true_length(), post->getLength())); } - return post; - } - return NULL; + return post; + } + return NULL; } bool Timeline::has_clip_been_split(int c) { - for (int i=0;iclips.at(clip); - if (c != NULL) { - QVector pre_clips; - QVector post_clips; + Clip* c = sequence->clips.at(clip); + if (c != NULL) { + QVector pre_clips; + QVector post_clips; - Clip* post = split_clip(ca, clip, frame); + Clip* post = split_clip(ca, clip, frame); - // if alt is not down, split clips links too - if (post == NULL) { - return false; - } else { - post_clips.append(post); - if (relink) { - pre_clips.append(clip); + // if alt is not down, split clips links too + if (post == NULL) { + return false; + } else { + post_clips.append(post); + if (relink) { + pre_clips.append(clip); - bool original_clip_is_selected = is_clip_selected(c, true); + bool original_clip_is_selected = is_clip_selected(c, true); - // find linked clips of old clip - for (int i=0;ilinked.size();i++) { - int l = c->linked.at(i); - if (!has_clip_been_split(l)) { - Clip* link = sequence->clips.at(l); - if ((original_clip_is_selected && is_clip_selected(link, true)) || !original_clip_is_selected) { - split_cache.append(l); - Clip* s = split_clip(ca, l, frame); - if (s != NULL) { - pre_clips.append(l); - post_clips.append(s); - } - } - } - } + // find linked clips of old clip + for (int i=0;ilinked.size();i++) { + int l = c->linked.at(i); + if (!has_clip_been_split(l)) { + Clip* link = sequence->clips.at(l); + if ((original_clip_is_selected && is_clip_selected(link, true)) || !original_clip_is_selected) { + split_cache.append(l); + Clip* s = split_clip(ca, l, frame); + if (s != NULL) { + pre_clips.append(l); + post_clips.append(s); + } + } + } + } - relink_clips_using_ids(pre_clips, post_clips); - } - ca->append(new AddClipCommand(sequence, post_clips)); - return true; - } - } - return false; + relink_clips_using_ids(pre_clips, post_clips); + } + ca->append(new AddClipCommand(sequence, post_clips)); + return true; + } + } + return false; } void Timeline::clean_up_selections(QVector& areas) { - for (int i=0;i ss.out) { - // do nothing - } else if (s.in >= ss.in && s.out <= ss.out) { - remove = true; - } else if (s.in <= ss.out && s.out > ss.out) { - ss.out = s.out; - remove = true; - } else if (s.out >= ss.in && s.in < ss.in) { - ss.in = s.in; - remove = true; - } - if (remove) { - areas.removeAt(i); - i--; - break; - } - } - } - } - } + for (int i=0;i ss.out) { + // do nothing + } else if (s.in >= ss.in && s.out <= ss.out) { + remove = true; + } else if (s.in <= ss.out && s.out > ss.out) { + ss.out = s.out; + remove = true; + } else if (s.out >= ss.in && s.in < ss.in) { + ss.in = s.in; + remove = true; + } + if (remove) { + areas.removeAt(i); + i--; + break; + } + } + } + } + } } bool selection_contains_transition(const Selection& s, Clip* c, int type) { - if (type == TA_OPENING_TRANSITION) { - return c->get_opening_transition() != NULL - && s.out == c->timeline_in + c->get_opening_transition()->get_true_length() - && ((c->get_opening_transition()->secondary_clip == NULL && s.in == c->timeline_in) - || (c->get_opening_transition()->secondary_clip != NULL && s.in == c->timeline_in - c->get_opening_transition()->get_true_length())); - } else { - return c->get_closing_transition() != NULL - && s.in == c->timeline_out - c->get_closing_transition()->get_true_length() - && ((c->get_closing_transition()->secondary_clip == NULL && s.out == c->timeline_out) - || (c->get_closing_transition()->secondary_clip != NULL && s.out == c->timeline_out + c->get_closing_transition()->get_true_length())); - } + if (type == TA_OPENING_TRANSITION) { + return c->get_opening_transition() != NULL + && s.out == c->timeline_in + c->get_opening_transition()->get_true_length() + && ((c->get_opening_transition()->secondary_clip == NULL && s.in == c->timeline_in) + || (c->get_opening_transition()->secondary_clip != NULL && s.in == c->timeline_in - c->get_opening_transition()->get_true_length())); + } else { + return c->get_closing_transition() != NULL + && s.in == c->timeline_out - c->get_closing_transition()->get_true_length() + && ((c->get_closing_transition()->secondary_clip == NULL && s.out == c->timeline_out) + || (c->get_closing_transition()->secondary_clip != NULL && s.out == c->timeline_out + c->get_closing_transition()->get_true_length())); + } } void Timeline::delete_areas_and_relink(ComboAction* ca, QVector& areas) { - clean_up_selections(areas); + clean_up_selections(areas); - QVector pre_clips; - QVector post_clips; + QVector pre_clips; + QVector post_clips; - for (int i=0;iclips.size();j++) { - Clip* c = sequence->clips.at(j); - if (c != NULL && c->track == s.track && !c->undeletable) { - if (selection_contains_transition(s, c, TA_OPENING_TRANSITION)) { + for (int i=0;iclips.size();j++) { + Clip* c = sequence->clips.at(j); + if (c != NULL && c->track == s.track && !c->undeletable) { + if (selection_contains_transition(s, c, TA_OPENING_TRANSITION)) { // delete opening transition - ca->append(new DeleteTransitionCommand(c->sequence, c->opening_transition)); - } else if (selection_contains_transition(s, c, TA_CLOSING_TRANSITION)) { + ca->append(new DeleteTransitionCommand(c->sequence, c->opening_transition)); + } else if (selection_contains_transition(s, c, TA_CLOSING_TRANSITION)) { // delete closing transition - ca->append(new DeleteTransitionCommand(c->sequence, c->closing_transition)); + ca->append(new DeleteTransitionCommand(c->sequence, c->closing_transition)); } else if (c->timeline_in >= s.in && c->timeline_out <= s.out) { - // clips falls entirely within deletion area - ca->append(new DeleteClipAction(sequence, j)); - } else if (c->timeline_in < s.in && c->timeline_out > s.out) { - // middle of clip is within deletion area + // clips falls entirely within deletion area + ca->append(new DeleteClipAction(sequence, j)); + } else if (c->timeline_in < s.in && c->timeline_out > s.out) { + // middle of clip is within deletion area - // duplicate clip - Clip* post = split_clip(ca, j, s.in, s.out); + // duplicate clip + Clip* post = split_clip(ca, j, s.in, s.out); pre_clips.append(j); post_clips.append(post); - } else if (c->timeline_in < s.in && c->timeline_out > s.in) { - // only out point is in deletion area - move_clip(ca, c, c->timeline_in, s.in, c->clip_in, c->track); + } else if (c->timeline_in < s.in && c->timeline_out > s.in) { + // only out point is in deletion area + move_clip(ca, c, c->timeline_in, s.in, c->clip_in, c->track); - if (c->get_closing_transition() != NULL) { - if (s.in < c->timeline_out - c->get_closing_transition()->get_true_length()) { - ca->append(new DeleteTransitionCommand(c->sequence, c->closing_transition)); + if (c->get_closing_transition() != NULL) { + if (s.in < c->timeline_out - c->get_closing_transition()->get_true_length()) { + ca->append(new DeleteTransitionCommand(c->sequence, c->closing_transition)); } else { - ca->append(new ModifyTransitionCommand(c, TA_CLOSING_TRANSITION, c->get_closing_transition()->get_true_length() - (c->timeline_out - s.in))); + ca->append(new ModifyTransitionCommand(c, TA_CLOSING_TRANSITION, c->get_closing_transition()->get_true_length() - (c->timeline_out - s.in))); } } - } else if (c->timeline_in < s.out && c->timeline_out > s.out) { - // only in point is in deletion area - move_clip(ca, c, s.out, c->timeline_out, c->clip_in + (s.out - c->timeline_in), c->track); + } else if (c->timeline_in < s.out && c->timeline_out > s.out) { + // only in point is in deletion area + move_clip(ca, c, s.out, c->timeline_out, c->clip_in + (s.out - c->timeline_in), c->track); - if (c->get_opening_transition() != NULL) { - if (s.out > c->timeline_in + c->get_opening_transition()->get_true_length()) { - ca->append(new DeleteTransitionCommand(c->sequence, c->opening_transition)); + if (c->get_opening_transition() != NULL) { + if (s.out > c->timeline_in + c->get_opening_transition()->get_true_length()) { + ca->append(new DeleteTransitionCommand(c->sequence, c->opening_transition)); } else { - ca->append(new ModifyTransitionCommand(c, TA_OPENING_TRANSITION, c->get_opening_transition()->get_true_length() - (s.out - c->timeline_in))); + ca->append(new ModifyTransitionCommand(c, TA_OPENING_TRANSITION, c->get_opening_transition()->get_true_length() - (s.out - c->timeline_in))); } } - } - } - } - } - relink_clips_using_ids(pre_clips, post_clips); - ca->append(new AddClipCommand(sequence, post_clips)); + } + } + } + } + relink_clips_using_ids(pre_clips, post_clips); + ca->append(new AddClipCommand(sequence, post_clips)); } void Timeline::copy(bool del) { - bool cleared = false; - bool copied = false; + bool cleared = false; + bool copied = false; - long min_in = 0; + long min_in = 0; - for (int i=0;iclips.size();i++) { - Clip* c = sequence->clips.at(i); - if (c != NULL) { + for (int i=0;iclips.size();i++) { + Clip* c = sequence->clips.at(i); + if (c != NULL) { for (int j=0;jselections.size();j++) { const Selection& s = sequence->selections.at(j); - if (s.track == c->track && !((c->timeline_in <= s.in && c->timeline_out <= s.in) || (c->timeline_in >= s.out && c->timeline_out >= s.out))) { - if (!cleared) { - clear_clipboard(); - cleared = true; - clipboard_type = CLIPBOARD_TYPE_CLIP; - } + if (s.track == c->track && !((c->timeline_in <= s.in && c->timeline_out <= s.in) || (c->timeline_in >= s.out && c->timeline_out >= s.out))) { + if (!cleared) { + clear_clipboard(); + cleared = true; + clipboard_type = CLIPBOARD_TYPE_CLIP; + } - Clip* copied_clip = c->copy(NULL); + Clip* copied_clip = c->copy(NULL); - copied_clip->cached_fr = sequence->frame_rate; + copied_clip->cached_fr = sequence->frame_rate; - // copy linked IDs (we correct these later in paste()) - copied_clip->linked = c->linked; + // copy linked IDs (we correct these later in paste()) + copied_clip->linked = c->linked; - if (copied_clip->timeline_in < s.in) { - copied_clip->clip_in += (s.in - copied_clip->timeline_in); - copied_clip->timeline_in = s.in; - } + if (copied_clip->timeline_in < s.in) { + copied_clip->clip_in += (s.in - copied_clip->timeline_in); + copied_clip->timeline_in = s.in; + } - if (copied_clip->timeline_out > s.out) { - copied_clip->timeline_out = s.out; - } + if (copied_clip->timeline_out > s.out) { + copied_clip->timeline_out = s.out; + } - if (copied) { - min_in = qMin(min_in, s.in); - } else { - min_in = s.in; - copied = true; - } + if (copied) { + min_in = qMin(min_in, s.in); + } else { + min_in = s.in; + copied = true; + } - copied_clip->load_id = i; + copied_clip->load_id = i; - clipboard.append(copied_clip); - } - } - } - } + clipboard.append(copied_clip); + } + } + } + } - for (int i=0;i(clipboard.at(i))->timeline_in -= min_in; - static_cast(clipboard.at(i))->timeline_out -= min_in; - } + for (int i=0;i(clipboard.at(i))->timeline_in -= min_in; + static_cast(clipboard.at(i))->timeline_out -= min_in; + } - if (del && copied) { + if (del && copied) { delete_selection(sequence->selections, false); - } + } } void Timeline::relink_clips_using_ids(QVector& old_clips, QVector& new_clips) { - // relink pasted clips - for (int i=0;iclips.at(old_clips.at(i)); - for (int j=0;jlinked.size();j++) { - for (int k=0;klinked.at(j) == old_clips.at(k)) { - new_clips.at(i)->linked.append(k); - } - } - } - } + // relink pasted clips + for (int i=0;iclips.at(old_clips.at(i)); + for (int j=0;jlinked.size();j++) { + for (int k=0;klinked.at(j) == old_clips.at(k)) { + new_clips.at(i)->linked.append(k); + } + } + } + } } void Timeline::paste(bool insert) { - if (clipboard.size() > 0) { - if (clipboard_type == CLIPBOARD_TYPE_CLIP) { - ComboAction* ca = new ComboAction(); + if (clipboard.size() > 0) { + if (clipboard_type == CLIPBOARD_TYPE_CLIP) { + ComboAction* ca = new ComboAction(); - // create copies and delete areas that we'll be pasting to - QVector delete_areas; - QVector pasted_clips; - long paste_start = LONG_MAX; - long paste_end = LONG_MIN; - for (int i=0;i(clipboard.at(i)); + // create copies and delete areas that we'll be pasting to + QVector delete_areas; + QVector pasted_clips; + long paste_start = LONG_MAX; + long paste_end = LONG_MIN; + for (int i=0;i(clipboard.at(i)); - // create copy of clip and offset by playhead - Clip* cc = c->copy(sequence); + // create copy of clip and offset by playhead + Clip* cc = c->copy(sequence); - // convert frame rates - cc->timeline_in = refactor_frame_number(cc->timeline_in, c->cached_fr, sequence->frame_rate); - cc->timeline_out = refactor_frame_number(cc->timeline_out, c->cached_fr, sequence->frame_rate); - cc->clip_in = refactor_frame_number(cc->clip_in, c->cached_fr, sequence->frame_rate); + // convert frame rates + cc->timeline_in = refactor_frame_number(cc->timeline_in, c->cached_fr, sequence->frame_rate); + cc->timeline_out = refactor_frame_number(cc->timeline_out, c->cached_fr, sequence->frame_rate); + cc->clip_in = refactor_frame_number(cc->clip_in, c->cached_fr, sequence->frame_rate); - cc->timeline_in += sequence->playhead; - cc->timeline_out += sequence->playhead; - cc->track = c->track; + cc->timeline_in += sequence->playhead; + cc->timeline_out += sequence->playhead; + cc->track = c->track; - paste_start = qMin(paste_start, cc->timeline_in); - paste_end = qMax(paste_end, cc->timeline_out); + paste_start = qMin(paste_start, cc->timeline_in); + paste_end = qMax(paste_end, cc->timeline_out); - pasted_clips.append(cc); + pasted_clips.append(cc); - if (!insert) { - Selection s; - s.in = cc->timeline_in; - s.out = cc->timeline_out; - s.track = c->track; - delete_areas.append(s); - } - } - if (insert) { - split_cache.clear(); - split_all_clips_at_point(ca, sequence->playhead); - ca->append(new RippleCommand(sequence, paste_start, paste_end - paste_start)); - } else { - delete_areas_and_relink(ca, delete_areas); - } + if (!insert) { + Selection s; + s.in = cc->timeline_in; + s.out = cc->timeline_out; + s.track = c->track; + delete_areas.append(s); + } + } + if (insert) { + split_cache.clear(); + split_all_clips_at_point(ca, sequence->playhead); + ca->append(new RippleCommand(sequence, paste_start, paste_end - paste_start)); + } else { + delete_areas_and_relink(ca, delete_areas); + } - // correct linked clips - for (int i=0;i(clipboard.at(i)); + // correct linked clips + for (int i=0;i(clipboard.at(i)); - for (int j=0;jlinked.size();j++) { - for (int k=0;k(clipboard.at(k)); - if (comp->load_id == oc->linked.at(j)) { - pasted_clips.at(i)->linked.append(k); - } - } - } - } + for (int j=0;jlinked.size();j++) { + for (int k=0;k(clipboard.at(k)); + if (comp->load_id == oc->linked.at(j)) { + pasted_clips.at(i)->linked.append(k); + } + } + } + } - ca->append(new AddClipCommand(sequence, pasted_clips)); + ca->append(new AddClipCommand(sequence, pasted_clips)); - undo_stack.push(ca); + undo_stack.push(ca); - update_ui(true); + update_ui(true); - if (config.paste_seeks) { - panel_sequence_viewer->seek(paste_end); - } - } else if (clipboard_type == CLIPBOARD_TYPE_EFFECT) { - ComboAction* ca = new ComboAction(); - bool push = false; + if (config.paste_seeks) { + panel_sequence_viewer->seek(paste_end); + } + } else if (clipboard_type == CLIPBOARD_TYPE_EFFECT) { + ComboAction* ca = new ComboAction(); + bool push = false; - bool replace = false; - bool skip = false; - bool ask_conflict = true; + bool replace = false; + bool skip = false; + bool ask_conflict = true; - for (int i=0;iclips.size();i++) { - Clip* c = sequence->clips.at(i); - if (c != NULL && is_clip_selected(c, true)) { - for (int j=0;j(clipboard.at(j)); - if ((c->track < 0) == (e->meta->subtype == EFFECT_TYPE_VIDEO)) { - int found = -1; - if (ask_conflict) { - replace = false; - skip = false; - } - for (int k=0;keffects.size();k++) { - if (c->effects.at(k)->meta == e->meta) { - found = k; - break; - } - } - if (found >= 0 && ask_conflict) { - QMessageBox box(this); - box.setWindowTitle("Effect already exists"); - box.setText("Clip '" + c->name + "' already contains a '" + e->meta->name + "' effect. Would you like to replace it with the pasted one or add it as a separate effect?"); - box.setIcon(QMessageBox::Icon::Question); + for (int i=0;iclips.size();i++) { + Clip* c = sequence->clips.at(i); + if (c != NULL && is_clip_selected(c, true)) { + for (int j=0;j(clipboard.at(j)); + if ((c->track < 0) == (e->meta->subtype == EFFECT_TYPE_VIDEO)) { + int found = -1; + if (ask_conflict) { + replace = false; + skip = false; + } + for (int k=0;keffects.size();k++) { + if (c->effects.at(k)->meta == e->meta) { + found = k; + break; + } + } + if (found >= 0 && ask_conflict) { + QMessageBox box(this); + box.setWindowTitle("Effect already exists"); + box.setText("Clip '" + c->name + "' already contains a '" + e->meta->name + "' effect. Would you like to replace it with the pasted one or add it as a separate effect?"); + box.setIcon(QMessageBox::Icon::Question); - box.addButton("Add", QMessageBox::YesRole); - QPushButton* replace_button = box.addButton("Replace", QMessageBox::NoRole); - QPushButton* skip_button = box.addButton("Skip", QMessageBox::RejectRole); + box.addButton("Add", QMessageBox::YesRole); + QPushButton* replace_button = box.addButton("Replace", QMessageBox::NoRole); + QPushButton* skip_button = box.addButton("Skip", QMessageBox::RejectRole); - QCheckBox* future_box = new QCheckBox("Do this for all conflicts found"); - box.setCheckBox(future_box); + QCheckBox* future_box = new QCheckBox("Do this for all conflicts found"); + box.setCheckBox(future_box); - box.exec(); + box.exec(); - if (box.clickedButton() == replace_button) { - replace = true; - } else if (box.clickedButton() == skip_button) { - skip = true; - } - ask_conflict = !future_box->isChecked(); - } + if (box.clickedButton() == replace_button) { + replace = true; + } else if (box.clickedButton() == skip_button) { + skip = true; + } + ask_conflict = !future_box->isChecked(); + } - if (found >= 0 && skip) { - // do nothing - } else if (found >= 0 && replace) { - EffectDeleteCommand* delcom = new EffectDeleteCommand(); - delcom->clips.append(c); - delcom->fx.append(found); - ca->append(delcom); + if (found >= 0 && skip) { + // do nothing + } else if (found >= 0 && replace) { + EffectDeleteCommand* delcom = new EffectDeleteCommand(); + delcom->clips.append(c); + delcom->fx.append(found); + ca->append(delcom); - ca->append(new AddEffectCommand(c, e->copy(c), NULL, found)); - push = true; - } else { - ca->append(new AddEffectCommand(c, e->copy(c), NULL)); - push = true; - } - } - } - } - } - if (push) { - ca->appendPost(new ReloadEffectsCommand()); - undo_stack.push(ca); - } else { - delete ca; - } - update_ui(true); - } - } + ca->append(new AddEffectCommand(c, e->copy(c), NULL, found)); + push = true; + } else { + ca->append(new AddEffectCommand(c, e->copy(c), NULL)); + push = true; + } + } + } + } + } + if (push) { + ca->appendPost(new ReloadEffectsCommand()); + undo_stack.push(ca); + } else { + delete ca; + } + update_ui(true); + } + } } void Timeline::ripple_to_in_point(bool in, bool ripple) { @@ -1147,137 +1146,137 @@ void Timeline::ripple_to_in_point(bool in, bool ripple) { } bool Timeline::split_selection(ComboAction* ca) { - bool split = false; + bool split = false; - // temporary relinking vectors - QVector pre_splits; - QVector post_splits; - QVector secondary_post_splits; + // temporary relinking vectors + QVector pre_splits; + QVector post_splits; + QVector secondary_post_splits; - // find clips within selection and split - for (int j=0;jclips.size();j++) { - Clip* clip = sequence->clips.at(j); - if (clip != NULL) { + // find clips within selection and split + for (int j=0;jclips.size();j++) { + Clip* clip = sequence->clips.at(j); + if (clip != NULL) { for (int i=0;iselections.size();i++) { const Selection& s = sequence->selections.at(i); - if (s.track == clip->track) { + if (s.track == clip->track) { if (clip->timeline_in < s.in && clip->timeline_out > s.out) { - Clip* split_A = clip->copy(sequence); - split_A->clip_in += (s.in - clip->timeline_in); - split_A->timeline_in = s.in; - split_A->timeline_out = s.out; - pre_splits.append(j); + Clip* split_A = clip->copy(sequence); + split_A->clip_in += (s.in - clip->timeline_in); + split_A->timeline_in = s.in; + split_A->timeline_out = s.out; + pre_splits.append(j); post_splits.append(split_A); - Clip* split_B = clip->copy(sequence); - split_B->clip_in += (s.out - clip->timeline_in); - split_B->timeline_in = s.out; - secondary_post_splits.append(split_B); + Clip* split_B = clip->copy(sequence); + split_B->clip_in += (s.out - clip->timeline_in); + split_B->timeline_in = s.out; + secondary_post_splits.append(split_B); - if (clip->get_opening_transition() != NULL) { - split_B->sequence->hard_delete_transition(split_B, TA_OPENING_TRANSITION); - split_A->sequence->hard_delete_transition(split_A, TA_OPENING_TRANSITION); + if (clip->get_opening_transition() != NULL) { + split_B->sequence->hard_delete_transition(split_B, TA_OPENING_TRANSITION); + split_A->sequence->hard_delete_transition(split_A, TA_OPENING_TRANSITION); } - if (clip->get_closing_transition() != NULL) { - ca->append(new DeleteTransitionCommand(clip->sequence, clip->closing_transition)); + if (clip->get_closing_transition() != NULL) { + ca->append(new DeleteTransitionCommand(clip->sequence, clip->closing_transition)); - split_A->sequence->hard_delete_transition(split_A, TA_CLOSING_TRANSITION); + split_A->sequence->hard_delete_transition(split_A, TA_CLOSING_TRANSITION); } - move_clip(ca, clip, clip->timeline_in, s.in, clip->clip_in, clip->track); - split = true; - } else { - Clip* post_a = split_clip(ca, j, s.in); - Clip* post_b = split_clip(ca, j, s.out); - if (post_a != NULL) { - pre_splits.append(j); - post_splits.append(post_a); - split = true; - } - if (post_b != NULL) { - if (post_a != NULL) { - pre_splits.append(j); - post_splits.append(post_b); - } else { - secondary_post_splits.append(post_b); - } - split = true; - } - } - } - } - } - } + move_clip(ca, clip, clip->timeline_in, s.in, clip->clip_in, clip->track); + split = true; + } else { + Clip* post_a = split_clip(ca, j, s.in); + Clip* post_b = split_clip(ca, j, s.out); + if (post_a != NULL) { + pre_splits.append(j); + post_splits.append(post_a); + split = true; + } + if (post_b != NULL) { + if (post_a != NULL) { + pre_splits.append(j); + post_splits.append(post_b); + } else { + secondary_post_splits.append(post_b); + } + split = true; + } + } + } + } + } + } - if (split) { - // relink after splitting - relink_clips_using_ids(pre_splits, post_splits); - relink_clips_using_ids(pre_splits, secondary_post_splits); - ca->append(new AddClipCommand(sequence, post_splits)); - ca->append(new AddClipCommand(sequence, secondary_post_splits)); + if (split) { + // relink after splitting + relink_clips_using_ids(pre_splits, post_splits); + relink_clips_using_ids(pre_splits, secondary_post_splits); + ca->append(new AddClipCommand(sequence, post_splits)); + ca->append(new AddClipCommand(sequence, secondary_post_splits)); - return true; - } - return false; + return true; + } + return false; } bool Timeline::split_all_clips_at_point(ComboAction* ca, long point) { - bool split = false; - for (int j=0;jclips.size();j++) { - Clip* c = sequence->clips.at(j); - if (c != NULL) { - // always relinks - if (split_clip_and_relink(ca, j, point, true)) { - split = true; - } - } - } - return split; + bool split = false; + for (int j=0;jclips.size();j++) { + Clip* c = sequence->clips.at(j); + if (c != NULL) { + // always relinks + if (split_clip_and_relink(ca, j, point, true)) { + split = true; + } + } + } + return split; } void Timeline::split_at_playhead() { - ComboAction* ca = new ComboAction(); - bool split_selected = false; - split_cache.clear(); + ComboAction* ca = new ComboAction(); + bool split_selected = false; + split_cache.clear(); if (sequence->selections.size() > 0) { - // see if whole clips are selected - QVector pre_clips; - QVector post_clips; - for (int j=0;jclips.size();j++) { - Clip* clip = sequence->clips.at(j); - if (clip != NULL && is_clip_selected(clip, true)) { + // see if whole clips are selected + QVector pre_clips; + QVector post_clips; + for (int j=0;jclips.size();j++) { + Clip* clip = sequence->clips.at(j); + if (clip != NULL && is_clip_selected(clip, true)) { Clip* s = split_clip(ca, j, sequence->playhead); - if (s != NULL) { - pre_clips.append(j); - post_clips.append(s); - split_selected = true; - } - } - } + if (s != NULL) { + pre_clips.append(j); + post_clips.append(s); + split_selected = true; + } + } + } - if (split_selected) { - // relink clips if we split - relink_clips_using_ids(pre_clips, post_clips); - ca->append(new AddClipCommand(sequence, post_clips)); - } else { - // split a selection if not - split_selected = split_selection(ca); - } - } + if (split_selected) { + // relink clips if we split + relink_clips_using_ids(pre_clips, post_clips); + ca->append(new AddClipCommand(sequence, post_clips)); + } else { + // split a selection if not + split_selected = split_selection(ca); + } + } - // if nothing was selected or no selections fell within playhead, simply split at playhead - if (!split_selected) { - split_selected = split_all_clips_at_point(ca, sequence->playhead); - } + // if nothing was selected or no selections fell within playhead, simply split at playhead + if (!split_selected) { + split_selected = split_all_clips_at_point(ca, sequence->playhead); + } - if (split_selected) { - undo_stack.push(ca); + if (split_selected) { + undo_stack.push(ca); update_ui(true); - } else { - delete ca; - } + } else { + delete ca; + } } void Timeline::deselect_area(long in, long out, int track) { @@ -1311,18 +1310,18 @@ void Timeline::deselect_area(long in, long out, int track) { } bool Timeline::snap_to_point(long point, long* l) { - int limit = get_snap_range(); - if (*l > point-limit-1 && *l < point+limit+1) { - snap_point = point; - *l = point; - snapped = true; - return true; - } - return false; + int limit = get_snap_range(); + if (*l > point-limit-1 && *l < point+limit+1) { + snap_point = point; + *l = point; + snapped = true; + return true; + } + return false; } bool Timeline::snap_to_timeline(long* l, bool use_playhead, bool use_markers, bool use_workarea) { - snapped = false; + snapped = false; if (snapping) { if (use_playhead && !panel_sequence_viewer->playing) { // snap to playhead @@ -1350,11 +1349,11 @@ bool Timeline::snap_to_timeline(long* l, bool use_playhead, bool use_markers, bo return true; } else if (snap_to_point(c->timeline_out, l)) { return true; - } else if (c->get_opening_transition() != NULL - && snap_to_point(c->timeline_in + c->get_opening_transition()->get_true_length(), l)) { + } else if (c->get_opening_transition() != NULL + && snap_to_point(c->timeline_in + c->get_opening_transition()->get_true_length(), l)) { return true; - } else if (c->get_closing_transition() != NULL - && snap_to_point(c->timeline_out - c->get_closing_transition()->get_true_length(), l)) { + } else if (c->get_closing_transition() != NULL + && snap_to_point(c->timeline_out - c->get_closing_transition()->get_true_length(), l)) { return true; } } @@ -1374,50 +1373,50 @@ void Timeline::set_marker() { } void Timeline::toggle_links() { - LinkCommand* command = new LinkCommand(); + LinkCommand* command = new LinkCommand(); command->s = sequence; - for (int i=0;iclips.size();i++) { - Clip* c = sequence->clips.at(i); - if (c != NULL && is_clip_selected(c, true)) { + for (int i=0;iclips.size();i++) { + Clip* c = sequence->clips.at(i); + if (c != NULL && is_clip_selected(c, true)) { command->clips.append(i); - if (c->linked.size() > 0) { - command->link = false; // prioritize unlinking + if (c->linked.size() > 0) { + command->link = false; // prioritize unlinking for (int j=0;jlinked.size();j++) { // add links to the command if (!command->clips.contains(c->linked.at(j))) { command->clips.append(c->linked.at(j)); } - } - } - } - } - if (command->clips.size() > 0) { - undo_stack.push(command); + } + } + } + } + if (command->clips.size() > 0) { + undo_stack.push(command); repaint_timeline(); - } else { - delete command; - } + } else { + delete command; + } } void Timeline::increase_track_height() { - for (int i=0;itimeline_area->setCursor(Qt::ArrowCursor); - tool = TIMELINE_TOOL_POINTER; + decheck_tool_buttons(sender()); + ui->timeline_area->setCursor(Qt::ArrowCursor); + tool = TIMELINE_TOOL_POINTER; creating = false; } void Timeline::on_toolEditButton_clicked() { - decheck_tool_buttons(sender()); - ui->timeline_area->setCursor(Qt::IBeamCursor); - tool = TIMELINE_TOOL_EDIT; + decheck_tool_buttons(sender()); + ui->timeline_area->setCursor(Qt::IBeamCursor); + tool = TIMELINE_TOOL_EDIT; creating = false; } void Timeline::on_toolRippleButton_clicked() { - decheck_tool_buttons(sender()); - ui->timeline_area->setCursor(Qt::ArrowCursor); - tool = TIMELINE_TOOL_RIPPLE; + decheck_tool_buttons(sender()); + ui->timeline_area->setCursor(Qt::ArrowCursor); + tool = TIMELINE_TOOL_RIPPLE; creating = false; } void Timeline::on_toolRollingButton_clicked() { - decheck_tool_buttons(sender()); - ui->timeline_area->setCursor(Qt::ArrowCursor); - tool = TIMELINE_TOOL_ROLLING; + decheck_tool_buttons(sender()); + ui->timeline_area->setCursor(Qt::ArrowCursor); + tool = TIMELINE_TOOL_ROLLING; creating = false; } void Timeline::on_toolRazorButton_clicked() { - decheck_tool_buttons(sender()); - ui->timeline_area->setCursor(Qt::IBeamCursor); - tool = TIMELINE_TOOL_RAZOR; + decheck_tool_buttons(sender()); + ui->timeline_area->setCursor(Qt::IBeamCursor); + tool = TIMELINE_TOOL_RAZOR; creating = false; } void Timeline::on_toolSlipButton_clicked() { - decheck_tool_buttons(sender()); - ui->timeline_area->setCursor(Qt::ArrowCursor); - tool = TIMELINE_TOOL_SLIP; + decheck_tool_buttons(sender()); + ui->timeline_area->setCursor(Qt::ArrowCursor); + tool = TIMELINE_TOOL_SLIP; creating = false; } void Timeline::on_toolSlideButton_clicked() { - decheck_tool_buttons(sender()); - ui->timeline_area->setCursor(Qt::ArrowCursor); - tool = TIMELINE_TOOL_SLIDE; + decheck_tool_buttons(sender()); + ui->timeline_area->setCursor(Qt::ArrowCursor); + tool = TIMELINE_TOOL_SLIDE; creating = false; } @@ -1558,9 +1557,9 @@ void Timeline::on_toolTransitionButton_clicked() { QMenu transition_menu(this); - for (int i=0;isetObjectName("v"); a->setData(reinterpret_cast(&em)); @@ -1569,9 +1568,9 @@ void Timeline::on_toolTransitionButton_clicked() { transition_menu.addSeparator(); - for (int i=0;isetObjectName("a"); a->setData(reinterpret_cast(&em)); @@ -1580,7 +1579,7 @@ void Timeline::on_toolTransitionButton_clicked() { connect(&transition_menu, SIGNAL(triggered(QAction*)), this, SLOT(transition_menu_select(QAction*))); - ui->toolTransitionButton->setChecked(false); + ui->toolTransitionButton->setChecked(false); transition_menu.exec(QCursor::pos()); } @@ -1597,38 +1596,38 @@ void Timeline::transition_menu_select(QAction* a) { decheck_tool_buttons(sender()); ui->timeline_area->setCursor(Qt::CrossCursor); tool = TIMELINE_TOOL_TRANSITION; - ui->toolTransitionButton->setChecked(true); + ui->toolTransitionButton->setChecked(true); } void Timeline::resize_move(double z) { - set_zoom_value(zoom * z); + set_zoom_value(zoom * z); } void Timeline::set_sb_max() { - ui->headers->set_scrollbar_max(ui->horizontalScrollBar, sequence->getEndFrame(), ui->editAreas->width() - getScreenPointFromFrame(zoom, 200)); + ui->headers->set_scrollbar_max(ui->horizontalScrollBar, sequence->getEndFrame(), ui->editAreas->width() - getScreenPointFromFrame(zoom, 200)); } void move_clip(ComboAction* ca, Clip *c, long iin, long iout, long iclip_in, int itrack, bool verify_transitions) { - ca->append(new MoveClipAction(c, iin, iout, iclip_in, itrack)); + ca->append(new MoveClipAction(c, iin, iout, iclip_in, itrack)); - if (verify_transitions) { - if (c->get_opening_transition() != NULL && c->get_opening_transition()->secondary_clip != NULL && c->get_opening_transition()->secondary_clip->timeline_out != iin) { - // separate transition - ca->append(new SetPointer((void**) &c->get_opening_transition()->secondary_clip, NULL)); - ca->append(new AddTransitionCommand(c->get_opening_transition()->secondary_clip, NULL, c->get_opening_transition(), NULL, TA_CLOSING_TRANSITION, 0)); - } + if (verify_transitions) { + if (c->get_opening_transition() != NULL && c->get_opening_transition()->secondary_clip != NULL && c->get_opening_transition()->secondary_clip->timeline_out != iin) { + // separate transition + ca->append(new SetPointer((void**) &c->get_opening_transition()->secondary_clip, NULL)); + ca->append(new AddTransitionCommand(c->get_opening_transition()->secondary_clip, NULL, c->get_opening_transition(), NULL, TA_CLOSING_TRANSITION, 0)); + } - if (c->get_closing_transition() != NULL && c->get_closing_transition()->secondary_clip != NULL && c->get_closing_transition()->parent_clip->timeline_in != iout) { - // separate transition - ca->append(new SetPointer((void**) &c->get_closing_transition()->secondary_clip, NULL)); - ca->append(new AddTransitionCommand(c, NULL, c->get_closing_transition(), NULL, TA_CLOSING_TRANSITION, 0)); - } - } + if (c->get_closing_transition() != NULL && c->get_closing_transition()->secondary_clip != NULL && c->get_closing_transition()->parent_clip->timeline_in != iout) { + // separate transition + ca->append(new SetPointer((void**) &c->get_closing_transition()->secondary_clip, NULL)); + ca->append(new AddTransitionCommand(c, NULL, c->get_closing_transition(), NULL, TA_CLOSING_TRANSITION, 0)); + } + } } void Timeline::on_toolHandButton_clicked() { - decheck_tool_buttons(sender()); - ui->timeline_area->setCursor(Qt::OpenHandCursor); - tool = TIMELINE_TOOL_HAND; - creating = false; + decheck_tool_buttons(sender()); + ui->timeline_area->setCursor(Qt::OpenHandCursor); + tool = TIMELINE_TOOL_HAND; + creating = false; } diff --git a/panels/viewer.cpp b/panels/viewer.cpp index 1fb1c318a..0430ab2d6 100644 --- a/panels/viewer.cpp +++ b/panels/viewer.cpp @@ -1,5 +1,4 @@ #include "viewer.h" -#include "ui_viewer.h" #include "playback/audio.h" #include "timeline.h" @@ -15,6 +14,8 @@ #include "ui_timeline.h" #include "playback/playback.h" #include "ui/viewerwidget.h" +#include "ui/viewercontainer.h" +#include "ui/labelslider.h" #include "debug.h" #define FRAMES_IN_ONE_MINUTE 1798 // 1800 - 2 @@ -32,62 +33,60 @@ extern "C" { #include Viewer::Viewer(QWidget *parent) : - QDockWidget(parent), + QDockWidget(parent), playing(false), - just_played(false), - media(NULL), - seq(NULL), - ui(new Ui::Viewer), - created_sequence(false), - cue_recording_internal(false), - panel_name("Viewer: "), - minimum_zoom(1.0) + just_played(false), + media(NULL), + seq(NULL), + created_sequence(false), + cue_recording_internal(false), + panel_name("Viewer: "), + minimum_zoom(1.0) { - ui->setupUi(this); - ui->headers->viewer = this; - ui->headers->snapping = false; - ui->headers->show_text(false); - ui->glViewerPane->viewer = this; - viewer_widget = ui->glViewerPane->child; - viewer_widget->viewer = this; - set_media(NULL); + setup_ui(); - ui->currentTimecode->setEnabled(false); - ui->currentTimecode->set_minimum_value(0); - ui->currentTimecode->set_default_value(qSNaN()); - ui->currentTimecode->set_value(0, false); - ui->currentTimecode->set_display_type(LABELSLIDER_FRAMENUMBER); - connect(ui->currentTimecode, SIGNAL(valueChanged()), this, SLOT(update_playhead())); + headers->viewer = this; + headers->snapping = false; + headers->show_text(false); + glViewerPane->viewer = this; + viewer_widget = glViewerPane->child; + viewer_widget->viewer = this; + set_media(NULL); + + currentTimecode->setEnabled(false); + currentTimecode->set_minimum_value(0); + currentTimecode->set_default_value(qSNaN()); + currentTimecode->set_value(0, false); + currentTimecode->set_display_type(LABELSLIDER_FRAMENUMBER); + connect(currentTimecode, SIGNAL(valueChanged()), this, SLOT(update_playhead())); recording_flasher.setInterval(500); connect(&playback_updater, SIGNAL(timeout()), this, SLOT(timer_update())); connect(&recording_flasher, SIGNAL(timeout()), this, SLOT(recording_flasher_update())); - connect(ui->horizontalScrollBar, SIGNAL(valueChanged(int)), ui->headers, SLOT(set_scroll(int))); - connect(ui->horizontalScrollBar, SIGNAL(valueChanged(int)), viewer_widget, SLOT(set_waveform_scroll(int))); - connect(ui->horizontalScrollBar, SIGNAL(resize_move(double)), this, SLOT(resize_move(double))); + connect(horizontalScrollBar, SIGNAL(valueChanged(int)), headers, SLOT(set_scroll(int))); + connect(horizontalScrollBar, SIGNAL(valueChanged(int)), viewer_widget, SLOT(set_waveform_scroll(int))); + connect(horizontalScrollBar, SIGNAL(resize_move(double)), this, SLOT(resize_move(double))); - update_playhead_timecode(0); - update_end_timecode(); + update_playhead_timecode(0); + update_end_timecode(); } -Viewer::~Viewer() { - delete ui; -} +Viewer::~Viewer() {} bool Viewer::is_focused() { - return ui->headers->hasFocus() - || viewer_widget->hasFocus() - || ui->btnSkipToStart->hasFocus() - || ui->btnRewind->hasFocus() - || ui->btnPlay->hasFocus() - || ui->btnFastForward->hasFocus() - || ui->btnSkipToEnd->hasFocus(); + return headers->hasFocus() + || viewer_widget->hasFocus() + || btnSkipToStart->hasFocus() + || btnRewind->hasFocus() + || btnPlay->hasFocus() + || btnFastForward->hasFocus() + || btnSkipToEnd->hasFocus(); } void Viewer::set_main_sequence() { clean_created_seq(); - set_sequence(true, sequence); + set_sequence(true, sequence); } void Viewer::reset_all_audio() { @@ -101,43 +100,43 @@ void Viewer::reset_all_audio() { if (c != NULL) c->reset_audio(); } } - clear_audio_ibuffer(); + clear_audio_ibuffer(); } long timecode_to_frame(const QString& s, int view, double frame_rate) { - QList list = s.split(QRegExp("[:;]")); + QList list = s.split(QRegExp("[:;]")); - if (view == TIMECODE_FRAMES || (list.size() == 1 && view != TIMECODE_MILLISECONDS)) { + if (view == TIMECODE_FRAMES || (list.size() == 1 && view != TIMECODE_MILLISECONDS)) { return s.toLong(); } int frRound = qRound(frame_rate); - int hours, minutes, seconds, frames; + int hours, minutes, seconds, frames; - if (view == TIMECODE_MILLISECONDS) { - long milliseconds = s.toLong(); + if (view == TIMECODE_MILLISECONDS) { + long milliseconds = s.toLong(); - hours = milliseconds/3600000; - milliseconds -= (hours*3600000); - minutes = milliseconds/60000; - milliseconds -= (minutes*60000); - seconds = milliseconds/1000; - milliseconds -= (seconds*1000); - frames = qRound64((milliseconds*0.001)*frame_rate); + hours = milliseconds/3600000; + milliseconds -= (hours*3600000); + minutes = milliseconds/60000; + milliseconds -= (minutes*60000); + seconds = milliseconds/1000; + milliseconds -= (seconds*1000); + frames = qRound64((milliseconds*0.001)*frame_rate); - seconds = qRound64(seconds * frame_rate); - minutes = qRound64(minutes * frame_rate * 60); - hours = qRound64(hours * frame_rate * 3600); - } else { - hours = ((list.size() > 0) ? list.at(0).toInt() : 0) * frRound * 3600; - minutes = ((list.size() > 1) ? list.at(1).toInt() : 0) * frRound * 60; - seconds = ((list.size() > 2) ? list.at(2).toInt() : 0) * frRound; - frames = (list.size() > 3) ? list.at(3).toInt() : 0; - } + seconds = qRound64(seconds * frame_rate); + minutes = qRound64(minutes * frame_rate * 60); + hours = qRound64(hours * frame_rate * 3600); + } else { + hours = ((list.size() > 0) ? list.at(0).toInt() : 0) * frRound * 3600; + minutes = ((list.size() > 1) ? list.at(1).toInt() : 0) * frRound * 60; + seconds = ((list.size() > 2) ? list.at(2).toInt() : 0) * frRound; + frames = (list.size() > 3) ? list.at(3).toInt() : 0; + } int f = (frames + seconds + minutes + hours); - if ((view == TIMECODE_DROP || view == TIMECODE_MILLISECONDS) && frame_rate_is_droppable(frame_rate)) { + if ((view == TIMECODE_DROP || view == TIMECODE_MILLISECONDS) && frame_rate_is_droppable(frame_rate)) { // return drop int d; int m; @@ -161,69 +160,69 @@ long timecode_to_frame(const QString& s, int view, double frame_rate) { } QString frame_to_timecode(long f, int view, double frame_rate) { - if (view == TIMECODE_FRAMES) { - return QString::number(f); - } + if (view == TIMECODE_FRAMES) { + return QString::number(f); + } - // return timecode - int hours = 0; - int mins = 0; - int secs = 0; - int frames = 0; - QString token = ":"; + // return timecode + int hours = 0; + int mins = 0; + int secs = 0; + int frames = 0; + QString token = ":"; - if ((view == TIMECODE_DROP || view == TIMECODE_MILLISECONDS) && 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. + if ((view == TIMECODE_DROP || view == TIMECODE_MILLISECONDS) && 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(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 frqRound64ames 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 + 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 frqRound64ames 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; - } + //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(frame_rate); - frames = f % frRound; - secs = (f / frRound) % 60; - mins = ((f / frRound) / 60) % 60; - hours = (((f / frRound) / 60) / 60); + int frRound = round(frame_rate); + frames = f % frRound; + secs = (f / frRound) % 60; + mins = ((f / frRound) / 60) % 60; + hours = (((f / frRound) / 60) / 60); - token = ";"; - } else { + token = ";"; + } else { // non-drop timecode - int int_fps = qRound(frame_rate); + 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; - } - if (view == TIMECODE_MILLISECONDS) { - return QString::number((hours*3600000)+(mins*60000)+(secs*1000)+qCeil(frames*1000/frame_rate)); - } - return QString(QString::number(hours).rightJustified(2, '0') + - ":" + QString::number(mins).rightJustified(2, '0') + - ":" + QString::number(secs).rightJustified(2, '0') + - token + QString::number(frames).rightJustified(2, '0') - ); + mins = f / (60*int_fps) % 60; + secs = f/int_fps % 60; + frames = f%int_fps; + } + if (view == TIMECODE_MILLISECONDS) { + return QString::number((hours*3600000)+(mins*60000)+(secs*1000)+qCeil(frames*1000/frame_rate)); + } + return QString(QString::number(hours).rightJustified(2, '0') + + ":" + QString::number(mins).rightJustified(2, '0') + + ":" + QString::number(secs).rightJustified(2, '0') + + token + QString::number(frames).rightJustified(2, '0') + ); } bool frame_rate_is_droppable(float rate) { @@ -234,8 +233,8 @@ void Viewer::seek(long p) { pause(); seq->playhead = p; update_parents(); - reset_all_audio(); - audio_scrub = true; + reset_all_audio(); + audio_scrub = true; } void Viewer::go_to_start() { @@ -278,7 +277,7 @@ void Viewer::cue_recording(long start, long end, int track) { void Viewer::uncue_recording() { cue_recording_internal = false; recording_flasher.stop(); - ui->btnPlay->setStyleSheet(QString()); + btnPlay->setStyleSheet(QString()); } bool Viewer::is_recording_cued() { @@ -298,7 +297,7 @@ void Viewer::play() { if (panel_footage_viewer->playing) panel_footage_viewer->pause(); if (seq != NULL) { - reset_all_audio(); + reset_all_audio(); if (is_recording_cued() && !start_recording()) { dout << "[ERROR] Failed to record audio"; return; @@ -316,7 +315,7 @@ void Viewer::play_wake() { if (just_played) { start_msecs = QDateTime::currentMSecsSinceEpoch(); playback_updater.start(); - if (audio_thread != NULL) audio_thread->notifyReceiver(); + if (audio_thread != NULL) audio_thread->notifyReceiver(); just_played = false; } } @@ -336,27 +335,27 @@ void Viewer::pause() { // import audio QStringList file_list; file_list.append(get_recorded_audio_filename()); - panel_project->process_file_list(file_list); + panel_project->process_file_list(file_list); // add it to the sequence Clip* c = new Clip(seq); - Media* m = panel_project->last_imported_media.at(0); - Footage* f = m->to_footage(); + Media* m = panel_project->last_imported_media.at(0); + Footage* f = m->to_footage(); - f->ready_lock.lock(); + f->ready_lock.lock(); - c->media = m; // latest media + c->media = m; // latest media c->media_stream = 0; c->timeline_in = recording_start; - c->timeline_out = f->get_length_in_frames(seq->frame_rate); + c->timeline_out = f->get_length_in_frames(seq->frame_rate); c->clip_in = 0; c->track = recording_track; c->color_r = 128; c->color_g = 192; c->color_b = 128; - c->name = m->get_name(); + c->name = m->get_name(); - f->ready_lock.unlock(); + f->ready_lock.unlock(); QVector add_clips; add_clips.append(c); @@ -366,24 +365,24 @@ void Viewer::pause() { } void Viewer::update_playhead_timecode(long p) { - ui->currentTimecode->set_value(p, false); + currentTimecode->set_value(p, false); } void Viewer::update_end_timecode() { - ui->endTimecode->setText((seq == NULL) ? frame_to_timecode(0, config.timecode_view, 30) : frame_to_timecode(seq->getEndFrame(), config.timecode_view, seq->frame_rate)); + endTimecode->setText((seq == NULL) ? frame_to_timecode(0, config.timecode_view, 30) : frame_to_timecode(seq->getEndFrame(), config.timecode_view, seq->frame_rate)); } void Viewer::update_header_zoom() { if (seq != NULL) { long sequenceEndFrame = seq->getEndFrame(); - if (cached_end_frame != sequenceEndFrame) { - minimum_zoom = (sequenceEndFrame > 0) ? ((double) ui->headers->width() / (double) sequenceEndFrame) : 1; - ui->headers->update_zoom(qMax(ui->headers->get_zoom(), minimum_zoom)); - set_sb_max(); - viewer_widget->waveform_zoom = ui->headers->get_zoom(); - } else { - ui->headers->update(); - } + if (cached_end_frame != sequenceEndFrame) { + minimum_zoom = (sequenceEndFrame > 0) ? ((double) headers->width() / (double) sequenceEndFrame) : 1; + headers->update_zoom(qMax(headers->get_zoom(), minimum_zoom)); + set_sb_max(); + viewer_widget->waveform_zoom = headers->get_zoom(); + } else { + headers->update(); + } } } @@ -392,137 +391,234 @@ void Viewer::update_parents() { update_ui(false); } else { update_viewer(); - } + } } void Viewer::resizeEvent(QResizeEvent *event) { - if (seq != NULL) { - set_sb_max(); - } + if (seq != NULL) { + set_sb_max(); + } } void Viewer::update_viewer() { - update_header_zoom(); + update_header_zoom(); viewer_widget->update(); if (seq != NULL) update_playhead_timecode(seq->playhead); - update_end_timecode(); + update_end_timecode(); } void Viewer::clear_inout_point() { - if (seq->using_workarea) { - undo_stack.push(new SetTimelineInOutCommand(seq, false, 0, 0)); - update_parents(); - } + if (seq->using_workarea) { + undo_stack.push(new SetTimelineInOutCommand(seq, false, 0, 0)); + update_parents(); + } } void Viewer::set_in_point() { - ui->headers->set_in_point(seq->playhead); + headers->set_in_point(seq->playhead); } void Viewer::set_out_point() { - ui->headers->set_out_point(seq->playhead); + headers->set_out_point(seq->playhead); } void Viewer::set_zoom(bool in) { - if (seq != NULL) { - set_zoom_value(in ? ui->headers->get_zoom()*2 : qMax(minimum_zoom, ui->headers->get_zoom()*0.5)); - } + if (seq != NULL) { + set_zoom_value(in ? headers->get_zoom()*2 : qMax(minimum_zoom, headers->get_zoom()*0.5)); + } } void Viewer::set_zoom_value(double d) { - ui->headers->update_zoom(d); - if (viewer_widget->waveform) { - viewer_widget->waveform_zoom = d; - viewer_widget->update(); - } - if (seq != NULL) { - set_sb_max(); - if (!ui->horizontalScrollBar->is_resizing()) - center_scroll_to_playhead(ui->horizontalScrollBar, ui->headers->get_zoom(), seq->playhead); - } + headers->update_zoom(d); + if (viewer_widget->waveform) { + viewer_widget->waveform_zoom = d; + viewer_widget->update(); + } + if (seq != NULL) { + set_sb_max(); + if (!horizontalScrollBar->is_resizing()) + center_scroll_to_playhead(horizontalScrollBar, headers->get_zoom(), seq->playhead); + } } void Viewer::set_sb_max() { - ui->headers->set_scrollbar_max(ui->horizontalScrollBar, seq->getEndFrame(), ui->headers->width()); + headers->set_scrollbar_max(horizontalScrollBar, seq->getEndFrame(), headers->width()); +} + +void Viewer::setup_ui() { + setSizePolicy(QSizePolicy::Maximum, QSizePolicy::Maximum); + + QWidget* contents = new QWidget(); + + QVBoxLayout* layout = new QVBoxLayout(contents); + layout->setSpacing(0); + layout->setMargin(0); + + glViewerPane = new ViewerContainer(contents); + glViewerPane->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); + layout->addWidget(glViewerPane); + + headers = new TimelineHeader(contents); + layout->addWidget(headers); + + horizontalScrollBar = new ResizableScrollBar(contents); + horizontalScrollBar->setSingleStep(20); + horizontalScrollBar->setOrientation(Qt::Horizontal); + layout->addWidget(horizontalScrollBar); + + + QWidget* lower_controls = new QWidget(contents); + + QHBoxLayout* lower_control_layout = new QHBoxLayout(lower_controls); + lower_control_layout->setMargin(0); + + // current time code + QWidget* current_timecode_container = new QWidget(lower_controls); + QHBoxLayout* current_timecode_container_layout = new QHBoxLayout(current_timecode_container); + current_timecode_container_layout->setSpacing(0); + current_timecode_container_layout->setMargin(0); + currentTimecode = new LabelSlider(current_timecode_container); + current_timecode_container_layout->addWidget(currentTimecode); + lower_control_layout->addWidget(current_timecode_container); + + QWidget* playback_controls = new QWidget(lower_controls); + + QHBoxLayout* playback_control_layout = new QHBoxLayout(playback_controls); + playback_control_layout->setSpacing(0); + playback_control_layout->setMargin(0); + + btnSkipToStart = new QPushButton(playback_controls); + QIcon goToStartIcon; + goToStartIcon.addFile(QStringLiteral(":/icons/prev.png"), QSize(), QIcon::Normal, QIcon::Off); + goToStartIcon.addFile(QStringLiteral(":/icons/prev-disabled.png"), QSize(), QIcon::Disabled, QIcon::Off); + btnSkipToStart->setIcon(goToStartIcon); + playback_control_layout->addWidget(btnSkipToStart); + + btnRewind = new QPushButton(playback_controls); + QIcon rewindIcon; + rewindIcon.addFile(QStringLiteral(":/icons/rew.png"), QSize(), QIcon::Normal, QIcon::Off); + rewindIcon.addFile(QStringLiteral(":/icons/rew-disabled.png"), QSize(), QIcon::Disabled, QIcon::Off); + btnRewind->setIcon(rewindIcon); + playback_control_layout->addWidget(btnRewind); + + btnPlay = new QPushButton(playback_controls); + QIcon playIcon; + playIcon.addFile(QStringLiteral(":/icons/play.png"), QSize(), QIcon::Normal, QIcon::Off); + playIcon.addFile(QStringLiteral(":/icons/play-disabled.png"), QSize(), QIcon::Disabled, QIcon::Off); + btnPlay->setIcon(playIcon); + playback_control_layout->addWidget(btnPlay); + + btnFastForward = new QPushButton(playback_controls); + QIcon ffIcon; + ffIcon.addFile(QStringLiteral(":/icons/ff.png"), QSize(), QIcon::Normal, QIcon::On); + ffIcon.addFile(QStringLiteral(":/icons/ff-disabled.png"), QSize(), QIcon::Disabled, QIcon::Off); + btnFastForward->setIcon(ffIcon); + playback_control_layout->addWidget(btnFastForward); + + btnSkipToEnd = new QPushButton(playback_controls); + QIcon nextIcon; + nextIcon.addFile(QStringLiteral(":/icons/next.png"), QSize(), QIcon::Normal, QIcon::Off); + nextIcon.addFile(QStringLiteral(":/icons/next-disabled.png"), QSize(), QIcon::Disabled, QIcon::Off); + btnSkipToEnd->setIcon(nextIcon); + playback_control_layout->addWidget(btnSkipToEnd); + + lower_control_layout->addWidget(playback_controls); + + QWidget* end_timecode_container = new QWidget(lower_controls); + + QHBoxLayout* end_timecode_layout = new QHBoxLayout(end_timecode_container); + end_timecode_layout->setSpacing(0); + end_timecode_layout->setMargin(0); + + endTimecode = new QLabel(end_timecode_container); + endTimecode->setAlignment(Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter); + + end_timecode_layout->addWidget(endTimecode); + + lower_control_layout->addWidget(end_timecode_container); + + layout->addWidget(lower_controls); + + setWidget(contents); } void Viewer::set_media(Media* m) { main_sequence = false; - media = m; - clean_created_seq(); - if (media != NULL) { - switch (media->get_type()) { - case MEDIA_TYPE_FOOTAGE: - { - Footage* footage = media->to_footage(); + media = m; + clean_created_seq(); + if (media != NULL) { + switch (media->get_type()) { + case MEDIA_TYPE_FOOTAGE: + { + Footage* footage = media->to_footage(); - seq = new Sequence(); - created_sequence = true; - seq->wrapper_sequence = true; - seq->name = footage->name; + seq = new Sequence(); + created_sequence = true; + seq->wrapper_sequence = true; + seq->name = footage->name; - seq->using_workarea = footage->using_inout; - if (footage->using_inout) { - seq->workarea_in = footage->in; - seq->workarea_out = footage->out; - } + seq->using_workarea = footage->using_inout; + if (footage->using_inout) { + seq->workarea_in = footage->in; + seq->workarea_out = footage->out; + } - seq->frame_rate = 30; + seq->frame_rate = 30; - if (footage->video_tracks.size() > 0) { - FootageStream* video_stream = footage->video_tracks.at(0); - seq->width = video_stream->video_width; - seq->height = video_stream->video_height; - if (video_stream->video_frame_rate > 0 && !video_stream->infinite_length) seq->frame_rate = video_stream->video_frame_rate; + if (footage->video_tracks.size() > 0) { + FootageStream* video_stream = footage->video_tracks.at(0); + seq->width = video_stream->video_width; + seq->height = video_stream->video_height; + if (video_stream->video_frame_rate > 0 && !video_stream->infinite_length) seq->frame_rate = video_stream->video_frame_rate; - Clip* c = new Clip(seq); - c->media = media; - c->media_stream = video_stream->file_index; - c->timeline_in = 0; - c->timeline_out = footage->get_length_in_frames(seq->frame_rate); - if (c->timeline_out <= 0) c->timeline_out = 150; - c->track = -1; - c->clip_in = 0; - c->recalculateMaxLength(); - seq->clips.append(c); - } else { - seq->width = 1920; - seq->height = 1080; - } + Clip* c = new Clip(seq); + c->media = media; + c->media_stream = video_stream->file_index; + c->timeline_in = 0; + c->timeline_out = footage->get_length_in_frames(seq->frame_rate); + if (c->timeline_out <= 0) c->timeline_out = 150; + c->track = -1; + c->clip_in = 0; + c->recalculateMaxLength(); + seq->clips.append(c); + } else { + seq->width = 1920; + seq->height = 1080; + } - if (footage->audio_tracks.size() > 0) { - FootageStream* audio_stream = footage->audio_tracks.at(0); - seq->audio_frequency = audio_stream->audio_frequency; + if (footage->audio_tracks.size() > 0) { + FootageStream* audio_stream = footage->audio_tracks.at(0); + seq->audio_frequency = audio_stream->audio_frequency; - Clip* c = new Clip(seq); - c->media = media; - c->media_stream = audio_stream->file_index; - c->timeline_in = 0; - c->timeline_out = footage->get_length_in_frames(seq->frame_rate); - c->track = 0; - c->clip_in = 0; - c->recalculateMaxLength(); - seq->clips.append(c); + Clip* c = new Clip(seq); + c->media = media; + c->media_stream = audio_stream->file_index; + c->timeline_in = 0; + c->timeline_out = footage->get_length_in_frames(seq->frame_rate); + c->track = 0; + c->clip_in = 0; + c->recalculateMaxLength(); + seq->clips.append(c); - if (footage->video_tracks.size() == 0) { - viewer_widget->waveform = true; - viewer_widget->waveform_clip = c; - viewer_widget->waveform_ms = audio_stream; - viewer_widget->update(); - } - } else { - seq->audio_frequency = 48000; - } + if (footage->video_tracks.size() == 0) { + viewer_widget->waveform = true; + viewer_widget->waveform_clip = c; + viewer_widget->waveform_ms = audio_stream; + viewer_widget->update(); + } + } else { + seq->audio_frequency = 48000; + } - seq->audio_layout = AV_CH_LAYOUT_STEREO; - } - break; - case MEDIA_TYPE_SEQUENCE: - seq = media->to_sequence(); - break; - } - } - set_sequence(false, seq); + seq->audio_layout = AV_CH_LAYOUT_STEREO; + } + break; + case MEDIA_TYPE_SEQUENCE: + seq = media->to_sequence(); + break; + } + } + set_sequence(false, seq); } void Viewer::on_btnSkipToStart_clicked() { @@ -546,45 +642,45 @@ void Viewer::on_btnPlay_clicked() { } void Viewer::update_playhead() { - seek(ui->currentTimecode->value()); + seek(currentTimecode->value()); } void Viewer::timer_update() { - long previous_playhead = seq->playhead; + long previous_playhead = seq->playhead; - seq->playhead = qRound(playhead_start + ((QDateTime::currentMSecsSinceEpoch()-start_msecs) * 0.001 * seq->frame_rate)); + seq->playhead = qRound(playhead_start + ((QDateTime::currentMSecsSinceEpoch()-start_msecs) * 0.001 * seq->frame_rate)); update_parents(); - long end_frame = (seq->using_workarea && previous_playhead < seq->workarea_out) ? seq->workarea_out : seq->getEndFrame(); - if ((!recording - && playing - && seq->playhead >= end_frame - && previous_playhead < end_frame) - || (recording && recording_start != recording_end && seq->playhead >= recording_end)) { - pause(); - } + long end_frame = (seq->using_workarea && previous_playhead < seq->workarea_out) ? seq->workarea_out : seq->getEndFrame(); + if ((!recording + && playing + && seq->playhead >= end_frame + && previous_playhead < end_frame) + || (recording && recording_start != recording_end && seq->playhead >= recording_end)) { + pause(); + } } void Viewer::recording_flasher_update() { - if (ui->btnPlay->styleSheet().isEmpty()) { - ui->btnPlay->setStyleSheet("background: red;"); + if (btnPlay->styleSheet().isEmpty()) { + btnPlay->setStyleSheet("background: red;"); } else { - ui->btnPlay->setStyleSheet(QString()); - } + btnPlay->setStyleSheet(QString()); + } } void Viewer::resize_move(double d) { - set_zoom_value(ui->headers->get_zoom()*d); + set_zoom_value(headers->get_zoom()*d); } void Viewer::clean_created_seq() { viewer_widget->waveform = false; if (created_sequence) { - // TODO delete undo commands referencing this sequence to avoid crashes - /*for (int i=0;iheaders->setEnabled(!null_sequence); - ui->currentTimecode->setEnabled(!null_sequence); - viewer_widget->setEnabled(!null_sequence); - viewer_widget->setVisible(!null_sequence); - ui->btnSkipToStart->setEnabled(!null_sequence); - ui->btnRewind->setEnabled(!null_sequence); - ui->btnPlay->setEnabled(!null_sequence); - ui->btnFastForward->setEnabled(!null_sequence); - ui->btnSkipToEnd->setEnabled(!null_sequence); + headers->setEnabled(!null_sequence); + currentTimecode->setEnabled(!null_sequence); + viewer_widget->setEnabled(!null_sequence); + viewer_widget->setVisible(!null_sequence); + btnSkipToStart->setEnabled(!null_sequence); + btnRewind->setEnabled(!null_sequence); + btnPlay->setEnabled(!null_sequence); + btnFastForward->setEnabled(!null_sequence); + btnSkipToEnd->setEnabled(!null_sequence); - if (!null_sequence) { - ui->currentTimecode->set_frame_rate(seq->frame_rate); + if (!null_sequence) { + currentTimecode->set_frame_rate(seq->frame_rate); playback_updater.setInterval(qFloor(1000 / seq->frame_rate)); - update_playhead_timecode(seq->playhead); - update_end_timecode(); + update_playhead_timecode(seq->playhead); + update_end_timecode(); - ui->glViewerPane->adjust(); + glViewerPane->adjust(); - setWindowTitle(panel_name + seq->name); - } else { - update_playhead_timecode(0); - update_end_timecode(); + setWindowTitle(panel_name + seq->name); + } else { + update_playhead_timecode(0); + update_end_timecode(); - setWindowTitle(panel_name + "(none)"); - } + setWindowTitle(panel_name + "(none)"); + } update_header_zoom(); viewer_widget->update(); - update(); + update(); } void Viewer::set_playpause_icon(bool play) { - ui->btnPlay->setIcon(QIcon((play) ? ":/icons/play.png" : ":/icons/pause.png")); + btnPlay->setIcon(QIcon((play) ? ":/icons/play.png" : ":/icons/pause.png")); } diff --git a/panels/viewer.h b/panels/viewer.h index 8ca343b3c..78edcd099 100644 --- a/panels/viewer.h +++ b/panels/viewer.h @@ -8,10 +8,12 @@ class Timeline; class ViewerWidget; class Media; struct Sequence; - -namespace Ui { -class Viewer; -} +class TimelineHeader; +class ResizableScrollBar; +class ViewerContainer; +class LabelSlider; +class QPushButton; +class QLabel; bool frame_rate_is_droppable(float rate); long timecode_to_frame(const QString& s, int view, double frame_rate); @@ -26,18 +28,18 @@ public: ~Viewer(); bool is_focused(); - void set_main_sequence(); - void set_media(Media *m); + void set_main_sequence(); + void set_media(Media *m); void compose(); - void set_playpause_icon(bool play); - void update_playhead_timecode(long p); - void update_end_timecode(); + void set_playpause_icon(bool play); + void update_playhead_timecode(long p); + void update_end_timecode(); void update_header_zoom(); void update_viewer(); - void clear_inout_point(); + void clear_inout_point(); void set_in_point(); void set_out_point(); - void set_zoom(bool in); + void set_zoom(bool in); // playback functions void go_to_start(); @@ -56,51 +58,63 @@ public: void cue_recording(long start, long end, int track); void uncue_recording(); - bool is_recording_cued(); + bool is_recording_cued(); long recording_start; long recording_end; - int recording_track; + int recording_track; - void reset_all_audio(); + void reset_all_audio(); void update_parents(); ViewerWidget* viewer_widget; - Media* media; + Media* media; Sequence* seq; - Ui::Viewer *ui; - - void resizeEvent(QResizeEvent *event); + void resizeEvent(QResizeEvent *event); public slots: void play_wake(); private slots: - void on_btnSkipToStart_clicked(); - void on_btnRewind_clicked(); - void on_btnPlay_clicked(); - void on_btnFastForward_clicked(); - void on_btnSkipToEnd_clicked(); + void on_btnSkipToStart_clicked(); + void on_btnRewind_clicked(); + void on_btnPlay_clicked(); + void on_btnFastForward_clicked(); + void on_btnSkipToEnd_clicked(); void update_playhead(); void timer_update(); void recording_flasher_update(); - void resize_move(double d); + void resize_move(double d); private: void clean_created_seq(); - void set_sequence(bool main, Sequence* s); + void set_sequence(bool main, Sequence* s); bool main_sequence; bool created_sequence; - long cached_end_frame; - QString panel_name; - double minimum_zoom; - void set_zoom_value(double d); - void set_sb_max(); + long cached_end_frame; + QString panel_name; + double minimum_zoom; + void set_zoom_value(double d); + void set_sb_max(); + + void setup_ui(); + + TimelineHeader* headers; + ResizableScrollBar* horizontalScrollBar; + ViewerContainer* glViewerPane; + LabelSlider* currentTimecode; + QLabel* endTimecode; + + QPushButton* btnSkipToStart; + QPushButton* btnRewind; + QPushButton* btnPlay; + QPushButton* btnFastForward; + QPushButton* btnSkipToEnd; bool cue_recording_internal; - QTimer recording_flasher; + QTimer recording_flasher; }; #endif // VIEWER_H diff --git a/panels/viewer.ui b/panels/viewer.ui deleted file mode 100644 index 69011823f..000000000 --- a/panels/viewer.ui +++ /dev/null @@ -1,259 +0,0 @@ - - - Viewer - - - - 0 - 0 - 583 - 396 - - - - - 0 - 0 - - - - Viewer - - - - - 0 - - - 0 - - - 0 - - - 0 - - - - - 0 - - - 0 - - - - - - 0 - 0 - - - - - - - - - - - 0 - - - 20 - - - 1826 - - - Qt::Horizontal - - - - - - - - 0 - 0 - - - - - 0 - - - 0 - - - 0 - - - 0 - - - - - - 0 - - - 0 - - - 0 - - - 0 - - - 0 - - - - - 0 - - - - - - - - - - - 0 - - - 0 - - - 0 - - - 0 - - - 0 - - - - - true - - - - :/icons/prev.png - :/icons/prev-disabled.png:/icons/prev.png - - - - - - - - :/icons/rew.png - :/icons/rew-disabled.png:/icons/rew.png - - - - - - - - :/icons/play.png - :/icons/play-disabled.png:/icons/play.png - - - - - - - - :/icons/ff.png - :/icons/ff-disabled.png - - - - - - - - - :/icons/next.png - :/icons/next-disabled.png:/icons/next.png - - - - - - - - - - - 0 - - - 0 - - - 0 - - - 0 - - - 0 - - - - - 0 - - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - - - - - - - - - - - - - - - - TimelineHeader - QWidget -
ui/timelineheader.h
- 1 -
- - ResizableScrollBar - QScrollBar -
ui/resizablescrollbar.h
-
- - ViewerContainer - QWidget -
ui/viewercontainer.h
- 1 -
- - LabelSlider - QLabel -
ui/labelslider.h
-
-
- - - - -
diff --git a/ui/keyframeview.cpp b/ui/keyframeview.cpp index c46dcb0c2..914b979b3 100644 --- a/ui/keyframeview.cpp +++ b/ui/keyframeview.cpp @@ -11,7 +11,7 @@ #include "panels/viewer.h" #include "ui/viewerwidget.h" #include "project/sequence.h" -#include "ui_effectcontrols.h" +#include "ui/resizablescrollbar.h" #include #include @@ -27,44 +27,44 @@ long KeyframeView::adjust_row_keyframe(EffectRow* row, long time) { KeyframeView::KeyframeView(QWidget *parent) : QWidget(parent), - visible_in(0), - visible_out(0), + visible_in(0), + visible_out(0), mousedown(false), dragging(false), keys_selected(false), - select_rect(false), + select_rect(false), x_scroll(0), - y_scroll(0), - scroll_drag(false) + y_scroll(0), + scroll_drag(false) { setFocusPolicy(Qt::ClickFocus); setMouseTracking(true); - setContextMenuPolicy(Qt::CustomContextMenu); - connect(this, SIGNAL(customContextMenuRequested(const QPoint&)), this, SLOT(show_context_menu(const QPoint&))); + setContextMenuPolicy(Qt::CustomContextMenu); + connect(this, SIGNAL(customContextMenuRequested(const QPoint&)), this, SLOT(show_context_menu(const QPoint&))); } void KeyframeView::show_context_menu(const QPoint& pos) { - if (selected_rows.size() > 0) { - QMenu menu(this); - QAction* linear = menu.addAction("Linear"); - linear->setData(KEYFRAME_TYPE_LINEAR); - QAction* smooth = menu.addAction("Smooth"); - smooth->setData(KEYFRAME_TYPE_SMOOTH); - /*QAction* bezier = menu.addAction("Bezier"); - bezier->setData(KEYFRAME_TYPE_BEZIER);*/ - connect(&menu, SIGNAL(triggered(QAction*)), this, SLOT(menu_set_key_type(QAction*))); - menu.exec(mapToGlobal(pos)); - } + if (selected_rows.size() > 0) { + QMenu menu(this); + QAction* linear = menu.addAction("Linear"); + linear->setData(KEYFRAME_TYPE_LINEAR); + QAction* smooth = menu.addAction("Smooth"); + smooth->setData(KEYFRAME_TYPE_SMOOTH); + /*QAction* bezier = menu.addAction("Bezier"); + bezier->setData(KEYFRAME_TYPE_BEZIER);*/ + connect(&menu, SIGNAL(triggered(QAction*)), this, SLOT(menu_set_key_type(QAction*))); + menu.exec(mapToGlobal(pos)); + } } void KeyframeView::menu_set_key_type(QAction* a) { - ComboAction* ca = new ComboAction(); - for (int i=0;iappend(new SetInt(&selected_rows.at(i)->keyframe_types[selected_keyframes.at(i)], a->data().toInt())); - } - undo_stack.push(ca); - update(); + ComboAction* ca = new ComboAction(); + for (int i=0;iappend(new SetInt(&selected_rows.at(i)->keyframe_types[selected_keyframes.at(i)], a->data().toInt())); + } + undo_stack.push(ca); + update(); } void KeyframeView::paintEvent(QPaintEvent*) { @@ -99,7 +99,7 @@ void KeyframeView::paintEvent(QPaintEvent*) { bool keyframe_selected = keyframeIsSelected(row, k); long keyframe_frame = adjust_row_keyframe(row, row->keyframe_times.at(k)); if (dragging && keyframe_selected) keyframe_frame += frame_diff; - draw_keyframe(p, row->keyframe_types.at(k), getScreenPointFromFrame(panel_effect_controls->zoom, keyframe_frame) - x_scroll, keyframe_y, keyframe_selected); + draw_keyframe(p, row->keyframe_types.at(k), getScreenPointFromFrame(panel_effect_controls->zoom, keyframe_frame) - x_scroll, keyframe_y, keyframe_selected); } rows.append(row); @@ -113,7 +113,7 @@ void KeyframeView::paintEvent(QPaintEvent*) { if (max_width < width()) { p.fillRect(QRect(max_width, 0, width(), height()), QColor(0, 0, 0, 64)); } - panel_effect_controls->ui->horizontalScrollBar->setMaximum(qMax(max_width - width(), 0)); + panel_effect_controls->horizontalScrollBar->setMaximum(qMax(max_width - width(), 0)); header->set_visible_in(visible_in); int playhead_x = getScreenPointFromFrame(panel_effect_controls->zoom, sequence->playhead-visible_in) - x_scroll; @@ -129,9 +129,9 @@ void KeyframeView::paintEvent(QPaintEvent*) { draw_selection_rectangle(p, QRect(rect_select_x, rect_select_y, rect_select_w, rect_select_h)); } - /*if (mouseover && mouseover_row < rowY.size()) { + /*if (mouseover && mouseover_row < rowY.size()) { draw_keyframe(p, getScreenPointFromFrame(panel_effect_controls->zoom, mouseover_frame - visible_in), rowY.at(mouseover_row), true); - }*/ + }*/ } bool KeyframeView::keyframeIsSelected(EffectRow *row, int keyframe) { @@ -173,98 +173,98 @@ void KeyframeView::set_y_scroll(int s) { } void KeyframeView::draw_keyframe(QPainter &p, int type, int x, int y, bool darker) { - int color = (darker) ? 100 : 160; - p.setPen(QColor(0, 0, 0)); - p.setBrush(QColor(color, color, color)); + int color = (darker) ? 100 : 160; + p.setPen(QColor(0, 0, 0)); + p.setBrush(QColor(color, color, color)); - switch (type) { - case KEYFRAME_TYPE_LINEAR: - { - QPoint points[KEYFRAME_POINT_COUNT] = {QPoint(x-KEYFRAME_SIZE, y), QPoint(x, y-KEYFRAME_SIZE), QPoint(x+KEYFRAME_SIZE, y), QPoint(x, y+KEYFRAME_SIZE)}; - p.drawPolygon(points, KEYFRAME_POINT_COUNT); - } - break; - case KEYFRAME_TYPE_SMOOTH: - p.drawEllipse(QPoint(x, y), KEYFRAME_SIZE, KEYFRAME_SIZE); - break; - } + switch (type) { + case KEYFRAME_TYPE_LINEAR: + { + QPoint points[KEYFRAME_POINT_COUNT] = {QPoint(x-KEYFRAME_SIZE, y), QPoint(x, y-KEYFRAME_SIZE), QPoint(x+KEYFRAME_SIZE, y), QPoint(x, y+KEYFRAME_SIZE)}; + p.drawPolygon(points, KEYFRAME_POINT_COUNT); + } + break; + case KEYFRAME_TYPE_SMOOTH: + p.drawEllipse(QPoint(x, y), KEYFRAME_SIZE, KEYFRAME_SIZE); + break; + } } void KeyframeView::resize_move(double d) { - header->update_zoom(header->get_zoom()*d); + header->update_zoom(header->get_zoom()*d); } void KeyframeView::mousePressEvent(QMouseEvent *event) { - rect_select_x = event->x(); - rect_select_y = event->y(); + rect_select_x = event->x(); + rect_select_y = event->y(); - if (panel_timeline->tool == TIMELINE_TOOL_HAND || event->buttons() & Qt::MiddleButton) { - scroll_drag = true; - return; - } + if (panel_timeline->tool == TIMELINE_TOOL_HAND || event->buttons() & Qt::MiddleButton) { + scroll_drag = true; + return; + } - int mouse_x = event->x() + x_scroll; - int mouse_y = event->y(); - int row_index = -1; - int keyframe_index = -1; - long frame_diff = 0; - long frame_min = getFrameFromScreenPoint(panel_effect_controls->zoom, mouse_x-KEYFRAME_SIZE); - drag_frame_start = getFrameFromScreenPoint(panel_effect_controls->zoom, mouse_x); - long frame_max = getFrameFromScreenPoint(panel_effect_controls->zoom, mouse_x+KEYFRAME_SIZE); - for (int i=0;i rowY.at(i)-KEYFRAME_SIZE-KEYFRAME_SIZE && mouse_y < rowY.at(i)+KEYFRAME_SIZE+KEYFRAME_SIZE) { - EffectRow* row = rows.at(i); - for (int j=0;jkeyframe_times.size();j++) { - long eval_keyframe_time = row->keyframe_times.at(j)-row->parent_effect->parent_clip->clip_in+(row->parent_effect->parent_clip->timeline_in-visible_in); - if (eval_keyframe_time >= frame_min && eval_keyframe_time <= frame_max) { - long eval_frame_diff = qAbs(eval_keyframe_time - drag_frame_start); - if (keyframe_index == -1 || eval_frame_diff < frame_diff) { - row_index = i; - keyframe_index = j; - frame_diff = eval_frame_diff; - } - } - } - break; - } - } - bool already_selected = false; - keys_selected = false; - if (keyframe_index > -1) already_selected = keyframeIsSelected(rows.at(row_index), keyframe_index); - if (!already_selected) { - if (!(event->modifiers() & Qt::ShiftModifier)) { - selected_rows.clear(); - selected_keyframes.clear(); - } - if (keyframe_index > -1) { - selected_rows.append(rows.at(row_index)); - selected_keyframes.append(keyframe_index); - } - } + int mouse_x = event->x() + x_scroll; + int mouse_y = event->y(); + int row_index = -1; + int keyframe_index = -1; + long frame_diff = 0; + long frame_min = getFrameFromScreenPoint(panel_effect_controls->zoom, mouse_x-KEYFRAME_SIZE); + drag_frame_start = getFrameFromScreenPoint(panel_effect_controls->zoom, mouse_x); + long frame_max = getFrameFromScreenPoint(panel_effect_controls->zoom, mouse_x+KEYFRAME_SIZE); + for (int i=0;i rowY.at(i)-KEYFRAME_SIZE-KEYFRAME_SIZE && mouse_y < rowY.at(i)+KEYFRAME_SIZE+KEYFRAME_SIZE) { + EffectRow* row = rows.at(i); + for (int j=0;jkeyframe_times.size();j++) { + long eval_keyframe_time = row->keyframe_times.at(j)-row->parent_effect->parent_clip->clip_in+(row->parent_effect->parent_clip->timeline_in-visible_in); + if (eval_keyframe_time >= frame_min && eval_keyframe_time <= frame_max) { + long eval_frame_diff = qAbs(eval_keyframe_time - drag_frame_start); + if (keyframe_index == -1 || eval_frame_diff < frame_diff) { + row_index = i; + keyframe_index = j; + frame_diff = eval_frame_diff; + } + } + } + break; + } + } + bool already_selected = false; + keys_selected = false; + if (keyframe_index > -1) already_selected = keyframeIsSelected(rows.at(row_index), keyframe_index); + if (!already_selected) { + if (!(event->modifiers() & Qt::ShiftModifier)) { + selected_rows.clear(); + selected_keyframes.clear(); + } + if (keyframe_index > -1) { + selected_rows.append(rows.at(row_index)); + selected_keyframes.append(keyframe_index); + } + } - if (selected_rows.size() > 0) { - keys_selected = true; - } + if (selected_rows.size() > 0) { + keys_selected = true; + } - update(); + update(); - if (event->button() == Qt::LeftButton) { - mousedown = true; - } + if (event->button() == Qt::LeftButton) { + mousedown = true; + } } void KeyframeView::mouseMoveEvent(QMouseEvent* event) { - if (panel_timeline->tool == TIMELINE_TOOL_HAND) { - setCursor(Qt::OpenHandCursor); - } else { - unsetCursor(); - } - if (scroll_drag) { - panel_effect_controls->ui->horizontalScrollBar->setValue(panel_effect_controls->ui->horizontalScrollBar->value() + rect_select_x - event->pos().x()); - panel_effect_controls->ui->verticalScrollBar->setValue(panel_effect_controls->ui->verticalScrollBar->value() + rect_select_y - event->pos().y()); - rect_select_x = event->pos().x(); - rect_select_y = event->pos().y(); - } else if (mousedown) { + if (panel_timeline->tool == TIMELINE_TOOL_HAND) { + setCursor(Qt::OpenHandCursor); + } else { + unsetCursor(); + } + if (scroll_drag) { + panel_effect_controls->horizontalScrollBar->setValue(panel_effect_controls->horizontalScrollBar->value() + rect_select_x - event->pos().x()); + panel_effect_controls->verticalScrollBar->setValue(panel_effect_controls->verticalScrollBar->value() + rect_select_y - event->pos().y()); + rect_select_x = event->pos().x(); + rect_select_y = event->pos().y(); + } else if (mousedown) { int mouse_x = event->x() + x_scroll; if (keys_selected) { // move keyframes @@ -333,7 +333,7 @@ void KeyframeView::mouseMoveEvent(QMouseEvent* event) { select_rect = true; } update(); - } + } } void KeyframeView::mouseReleaseEvent(QMouseEvent*) { @@ -347,8 +347,8 @@ void KeyframeView::mouseReleaseEvent(QMouseEvent*) { select_rect = false; dragging = false; - mousedown = false; - scroll_drag = false; + mousedown = false; + scroll_drag = false; panel_timeline->snapped = false; update(); } diff --git a/ui/resizablescrollbar.cpp b/ui/resizablescrollbar.cpp index 0bde2cfeb..f08bba77e 100644 --- a/ui/resizablescrollbar.cpp +++ b/ui/resizablescrollbar.cpp @@ -9,96 +9,98 @@ #define RESIZE_HANDLE_SIZE 10 ResizableScrollBar::ResizableScrollBar(QWidget *parent) : - QScrollBar(parent), - resize_init(false), - resize_proc(false) + QScrollBar(parent), + resize_init(false), + resize_proc(false) { - setMouseTracking(true); + setSingleStep(20); + setMaximum(0); + setMouseTracking(true); } bool ResizableScrollBar::is_resizing() { - return resize_proc; + return resize_proc; } void ResizableScrollBar::resizeEvent(QResizeEvent *event) { - setPageStep(event->size().width()); + setPageStep(event->size().width()); } void ResizableScrollBar::mousePressEvent(QMouseEvent *e) { - if (resize_init) { - QStyleOptionSlider opt; - initStyleOption(&opt); + if (resize_init) { + QStyleOptionSlider opt; + initStyleOption(&opt); - QRect sr = style()->subControlRect(QStyle::CC_ScrollBar, &opt, - QStyle::SC_ScrollBarSlider, this); + QRect sr = style()->subControlRect(QStyle::CC_ScrollBar, &opt, + QStyle::SC_ScrollBarSlider, this); - resize_proc = true; - resize_start = e->pos().x(); + resize_proc = true; + resize_start = e->pos().x(); - resize_start_max = maximum(); - resize_start_width = sr.width(); - } else { - QScrollBar::mousePressEvent(e); - } + resize_start_max = maximum(); + resize_start_width = sr.width(); + } else { + QScrollBar::mousePressEvent(e); + } } void ResizableScrollBar::mouseMoveEvent(QMouseEvent *e) { - QStyleOptionSlider opt; - initStyleOption(&opt); + QStyleOptionSlider opt; + initStyleOption(&opt); - QRect sr = style()->subControlRect(QStyle::CC_ScrollBar, &opt, - QStyle::SC_ScrollBarSlider, this); - QRect gr = style()->subControlRect(QStyle::CC_ScrollBar, &opt, - QStyle::SC_ScrollBarGroove, this); + QRect sr = style()->subControlRect(QStyle::CC_ScrollBar, &opt, + QStyle::SC_ScrollBarSlider, this); + QRect gr = style()->subControlRect(QStyle::CC_ScrollBar, &opt, + QStyle::SC_ScrollBarGroove, this); - if (resize_proc) { - int diff = (e->pos().x() - resize_start); - if (resize_top) diff = -diff; - double scale = double(sr.width())/double(sr.width()+diff); - if (!qIsInf(scale) && !qIsNull(scale)) { - emit resize_move(scale); - resize_start = e->pos().x(); + if (resize_proc) { + int diff = (e->pos().x() - resize_start); + if (resize_top) diff = -diff; + double scale = double(sr.width())/double(sr.width()+diff); + if (!qIsInf(scale) && !qIsNull(scale)) { + emit resize_move(scale); + resize_start = e->pos().x(); - if (resize_top) { - int slider_min = gr.x(); - int slider_max = gr.right() - (sr.width()+diff); - int val = QStyle::sliderValueFromPosition(minimum(), maximum(), e->pos().x() - slider_min, slider_max - slider_min, opt.upsideDown); + if (resize_top) { + int slider_min = gr.x(); + int slider_max = gr.right() - (sr.width()+diff); + int val = QStyle::sliderValueFromPosition(minimum(), maximum(), e->pos().x() - slider_min, slider_max - slider_min, opt.upsideDown); - setValue(val); - } else { - setValue(qRound(value() * scale)); - } - } - } else { - bool new_resize_init = false; + setValue(val); + } else { + setValue(qRound(value() * scale)); + } + } + } else { + bool new_resize_init = false; - if ((orientation() == Qt::Horizontal && e->pos().x() > sr.left()-RESIZE_HANDLE_SIZE && e->pos().x() < sr.left()+RESIZE_HANDLE_SIZE) - || (orientation() == Qt::Vertical && e->pos().y() > sr.top()-RESIZE_HANDLE_SIZE && e->pos().y() < sr.top()+RESIZE_HANDLE_SIZE)) { - new_resize_init = true; - resize_top = true; - } else if ((orientation() == Qt::Horizontal && e->pos().x() > sr.right()-RESIZE_HANDLE_SIZE && e->pos().x() < sr.right()+RESIZE_HANDLE_SIZE) - || (orientation() == Qt::Vertical && e->pos().y() > sr.bottom()-RESIZE_HANDLE_SIZE && e->pos().y() < sr.bottom()+RESIZE_HANDLE_SIZE)) { - new_resize_init = true; - resize_top = false; - } + if ((orientation() == Qt::Horizontal && e->pos().x() > sr.left()-RESIZE_HANDLE_SIZE && e->pos().x() < sr.left()+RESIZE_HANDLE_SIZE) + || (orientation() == Qt::Vertical && e->pos().y() > sr.top()-RESIZE_HANDLE_SIZE && e->pos().y() < sr.top()+RESIZE_HANDLE_SIZE)) { + new_resize_init = true; + resize_top = true; + } else if ((orientation() == Qt::Horizontal && e->pos().x() > sr.right()-RESIZE_HANDLE_SIZE && e->pos().x() < sr.right()+RESIZE_HANDLE_SIZE) + || (orientation() == Qt::Vertical && e->pos().y() > sr.bottom()-RESIZE_HANDLE_SIZE && e->pos().y() < sr.bottom()+RESIZE_HANDLE_SIZE)) { + new_resize_init = true; + resize_top = false; + } - if (resize_init != new_resize_init) { - if (new_resize_init) { - setCursor(Qt::SizeHorCursor); - } else { - unsetCursor(); - } - resize_init = new_resize_init; - } + if (resize_init != new_resize_init) { + if (new_resize_init) { + setCursor(Qt::SizeHorCursor); + } else { + unsetCursor(); + } + resize_init = new_resize_init; + } - QScrollBar::mouseMoveEvent(e); - } + QScrollBar::mouseMoveEvent(e); + } } void ResizableScrollBar::mouseReleaseEvent(QMouseEvent *e) { - if (resize_proc) { - resize_proc = false; - } else { - QScrollBar::mouseReleaseEvent(e); - } + if (resize_proc) { + resize_proc = false; + } else { + QScrollBar::mouseReleaseEvent(e); + } }