diff --git a/dialogs/texteditdialog.cpp b/dialogs/texteditdialog.cpp index 00e338c3a..c1fb194b3 100644 --- a/dialogs/texteditdialog.cpp +++ b/dialogs/texteditdialog.cpp @@ -24,6 +24,7 @@ #include #include #include +#include #include #include "ui/icons.h" @@ -166,7 +167,9 @@ TextEditDialog::TextEditDialog(QWidget *parent, const QString &s, bool rich_text textEdit->setPlainText(s); } - UpdateUIFromTextCursor(); + // Helps ensure the UI elements update correctly at the beginning - when the cursor is at the start, the UI elements + // show up blank... + textEdit->moveCursor(QTextCursor::End); } const QString& TextEditDialog::get_string() { diff --git a/effects/effect.cpp b/effects/effect.cpp index 964487a90..b016c07bc 100644 --- a/effects/effect.cpp +++ b/effects/effect.cpp @@ -121,7 +121,6 @@ Effect::Effect(Clip* c, const EffectMeta *em) : flags_(0), glslProgram(nullptr), texture(nullptr), - enable_always_update_(false), isOpen(false), bound(false), iterations(1) @@ -489,12 +488,7 @@ void Effect::load_from_file() { bool Effect::AlwaysUpdate() { - return enable_always_update_; -} - -void Effect::SetAlwaysUpdate(bool b) -{ - enable_always_update_ = b; + return false; } bool Effect::IsEnabled() { diff --git a/effects/effect.h b/effects/effect.h index 4944ad5d4..acf5e255b 100644 --- a/effects/effect.h +++ b/effects/effect.h @@ -233,8 +233,8 @@ protected: QImage img; QOpenGLTexture* texture; - bool AlwaysUpdate(); - void SetAlwaysUpdate(bool b); + // enable effect to update constantly + virtual bool AlwaysUpdate(); private: bool isOpen; @@ -249,9 +249,6 @@ private: QVector gizmo_dragging_actions_; - // enable effect to update constantly - bool enable_always_update_; - // superimpose functions virtual void redraw(double timecode); bool valueHasChanged(double timecode); diff --git a/effects/internal/richtexteffect.cpp b/effects/internal/richtexteffect.cpp index 2ce6250a7..d03cd2085 100644 --- a/effects/internal/richtexteffect.cpp +++ b/effects/internal/richtexteffect.cpp @@ -2,6 +2,16 @@ #include +#include "timeline/clip.h" + +enum AutoscrollDirection { + SCROLL_OFF, + SCROLL_UP, + SCROLL_DOWN, + SCROLL_LEFT, + SCROLL_RIGHT, +}; + RichTextEffect::RichTextEffect(Clip *c, const EffectMeta *em) : Effect(c, em) { @@ -9,6 +19,7 @@ RichTextEffect::RichTextEffect(Clip *c, const EffectMeta *em) : EffectRow* text_row = new EffectRow(this, tr("Text")); text_val = new StringField(text_row, "text"); + text_val->SetColumnSpan(2); EffectRow* padding_row = new EffectRow(this, tr("Padding")); padding_field = new DoubleField(padding_row, "padding"); @@ -24,6 +35,16 @@ RichTextEffect::RichTextEffect(Clip *c, const EffectMeta *em) : vertical_align->AddItem(tr("Center"), Qt::AlignCenter); vertical_align->AddItem(tr("Bottom"), Qt::AlignBottom); vertical_align->SetValueAt(0, Qt::AlignCenter); + vertical_align->SetColumnSpan(2); + + EffectRow* autoscroll_row = new EffectRow(this, tr("Auto-Scroll")); + autoscroll = new ComboField(autoscroll_row, "autoscroll"); + autoscroll->AddItem(tr("Off"), SCROLL_OFF); + autoscroll->AddItem(tr("Up"), SCROLL_UP); + autoscroll->AddItem(tr("Down"), SCROLL_DOWN); + autoscroll->AddItem(tr("Left"), SCROLL_LEFT); + autoscroll->AddItem(tr("Right"), SCROLL_RIGHT); + autoscroll->SetColumnSpan(2); // Create default text text_val->SetValueAt(0, "" @@ -54,10 +75,47 @@ void RichTextEffect::redraw(double timecode) int translate_x = qRound(position_x->GetDoubleAt(timecode) + padding); int translate_y = qRound(position_y->GetDoubleAt(timecode) + padding); - if (vertical_align->GetValueAt(timecode).toInt() == Qt::AlignCenter) { - translate_y += height / 2 - td.size().height() / 2; - } else if (vertical_align->GetValueAt(timecode).toInt() == Qt::AlignBottom) { - translate_y += height - td.size().height(); + int doc_height = qRound(td.size().height()); + + AutoscrollDirection auto_scroll_dir = static_cast(autoscroll->GetValueAt(timecode).toInt()); + + double scroll_progress; + + if (auto_scroll_dir != SCROLL_OFF) { + double clip_length_secs = double(parent_clip->length()) / parent_clip->media_frame_rate(); + scroll_progress = (timecode - double(parent_clip->clip_in()) / parent_clip->media_frame_rate()) / clip_length_secs; + } + + if (auto_scroll_dir == SCROLL_OFF || auto_scroll_dir == SCROLL_LEFT || auto_scroll_dir == SCROLL_RIGHT) { + + // If we're not auto-scrolling the vertical direction, respect the vertical alignment + if (vertical_align->GetValueAt(timecode).toInt() == Qt::AlignCenter) { + translate_y += height / 2 - doc_height / 2; + } else if (vertical_align->GetValueAt(timecode).toInt() == Qt::AlignBottom) { + translate_y += height - doc_height; + } + + // Check if we are autoscrolling + if (auto_scroll_dir != SCROLL_OFF) { + + if (auto_scroll_dir == SCROLL_LEFT) { + scroll_progress = 1.0 - scroll_progress; + } + + int doc_width = td.size().width(); + translate_x += qRound(-doc_width + (img.width() + doc_width) * scroll_progress); + } + + } else if (auto_scroll_dir == SCROLL_UP || auto_scroll_dir == SCROLL_DOWN) { + + // Auto-scroll bottom to top or top to bottom + + if (auto_scroll_dir == SCROLL_UP) { + scroll_progress = 1.0 - scroll_progress; + } + + translate_y += qRound(-doc_height + (height + doc_height)*scroll_progress); + } QRect clip_rect = img.rect(); @@ -67,3 +125,8 @@ void RichTextEffect::redraw(double timecode) td.drawContents(&p, clip_rect); } + +bool RichTextEffect::AlwaysUpdate() +{ + return autoscroll->GetValueAt(autoscroll->Now()).toInt() != SCROLL_OFF; +} diff --git a/effects/internal/richtexteffect.h b/effects/internal/richtexteffect.h index b172af288..a636be3d3 100644 --- a/effects/internal/richtexteffect.h +++ b/effects/internal/richtexteffect.h @@ -8,12 +8,15 @@ class RichTextEffect : public Effect { public: RichTextEffect(Clip* c, const EffectMeta *em); void redraw(double timecode); +protected: + virtual bool AlwaysUpdate() override; private: StringField* text_val; DoubleField* padding_field; DoubleField* position_x; DoubleField* position_y; ComboField* vertical_align; + ComboField* autoscroll; }; #endif // RICHTEXTEFFECT_H diff --git a/effects/internal/timecodeeffect.cpp b/effects/internal/timecodeeffect.cpp index 6b37a6795..43b195bc0 100644 --- a/effects/internal/timecodeeffect.cpp +++ b/effects/internal/timecodeeffect.cpp @@ -46,7 +46,6 @@ TimecodeEffect::TimecodeEffect(Clip* c, const EffectMeta* em) : Effect(c, em) { - SetAlwaysUpdate(true); SetFlags(Effect::SuperimposeFlag); EffectRow* tc_row = new EffectRow(this, tr("Timecode")); @@ -138,3 +137,8 @@ void TimecodeEffect::redraw(double timecode) { p.setBrush(color_val->GetColorAt(timecode)); p.drawPath(path); } + +bool TimecodeEffect::AlwaysUpdate() +{ + return true; +} diff --git a/effects/internal/timecodeeffect.h b/effects/internal/timecodeeffect.h index 2f48d9bc7..d51565940 100644 --- a/effects/internal/timecodeeffect.h +++ b/effects/internal/timecodeeffect.h @@ -29,20 +29,23 @@ class TimecodeEffect : public Effect { Q_OBJECT public: - TimecodeEffect(Clip* c, const EffectMeta *em); - void redraw(double timecode); - DoubleField* scale_val; - ColorField* color_val; - ColorField* color_bg_val; - DoubleField* bg_alpha; - DoubleField* offset_x_val; - DoubleField* offset_y_val; - StringField* prepend_text; - ComboField* tc_select; + TimecodeEffect(Clip* c, const EffectMeta *em); + void redraw(double timecode); + DoubleField* scale_val; + ColorField* color_val; + ColorField* color_bg_val; + DoubleField* bg_alpha; + DoubleField* offset_x_val; + DoubleField* offset_y_val; + StringField* prepend_text; + ComboField* tc_select; + +protected: + virtual bool AlwaysUpdate() override; private: - QFont font; - QString display_timecode; + QFont font; + QString display_timecode; }; #endif // TIMECODEEFFECT_H diff --git a/ui/effectui.cpp b/ui/effectui.cpp index 62652e7ab..6ecec732c 100644 --- a/ui/effectui.cpp +++ b/ui/effectui.cpp @@ -79,8 +79,8 @@ EffectUI::EffectUI(Effect* e) : } enabled_check->setChecked(e->IsEnabled()); - connect(enabled_check, SIGNAL(toggled(bool)), e, SLOT(FieldChanged())); connect(enabled_check, SIGNAL(toggled(bool)), e, SLOT(SetEnabled(bool))); + connect(enabled_check, SIGNAL(toggled(bool)), e, SLOT(FieldChanged())); } Effect *EffectUI::GetEffect()