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