Merge branch 'master' into multicam

This commit is contained in:
itsmattkc
2022-09-29 21:18:30 -07:00
17 changed files with 191 additions and 171 deletions
+27 -16
View File
@@ -90,6 +90,15 @@ void AudioVisualWaveform::OverwriteSamplesFromMipmap(const AudioVisualWaveform::
input_length = samples_length;
}
void AudioVisualWaveform::ValidateVirtualStart(const rational &new_start)
{
if (length_ == 0) {
virtual_start_ = new_start;
} else if (virtual_start_ > new_start) {
TrimIn(new_start - virtual_start_);
}
}
void AudioVisualWaveform::OverwriteSamples(const SampleBuffer &samples, int sample_rate, const rational &start)
{
if (!channels_) {
@@ -97,18 +106,12 @@ void AudioVisualWaveform::OverwriteSamples(const SampleBuffer &samples, int samp
return;
}
// Old less optimized code. Keeping this around as a reference, but the below code is at least
// 10x faster so this shouldn't be used in production.
//
// size_t input_start, input_length;
// for (auto it=mipmapped_data_.begin(); it!=mipmapped_data_.end(); it++) {
// OverwriteSamplesFromBuffer(samples, sample_rate, start, it->first.toDouble(), it->second, input_start, input_length);
// }
ValidateVirtualStart(start);
// Process the largest mipmap directly for the samples
auto current_mipmap = mipmapped_data_.rbegin();
size_t input_start, input_length;
OverwriteSamplesFromBuffer(samples, sample_rate, start, current_mipmap->first.toDouble(), current_mipmap->second, input_start, input_length);
OverwriteSamplesFromBuffer(samples, sample_rate, start - virtual_start_, current_mipmap->first.toDouble(), current_mipmap->second, input_start, input_length);
while (true) {
// For each smaller mipmap, we just process from the mipmap before it, making each one
@@ -120,7 +123,7 @@ void AudioVisualWaveform::OverwriteSamples(const SampleBuffer &samples, int samp
}
OverwriteSamplesFromMipmap(previous_mipmap->second, previous_mipmap->first.toDouble(),
input_start, input_length, start, current_mipmap->first.toDouble(),
input_start, input_length, start - virtual_start_, current_mipmap->first.toDouble(),
current_mipmap->second);
}
@@ -130,6 +133,8 @@ void AudioVisualWaveform::OverwriteSamples(const SampleBuffer &samples, int samp
void AudioVisualWaveform::OverwriteSums(const AudioVisualWaveform &sums, const rational &dest, const rational& offset, const rational& length)
{
ValidateVirtualStart(dest);
for (auto it=mipmapped_data_.begin(); it!=mipmapped_data_.end(); it++) {
rational rate = it->first;
@@ -139,7 +144,7 @@ void AudioVisualWaveform::OverwriteSums(const AudioVisualWaveform &sums, const r
double rate_dbl = rate.toDouble();
// Get our destination sample
size_t our_start_index = time_to_samples(dest, rate_dbl);
size_t our_start_index = time_to_samples(dest - virtual_start_, rate_dbl);
// Get our source sample
size_t their_start_index = time_to_samples(offset, rate_dbl);
@@ -172,6 +177,8 @@ void AudioVisualWaveform::OverwriteSums(const AudioVisualWaveform &sums, const r
void AudioVisualWaveform::OverwriteSilence(const rational &start, const rational &length)
{
ValidateVirtualStart(start);
for (auto it=mipmapped_data_.begin(); it!=mipmapped_data_.end(); it++) {
rational rate = it->first;
@@ -180,7 +187,7 @@ void AudioVisualWaveform::OverwriteSilence(const rational &start, const rational
double rate_dbl = rate.toDouble();
// Get our destination sample
size_t our_start_index = time_to_samples(start, rate_dbl);
size_t our_start_index = time_to_samples(start - virtual_start_, rate_dbl);
size_t our_length_index = time_to_samples(length, rate_dbl);
size_t our_end_index = our_start_index + our_length_index;
@@ -190,6 +197,8 @@ void AudioVisualWaveform::OverwriteSilence(const rational &start, const rational
memset(reinterpret_cast<char*>(our_arr.data()) + our_start_index * sizeof(SamplePerChannel), 0, our_length_index * sizeof(SamplePerChannel));
}
length_ = qMax(length_, start + length);
}
void AudioVisualWaveform::TrimIn(rational length)
@@ -198,6 +207,8 @@ void AudioVisualWaveform::TrimIn(rational length)
return;
}
virtual_start_ += length;
bool negative = (length < 0);
if (negative) {
length = -length;
@@ -225,9 +236,9 @@ void AudioVisualWaveform::TrimIn(rational length)
AudioVisualWaveform AudioVisualWaveform::Mid(const rational &offset) const
{
AudioVisualWaveform mid = *this;
AudioVisualWaveform mid = *this;
mid.TrimIn(offset);
mid.TrimIn(offset - virtual_start_);
return mid;
}
@@ -236,7 +247,7 @@ AudioVisualWaveform AudioVisualWaveform::Mid(const rational &offset, const ratio
{
AudioVisualWaveform mid = *this;
mid.TrimRange(offset, length);
mid.TrimRange(offset - virtual_start_, length);
return mid;
}
@@ -273,7 +284,7 @@ AudioVisualWaveform::Sample AudioVisualWaveform::GetSummaryFromTime(const ration
double rate_dbl = using_mipmap->first.toDouble();
size_t start_sample = time_to_samples(start, rate_dbl);
size_t start_sample = time_to_samples(start - virtual_start_, rate_dbl);
size_t sample_length = time_to_samples(length, rate_dbl);
const Sample &mipmap_data = using_mipmap->second;
@@ -421,7 +432,7 @@ void AudioVisualWaveform::DrawWaveform(QPainter *painter, const QRect& rect, con
double rate_dbl = rate.toDouble();
const Sample& arr = using_mipmap->second;
size_t start_sample_index = samples.time_to_samples(start_time, rate_dbl);
size_t start_sample_index = samples.time_to_samples(start_time - samples.virtual_start_, rate_dbl);
if (start_sample_index >= arr.size()) {
return;
+4
View File
@@ -123,6 +123,10 @@ private:
std::map<rational, Sample>::const_iterator GetMipmapForScale(double scale) const;
void ValidateVirtualStart(const rational &new_start);
rational virtual_start_;
int channels_;
std::map<rational, Sample> mipmapped_data_;
+11
View File
@@ -126,6 +126,17 @@ public:
return false;
}
bool OverlapsWith(const TimeRange& r, bool in_inclusive = true, bool out_inclusive = true) const
{
for (const TimeRange &range : array_) {
if (range.OverlapsWith(r, in_inclusive, out_inclusive)) {
return true;
}
}
return false;
}
bool isEmpty() const
{
return array_.isEmpty();
@@ -59,7 +59,7 @@ void GeneratorWithMerge::PushMergableJob(const NodeValueRow &value, TexturePtr j
merge.SetShaderID(QStringLiteral("mrg"));
merge.Insert(MergeNode::kBaseIn, value[kBaseInput]);
merge.Insert(MergeNode::kBlendIn, NodeValue(NodeValue::kTexture, base->toJob(*job->job()), this));
merge.Insert(MergeNode::kBlendIn, NodeValue(NodeValue::kTexture, job, this));
table->Push(NodeValue::kTexture, base->toJob(merge), this);
} else {
+51 -70
View File
@@ -22,113 +22,94 @@
namespace olive {
#define super PlaybackCache
AudioWaveformCache::AudioWaveformCache(QObject *parent) :
PlaybackCache{parent}
super{parent}
{
waveforms_ = std::make_shared<AudioVisualWaveform>();
}
void AudioWaveformCache::WriteWaveform(const TimeRange &range, const TimeRangeList &valid_ranges, const AudioVisualWaveform *waveform)
{
// Write each valid range to the segments
foreach (const TimeRange& r, valid_ranges) {
#ifdef AVW_USE_LIST
// Write visual
TimeRangeList::util_remove(&waveforms_, r);
if (waveform) {
TimeRangeWithWaveform wv = r;
rational local_start = r.in() - range.in();
if (local_start != 0) {
wv.waveform = waveform->Mid(local_start, r.length());
} else {
wv.waveform = *waveform;
}
waveforms_.append(wv);
waveforms_->OverwriteSums(*waveform, r.in(), r.in() - range.in(), r.length());
}
#else
if (waveform) {
waveforms_.OverwriteSums(*waveform, r.in(), r.in() - range.in(), r.length());
}
#endif
Validate(r);
}
}
void DrawSubRect(QPainter *painter, const QRect &rect, const double &scale, const TimeRange &wave_range, const AudioVisualWaveform &waveform, const TimeRange &subrange)
{
// Find start time of passthrough
TimeRange intersect = wave_range.Intersected(subrange);
// Create new rect that starts at the offset of pass_start from start_time
// Set rect width to either length of passthrough or until the end
QRect pass_rect(rect.x() + (intersect.in() - wave_range.in()).toDouble() * scale,
rect.y(),
intersect.length().toDouble() * scale,
rect.height());
// Draw waveform with this info
AudioVisualWaveform::DrawWaveform(painter, pass_rect, scale, waveform, intersect.in());
}
void AudioWaveformCache::Draw(QPainter *painter, const QRect &rect, const double &scale, const rational &start_time) const
{
rational end = start_time + rational::fromDouble(rect.width() / scale);
TimeRange draw_range(start_time, end);
if (!passthroughs_.empty()) {
TimeRange wave_range(start_time, start_time + rational::fromDouble(rect.width() / scale));
TimeRangeList draw_range = {wave_range};
for (const WaveformPassthrough &p : passthroughs_) {
if (draw_range.OverlapsWith(p, true, false)) {
DrawSubRect(painter, rect, scale, wave_range, *p.waveform, p);
#ifdef AVW_USE_LIST
foreach (const TimeRangeWithWaveform &wv, waveforms_) {
if (wv.OverlapsWith(draw_range)) {
rational substart = std::max(wv.in(), draw_range.in());
rational subend = std::min(wv.out(), draw_range.out());
QRect subrect = rect;
subrect.setLeft(subrect.left() + (substart - draw_range.in()).toDouble()*scale);
subrect.setWidth((subend - substart).toDouble()*scale);
rational local_start = substart - wv.in();
AudioVisualWaveform::DrawWaveform(painter, subrect, scale, wv.waveform, local_start);
// Remove this range
draw_range.remove(p);
}
}
for (const TimeRange &r : draw_range) {
DrawSubRect(painter, rect, scale, wave_range, *waveforms_, r);
}
} else {
AudioVisualWaveform::DrawWaveform(painter, rect, scale, *waveforms_, start_time);
}
#else
AudioVisualWaveform::DrawWaveform(painter, rect, scale, waveforms_, start_time);
#endif
}
AudioVisualWaveform::Sample AudioWaveformCache::GetSummaryFromTime(const rational &start, const rational &length) const
{
#ifdef AVW_USE_LIST
QMap<rational, AudioVisualWaveform::Sample> sample;
TimeRange acquire(start, start+length);
foreach (const TimeRangeWithWaveform &wv, waveforms_) {
if (wv.OverlapsWith(acquire)) {
TimeRange this_range = wv.Intersected(acquire);
auto sum = wv.waveform.GetSummaryFromTime(this_range.in() - wv.in(), this_range.length());
sample.insert(this_range.in(), sum);
}
}
AudioVisualWaveform::Sample result;
for (auto it=sample.cbegin(); it!=sample.cend(); it++) {
result.insert(result.end(), it.value().begin(), it.value().end());
}
return result;
#else
return waveforms_.GetSummaryFromTime(start, length);
#endif
return waveforms_->GetSummaryFromTime(start, length);
}
rational AudioWaveformCache::length() const
{
#ifdef AVW_USE_LIST
rational len = 0;
foreach (const TimeRangeWithWaveform &wv, waveforms_) {
len = std::max(len, wv.out());
}
return len;
#else
return waveforms_.length();
#endif
return waveforms_->length();
}
void AudioWaveformCache::SetPassthrough(PlaybackCache *cache)
{
AudioWaveformCache *c = static_cast<AudioWaveformCache*>(cache);
waveforms_ = c->waveforms_;
for (const TimeRange &r : c->GetValidatedRanges()) {
Validate(r);
WaveformPassthrough t = r;
t.waveform = c->waveforms_;
passthroughs_.append(t);
}
passthroughs_.append(c->passthroughs_);
SetParameters(c->GetParameters());
SetSavingEnabled(c->IsSavingEnabled());
}
void AudioWaveformCache::InvalidateEvent(const TimeRange& range)
{
TimeRangeList::util_remove(&passthroughs_, range);
super::InvalidateEvent(range);
}
}
+18 -37
View File
@@ -24,8 +24,6 @@
#include "audio/audiovisualwaveform.h"
#include "playbackcache.h"
//#define AVW_USE_LIST
namespace olive {
class AudioWaveformCache : public PlaybackCache
@@ -40,7 +38,7 @@ public:
void SetParameters(const AudioParams &p)
{
params_ = p;
waveforms_.set_channel_count(p.channel_count());
waveforms_->set_channel_count(p.channel_count());
}
void Draw(QPainter* painter, const QRect &rect, const double &scale, const rational &start_time) const;
@@ -51,45 +49,28 @@ public:
virtual void SetPassthrough(PlaybackCache *cache) override;
protected:
virtual void InvalidateEvent(const TimeRange& range) override;
private:
#ifdef AVW_USE_LIST
class TimeRangeWithWaveform : public TimeRange
{
public:
TimeRangeWithWaveform() = default;
TimeRangeWithWaveform(const TimeRange &r) :
TimeRange(r)
{
}
using WaveformPtr = std::shared_ptr<AudioVisualWaveform>;
void set_in(const rational& in)
{
waveform.TrimIn(in - this->in());
TimeRange::set_in(in);
}
void set_out(const rational& out)
{
waveform.Resize(out - this->in());
TimeRange::set_out(out);
}
void set_range(const rational& in, const rational& out)
{
waveform.TrimRange(in, out-in);
TimeRange::set_range(in, out);
}
AudioVisualWaveform waveform;
};
QVector<TimeRangeWithWaveform> waveforms_;
#else
AudioVisualWaveform waveforms_;
#endif
WaveformPtr waveforms_;
AudioParams params_;
class WaveformPassthrough : public TimeRange
{
public:
WaveformPassthrough(const TimeRange &r) :
TimeRange(r)
{}
WaveformPtr waveform;
};
QVector<WaveformPassthrough> passthroughs_;
};
}
+9 -2
View File
@@ -55,7 +55,11 @@ RenderManager::RenderManager(QObject *parent) :
video_thread_ = CreateThread(context_);
dry_run_thread_ = CreateThread();
audio_thread_ = CreateThread();
waveform_thread_ = CreateThread();
waveform_threads_.resize(QThread::idealThreadCount());
for (size_t i=0; i<waveform_threads_.size(); i++) {
waveform_threads_[i] = CreateThread();
}
}
decoder_clear_timer_ = new QTimer(this);
@@ -136,7 +140,10 @@ RenderTicketPtr RenderManager::RenderAudio(const RenderAudioParams &params)
ticket->setProperty("mode", params.mode);
if (params.generate_waveforms) {
waveform_thread_->AddTicket(ticket);
size_t thread_index = last_waveform_thread_%waveform_threads_.size();
RenderThread *thread = waveform_threads_[thread_index];
thread->AddTicket(ticket);
last_waveform_thread_++;
} else {
audio_thread_->AddTicket(ticket);
}
+3 -1
View File
@@ -232,7 +232,9 @@ private:
RenderThread *video_thread_;
RenderThread *dry_run_thread_;
RenderThread *audio_thread_;
RenderThread *waveform_thread_;
std::vector<RenderThread *> waveform_threads_;
size_t last_waveform_thread_;
std::list<RenderThread *> render_threads_;
@@ -440,6 +440,10 @@ void ColorValuesTab::HexChanged(const QString &s)
uint32_t hex = s.toULong(&ok, 16);
if (ok) {
if (hex >= 0x1000000) {
hex >>= 8;
}
uint32_t r = (hex & 0xFF0000) >> 16;
uint32_t g = (hex & 0x00FF00) >> 8;
uint32_t b = (hex & 0x0000FF);
+2 -4
View File
@@ -76,7 +76,7 @@ NodeParamView::NodeParamView(bool create_keyframe_view, QWidget *parent) :
// Create contexts for three different types
context_items_.resize(Track::kCount + 1);
for (int i=0; i<context_items_.size(); i++) {
NodeParamViewContext *c = new NodeParamViewContext;
NodeParamViewContext *c = new NodeParamViewContext(param_widget_area_);
c->setVisible(false);
connect(c, &NodeParamViewContext::AboutToDeleteItem, this, &NodeParamView::ItemAboutToBeRemoved, Qt::DirectConnection);
@@ -245,8 +245,6 @@ void NodeParamView::DeselectNodes(const QVector<Node *> &nodes)
void NodeParamView::UpdateContexts()
{
//TIME_THIS_FUNCTION;
bool changes_made = false;
foreach (Node *ctx, current_contexts_) {
@@ -735,7 +733,7 @@ void NodeParamView::AddNode(Node *n, Node *ctx, NodeParamViewContext *context)
return;
}
NodeParamViewItem* item = new NodeParamViewItem(n, IsGroupMode() ? kCheckBoxesOnNonConnected : kNoCheckBoxes, context);
NodeParamViewItem* item = new NodeParamViewItem(n, IsGroupMode() ? kCheckBoxesOnNonConnected : kNoCheckBoxes, context->GetDockArea());
connect(item, &NodeParamViewItem::RequestSetTime, this, &NodeParamView::SetTimeAndSignal);
connect(item, &NodeParamViewItem::RequestSelectNode, this, &NodeParamView::SelectNodeFromConnectedLink);
@@ -50,13 +50,13 @@ NodeParamViewConnectedLabel::NodeParamViewConnectedLabel(const NodeInput &input,
label_layout->setMargin(0);
layout->addLayout(label_layout);
CollapseButton *collapse_btn = new CollapseButton();
CollapseButton *collapse_btn = new CollapseButton(this);
collapse_btn->setChecked(false);
label_layout->addWidget(collapse_btn);
label_layout->addWidget(new QLabel(tr("Connected to")));
label_layout->addWidget(new QLabel(tr("Connected to"), this));
connected_to_lbl_ = new ClickableLabel();
connected_to_lbl_ = new ClickableLabel(this);
connected_to_lbl_->setCursor(Qt::PointingHandCursor);
connected_to_lbl_->setContextMenuPolicy(Qt::CustomContextMenu);
connect(connected_to_lbl_, &ClickableLabel::MouseClicked, this, &NodeParamViewConnectedLabel::ConnectionClicked);
@@ -80,18 +80,23 @@ NodeParamViewConnectedLabel::NodeParamViewConnectedLabel(const NodeInput &input,
connect(input_.node(), &Node::InputConnected, this, &NodeParamViewConnectedLabel::InputConnected);
connect(input_.node(), &Node::InputDisconnected, this, &NodeParamViewConnectedLabel::InputDisconnected);
// Set up table area
value_tree_ = new NodeValueTree();
value_tree_->setVisible(false);
layout->addWidget(value_tree_);
// Creating the tree is expensive, hold off until the user specifically requests it
value_tree_ = nullptr;
connect(collapse_btn, &CollapseButton::toggled, this, &NodeParamViewConnectedLabel::SetValueTreeVisible);
}
void NodeParamViewConnectedLabel::CreateTree()
{
// Set up table area
value_tree_ = new NodeValueTree(this);
layout()->addWidget(value_tree_);
}
void NodeParamViewConnectedLabel::SetTime(const rational &time)
{
time_ = time;
if (value_tree_->isVisible()) {
if (value_tree_ && value_tree_->isVisible()) {
UpdateValueTree();
}
}
@@ -154,14 +159,22 @@ void NodeParamViewConnectedLabel::UpdateLabel()
void NodeParamViewConnectedLabel::UpdateValueTree()
{
value_tree_->SetNode(input_, time_);
if (value_tree_) {
value_tree_->SetNode(input_, time_);
}
}
void NodeParamViewConnectedLabel::SetValueTreeVisible(bool e)
{
value_tree_->setVisible(e);
if (value_tree_) {
value_tree_->setVisible(e);
}
if (e) {
if (!value_tree_) {
CreateTree();
}
UpdateValueTree();
}
}
@@ -51,6 +51,8 @@ private:
void UpdateValueTree();
void CreateTree();
ClickableLabel* connected_to_lbl_;
NodeInput input_;
+10 -10
View File
@@ -88,7 +88,7 @@ void NodeParamViewItem::RecreateBody()
body_->deleteLater();
}
body_ = new NodeParamViewItemBody(node_, create_checkboxes_);
body_ = new NodeParamViewItemBody(node_, create_checkboxes_, this);
connect(body_, &NodeParamViewItemBody::RequestSelectNode, this, &NodeParamViewItem::RequestSelectNode);
connect(body_, &NodeParamViewItemBody::RequestSetTime, this, &NodeParamViewItem::RequestSetTime);
connect(body_, &NodeParamViewItemBody::ArrayExpandedChanged, this, &NodeParamViewItem::ArrayExpandedChanged);
@@ -148,7 +148,7 @@ NodeParamViewItemBody::NodeParamViewItemBody(Node* node, NodeParamViewCheckBoxBe
if (n->InputIsArray(input)) {
// Insert here
QWidget* array_widget = new QWidget();
QWidget* array_widget = new QWidget(this);
QGridLayout* array_layout = new QGridLayout(array_widget);
array_layout->setContentsMargins(QtUtils::QFontMetricsWidth(fontMetrics(), QStringLiteral(" ")), 0, 0, 0);
@@ -160,7 +160,7 @@ NodeParamViewItemBody::NodeParamViewItemBody(Node* node, NodeParamViewCheckBoxBe
int arr_sz = 0;
// Add one last add button for appending to the array
NodeParamViewArrayButton* append_btn = new NodeParamViewArrayButton(NodeParamViewArrayButton::kAdd);
NodeParamViewArrayButton* append_btn = new NodeParamViewArrayButton(NodeParamViewArrayButton::kAdd, this);
connect(append_btn, &NodeParamViewArrayButton::clicked, this, &NodeParamViewItemBody::ArrayAppendClicked);
array_layout->addWidget(append_btn, arr_sz, kArrayInsertColumn);
@@ -186,7 +186,7 @@ void NodeParamViewItemBody::CreateWidgets(QGridLayout* layout, Node *node, const
// Create optional checkbox if requested
if (create_checkboxes_) {
ui_objects.optional_checkbox = new QCheckBox();
ui_objects.optional_checkbox = new QCheckBox(this);
connect(ui_objects.optional_checkbox, &QCheckBox::clicked, this, &NodeParamViewItemBody::OptionalCheckBoxClicked);
layout->addWidget(ui_objects.optional_checkbox, row, kOptionalCheckBox);
@@ -196,7 +196,7 @@ void NodeParamViewItemBody::CreateWidgets(QGridLayout* layout, Node *node, const
}
// Add descriptor label
ui_objects.main_label = new QLabel();
ui_objects.main_label = new QLabel(this);
// Create input label
layout->addWidget(ui_objects.main_label, row, kLabelColumn);
@@ -205,7 +205,7 @@ void NodeParamViewItemBody::CreateWidgets(QGridLayout* layout, Node *node, const
if (element == -1) {
// Create a collapse toggle for expanding/collapsing the array
CollapseButton* array_collapse_btn = new CollapseButton();
CollapseButton* array_collapse_btn = new CollapseButton(this);
// Default to collapsed
array_collapse_btn->setChecked(false);
@@ -220,8 +220,8 @@ void NodeParamViewItemBody::CreateWidgets(QGridLayout* layout, Node *node, const
} else {
NodeParamViewArrayButton* insert_element_btn = new NodeParamViewArrayButton(NodeParamViewArrayButton::kAdd);
NodeParamViewArrayButton* remove_element_btn = new NodeParamViewArrayButton(NodeParamViewArrayButton::kRemove);
NodeParamViewArrayButton* insert_element_btn = new NodeParamViewArrayButton(NodeParamViewArrayButton::kAdd, this);
NodeParamViewArrayButton* remove_element_btn = new NodeParamViewArrayButton(NodeParamViewArrayButton::kRemove, this);
layout->addWidget(insert_element_btn, row, kArrayInsertColumn);
layout->addWidget(remove_element_btn, row, kArrayRemoveColumn);
@@ -249,14 +249,14 @@ void NodeParamViewItemBody::CreateWidgets(QGridLayout* layout, Node *node, const
if (node->IsInputConnectable(input)) {
// Create clickable label used when an input is connected
ui_objects.connected_label = new NodeParamViewConnectedLabel(resolved);
ui_objects.connected_label = new NodeParamViewConnectedLabel(resolved, this);
connect(ui_objects.connected_label, &NodeParamViewConnectedLabel::RequestSelectNode, this, &NodeParamViewItemBody::RequestSelectNode);
layout->addWidget(ui_objects.connected_label, row, kWidgetStartColumn, 1, kKeyControlColumn - kWidgetStartColumn);
}
// Add keyframe control to this layout if parameter is keyframable
if (node->IsInputKeyframable(input)) {
ui_objects.key_control = new NodeParamViewKeyframeControl();
ui_objects.key_control = new NodeParamViewKeyframeControl(this);
ui_objects.key_control->SetInput(resolved);
layout->addWidget(ui_objects.key_control, row, kKeyControlColumn);
connect(ui_objects.key_control, &NodeParamViewKeyframeControl::RequestSetTime, this, &NodeParamViewItemBody::RequestSetTime);
@@ -33,31 +33,31 @@ NodeParamViewItemTitleBar::NodeParamViewItemTitleBar(QWidget *parent) :
{
QHBoxLayout* layout = new QHBoxLayout(this);
collapse_btn_ = new CollapseButton();
collapse_btn_ = new CollapseButton(this);
connect(collapse_btn_, &QPushButton::clicked, this, &NodeParamViewItemTitleBar::ExpandedStateChanged);
layout->addWidget(collapse_btn_);
lbl_ = new QLabel();
lbl_ = new QLabel(this);
layout->addWidget(lbl_);
// Place next buttons on the far side
layout->addStretch();
add_fx_btn_ = new QPushButton();
add_fx_btn_ = new QPushButton(this);
add_fx_btn_->setIcon(icon::AddEffect);
add_fx_btn_->setFixedSize(add_fx_btn_->sizeHint().height(), add_fx_btn_->sizeHint().height());
add_fx_btn_->setVisible(false);
layout->addWidget(add_fx_btn_);
connect(add_fx_btn_, &QPushButton::clicked, this, &NodeParamViewItemTitleBar::AddEffectButtonClicked);
pin_btn_ = new QPushButton(QStringLiteral("P"));
pin_btn_ = new QPushButton(QStringLiteral("P"), this);
pin_btn_->setCheckable(true);
pin_btn_->setFixedSize(pin_btn_->sizeHint().height(), pin_btn_->sizeHint().height());
pin_btn_->setVisible(false);
layout->addWidget(pin_btn_);
connect(pin_btn_, &QPushButton::clicked, this, &NodeParamViewItemTitleBar::PinToggled);
enabled_checkbox_ = new QCheckBox();
enabled_checkbox_ = new QCheckBox(this);
enabled_checkbox_->setVisible(false);
layout->addWidget(enabled_checkbox_);
connect(enabled_checkbox_, &QCheckBox::clicked, this, &NodeParamViewItemTitleBar::EnabledCheckBoxClicked);
@@ -33,7 +33,11 @@ class NodeParamViewKeyframeControl : public QWidget, public TimeTargetObject
{
Q_OBJECT
public:
NodeParamViewKeyframeControl(bool right_align = true, QWidget* parent = nullptr);
NodeParamViewKeyframeControl(bool right_align, QWidget* parent = nullptr);
NodeParamViewKeyframeControl(QWidget* parent = nullptr) :
NodeParamViewKeyframeControl(true, parent)
{
}
const NodeInput& GetConnectedInput() const
{
@@ -71,9 +71,11 @@ int GetSliderCount(NodeValue::Type type)
void NodeParamViewWidgetBridge::CreateWidgets()
{
QWidget *parent = dynamic_cast<QWidget*>(this->parent());
if (GetInnerInput().IsArray() && GetInnerInput().element() == -1) {
NodeParamViewArrayWidget* w = new NodeParamViewArrayWidget(GetInnerInput().node(), GetInnerInput().input());
NodeParamViewArrayWidget* w = new NodeParamViewArrayWidget(GetInnerInput().node(), GetInnerInput().input(), parent);
connect(w, &NodeParamViewArrayWidget::DoubleClicked, this, &NodeParamViewWidgetBridge::ArrayWidgetDoubleClicked);
widgets_.append(w);
@@ -94,12 +96,12 @@ void NodeParamViewWidgetBridge::CreateWidgets()
break;
case NodeValue::kInt:
{
CreateSliders<IntegerSlider>(1);
CreateSliders<IntegerSlider>(1, parent);
break;
}
case NodeValue::kRational:
{
CreateSliders<RationalSlider>(1);
CreateSliders<RationalSlider>(1, parent);
break;
}
case NodeValue::kFloat:
@@ -107,12 +109,12 @@ void NodeParamViewWidgetBridge::CreateWidgets()
case NodeValue::kVec3:
case NodeValue::kVec4:
{
CreateSliders<FloatSlider>(GetSliderCount(t));
CreateSliders<FloatSlider>(GetSliderCount(t), parent);
break;
}
case NodeValue::kCombo:
{
QComboBox* combobox = new QComboBox();
QComboBox* combobox = new QComboBox(parent);
QStringList items = GetInnerInput().GetComboBoxStrings();
foreach (const QString& s, items) {
@@ -125,21 +127,21 @@ void NodeParamViewWidgetBridge::CreateWidgets()
}
case NodeValue::kFile:
{
FileField* file_field = new FileField();
FileField* file_field = new FileField(parent);
widgets_.append(file_field);
connect(file_field, &FileField::FilenameChanged, this, &NodeParamViewWidgetBridge::WidgetCallback);
break;
}
case NodeValue::kColor:
{
ColorButton* color_button = new ColorButton(GetInnerInput().node()->project()->color_manager());
ColorButton* color_button = new ColorButton(GetInnerInput().node()->project()->color_manager(), parent);
widgets_.append(color_button);
connect(color_button, &ColorButton::ColorChanged, this, &NodeParamViewWidgetBridge::WidgetCallback);
break;
}
case NodeValue::kText:
{
NodeParamViewTextEdit* line_edit = new NodeParamViewTextEdit();
NodeParamViewTextEdit* line_edit = new NodeParamViewTextEdit(parent);
widgets_.append(line_edit);
connect(line_edit, &NodeParamViewTextEdit::textEdited, this, &NodeParamViewWidgetBridge::WidgetCallback);
connect(line_edit, &NodeParamViewTextEdit::RequestEditInViewer, this, &NodeParamViewWidgetBridge::RequestEditTextInViewer);
@@ -147,21 +149,21 @@ void NodeParamViewWidgetBridge::CreateWidgets()
}
case NodeValue::kBoolean:
{
QCheckBox* check_box = new QCheckBox();
QCheckBox* check_box = new QCheckBox(parent);
widgets_.append(check_box);
connect(check_box, &QCheckBox::clicked, this, &NodeParamViewWidgetBridge::WidgetCallback);
break;
}
case NodeValue::kFont:
{
QFontComboBox* font_combobox = new QFontComboBox();
QFontComboBox* font_combobox = new QFontComboBox(parent);
widgets_.append(font_combobox);
connect(font_combobox, &QFontComboBox::currentFontChanged, this, &NodeParamViewWidgetBridge::WidgetCallback);
break;
}
case NodeValue::kBezier:
{
BezierWidget *bezier = new BezierWidget();
BezierWidget *bezier = new BezierWidget(parent);
widgets_.append(bezier);
connect(bezier->x_slider(), &FloatSlider::ValueChanged, this, &NodeParamViewWidgetBridge::WidgetCallback);
@@ -384,10 +386,10 @@ void NodeParamViewWidgetBridge::WidgetCallback()
}
template <typename T>
void NodeParamViewWidgetBridge::CreateSliders(int count)
void NodeParamViewWidgetBridge::CreateSliders(int count, QWidget *parent)
{
for (int i=0;i<count;i++) {
T* fs = new T();
T* fs = new T(parent);
fs->SliderBase::SetDefaultValue(GetInnerInput().GetSplitDefaultValueForTrack(i));
fs->SetLadderElementCount(2);
@@ -75,7 +75,7 @@ private:
void SetProperty(const QString &key, const QVariant &value);
template <typename T>
void CreateSliders(int count);
void CreateSliders(int count, QWidget *parent);
void UpdateWidgetValues();