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