All Classes Namespaces Functions Variables Enumerations Properties Pages
layeropacitydialog.cpp
1 #include "layeropacitydialog.h"
2 #include "ui_layeropacitydialog.h"
3 
4 #include "layermanager.h"
5 #include "playbackmanager.h"
6 #include "layer.h"
7 #include "layerbitmap.h"
8 #include "bitmapimage.h"
9 #include "layervector.h"
10 #include "vectorimage.h"
11 
12 
13 LayerOpacityDialog::LayerOpacityDialog(QWidget *parent) :
14  QDialog(parent, Qt::Tool),
15  ui(new Ui::LayerOpacityDialog)
16 {
17  ui->setupUi(this);
18 }
19 
20 LayerOpacityDialog::~LayerOpacityDialog()
21 {
22  delete ui;
23 }
24 
25 void LayerOpacityDialog::setCore(Editor *editor)
26 {
27  mEditor = editor;
28  mLayerManager = mEditor->layers();
29  mPlayBack = mEditor->playback();
30 }
31 
32 void LayerOpacityDialog::initUI()
33 {
34 
35  connect(ui->chooseOpacitySlider, &QSlider::valueChanged, this, &LayerOpacityDialog::opacitySliderChanged);
36  auto spinboxValueChanged = static_cast<void (QDoubleSpinBox::*)(double)>(&QDoubleSpinBox::valueChanged);
37  connect(ui->chooseOpacitySpinBox, spinboxValueChanged, this, &LayerOpacityDialog::opacitySpinboxChanged);
38  connect(ui->btnFadeIn, &QPushButton::pressed, this, &LayerOpacityDialog::fadeInPressed);
39  connect(ui->btnFadeOut, &QPushButton::pressed, this, &LayerOpacityDialog::fadeOutPressed);
41  connect(ui->rbActiveKeyframe, &QRadioButton::toggled, this, &LayerOpacityDialog::updateUI);
42  connect(ui->rbSelectedKeyframes, &QRadioButton::toggled, this, &LayerOpacityDialog::updateUI);
43  connect(ui->rbActiveLayer, &QRadioButton::toggled, this, &LayerOpacityDialog::updateUI);
44 
46 
47  connect(mEditor, &Editor::objectLoaded, this, &LayerOpacityDialog::onObjectLoaded);
48  connect(mEditor, &Editor::scrubbed, this, &LayerOpacityDialog::onCurrentFrameChanged);
49  connect(mPlayBack, &PlaybackManager::playStateChanged, this, &LayerOpacityDialog::onPlayStateChanged);
50  connect(mLayerManager, &LayerManager::currentLayerChanged, this, &LayerOpacityDialog::onCurrentLayerChanged);
51  connect(mEditor, &Editor::selectedFramesChanged, this, &LayerOpacityDialog::onSelectedFramesChanged);
52 
53  onObjectLoaded();
54 }
55 
56 void LayerOpacityDialog::updateUI()
57 {
58  Layer* currentLayer = mLayerManager->currentLayer();
59  if (currentLayer == nullptr) { return; }
60 
61  ui->labLayerInfo->setText(tr("Layer: %1").arg(currentLayer->name()));
62  if (currentLayer->type() != Layer::BITMAP && currentLayer->type() != Layer::VECTOR) {
63  setCanAdjust(false, false);
64  return;
65  }
66 
67  bool canAdjust = false;
68  if (ui->rbActiveKeyframe->isChecked()) {
69  KeyFrame* keyframe = currentLayer->getLastKeyFrameAtPosition(mEditor->currentFrame());
70  canAdjust = keyframe != nullptr;
71  } else if (ui->rbSelectedKeyframes->isChecked()) {
72  canAdjust = !currentLayer->getSelectedFramesByPos().isEmpty();
73  } else if (ui->rbActiveLayer->isChecked()) {
74  canAdjust = true;
75  }
76 
77  ui->chooseOpacitySlider->setEnabled(canAdjust);
78  ui->chooseOpacitySpinBox->setEnabled(canAdjust);
79 }
80 
81 void LayerOpacityDialog::onObjectLoaded()
82 {
83  Layer* currentLayer = mLayerManager->currentLayer();
84  if (currentLayer == nullptr) { return; }
85 
86  if (currentLayer->type() != Layer::BITMAP && currentLayer->type() != Layer::VECTOR) { return; }
87 
88  KeyFrame* keyframe = currentLayer->getLastKeyFrameAtPosition(mEditor->currentFrame());
89 
90  if (keyframe) {
91  updateValues(getOpacityForKeyFrame(currentLayer, keyframe));
92  } else {
93  updateValues(100);
94  }
95 
96  updateUI();
97 }
98 
99 qreal LayerOpacityDialog::getOpacityForKeyFrame(Layer* layer, const KeyFrame* keyframe) const
100 {
101  if (layer->type() == Layer::BITMAP) {
102  const BitmapImage* bitmap = static_cast<const BitmapImage*>(keyframe);
103  return bitmap->getOpacity();
104  } else if (layer->type() == Layer::VECTOR) {
105  const VectorImage* vector = static_cast<const VectorImage*>(keyframe);
106  return vector->getOpacity();
107  } else {
108  return -1;
109  }
110 }
111 
112 void LayerOpacityDialog::setOpacityForKeyFrame(Layer* layer, KeyFrame* keyframe, qreal opacity)
113 {
114  if (layer->type() == Layer::BITMAP) {
115  BitmapImage* bitmap = static_cast<BitmapImage*>(keyframe);
116  bitmap->setOpacity(opacity);
117  layer->markFrameAsDirty(bitmap->pos());
118  } else if (layer->type() == Layer::VECTOR) {
119  VectorImage* vector = static_cast<VectorImage*>(keyframe);
120  vector->setOpacity(opacity);
121  layer->markFrameAsDirty(vector->pos());
122  }
123 }
124 
125 void LayerOpacityDialog::opacitySliderChanged(int value)
126 {
127  ui->chooseOpacitySpinBox->setValue(value * mSpinBoxMultiplier);
128  opacityValueChanged();
129 }
130 
131 void LayerOpacityDialog::opacitySpinboxChanged(double value)
132 {
133  ui->chooseOpacitySlider->setValue(static_cast<int>(value * 5.0));
134  opacityValueChanged();
135 }
136 
137 void LayerOpacityDialog::fade(OpacityFadeType fadeType)
138 {
139  QSignalBlocker b1(ui->chooseOpacitySlider);
140  QSignalBlocker b2(ui->chooseOpacitySpinBox);
141 
142  Layer* currentLayer = mLayerManager->currentLayer();
143  if (currentLayer == nullptr) { return; }
144 
145  if (currentLayer->type() != Layer::BITMAP && currentLayer->type() != Layer::VECTOR) { return; }
146 
147  QList<int> selectedKeys = currentLayer->getSelectedFramesByPos();
148 
149  if (selectedKeys.count() < mMinSelectedFrames) { return; }
150 
151  // OUT
152  int fadeFromPos = selectedKeys.first();
153  int fadeStart = 1;
154  int fadeEnd = selectedKeys.count();
155 
156  if (fadeType == OpacityFadeType::IN) {
157  fadeFromPos = selectedKeys.last();
158  fadeStart = 0;
159  fadeEnd = selectedKeys.count() - 1;
160  }
161 
162  KeyFrame* keyframe = currentLayer->getLastKeyFrameAtPosition(fadeFromPos);
163  if (keyframe == nullptr) { return; }
164 
165  qreal initialOpacity = getOpacityForKeyFrame(currentLayer, keyframe);
166 
167  qreal imageCount = static_cast<qreal>(selectedKeys.count());
168  for (int i = fadeStart; i < fadeEnd; i++)
169  {
170  keyframe = currentLayer->getLastKeyFrameAtPosition(selectedKeys.at(i));
171  if (keyframe == nullptr) { continue; }
172 
173  qreal newOpacity = 0;
174  if (fadeType == OpacityFadeType::IN) {
175  newOpacity = static_cast<qreal>((i + 1) / imageCount) * initialOpacity;
176  } else {
177  newOpacity = static_cast<qreal>(initialOpacity - (i / imageCount) * initialOpacity);
178  }
179  setOpacityForKeyFrame(currentLayer, keyframe, newOpacity);
180  }
181 
182  keyframe = currentLayer->getLastKeyFrameAtPosition(mEditor->currentFrame());
183  if (keyframe == nullptr) { return; }
184 
185  qreal imageOpacity = getOpacityForKeyFrame(currentLayer, keyframe);
186  updateValues(imageOpacity);
187 
188  emit mEditor->framesModified();
189 }
190 
191 void LayerOpacityDialog::fadeInPressed()
192 {
193  fade(OpacityFadeType::IN);
194 }
195 
196 void LayerOpacityDialog::fadeOutPressed()
197 {
198  fade(OpacityFadeType::OUT);
199 }
200 
201 void LayerOpacityDialog::onCurrentLayerChanged(int)
202 {
203  onCurrentFrameChanged(mEditor->currentFrame());
204  updateUI();
205 }
206 
207 void LayerOpacityDialog::onCurrentFrameChanged(int frame)
208 {
209  if (mPlayerIsPlaying) { return; }
210 
211  Layer* currentLayer = mLayerManager->currentLayer();
212  if (currentLayer == nullptr) { return; }
213 
214  if (currentLayer->type() != Layer::BITMAP && currentLayer->type() != Layer::VECTOR) {
215  setCanAdjust(false, false);
216  return;
217  }
218 
219  KeyFrame* keyframe = currentLayer->getLastKeyFrameAtPosition(frame);
220  if (keyframe) {
221  updateValues(getOpacityForKeyFrame(currentLayer, keyframe));
222  }
223  updateUI();
224 }
225 
226 void LayerOpacityDialog::onSelectedFramesChanged()
227 {
228  Layer* currentLayer = mLayerManager->currentLayer();
229  if (currentLayer == nullptr) { return; }
230 
231  QList<int> frames = currentLayer->getSelectedFramesByPos();
232 
233  ui->groupBoxFade->setEnabled(frames.count() >= mMinSelectedFrames);
234  updateUI();
235 }
236 
237 void LayerOpacityDialog::onPlayStateChanged(bool isPlaying)
238 {
239  mPlayerIsPlaying = isPlaying;
240 
241  if (!mPlayerIsPlaying) {
242  onCurrentFrameChanged(mEditor->currentFrame());
243  }
244  updateUI();
245 }
246 
247 void LayerOpacityDialog::updateValues(qreal opacity)
248 {
249  QSignalBlocker b1(ui->chooseOpacitySlider);
250  QSignalBlocker b2(ui->chooseOpacitySpinBox);
251 
252  int newOpacity = static_cast<int>(opacity * mMultiplier);
253  ui->chooseOpacitySlider->setValue(newOpacity);
254  ui->chooseOpacitySpinBox->setValue(newOpacity * mSpinBoxMultiplier);
255 }
256 
257 void LayerOpacityDialog::opacityValueChanged()
258 {
259  if (ui->rbActiveKeyframe->isChecked()) {
260  setOpacityForCurrentKeyframe();
261  } else if (ui->rbActiveLayer->isChecked()) {
262  setOpacityForLayer();
263  } else if (ui->rbSelectedKeyframes->isChecked()) {
264  setOpacityForSelectedKeyframes();
265  }
266 }
267 
268 void LayerOpacityDialog::setOpacityForCurrentKeyframe()
269 {
270  Layer* currentLayer = mLayerManager->currentLayer();
271  if (currentLayer == nullptr) { return; }
272 
273  if (currentLayer->type() != Layer::BITMAP && currentLayer->type() != Layer::VECTOR) { return; }
274 
275  KeyFrame* keyframe = currentLayer->getLastKeyFrameAtPosition(mEditor->currentFrame());
276  if (keyframe == nullptr) { return; }
277 
278  qreal opacity = ui->chooseOpacitySlider->value() / mMultiplier;
279  setOpacityForKeyFrame(currentLayer, keyframe, opacity);
280 
281  emit mEditor->framesModified();
282 }
283 
284 void LayerOpacityDialog::setOpacityForSelectedKeyframes()
285 {
286  Layer* currentLayer = mLayerManager->currentLayer();
287  if (currentLayer == nullptr) { return; }
288 
289  QList<int> frames = currentLayer->getSelectedFramesByPos();
290 
291  if (frames.isEmpty()) { return; }
292 
293  qreal opacity = static_cast<qreal>(ui->chooseOpacitySlider->value()) / mMultiplier;
294 
295  for (int pos : frames)
296  {
297  KeyFrame* keyframe = currentLayer->getKeyFrameAt(pos);
298  Q_ASSERT(keyframe);
299 
300  setOpacityForKeyFrame(currentLayer, keyframe, opacity);
301  }
302 
303  emit mEditor->framesModified();
304 }
305 
306 void LayerOpacityDialog::setOpacityForLayer()
307 {
308  Layer* currentLayer = mLayerManager->currentLayer();
309  if (currentLayer == nullptr) { return; }
310 
311  qreal opacity = static_cast<qreal>(ui->chooseOpacitySlider->value()) / mMultiplier;
312 
313  currentLayer->foreachKeyFrame([this, currentLayer, opacity](KeyFrame* keyframe) {
314  Q_ASSERT(keyframe);
315 
316  setOpacityForKeyFrame(currentLayer, keyframe, opacity);
317  });
318 
319  emit mEditor->framesModified();
320 }
321 
322 void LayerOpacityDialog::setCanAdjust(bool opacity, bool fade)
323 {
324  ui->groupBoxFade->setEnabled(fade);
325  ui->chooseOpacitySlider->setEnabled(opacity);
326  ui->chooseOpacitySpinBox->setEnabled(opacity);
327 }
bool close()
void setupUi(QWidget *widget)
const T & at(int i) const const
void scrubbed(int frameNumber)
This should be emitted after scrubbing.
QString tr(const char *sourceText, const char *disambiguation, int n)
void finished(int result)
int count(const T &value) const const
void markFrameAsDirty(const int frameNumber)
Mark the frame position as dirty.
Definition: layer.h:166
void valueChanged(double d)
bool isEmpty() const const
Definition: layer.h:38
QPoint pos() const const
T & first()
void toggled(bool checked)
T & last()
void valueChanged(int value)
Definition: editor.h:55
QMetaObject::Connection connect(const QObject *sender, const char *signal, const QObject *receiver, const char *method, Qt::ConnectionType type)
void framesModified()
This should be emitted after modifying multiple frames.