File indexing completed on 2025-02-02 04:11:26
0001 /* 0002 * SPDX-FileCopyrightText: 2019-2023 Mattia Basaglia <dev@dragon.best> 0003 * 0004 * SPDX-License-Identifier: GPL-3.0-or-later 0005 */ 0006 0007 #include "timing_dialog.hpp" 0008 #include "ui_timing_dialog.h" 0009 0010 #include <limits> 0011 0012 #include <QEvent> 0013 0014 #include "command/undo_macro_guard.hpp" 0015 #include "command/animation_commands.hpp" 0016 #include "model/simple_visitor.hpp" 0017 #include "model/assets/composition.hpp" 0018 0019 using namespace glaxnimate::gui; 0020 using namespace glaxnimate; 0021 0022 class TimingDialog::Private 0023 { 0024 public: 0025 model::Composition* comp; 0026 bool changed = false; 0027 Ui::TimingDialog ui; 0028 }; 0029 0030 TimingDialog::TimingDialog(model::Composition* comp, QWidget* parent) 0031 : QDialog(parent), d(std::make_unique<Private>()) 0032 { 0033 d->comp = comp; 0034 d->ui.setupUi(this); 0035 0036 d->ui.spin_seconds->setMaximum(std::numeric_limits<float>::max()); 0037 d->ui.spin_frames->setMaximum(std::numeric_limits<int>::max()); 0038 0039 d->ui.spin_seconds->blockSignals(true); 0040 d->ui.spin_fps->blockSignals(true); 0041 d->ui.spin_frames->blockSignals(true); 0042 0043 float fps = comp->fps.get(); 0044 d->ui.spin_fps->setValue(fps); 0045 float n_frames = d->comp->animation->last_frame.get() - d->comp->animation->first_frame.get(); 0046 if ( fps != 0 ) 0047 d->ui.spin_seconds->setValue(n_frames / fps); 0048 0049 d->ui.spin_frames->setValue(n_frames); 0050 0051 0052 d->ui.spin_seconds->blockSignals(false); 0053 d->ui.spin_fps->blockSignals(false); 0054 d->ui.spin_frames->blockSignals(false); 0055 } 0056 0057 TimingDialog::~TimingDialog() = default; 0058 0059 void TimingDialog::changeEvent ( QEvent* e ) 0060 { 0061 QDialog::changeEvent(e); 0062 0063 if ( e->type() == QEvent::LanguageChange) 0064 { 0065 d->ui.retranslateUi(this); 0066 } 0067 } 0068 0069 void TimingDialog::btn_clicked(QAbstractButton* button) 0070 { 0071 auto role = d->ui.button_box->buttonRole(button); 0072 0073 if ( role == QDialogButtonBox::RejectRole ) 0074 { 0075 reject(); 0076 return; 0077 } 0078 0079 if ( d->changed ) 0080 { 0081 0082 qreal last_frame = d->comp->animation->first_frame.get() + d->ui.spin_frames->value(); 0083 command::UndoMacroGuard guard(i18n("Change Animation Properties"), d->comp->document()); 0084 0085 if ( d->ui.check_layer_scale->isChecked() ) 0086 { 0087 if ( last_frame != 0 ) 0088 { 0089 qreal multiplier = last_frame / d->comp->animation->last_frame.get(); 0090 d->comp->push_command(new command::StretchTimeCommand(d->comp, multiplier)); 0091 } 0092 } 0093 else 0094 { 0095 d->comp->animation->last_frame.set_undoable(last_frame); 0096 0097 if ( d->ui.check_layer_trim->isChecked() ) 0098 { 0099 model::simple_visit<model::Layer>(d->comp, true, [last_frame](model::Layer* layer){ 0100 if ( layer->animation->last_frame.get() > last_frame ) 0101 layer->animation->last_frame.set(last_frame); 0102 }); 0103 } 0104 } 0105 0106 d->comp->fps.set(d->ui.spin_fps->value()); 0107 } 0108 0109 if ( role == QDialogButtonBox::AcceptRole ) 0110 accept(); 0111 } 0112 0113 void TimingDialog::changed_fps(double fps) 0114 { 0115 d->ui.spin_seconds->setValue(d->ui.spin_frames->value() / fps); 0116 d->changed = true; 0117 } 0118 0119 void TimingDialog::changed_frames(int f) 0120 { 0121 d->ui.spin_seconds->setValue(f / d->ui.spin_fps->value()); 0122 d->changed = true; 0123 } 0124 0125 void TimingDialog::changed_seconds(double s) 0126 { 0127 d->ui.spin_frames->setValue(qRound(d->ui.spin_fps->value() * s)); 0128 d->changed = true; 0129 } 0130 0131