diff --git a/effects/fields/doublefield.cpp b/effects/fields/doublefield.cpp index 64d338587..a62836c52 100644 --- a/effects/fields/doublefield.cpp +++ b/effects/fields/doublefield.cpp @@ -23,11 +23,13 @@ double DoubleField::GetDoubleAt(double timecode) void DoubleField::SetMinimum(double minimum) { min_ = minimum; + emit MinimumChanged(min_); } void DoubleField::SetMaximum(double maximum) { max_ = maximum; + emit MaximumChanged(max_); } void DoubleField::SetDefault(double d) @@ -89,6 +91,8 @@ QWidget *DoubleField::CreateWidget(QWidget *existing) connect(ls, SIGNAL(valueChanged(double)), this, SLOT(UpdateFromWidget(double))); connect(ls, SIGNAL(clicked()), this, SIGNAL(Clicked())); connect(this, SIGNAL(EnabledChanged(bool)), ls, SLOT(setEnabled(bool))); + connect(this, SIGNAL(MaximumChanged(double)), ls, SLOT(SetMaximum(double))); + connect(this, SIGNAL(MinimumChanged(double)), ls, SLOT(SetMinimum(double))); return ls; } diff --git a/effects/fields/doublefield.h b/effects/fields/doublefield.h index 4ba53da8a..9b2882f4e 100644 --- a/effects/fields/doublefield.h +++ b/effects/fields/doublefield.h @@ -37,6 +37,9 @@ public: virtual QWidget* CreateWidget(QWidget *existing = nullptr) override; virtual void UpdateWidgetValue(QWidget* widget, double timecode) override; +signals: + void MaximumChanged(double maximum); + void MinimumChanged(double maximum); private: double min_; double max_; diff --git a/effects/transition.cpp b/effects/transition.cpp index 18b064ed7..d3a9d40cf 100644 --- a/effects/transition.cpp +++ b/effects/transition.cpp @@ -48,10 +48,12 @@ Transition::Transition(Clip *c, Clip *s, const EffectMeta* em) : EffectRow* length_row = new EffectRow(this, tr("Length"), false, false); length_field = new DoubleField(length_row, "length"); length_field->SetDefault(30); - length_field->SetMinimum(0); + length_field->SetMinimum(1); length_field->SetDisplayType(LabelSlider::FrameNumber); length_field->SetFrameRate(parent_clip->sequence == nullptr ? parent_clip->cached_frame_rate() : parent_clip->sequence->frame_rate); + + connect(length_field, SIGNAL(Changed()), this, SLOT(UpdateMaximumLength())); } TransitionPtr Transition::copy(Clip *c, Clip *s) { @@ -119,6 +121,42 @@ TransitionPtr Transition::CreateFromMeta(Clip* c, Clip* s, const EffectMeta* em) return nullptr; } +void Transition::UpdateMaximumLength() +{ + // Get the maximum area this transition can occupy on the clip + long maximum_length = GetMaximumEmptySpaceOnClip(parent_clip); + + // If this clip is a shared transition, get the maximum area this can occupy on the other clip too + if (secondary_clip != nullptr) { + long secondary_max_length = GetMaximumEmptySpaceOnClip(secondary_clip); + + maximum_length = qMin(secondary_max_length, maximum_length); + } + + length_field->SetMaximum(maximum_length); +} + +long Transition::GetMaximumEmptySpaceOnClip(Clip *c) +{ + long maximum_transition_length = c->length(); + + Transition* opposite_transition; + + // See if this clip has a transition on the opposite side that we need to account for + if (c->opening_transition.get() == this) { + opposite_transition = c->closing_transition.get(); + } else { + opposite_transition = c->opening_transition.get(); + } + + // If is does, subtract the maximum length by the transition's length + if (opposite_transition != nullptr) { + maximum_transition_length -= opposite_transition->get_true_length(); + } + + return maximum_transition_length; +} + TransitionPtr Transition::Create(Clip* c, Clip* s, const EffectMeta* em, long length) { TransitionPtr t(CreateFromMeta(c, s, em)); if (t != nullptr) { diff --git a/effects/transition.h b/effects/transition.h index 93d5e8552..8895d9dd7 100644 --- a/effects/transition.h +++ b/effects/transition.h @@ -62,6 +62,10 @@ public: private: DoubleField* length_field; + +private slots: + void UpdateMaximumLength(); + long GetMaximumEmptySpaceOnClip(Clip* c); }; #endif // TRANSITION_H diff --git a/ui/effectui.cpp b/ui/effectui.cpp index aee029148..11284d092 100644 --- a/ui/effectui.cpp +++ b/ui/effectui.cpp @@ -143,8 +143,6 @@ void EffectUI::AddAdditionalEffect(Effect *e) for (int j=0;jFieldCount();j++) { - EffectField* field = row->Field(j); - // Attach existing field widget to this effect's field e->row(i)->Field(j)->CreateWidget(Widget(i, j)); diff --git a/ui/labelslider.h b/ui/labelslider.h index c1402d1de..9727c26d1 100644 --- a/ui/labelslider.h +++ b/ui/labelslider.h @@ -61,30 +61,6 @@ public: */ void SetDefault(double v); - /** - * @brief Set the minimum value - * - * If a minimum value is set, the value will never go below it. If the user manually sets a value lower than - * the minimum, it will automatically snap to the minimum. - * - * @param v - * - * Value to set as minimum - */ - void SetMinimum(double v); - - /** - * @brief Set the maximum value - * - * If a maximum value is set, the value will never go above it. If the user manually sets a value higher than - * the maximum, it will automatically snap to the maximum. - * - * @param v - * - * Value to set as maximum - */ - void SetMaximum(double v); - /** * @brief Returns the internal value as a double * @return The internal value. This will not respect the `display_type`, i.e. 100% will return as 1.0, 12dB will @@ -145,6 +121,31 @@ public: * Defaults to 1 */ void SetDecimalPlaces(int places); +public slots: + /** + * @brief Set the minimum value + * + * If a minimum value is set, the value will never go below it. If the user manually sets a value lower than + * the minimum, it will automatically snap to the minimum. + * + * @param v + * + * Value to set as minimum + */ + void SetMinimum(double v); + + /** + * @brief Set the maximum value + * + * If a maximum value is set, the value will never go above it. If the user manually sets a value higher than + * the maximum, it will automatically snap to the maximum. + * + * @param v + * + * Value to set as maximum + */ + void SetMaximum(double v); + protected: void mousePressEvent(QMouseEvent *ev); void mouseMoveEvent(QMouseEvent *ev);