diff --git a/effects/effects.h b/effects/effects.h index e693a75cf..4fe398f86 100644 --- a/effects/effects.h +++ b/effects/effects.h @@ -4,15 +4,17 @@ #include "project/effect.h" #include +#include #include #include class QSpinBox; class QCheckBox; -class QComboBox; class LabelSlider; class QOpenGLTexture; class QTextEdit; class QPushButton; +class ColorButton; +class ComboBoxEx; enum VideoEffects { VIDEO_TRANSFORM_EFFECT, @@ -51,7 +53,7 @@ public: LabelSlider* anchor_x_box; LabelSlider* anchor_y_box; LabelSlider* opacity; - QComboBox* blend_mode_box; + ComboBoxEx* blend_mode_box; public slots: void toggle_uniform_scale(bool enabled); private: @@ -99,15 +101,13 @@ public: void save(QXmlStreamWriter* stream); QTextEdit* text_val; LabelSlider* size_val; - QPushButton* set_color_button; - QColor color; + ColorButton* set_color_button; + ComboBoxEx* set_font_combobox; private slots: - void set_color(); void update_texture(); private: - void set_button_color(); - QPixmap pixmap; QOpenGLTexture* texture; + QFont font; }; // audio effects diff --git a/effects/paneffect.cpp b/effects/paneffect.cpp index 0ac89037e..57269e131 100644 --- a/effects/paneffect.cpp +++ b/effects/paneffect.cpp @@ -8,20 +8,12 @@ #include "ui/labelslider.h" #include "ui/collapsiblewidget.h" -PanEffect::PanEffect(Clip* c) : Effect(c) { - setup_effect(EFFECT_TYPE_AUDIO, AUDIO_PAN_EFFECT); - - QGridLayout* ui_layout = new QGridLayout(); - +PanEffect::PanEffect(Clip* c) : Effect(c, EFFECT_TYPE_AUDIO, AUDIO_PAN_EFFECT) { ui_layout->addWidget(new QLabel("Pan:"), 0, 0); pan_val = new LabelSlider(); pan_val->set_minimum_value(-100); pan_val->set_maximum_value(100); - ui_layout->addWidget(pan_val, 0, 1); - - ui->setLayout(ui_layout); - - container->setContents(ui); + ui_layout->addWidget(pan_val, 0, 1); // set defaults pan_val->set_value(0); diff --git a/effects/shakeeffect.cpp b/effects/shakeeffect.cpp index 5c79e0c9e..629c36cf8 100644 --- a/effects/shakeeffect.cpp +++ b/effects/shakeeffect.cpp @@ -12,11 +12,7 @@ #include "project/sequence.h" #include "panels/timeline.h" -ShakeEffect::ShakeEffect(Clip *c) : Effect(c) { - setup_effect(EFFECT_TYPE_VIDEO, VIDEO_SHAKE_EFFECT); - - QGridLayout* ui_layout = new QGridLayout(); - +ShakeEffect::ShakeEffect(Clip *c) : Effect(c, EFFECT_TYPE_VIDEO, VIDEO_SHAKE_EFFECT) { ui_layout->addWidget(new QLabel("Intensity:"), 0, 0); intensity_val = new LabelSlider(); intensity_val->set_minimum_value(0); @@ -32,10 +28,6 @@ ShakeEffect::ShakeEffect(Clip *c) : Effect(c) { frequency_val->set_minimum_value(0); ui_layout->addWidget(frequency_val, 2, 1); - ui->setLayout(ui_layout); - - container->setContents(ui); - // set defaults intensity_val->set_value(50); rotation_val->set_value(0); diff --git a/effects/texteffect.cpp b/effects/texteffect.cpp index 078b47ab6..9e588717b 100644 --- a/effects/texteffect.cpp +++ b/effects/texteffect.cpp @@ -7,42 +7,62 @@ #include #include #include +#include +#include #include #include "ui/labelslider.h" #include "ui/collapsiblewidget.h" #include "project/clip.h" #include "project/sequence.h" +#include "ui/comboboxex.h" +#include "ui/colorbutton.h" -TextEffect::TextEffect(Clip *c) : Effect(c), texture(NULL) { - setup_effect(EFFECT_TYPE_VIDEO, VIDEO_TEXT_EFFECT); - - QGridLayout* ui_layout = new QGridLayout(); +class FontCombobox : public ComboBoxEx { +public: + FontCombobox(QWidget* parent = 0) : ComboBoxEx(parent) {} +protected: + void showPopup() { + QString current = currentText(); + clear(); + QStringList fonts = QFontDatabase().families(); + bool found = false; + for (int i=0;iaddWidget(new QLabel("Text:"), 0, 0); text_val = new QTextEdit(); text_val->setUndoRedoEnabled(true); ui_layout->addWidget(text_val, 0, 1); - ui_layout->addWidget(new QLabel("Size:"), 1, 0); + ui_layout->addWidget(new QLabel("Font:"), 1, 0); + set_font_combobox = new FontCombobox(); + ui_layout->addWidget(set_font_combobox, 1, 1); + + ui_layout->addWidget(new QLabel("Size:"), 2, 0); size_val = new LabelSlider(); size_val->set_minimum_value(0); - ui_layout->addWidget(size_val, 1, 1); + ui_layout->addWidget(size_val, 2, 1); - ui_layout->addWidget(new QLabel("Color:"), 2, 0); - set_color_button = new QPushButton(); - ui_layout->addWidget(set_color_button, 2, 1); + ui_layout->addWidget(new QLabel("Color:"), 3, 0); + set_color_button = new ColorButton(); + ui_layout->addWidget(set_color_button, 3, 1); - ui->setLayout(ui_layout); - - container->setContents(ui); - - color = Qt::white; - set_button_color(); + set_font_combobox->addItem(font.family()); connect(text_val, SIGNAL(textChanged()), this, SLOT(update_texture())); connect(size_val, SIGNAL(valueChanged()), this, SLOT(update_texture())); - connect(set_color_button, SIGNAL(clicked(bool)), this, SLOT(set_color())); + connect(set_color_button, SIGNAL(color_changed()), this, SLOT(update_texture())); + connect(set_font_combobox, SIGNAL(currentTextChanged(QString)), this, SLOT(update_texture())); size_val->set_value(24); text_val->setText("Sample Text"); @@ -53,38 +73,27 @@ TextEffect::~TextEffect() { delete texture; } -void TextEffect::set_button_color() { - QPalette pal = set_color_button->palette(); - pal.setColor(QPalette::Button, color); - set_color_button->setPalette(pal); -} - -void TextEffect::set_color() { - color = QColorDialog::getColor(color, NULL); - set_button_color(); - update_texture(); -} - void TextEffect::update_texture() { - pixmap = QPixmap(parent_clip->sequence->width, parent_clip->sequence->height); + QImage pixmap(parent_clip->sequence->width, parent_clip->sequence->height, QImage::Format_ARGB32_Premultiplied); pixmap.fill(Qt::transparent); QPainter p(&pixmap); p.setRenderHint(QPainter::TextAntialiasing, true); // set font - QFont font = p.font(); + font.setFamily(set_font_combobox->currentText()); font.setPointSize(size_val->value()); + font.setStyleHint(QFont::Helvetica, QFont::PreferAntialias); p.setFont(font); - p.setPen(color); + p.setPen(set_color_button->get_color()); p.drawText(QRect(0, 0, pixmap.width(), pixmap.height()), Qt::AlignCenter | Qt::TextWordWrap, text_val->toPlainText()); if (texture == NULL) { - texture = new QOpenGLTexture(pixmap.toImage()); + texture = new QOpenGLTexture(pixmap); } else { texture->destroy(); - texture->setData(pixmap.toImage()); + texture->setData(pixmap); } // queue a repaint of the canvas @@ -95,8 +104,8 @@ void TextEffect::post_gl() { if (texture != NULL) { texture->bind(); - int half_width = pixmap.width()/2; - int half_height = pixmap.height()/2; + int half_width = parent_clip->sequence->width/2; + int half_height = parent_clip->sequence->height/2; glBegin(GL_QUADS); glTexCoord2f(0.0, 0.0); @@ -117,7 +126,7 @@ Effect* TextEffect::copy(Clip* c) { TextEffect* e = new TextEffect(c); e->text_val->setPlainText(text_val->toPlainText()); e->size_val->set_value(size_val->value()); - e->color = color; + e->set_color_button->set_color(set_color_button->get_color()); return e; } @@ -128,16 +137,17 @@ void TextEffect::load(QXmlStreamReader* stream) { if (a.name() == "size") { size_val->set_value(a.value().toDouble()); } else if (a.name() == "r") { - color.setRed(a.value().toInt()); + set_color_button->get_color().setRed(a.value().toInt()); } else if (a.name() == "g") { - color.setGreen(a.value().toInt()); + set_color_button->get_color().setGreen(a.value().toInt()); } else if (a.name() == "b") { - color.setBlue(a.value().toInt()); + set_color_button->get_color().setBlue(a.value().toInt()); } } while (!(stream->name() == "effect" && stream->isEndElement())) { stream->readNext(); if (stream->name() == "text" && stream->isStartElement()) { + stream->readNext(); text_val->setPlainText(stream->text().toString()); } } @@ -145,8 +155,8 @@ void TextEffect::load(QXmlStreamReader* stream) { void TextEffect::save(QXmlStreamWriter* stream) { stream->writeAttribute("size", QString::number(size_val->value())); - stream->writeAttribute("r", QString::number(color.red())); - stream->writeAttribute("g", QString::number(color.green())); - stream->writeAttribute("b", QString::number(color.blue())); + stream->writeAttribute("r", QString::number(set_color_button->get_color().red())); + stream->writeAttribute("g", QString::number(set_color_button->get_color().green())); + stream->writeAttribute("b", QString::number(set_color_button->get_color().blue())); stream->writeTextElement("text", text_val->toPlainText()); } diff --git a/effects/transformeffect.cpp b/effects/transformeffect.cpp index 316d1ebc1..a5e406c34 100644 --- a/effects/transformeffect.cpp +++ b/effects/transformeffect.cpp @@ -14,17 +14,14 @@ #include "project/sequence.h" #include "io/media.h" #include "ui/labelslider.h" +#include "ui/comboboxex.h" #define BLEND_MODE_NORMAL 0 #define BLEND_MODE_SCREEN 1 #define BLEND_MODE_MULTIPLY 2 #define BLEND_MODE_OVERLAY 3 -TransformEffect::TransformEffect(Clip* c) : Effect(c) { - setup_effect(EFFECT_TYPE_VIDEO, VIDEO_TRANSFORM_EFFECT); - - QGridLayout* ui_layout = new QGridLayout(); - +TransformEffect::TransformEffect(Clip* c) : Effect(c, EFFECT_TYPE_VIDEO, VIDEO_TRANSFORM_EFFECT) { ui_layout->addWidget(new QLabel("Position:"), 0, 0); position_x = new LabelSlider(); ui_layout->addWidget(position_x, 0, 1); @@ -63,17 +60,13 @@ TransformEffect::TransformEffect(Clip* c) : Effect(c) { ui_layout->addWidget(opacity, 5, 1); ui_layout->addWidget(new QLabel("Blend Mode:"), 6, 0); - blend_mode_box = new QComboBox(); + blend_mode_box = new ComboBoxEx(); blend_mode_box->addItem("Normal", BLEND_MODE_NORMAL); blend_mode_box->addItem("Overlay", BLEND_MODE_OVERLAY); blend_mode_box->addItem("Screen", BLEND_MODE_SCREEN); blend_mode_box->addItem("Multiply", BLEND_MODE_MULTIPLY); ui_layout->addWidget(blend_mode_box, 6, 1); - ui->setLayout(ui_layout); - - container->setContents(ui); - // set defaults position_x->set_default_value(c->sequence->width/2); position_y->set_default_value(c->sequence->height/2); @@ -98,6 +91,7 @@ TransformEffect::TransformEffect(Clip* c) : Effect(c) { connect(opacity, SIGNAL(valueChanged()), this, SLOT(field_changed())); connect(uniform_scale_box, SIGNAL(toggled(bool)), this, SLOT(toggle_uniform_scale(bool))); connect(uniform_scale_box, SIGNAL(toggled(bool)), this, SLOT(field_changed())); + connect(uniform_scale_box, SIGNAL(clicked(bool)), this, SLOT(checkbox_command())); connect(blend_mode_box, SIGNAL(currentIndexChanged(int)), this, SLOT(field_changed())); } diff --git a/effects/volumeeffect.cpp b/effects/volumeeffect.cpp index b79043dd6..f3335bd0d 100644 --- a/effects/volumeeffect.cpp +++ b/effects/volumeeffect.cpp @@ -9,20 +9,12 @@ #include "ui/labelslider.h" #include "ui/collapsiblewidget.h" -VolumeEffect::VolumeEffect(Clip* c) : Effect(c) { - setup_effect(EFFECT_TYPE_AUDIO, AUDIO_VOLUME_EFFECT); - - QGridLayout* ui_layout = new QGridLayout(); - - ui_layout->addWidget(new QLabel("Volume:"), 0, 0); +VolumeEffect::VolumeEffect(Clip* c) : Effect(c, EFFECT_TYPE_AUDIO, AUDIO_VOLUME_EFFECT) { + ui_layout->addWidget(new QLabel("Volume:"), 0, 0); volume_val = new LabelSlider(); volume_val->set_minimum_value(0); volume_val->set_maximum_value(400); - ui_layout->addWidget(volume_val, 0, 1); - - ui->setLayout(ui_layout); - - container->setContents(ui); + ui_layout->addWidget(volume_val, 0, 1); // set defaults volume_val->set_value(100); diff --git a/mainwindow.cpp b/mainwindow.cpp index 952f13cea..5a98eb94f 100644 --- a/mainwindow.cpp +++ b/mainwindow.cpp @@ -31,7 +31,6 @@ #define OLIVE_FILE_FILTER "Olive Project (*.ove)" -QString autorecovery_filename; QTimer autorecovery_timer; void MainWindow::setup_layout() { @@ -292,12 +291,8 @@ void MainWindow::on_action_Paste_triggered() void MainWindow::autorecover_interval() { if (project_changed) { - QString old_filename = project_url; - project_url = autorecovery_filename; - panel_project->save_project(); + panel_project->save_project(true); qDebug() << "[INFO] Auto-recovery project saved"; - project_url = old_filename; - project_changed = true; } } @@ -308,7 +303,7 @@ bool MainWindow::save_project_as() { fn += ".ove"; } project_url = fn; - panel_project->save_project(); + panel_project->save_project(false); return true; } return false; @@ -318,7 +313,7 @@ bool MainWindow::save_project() { if (project_url.isEmpty()) { return save_project_as(); } else { - panel_project->save_project(); + panel_project->save_project(false); return true; } } @@ -361,11 +356,12 @@ void MainWindow::on_action_Open_Project_triggered() void MainWindow::on_actionProject_triggered() { if (can_close_project()) { - project_url.clear(); - project_changed = false; + panel_effect_controls->clear_effects(true); panel_project->new_project(); undo_stack.clear(); panel_timeline->redraw_all_clips(false); + project_url.clear(); + project_changed = false; } } diff --git a/olive.pro b/olive.pro index 767dfdfa8..8ec662c6f 100644 --- a/olive.pro +++ b/olive.pro @@ -62,7 +62,9 @@ SOURCES += \ project/undo.cpp \ ui/scrollarea.cpp \ effects/shakeeffect.cpp \ - effects/texteffect.cpp + effects/texteffect.cpp \ + ui/comboboxex.cpp \ + ui/colorbutton.cpp HEADERS += \ mainwindow.h \ @@ -97,7 +99,9 @@ HEADERS += \ effects/transition.h \ ui/audiomonitor.h \ project/undo.h \ - ui/scrollarea.h + ui/scrollarea.h \ + ui/comboboxex.h \ + ui/colorbutton.h FORMS += \ mainwindow.ui \ diff --git a/panels/effectcontrols.cpp b/panels/effectcontrols.cpp index 3155df5ab..76c55c21b 100644 --- a/panels/effectcontrols.cpp +++ b/panels/effectcontrols.cpp @@ -12,6 +12,7 @@ #include "ui/collapsiblewidget.h" #include "project/sequence.h" #include "project/undo.h" +#include "panels/project.h" EffectControls::EffectControls(QWidget *parent) : QDockWidget(parent), @@ -37,6 +38,7 @@ void EffectControls::menu_select(QAction* q) { } } undo_stack.push(command); + project_changed = true; } void EffectControls::show_menu(bool video) { @@ -134,6 +136,7 @@ void EffectControls::delete_effects() { } if (command->clips.size() > 0) { undo_stack.push(command); + project_changed = true; } else { delete command; } diff --git a/panels/project.cpp b/panels/project.cpp index e184e48d6..e5f08a559 100644 --- a/panels/project.cpp +++ b/panels/project.cpp @@ -34,6 +34,7 @@ extern "C" { #define MAXIMUM_RECENT_PROJECTS 10 +QString autorecovery_filename; bool project_changed = false; QString project_url = ""; QStringList recent_projects; @@ -556,8 +557,9 @@ bool Project::load_worker(QFile& f, QXmlStreamReader& stream, int type) { { QTreeWidgetItem* parent = NULL; Sequence* s = new Sequence(); + bool open_sequence = false; - // load attributes about stream + // load attributes about sequence for (int j=0;jaudio_frequency = attr.value().toInt(); } else if (attr.name() == "alayout") { s->audio_layout = attr.value().toInt(); + } else if (attr.name() == "open") { + open_sequence = true; } } @@ -692,6 +696,8 @@ bool Project::load_worker(QFile& f, QXmlStreamReader& stream, int type) { } new_sequence(NULL, s, false, parent); + + if (open_sequence) set_sequence(s); } break; } @@ -835,6 +841,9 @@ void Project::save_folder(QXmlStreamWriter& stream, QTreeWidgetItem* parent, int stream.writeAttribute("framerate", QString::number(s->frame_rate)); stream.writeAttribute("afreq", QString::number(s->audio_frequency)); stream.writeAttribute("alayout", QString::number(s->audio_layout)); + if (s == sequence) { + stream.writeAttribute("open", "1"); + } for (int j=0;jclip_count();j++) { Clip* c = s->get_clip(j); if (c != NULL) { @@ -883,11 +892,11 @@ void Project::save_folder(QXmlStreamWriter& stream, QTreeWidgetItem* parent, int } } -void Project::save_project() { +void Project::save_project(bool autorecovery) { folder_id = 1; media_id = 0; - QFile file(project_url); + QFile file(autorecovery ? autorecovery_filename : project_url); if (!file.open(QIODevice::WriteOnly/* | QIODevice::Text*/)) { qDebug() << "[ERROR] Could not open file"; return; @@ -921,9 +930,10 @@ void Project::save_project() { file.close(); - add_recent_project(project_url); - - project_changed = false; + if (!autorecovery) { + add_recent_project(project_url); + project_changed = false; + } } void Project::save_recent_projects() { diff --git a/panels/project.h b/panels/project.h index 7b4e86b0d..ca96c67ae 100644 --- a/panels/project.h +++ b/panels/project.h @@ -31,6 +31,7 @@ namespace Ui { class Project; } +extern QString autorecovery_filename; extern bool project_changed; extern QString project_url; extern QStringList recent_projects; @@ -56,7 +57,7 @@ public: void new_project(); void load_project(); - void save_project(); + void save_project(bool autorecovery); QTreeWidgetItem* new_folder(); diff --git a/project/effect.cpp b/project/effect.cpp index 55a9aaa95..1592aa692 100644 --- a/project/effect.cpp +++ b/project/effect.cpp @@ -5,27 +5,36 @@ #include "ui/viewerwidget.h" #include "ui/collapsiblewidget.h" #include "effects/effects.h" +#include "panels/project.h" +#include "project/undo.h" #include +#include -Effect::Effect(Clip* c) : parent_clip(c) { - type = EFFECT_TYPE_INVALID; -} - -void Effect::setup_effect(int t, int i) { - type = t; - id = i; +Effect::Effect(Clip* c, int t, int i) : parent_clip(c), type(t), id(i) { container = new CollapsibleWidget(); if (type == EFFECT_TYPE_VIDEO) { container->setText(video_effect_names[i]); } else if (type == EFFECT_TYPE_AUDIO) { container->setText(audio_effect_names[i]); } + connect(container->enabled_check, SIGNAL(clicked(bool)), this, SLOT(checkbox_command())); + connect(container->enabled_check, SIGNAL(clicked(bool)), this, SLOT(field_changed())); ui = new QWidget(); + + ui_layout = new QGridLayout(); + ui->setLayout(ui_layout); + container->setContents(ui); } void Effect::field_changed() { panel_viewer->viewer_widget->update(); + project_changed = true; +} + +void Effect::checkbox_command() { + CheckboxCommand* c = new CheckboxCommand(static_cast(sender())); + undo_stack.push(c); } bool Effect::is_enabled() { diff --git a/project/effect.h b/project/effect.h index 320b6b5c1..d5ef79f4b 100644 --- a/project/effect.h +++ b/project/effect.h @@ -5,6 +5,7 @@ #include class QWidget; class CollapsibleWidget; +class QGridLayout; struct Clip; class QXmlStreamReader; @@ -16,13 +17,14 @@ class Effect : public QObject { Q_OBJECT public: - Effect(Clip* c); // default constructor + Effect(Clip* c, int t, int i); // default constructor + Clip* parent_clip; int type; int id; QString name; CollapsibleWidget* container; + QGridLayout* ui_layout; QWidget* ui; - Clip* parent_clip; bool is_enabled(); @@ -34,12 +36,9 @@ public: virtual void process_gl(int* anchor_x, int* anchor_y); virtual void post_gl(); virtual void process_audio(quint8* samples, int nb_bytes); - public slots: void field_changed(); - -protected: - void setup_effect(int t, int i); + void checkbox_command(); }; #endif // EFFECT_H diff --git a/project/undo.cpp b/project/undo.cpp index 1e67ff26f..655b15207 100644 --- a/project/undo.cpp +++ b/project/undo.cpp @@ -3,6 +3,7 @@ #include #include #include +#include #include "project/clip.h" #include "project/sequence.h" @@ -383,3 +384,18 @@ void LinkCommand::redo() { } } } + +CheckboxCommand::CheckboxCommand(QCheckBox* b) : box(b), done(true), checked(box->isChecked()) {} + +CheckboxCommand::~CheckboxCommand() {} + +void CheckboxCommand::undo() { + box->setChecked(!checked); + done = false; +} + +void CheckboxCommand::redo() { + if (!done) { + box->setChecked(checked); + } +} diff --git a/project/undo.h b/project/undo.h index 0f3d91d10..4b3ef7de5 100644 --- a/project/undo.h +++ b/project/undo.h @@ -2,6 +2,7 @@ #define UNDO_H class QTreeWidgetItem; +class QCheckBox; struct Clip; struct Sequence; @@ -79,4 +80,16 @@ private: QVector< QVector > old_links; }; +class CheckboxCommand : public QUndoCommand { +public: + CheckboxCommand(QCheckBox* b); + ~CheckboxCommand(); + void undo(); + void redo(); +private: + QCheckBox* box; + bool checked; + bool done; +}; + #endif // UNDO_H diff --git a/ui/colorbutton.cpp b/ui/colorbutton.cpp new file mode 100644 index 000000000..5a0245bec --- /dev/null +++ b/ui/colorbutton.cpp @@ -0,0 +1,48 @@ +#include "colorbutton.h" + +#include "project/undo.h" + +#include + +ColorButton::ColorButton(QWidget *parent) + : QPushButton(parent), color(Qt::white) { + set_button_color(); + connect(this, SIGNAL(clicked(bool)), this, SLOT(open_dialog())); +} + +QColor ColorButton::get_color() { + return color; +} + +void ColorButton::set_color(QColor c) { + color = c; +} + +void ColorButton::set_button_color() { + QPalette pal = palette(); + pal.setColor(QPalette::Button, color); + setPalette(pal); +} + +void ColorButton::open_dialog() { + QColor old_color = color; + QColor new_color = QColorDialog::getColor(color, NULL); + if (old_color != new_color) { + ColorCommand* command = new ColorCommand(this, old_color, new_color); + undo_stack.push(command); + + set_button_color(); + emit color_changed(); + } +} + +ColorCommand::ColorCommand(ColorButton* s, QColor o, QColor n) + : sender(s), old_color(o), new_color(n) {} + +void ColorCommand::undo() { + sender->set_color(old_color); +} + +void ColorCommand::redo() { + sender->set_color(new_color); +} diff --git a/ui/colorbutton.h b/ui/colorbutton.h new file mode 100644 index 000000000..3be4e6423 --- /dev/null +++ b/ui/colorbutton.h @@ -0,0 +1,34 @@ +#ifndef COLORBUTTON_H +#define COLORBUTTON_H + +#include +#include +#include + +class ColorButton : public QPushButton { + Q_OBJECT +public: + ColorButton(QWidget* parent = 0); + QColor get_color(); + void set_color(QColor c); +private: + QColor color; + void set_button_color(); +signals: + void color_changed(); +private slots: + void open_dialog(); +}; + +class ColorCommand : public QUndoCommand { +public: + ColorCommand(ColorButton* s, QColor o, QColor n); + void undo(); + void redo(); +private: + ColorButton* sender; + QColor old_color; + QColor new_color; +}; + +#endif // COLORBUTTON_H diff --git a/ui/comboboxex.cpp b/ui/comboboxex.cpp new file mode 100644 index 000000000..0aa84914a --- /dev/null +++ b/ui/comboboxex.cpp @@ -0,0 +1,41 @@ +#include "comboboxex.h" + +#include "project/undo.h" + +#include +#include + +class ComboBoxExCommand : public QUndoCommand { +public: + ComboBoxExCommand(ComboBoxEx* obj, int old_index, int new_index) : + combobox(obj), old_val(old_index), new_val(new_index), done(true) {} + void undo() { + combobox->setCurrentIndex(old_val); + done = false; + } + void redo() { + if (!done) { + combobox->setCurrentIndex(new_val); + } + } +private: + ComboBoxEx* combobox; + int old_val; + int new_val; + bool done; +}; + +ComboBoxEx::ComboBoxEx(QWidget *parent) : QComboBox(parent), index(0) { + connect(this, SIGNAL(activated(int)), this, SLOT(index_changed(int))); +} + +void ComboBoxEx::index_changed(int i) { + if (index != i) { + undo_stack.push(new ComboBoxExCommand(this, index, i)); + index = i; + } +} + +void ComboBoxEx::wheelEvent(QWheelEvent* e) { + e->ignore(); +} diff --git a/ui/comboboxex.h b/ui/comboboxex.h new file mode 100644 index 000000000..1aae6b9c4 --- /dev/null +++ b/ui/comboboxex.h @@ -0,0 +1,18 @@ +#ifndef COMBOBOXEX_H +#define COMBOBOXEX_H + +#include +#include + +class ComboBoxEx : public QComboBox { + Q_OBJECT +public: + ComboBoxEx(QWidget* parent = 0); +private slots: + void index_changed(int); +private: + int index; + void wheelEvent(QWheelEvent* e); +}; + +#endif // COMBOBOXEX_H diff --git a/ui/viewerwidget.cpp b/ui/viewerwidget.cpp index 899cd58cf..74e19cbc3 100644 --- a/ui/viewerwidget.cpp +++ b/ui/viewerwidget.cpp @@ -19,8 +19,7 @@ extern "C" { #include } -ViewerWidget::ViewerWidget(QWidget *parent) : QOpenGLWidget(parent) -{ +ViewerWidget::ViewerWidget(QWidget *parent) : QOpenGLWidget(parent) { multithreaded = true; enable_paint = true; force_audio = false; @@ -130,7 +129,7 @@ void ViewerWidget::paintGL() { // perform all transform effects for (int j=0;jeffects.size();j++) { - c->effects.at(j)->process_gl(&anchor_x, &anchor_y); + if (c->effects.at(j)->is_enabled()) c->effects.at(j)->process_gl(&anchor_x, &anchor_y); } if (c->opening_transition != NULL) { @@ -169,7 +168,7 @@ void ViewerWidget::paintGL() { // perform all transform effects for (int j=0;jeffects.size();j++) { - c->effects.at(j)->post_gl(); + if (c->effects.at(j)->is_enabled()) c->effects.at(j)->post_gl(); } } } else if (render_audio &&