aboutsummaryrefslogtreecommitdiff
path: root/src/animationlayer.h
diff options
context:
space:
mode:
authorTrickyLeifa <date.epoch@gmail.com>2024-05-22 22:10:29 +0200
committerTrickyLeifa <date.epoch@gmail.com>2024-05-22 22:10:29 +0200
commit695d51dbfe858d877408de78b424c1af8fc30e3a (patch)
tree8add1fce52295ff7acd19856d6cd19f1ce2b3928 /src/animationlayer.h
parent137a2d3a04bb0381d1923b1a9530d1cdd9872e88 (diff)
Complete AOLayer reimplementation, ...
* Complete AOLayer reimplementation * Reimplemented sliding as well.
Diffstat (limited to 'src/animationlayer.h')
-rw-r--r--src/animationlayer.h261
1 files changed, 261 insertions, 0 deletions
diff --git a/src/animationlayer.h b/src/animationlayer.h
new file mode 100644
index 00000000..da64354a
--- /dev/null
+++ b/src/animationlayer.h
@@ -0,0 +1,261 @@
+#pragma once
+
+#include "animationloader.h"
+
+#include <QBitmap>
+#include <QDebug>
+#include <QLabel>
+#include <QPropertyAnimation>
+#include <QTimer>
+
+// #define DEBUG_MOVIE
+
+#ifdef DEBUG_MOVIE
+#include <QElapsedTimer>
+#endif
+
+class AOApplication;
+class VPath;
+
+// "Brief" explanation of what the hell this is:
+//
+// AOLayer handles all animations both inside and outside
+// the viewport. It was originally devised as a layering
+// system, but turned into a full refactor of the existing
+// animation code.
+//
+// AOLayer has six subclasses, all of which differ mainly in
+// how they handle path resolution.
+//
+// - BackgroundLayer: self-explanatory, handles files found in base/background
+// - CharLayer: handles all the "wonderful" quirks of character path resolution
+// - SplashLayer: handles elements that can either be provided by a misc/ directory
+// or by the theme - speedlines, shouts, WT/CE, et cetera
+// - EffectLayer: this is basically a dummy layer since effects do their own wonky
+// path resolution in a different file
+// - InterfaceLayer: handles UI elements like the chat arrow and the music display
+// - StickerLayer: Crystalwarrior really wanted this. Handles "stickers," whatever those are.
+//
+// For questions comments or concerns, bother someone else
+
+namespace kal
+{
+class AnimationLayer : public QLabel
+{
+ Q_OBJECT
+
+public:
+ explicit AnimationLayer(QWidget *parent = nullptr);
+ virtual ~AnimationLayer();
+
+ QString fileName();
+ void setFileName(QString fileName);
+
+ void startPlayback();
+ void stopPlayback();
+ void restartPlayback();
+ void pausePlayback(bool enabled);
+
+ QSize frameSize();
+
+ int frameCount();
+ int currentFrameNumber();
+ void jumpToFrame(int number);
+
+ void setPlayOnce(bool enabled);
+ void setStretchToFit(bool enabled);
+ void setResetCacheWhenStopped(bool enabled);
+ void setFlipped(bool enabled);
+ void setTransformationMode(Qt::TransformationMode mode);
+ void setMinimumDurationPerFrame(int duration);
+ void setMaximumDurationPerFrame(int duration);
+
+public Q_SLOTS:
+ void setMaskingRect(QRect rect);
+
+Q_SIGNALS:
+ void startedPlayback();
+ void stoppedPlayback(); /* Is emitted whenever playback is stopped, whether by user or by reaching the end */
+ void finishedPlayback(); /* Is emitted only when playback reaches the end */
+ void frameNumberChanged(int frameNumber);
+
+protected:
+ void resizeEvent(QResizeEvent *event) override;
+
+private:
+ QString m_file_name;
+ bool m_play_once = false;
+ bool m_stretch_to_fit = false;
+ bool m_reset_cache_when_stopped = false;
+ bool m_flipped = false;
+ int m_minimum_duration = 0;
+ int m_maximum_duration = 0;
+ Qt::TransformationMode m_transformation_mode = Qt::FastTransformation;
+ AnimationLoader *m_loader = nullptr;
+ QSize m_frame_size;
+ QRect m_frame_rect;
+ QRect m_mask_rect_hint;
+ QRect m_mask_rect;
+ QRect m_display_rect;
+ QSize m_scaled_frame_size;
+ bool m_processing = false;
+ bool m_pause = false;
+ QTimer *m_ticker = nullptr;
+ bool m_first_frame = false;
+ int m_frame_number = 0;
+ int m_frame_count = 0;
+ AnimationFrame m_current_frame;
+
+ void createLoader();
+ void deleteLoader();
+
+ void resetData();
+
+ void calculateFrameGeometry();
+
+ void finishPlayback();
+
+ void prepareNextTick();
+
+ void displayCurrentFrame();
+
+private Q_SLOTS:
+ void frameTicker();
+};
+
+class CharacterAnimationLayer : public AnimationLayer
+{
+ Q_OBJECT
+
+public:
+ enum EmoteType
+ {
+ NoEmoteType,
+ PreEmote,
+ IdleEmote,
+ TalkEmote,
+ PostEmote,
+ };
+
+ enum EffectType
+ {
+ SfxEffect,
+ ShakeEffect,
+ FlashEffect,
+ };
+
+ class FrameEffect
+ {
+ public:
+ QString emote_name;
+ EffectType type = SfxEffect;
+ QString file_name;
+ };
+
+ CharacterAnimationLayer(AOApplication *ao_app, QWidget *parent = nullptr);
+
+ void loadCharacterEmote(QString character, QString fileName, EmoteType emoteType, int durationLimit = 0);
+
+ void setFrameEffects(QStringList data);
+
+Q_SIGNALS:
+ void finishedPreOrPostEmotePlayback();
+
+ void soundEffect(QString sfx);
+ void shakeEffect();
+ void flashEffect();
+
+private:
+ AOApplication *ao_app;
+
+ QString m_character;
+ QString m_emote;
+ EmoteType m_emote_type = NoEmoteType;
+ QTimer *m_duration_timer = nullptr;
+ int m_duration = 0;
+
+ QMap<int, QList<FrameEffect>> m_effects;
+
+ void startTimeLimit();
+
+private Q_SLOTS:
+ void onPlaybackStopped();
+ void onPlaybackFinished();
+ void onDurationLimitReached();
+
+ void notifyFrameEffect(int frame);
+ void notifyEmotePlaybackFinished();
+};
+
+class BackgroundAnimationLayer : public AnimationLayer
+{
+ Q_OBJECT
+
+public:
+ BackgroundAnimationLayer(AOApplication *ao_app, QWidget *parent = nullptr);
+
+ void loadAndPlayAnimation(QString fileName);
+
+private:
+ AOApplication *ao_app;
+};
+
+class SplashAnimationLayer : public AnimationLayer
+{
+ Q_OBJECT
+
+public:
+ SplashAnimationLayer(AOApplication *ao_app, QWidget *parent = nullptr);
+
+ void loadAndPlayAnimation(QString fileName, QString character, QString miscellaneous);
+
+private:
+ AOApplication *ao_app;
+};
+
+class EffectAnimationLayer : public AnimationLayer
+{
+ Q_OBJECT
+
+public:
+ EffectAnimationLayer(AOApplication *ao_app, QWidget *parent = nullptr);
+
+ void loadAndPlayAnimation(QString fileName, bool repeat = false);
+
+ void setHideWhenStopped(bool enabled);
+
+private:
+ AOApplication *ao_app;
+
+ bool m_hide_when_stopped = false;
+
+private Q_SLOTS:
+ void maybeHide();
+};
+
+class InterfaceAnimationLayer : public AnimationLayer
+{
+ Q_OBJECT
+
+public:
+ InterfaceAnimationLayer(AOApplication *ao_app, QWidget *parent = nullptr);
+
+ void loadAndPlayAnimation(QString fileName, QString miscName);
+
+private:
+ AOApplication *ao_app;
+};
+
+class StickerAnimationLayer : public AnimationLayer
+{
+ Q_OBJECT
+
+public:
+ StickerAnimationLayer(AOApplication *ao_app, QWidget *parent = nullptr);
+
+ void loadAndPlayAnimation(QString fileName);
+
+private:
+ AOApplication *ao_app;
+};
+} // namespace kal