Files
utun2/tools/chatgui/src/imageviewer_window.h
T

71 lines
4.8 KiB
C++

/* Просмотр изображения в GUI-потоке: вписывание, Ctrl+колесо (1..8 от вписанного размера),
* перенос увеличенного изображения левой кнопкой, сброс двойным левым кликом, закрытие по Esc.
* Подходит для отдельного окна и вложенного виджета; fullscreen здесь не реализован.
* Закрытие не удаляет объект (WA_DeleteOnClose=false); владелец может повторно показать его. */
#pragma once
#include <QWidget>
#include <QPixmap>
class QPushButton;
class QLabel;
class QTimer;
class QPropertyAnimation;
class QGraphicsOpacityEffect;
class ImageViewerWindow : public QWidget {
Q_OBJECT
public:
/* parent владеет виджетом; без parent время жизни контролирует вызывающий код. */
explicit ImageViewerWindow(QWidget *parent = nullptr);
/* Синхронно читает path с EXIF-поворотом; успех сбрасывает масштаб/смещение, ошибка очищает изображение и логируется. */
void loadFile(const QString& path);
/* Заменяет изображение и сбрасывает вид; пустое изображение включает текст заглушки. */
void loadImage(const QImage& image);
/* Текст при пустом изображении; пустая строка выбирает стандартное сообщение об ошибке. */
void setPlaceholder(const QString& text) { m_placeholder = text; update(); }
signals:
/* Испускается из closeEvent до стандартного закрытия QWidget; для удаления используйте deleteLater. */
void closed();
protected:
void paintEvent(QPaintEvent *event) override;
void wheelEvent(QWheelEvent *event) override;
void mousePressEvent(QMouseEvent *event) override;
void mouseMoveEvent(QMouseEvent *event) override;
void mouseReleaseEvent(QMouseEvent *event) override;
void mouseDoubleClickEvent(QMouseEvent *event) override;
void keyPressEvent(QKeyEvent *event) override;
void closeEvent(QCloseEvent *event) override;
void resizeEvent(QResizeEvent *event) override;
private:
/* Возвращает вписанный размер, нулевое смещение и снимает состояние перетаскивания. */
void resetView();
/* Ограничивает смещение краями увеличенного изображения; по вписавшейся оси смещение равно нулю. */
void clampOffset();
/* Показывает кнопку/подсказку с анимацией и перезапускает таймер скрытия на 1 секунду. */
void showOverlay();
/* Запускает затухание кнопки/подсказки на 300 мс. */
void hideOverlay();
/* Перезапускает anim от текущей прозрачности eff к target за durMs миллисекунд. */
void fadeTo(QPropertyAnimation* anim, QGraphicsOpacityEffect* eff,
int durMs, double target);
QPixmap m_image; /* Текущее изображение; пустое — рисуется заглушка. */
QString m_placeholder; /* Необязательный текст заглушки. */
double m_scale = 1.0; /* Множитель базового вписывания, 1..8. */
QPointF m_offset; /* смещение изображения в пикселях виджета */
bool m_dragging = false; /* Идёт перенос левой кнопкой. */
QPointF m_dragStart; /* Координаты мыши в виджете в начале переноса. */
QPointF m_offsetStart; /* Смещение изображения в начале переноса. */
QPushButton* m_closeBtn = nullptr; /* Дочерняя кнопка закрытия. */
QGraphicsOpacityEffect* m_closeEffect = nullptr; /* Эффект принадлежит кнопке. */
QPropertyAnimation* m_closeFade = nullptr; /* Дочерняя анимация кнопки. */
QLabel* m_hintLabel = nullptr; /* Дочерняя подсказка о Ctrl+колесе. */
QGraphicsOpacityEffect* m_hintEffect = nullptr; /* Эффект принадлежит подсказке. */
QPropertyAnimation* m_hintFade = nullptr; /* Дочерняя анимация подсказки. */
QTimer* m_hideTimer = nullptr; /* Дочерний однократный таймер скрытия. */
};