Merge branch 'master' into pr/1875

This commit is contained in:
itsmattkc
2022-05-03 18:51:59 -07:00
84 changed files with 1005 additions and 574 deletions
+3 -2
View File
@@ -39,7 +39,8 @@ NodeParamView::NodeParamView(bool create_keyframe_view, QWidget *parent) :
super(true, false, parent),
last_scroll_val_(0),
focused_node_(nullptr),
time_target_(nullptr)
time_target_(nullptr),
show_all_nodes_(false)
{
// Create horizontal layout to place scroll area in (and keyframe editing eventually)
QHBoxLayout* layout = new QHBoxLayout(this);
@@ -453,7 +454,7 @@ void NodeParamView::RemoveContext(Node *ctx)
void NodeParamView::AddNode(Node *n, Node *ctx, NodeParamViewContext *context)
{
if ((n->GetFlags() & Node::kDontShowInParamView) && !IsGroupMode()) {
if ((n->GetFlags() & Node::kDontShowInParamView) && !IsGroupMode() && !show_all_nodes_) {
return;
}
+2
View File
@@ -143,6 +143,8 @@ private:
QVector<Node*> contexts_;
QVector<Node*> current_contexts_;
bool show_all_nodes_;
private slots:
void UpdateGlobalScrollBar();
@@ -26,6 +26,7 @@
#include <QVector3D>
#include <QVector4D>
#include "common/qtutils.h"
#include "core.h"
#include "node/node.h"
#include "node/project/sequence/sequence.h"
@@ -86,11 +87,6 @@ void NodeParamViewWidgetBridge::CreateWidgets()
case NodeValue::kTexture:
case NodeValue::kMatrix:
case NodeValue::kSamples:
case NodeValue::kFootageJob:
case NodeValue::kShaderJob:
case NodeValue::kSampleJob:
case NodeValue::kGenerateJob:
case NodeValue::kColorTransformJob:
case NodeValue::kVideoParams:
case NodeValue::kAudioParams:
case NodeValue::kDataTypeCount:
@@ -241,11 +237,6 @@ void NodeParamViewWidgetBridge::WidgetCallback()
case NodeValue::kTexture:
case NodeValue::kMatrix:
case NodeValue::kSamples:
case NodeValue::kFootageJob:
case NodeValue::kShaderJob:
case NodeValue::kSampleJob:
case NodeValue::kGenerateJob:
case NodeValue::kColorTransformJob:
case NodeValue::kVideoParams:
case NodeValue::kAudioParams:
case NodeValue::kDataTypeCount:
@@ -396,6 +387,10 @@ void NodeParamViewWidgetBridge::CreateSliders(int count)
T* fs = new T();
fs->SliderBase::SetDefaultValue(GetInnerInput().GetSplitDefaultValueForTrack(i));
fs->SetLadderElementCount(2);
// HACK: Force some spacing between sliders
fs->setContentsMargins(0, 0, QtUtils::QFontMetricsWidth(fs->fontMetrics(), QStringLiteral(" ")), 0);
widgets_.append(fs);
connect(fs, &T::ValueChanged, this, &NodeParamViewWidgetBridge::WidgetCallback);
}
@@ -419,11 +414,6 @@ void NodeParamViewWidgetBridge::UpdateWidgetValues()
case NodeValue::kTexture:
case NodeValue::kMatrix:
case NodeValue::kSamples:
case NodeValue::kFootageJob:
case NodeValue::kShaderJob:
case NodeValue::kSampleJob:
case NodeValue::kGenerateJob:
case NodeValue::kColorTransformJob:
case NodeValue::kVideoParams:
case NodeValue::kAudioParams:
case NodeValue::kDataTypeCount:
@@ -139,10 +139,6 @@ void NodeTableView::SetTime(const rational &time)
switch (value.type()) {
case NodeValue::kVideoParams:
case NodeValue::kAudioParams:
case NodeValue::kFootageJob:
case NodeValue::kShaderJob:
case NodeValue::kSampleJob:
case NodeValue::kGenerateJob:
// These types have no string representation
break;
case NodeValue::kTexture:
+46 -7
View File
@@ -97,6 +97,8 @@ ProjectExplorer::ProjectExplorer(QWidget *parent) :
connect(tree_view_, &ProjectExplorerTreeView::customContextMenuRequested, this, &ProjectExplorer::ShowContextMenu);
connect(list_view_, &ProjectExplorerListView::customContextMenuRequested, this, &ProjectExplorer::ShowContextMenu);
connect(icon_view_, &ProjectExplorerIconView::customContextMenuRequested, this, &ProjectExplorer::ShowContextMenu);
UpdateNavBarText();
}
const ProjectToolbar::ViewType &ProjectExplorer::view_type() const
@@ -151,13 +153,7 @@ void ProjectExplorer::BrowseToFolder(const QModelIndex &index)
list_view_->setRootIndex(index);
// Set navbar text to folder's name
if (index.isValid()) {
Folder* f = static_cast<Folder*>(sort_model_.mapToSource(index).internalPointer());
nav_bar_->set_text(f->GetLabel());
} else {
// Or set it to an empty string if the index is valid (which means we're browsing to the root directory)
nav_bar_->set_text(QString());
}
UpdateNavBarText();
// Set directory up enabled button based on whether we're in root or not
nav_bar_->set_dir_up_enabled(index.isValid());
@@ -246,6 +242,21 @@ QString ProjectExplorer::GetHumanReadableNodeName(Node *node)
}
}
void ProjectExplorer::UpdateNavBarText()
{
QString absolute;
Folder* f = static_cast<Folder*>(sort_model_.mapToSource(list_view_->rootIndex()).internalPointer());
while (f && f != project()->root()) {
absolute.prepend(QStringLiteral("%1 / ").arg(f->GetLabel()));
f = f->folder();
}
absolute.prepend(QStringLiteral("/ "));
nav_bar_->set_text(absolute);
}
QAbstractItemView *ProjectExplorer::CurrentView() const
{
return static_cast<QAbstractItemView*>(stacked_widget_->currentWidget());
@@ -667,4 +678,32 @@ void ProjectExplorer::DeleteSelected()
}
}
bool ProjectExplorer::SelectItem(Node *n)
{
DeselectAll();
QModelIndex index = model_.CreateIndexFromItem(n);
if (index.isValid()) {
index = sort_model_.mapFromSource(index);
QModelIndex parent = index.parent();
if (view_type() == ProjectToolbar::TreeView) {
// Expand all folders until this index is visible
while (parent.isValid()) {
tree_view_->expand(parent);
parent = parent.parent();
}
} else {
BrowseToFolder(parent);
}
CurrentView()->selectionModel()->select(index, QItemSelectionModel::Select | QItemSelectionModel::Rows);
return true;
}
return false;
}
}
@@ -85,6 +85,8 @@ public:
void DeleteSelected();
bool SelectItem(Node *n);
public slots:
void set_view_type(ProjectToolbar::ViewType type);
@@ -138,6 +140,8 @@ private:
static QString GetHumanReadableNodeName(Node* node);
void UpdateNavBarText();
/**
* @brief Get the currently active QAbstractItemView
*/
+1
View File
@@ -21,6 +21,7 @@ set(OLIVE_SOURCES
widget/standardcombos/interlacedcombobox.h
widget/standardcombos/pixelaspectratiocombobox.h
widget/standardcombos/pixelformatcombobox.h
widget/standardcombos/sampleformatcombobox.h
widget/standardcombos/sampleratecombobox.h
widget/standardcombos/standardcombos.h
widget/standardcombos/videodividercombobox.h
@@ -0,0 +1,87 @@
/***
Olive - Non-Linear Video Editor
Copyright (C) 2021 Olive Team
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
***/
#ifndef SAMPLEFORMATCOMBOBOX_H
#define SAMPLEFORMATCOMBOBOX_H
#include <QComboBox>
#include "render/audioparams.h"
namespace olive {
class SampleFormatComboBox : public QComboBox
{
Q_OBJECT
public:
SampleFormatComboBox(QWidget* parent = nullptr) :
QComboBox(parent),
attempt_to_restore_format_(true)
{
}
void SetAttemptToRestoreFormat(bool e) { attempt_to_restore_format_ = e; }
void SetAvailableFormats(const std::vector<AudioParams::Format> &formats)
{
AudioParams::Format tmp = AudioParams::kFormatInvalid;
if (attempt_to_restore_format_) {
tmp = GetSampleFormat();
}
clear();
foreach (const AudioParams::Format &of, formats) {
AddFormatItem(of);
}
if (attempt_to_restore_format_) {
SetSampleFormat(tmp);
}
}
AudioParams::Format GetSampleFormat() const
{
return static_cast<AudioParams::Format>(this->currentData().toInt());
}
void SetSampleFormat(AudioParams::Format fmt)
{
for (int i=0; i<this->count(); i++) {
if (this->itemData(i).toInt() == fmt) {
this->setCurrentIndex(i);
break;
}
}
}
private:
void AddFormatItem(AudioParams::Format f)
{
this->addItem(AudioParams::FormatToString(f), f);
}
bool attempt_to_restore_format_;
};
}
#endif // SAMPLEFORMATCOMBOBOX_H
@@ -26,6 +26,7 @@
#include "interlacedcombobox.h"
#include "pixelaspectratiocombobox.h"
#include "pixelformatcombobox.h"
#include "sampleformatcombobox.h"
#include "sampleratecombobox.h"
#include "videodividercombobox.h"
@@ -1071,6 +1071,14 @@ void TimelineWidget::ShowContextMenu()
menu.addSeparator();
if (ClipBlock *clip = dynamic_cast<ClipBlock*>(selected.first())) {
if (clip->connected_viewer()) {
QAction *reveal_in_project = menu.addAction(tr("Reveal in Project"));
reveal_in_project->setData(reinterpret_cast<quintptr>(clip->connected_viewer()));
connect(reveal_in_project, &QAction::triggered, this, &TimelineWidget::RevealInProject);
}
}
QAction* properties_action = menu.addAction(tr("Properties"));
connect(properties_action, &QAction::triggered, this, &TimelineWidget::ShowSpeedDurationDialogForSelectedClips);
}
@@ -1215,6 +1223,15 @@ void TimelineWidget::SignalBlockSelectionChange()
signal_block_change_timer_->start();
}
void TimelineWidget::RevealInProject()
{
QAction *a = static_cast<QAction*>(sender());
ViewerOutput *item_to_reveal = reinterpret_cast<ViewerOutput*>(a->data().value<quintptr>());
emit RevealViewerInProject(item_to_reveal);
}
void TimelineWidget::AddGhost(TimelineViewGhostItem *ghost)
{
ghost_items_.append(ghost);
@@ -269,6 +269,8 @@ signals:
void RequestCaptureStart(const TimeRange &time, const Track::Reference &track);
void RevealViewerInProject(ViewerOutput *r);
protected:
virtual void resizeEvent(QResizeEvent *event) override;
@@ -410,6 +412,8 @@ private slots:
void SignalBlockSelectionChange();
void RevealInProject();
};
}
+1 -1
View File
@@ -21,7 +21,7 @@ void RecordTool::MousePress(TimelineViewMouseEvent *event)
return;
}
if (t->type() != Track::kAudio) {
if (t && t->type() != Track::kAudio) {
// We only support audio tracks here
return;
}
+1 -1
View File
@@ -252,7 +252,7 @@ void SeekableWidget::SeekToScenePoint(qreal scene)
return;
}
rational playhead_time = SceneToTime(scene);
rational playhead_time = qMax(rational(0), SceneToTime(scene));
if (Core::instance()->snapping() && GetSnapService()) {
rational movement;
+25 -4
View File
@@ -388,7 +388,6 @@ void ViewerWidget::StartCapture(TimelineWidget *source, const TimeRange &time, c
SetTimeAndSignal(time.in());
ArmForRecording();
recording_filename_ = QStringLiteral("/home/matt/Desktop/ass.mp3");
recording_callback_ = source;
recording_range_ = time;
recording_track_ = track;
@@ -1167,7 +1166,31 @@ void ViewerWidget::Play(bool in_to_out_only)
in_to_out_only = false;
}
} else if (record_armed_) {
if (AudioManager::instance()->StartRecording(recording_filename_, GetConnectedNode()->GetAudioParams())) {
DisarmRecording();
if (GetConnectedNode()->project()->filename().isEmpty()) {
QMessageBox::critical(this, tr("Audio Recording"), tr("Project must be saved before you can record audio."));
return;
}
QDir audio_path(QFileInfo(GetConnectedNode()->project()->filename()).dir().filePath(tr("audio")));
if (!audio_path.exists()) {
audio_path.mkpath(QStringLiteral("."));
}
recording_filename_ = audio_path.filePath(QStringLiteral("%1.%2").arg(
QDateTime::currentDateTime().toString("yyyy-MM-dd hh-mm-ss"),
ExportFormat::GetExtension(static_cast<ExportFormat::Format>(Config::Current()[QStringLiteral("AudioRecordingFormat")].toInt())))
);
AudioParams ap(OLIVE_CONFIG("AudioRecordingSampleRate").toInt(), OLIVE_CONFIG("AudioRecordingChannelLayout").toULongLong(), static_cast<AudioParams::Format>(OLIVE_CONFIG("AudioRecordingSampleFormat").toInt()));
EncodingParams encode_param;
encode_param.EnableAudio(ap, static_cast<ExportCodec::Codec>(OLIVE_CONFIG("AudioRecordingCodec").toInt()));
encode_param.SetFilename(recording_filename_);
encode_param.set_audio_bit_rate(OLIVE_CONFIG("AudioRecordingBitRate").toInt() * 1000);
if (AudioManager::instance()->StartRecording(encode_param)) {
recording_ = true;
controls_->SetPauseButtonRecordingState(true);
recording_callback_->EnableRecordingOverlay(TimelineCoordinate(recording_range_.in(), recording_track_));
@@ -1175,8 +1198,6 @@ void ViewerWidget::Play(bool in_to_out_only)
QMessageBox::critical(this, tr("Audio Recording"), tr("Failed to start audio recording"));
return;
}
DisarmRecording();
}
PlayInternal(1, in_to_out_only);