File indexing completed on 2025-02-02 04:11:33
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 "frame_controls_widget.hpp" 0008 #include "ui_frame_controls_widget.h" 0009 0010 #include <cmath> 0011 0012 #include "glaxnimate_app.hpp" 0013 0014 using namespace glaxnimate::gui; 0015 using namespace glaxnimate; 0016 0017 FrameControlsWidget::FrameControlsWidget(QWidget* parent) 0018 : QWidget(parent), d(std::make_unique<Ui::FrameControlsWidget>()) 0019 { 0020 d->setupUi(this); 0021 0022 #ifdef Q_OS_ANDROID 0023 d->layout->setMargin(0); 0024 d->layout->setSpacing(0); 0025 #endif 0026 0027 d->button_record->setIcon(QIcon::fromTheme("keyframe-record")); 0028 0029 d->button_next_kf->setVisible(false); 0030 d->button_prev_kf->setVisible(false); 0031 connect(d->button_record, &QAbstractButton::clicked, this, &FrameControlsWidget::record_toggled); 0032 connect(d->button_loop, &QAbstractButton::clicked, this, &FrameControlsWidget::loop_changed); 0033 } 0034 0035 FrameControlsWidget::~FrameControlsWidget() = default; 0036 0037 void FrameControlsWidget::changeEvent ( QEvent* e ) 0038 { 0039 QWidget::changeEvent(e); 0040 if ( e->type() == QEvent::LanguageChange) 0041 { 0042 d->retranslateUi(this); 0043 } 0044 } 0045 0046 void FrameControlsWidget::play_toggled(bool checked) 0047 { 0048 if ( checked ) 0049 play(); 0050 else 0051 pause(); 0052 } 0053 0054 void FrameControlsWidget::set_min(int min) 0055 { 0056 d->spin_frame->setMinimum(min); 0057 Q_EMIT min_changed(min); 0058 } 0059 0060 void FrameControlsWidget::set_max(int max) 0061 { 0062 d->spin_frame->setMaximum(max-1); 0063 Q_EMIT max_changed(max-1); 0064 } 0065 0066 void FrameControlsWidget::set_range(int min, int max) 0067 { 0068 d->spin_frame->setRange(min, max-1); 0069 d->spin_frame->setValue(min); 0070 Q_EMIT min_changed(min); 0071 Q_EMIT max_changed(max-1); 0072 } 0073 0074 void FrameControlsWidget::set_fps(qreal fps) 0075 { 0076 this->fps = fps; 0077 Q_EMIT fps_changed(fps); 0078 } 0079 0080 void FrameControlsWidget::timerEvent(QTimerEvent*) 0081 { 0082 if ( d->spin_frame->maximum() <= d->spin_frame->minimum() || fps <= 0 ) 0083 return; 0084 0085 auto range_frames = d->spin_frame->maximum() - d->spin_frame->minimum(); 0086 0087 std::chrono::duration<double> offset = std::chrono::high_resolution_clock::now() - playback_start; 0088 auto seconds_off = offset.count(); 0089 qreal frame_off = seconds_off * fps + frame_start; 0090 0091 if ( frame_off >= range_frames && !d->button_loop->isChecked() ) 0092 { 0093 pause(); 0094 d->spin_frame->setValue(d->spin_frame->minimum()); 0095 return; 0096 } 0097 0098 d->spin_frame->setValue(d->spin_frame->minimum() + qRound(std::fmod(frame_off, range_frames))); 0099 } 0100 0101 void FrameControlsWidget::play() 0102 { 0103 if ( !timer ) 0104 { 0105 timer = startTimer(playback_tick, Qt::PreciseTimer); 0106 playback_start = std::chrono::high_resolution_clock::now(); 0107 frame_start = d->spin_frame->value(); 0108 d->button_play->setChecked(true); 0109 d->button_play->setIcon(QIcon::fromTheme("media-playback-pause")); 0110 Q_EMIT play_started(); 0111 } 0112 } 0113 0114 void FrameControlsWidget::pause() 0115 { 0116 if ( timer ) 0117 { 0118 killTimer(timer); 0119 timer = 0; 0120 d->button_play->setChecked(false); 0121 d->button_play->setIcon(QIcon::fromTheme("media-playback-start")); 0122 Q_EMIT play_stopped(); 0123 } 0124 } 0125 0126 void FrameControlsWidget::commit_time() 0127 { 0128 Q_EMIT frame_selected(d->spin_frame->value()); 0129 } 0130 0131 void FrameControlsWidget::go_first() 0132 { 0133 d->spin_frame->setValue(d->spin_frame->minimum()); 0134 } 0135 0136 void FrameControlsWidget::go_last() 0137 { 0138 d->spin_frame->setValue(d->spin_frame->maximum()); 0139 } 0140 0141 void FrameControlsWidget::go_next() 0142 { 0143 int i = d->spin_frame->value(); 0144 if ( i >= d->spin_frame->maximum() && d->button_loop->isChecked() ) 0145 d->spin_frame->setValue(d->spin_frame->minimum()); 0146 else 0147 d->spin_frame->setValue(i+1); 0148 } 0149 0150 void FrameControlsWidget::go_prev() 0151 { 0152 int i = d->spin_frame->value(); 0153 if ( i <= d->spin_frame->minimum() && d->button_loop->isChecked() ) 0154 d->spin_frame->setValue(d->spin_frame->maximum()); 0155 else 0156 d->spin_frame->setValue(i-1); 0157 } 0158 0159 void FrameControlsWidget::set_frame(int frame) 0160 { 0161 d->spin_frame->setValue(frame); 0162 } 0163 0164 void FrameControlsWidget::set_record_enabled(bool enabled) 0165 { 0166 d->button_record->setChecked(enabled); 0167 } 0168 0169 void FrameControlsWidget::toggle_play() 0170 { 0171 if ( timer ) 0172 pause(); 0173 else 0174 play(); 0175 } 0176 0177 void FrameControlsWidget::set_loop(bool loop) 0178 { 0179 d->button_loop->setChecked(loop); 0180 }