Skip to content

Commit

Permalink
chore: [merge] merge imageviewer newer code to album
Browse files Browse the repository at this point in the history
   merge imageviewer newer code to album

Log: merge imageviewer newer code to album
  • Loading branch information
starhcq committed Sep 20, 2024
1 parent 88e7c20 commit 6f8899c
Show file tree
Hide file tree
Showing 14 changed files with 212 additions and 61 deletions.
7 changes: 7 additions & 0 deletions src/qml/PreviewImageViewer/FullImageView.qml
Original file line number Diff line number Diff line change
Expand Up @@ -190,6 +190,13 @@ Item {
id: imageViewer

anchors.fill: parent

onTargetImageChanged: {
delayAnimationTimer.start();
}
onTargetImageReadyChanged: {
delayAnimationTimer.start();
}
}

// 缩放变更时触发显示/隐藏标题栏/底部栏
Expand Down
90 changes: 73 additions & 17 deletions src/qml/PreviewImageViewer/ImageDelegate/BaseImageDelegate.qml
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ Item {
property bool inited: false
property ImageInputHandler inputHandler: null
// PathView下不再提供 index === GControl.currentIndex
property bool isCurrentImage: parent.PathView.isCurrentItem
property bool isCurrentImage: parent.PathView.view.currentIndex === model.index
// 坐标偏移,用于动画效果时调整显示位置
property real offset: 0
// 图片绘制区域到边框的位置
Expand All @@ -53,13 +53,10 @@ Item {
}

function reset() {
if (targetImage.paintedWidth > 0) {
resetCache();
}
if (targetImage) {
// 匹配缩放处理,对于动图,首次加载传入的 paintedWidth 可能为0
if (targetImage.paintedWidth > 0 && imageInfo.width < targetImage.width && imageInfo.height < targetImage.height) {
targetImage.scale = imageInfo.width / targetImage.paintedWidth;
} else {
targetImage.scale = 1;
}
targetImage.rotation = 0;
}

Expand All @@ -69,9 +66,34 @@ Item {
}
}

function resetCache() {
if (inited || null === targetImage || undefined === targetImage) {
return;
}
if (targetImage.paintedWidth <= 0) {
return;
}

// 重置缩放
if (targetImageInfo.scale <= 0) {
// 匹配缩放处理,对于动图,首次加载传入的 paintedWidth 可能为 0
if (imageInfo.width < targetImage.width && imageInfo.height < targetImage.height) {
targetImage.scale = imageInfo.width / targetImage.paintedWidth;
} else {
targetImage.scale = 1;
}
targetImageInfo.scale = targetImage.scale;
} else {
targetImage.scale = targetImageInfo.scale;
}
targetImage.x = targetImageInfo.x;
targetImage.y = targetImageInfo.y;
inited = true;
}

function updateOffset() {
// 需要考虑缩放时的处理
var realWidth = targetImage.paintedWidth * targetImage.scale;
// 需要考虑缩放时的处理(cache中缓存缩放值时优先采用cache)
var realWidth = targetImage.paintedWidth * (targetImageInfo.scale <= 0 ? targetImageInfo.scale : targetImage.scale);
// 图片加载过程时,图片可能未加载完成,调整默认的缩放比值以获取近似值
if (realWidth <= 0) {
if (imageInfo.width < baseDelegate.width && imageInfo.height < baseDelegate.height) {
Expand Down Expand Up @@ -110,16 +132,34 @@ Item {
// 用于绘制更新后缩放等处理
function onPaintedWidthChanged() {
if (!inited) {
if (targetImage.paintedWidth > 0) {
inited = true;
}
reset();
}
updateOffset();
}

function onScaleChanged() {
updateOffset();

// 更新缓存状态
targetImageInfo.scale = targetImage.scale;
}

function onSourceChanged() {
inited = false;
}

function onStatusChanged() {
if (Image.Ready === targetImage.status) {
resetCache();
}
}

function onXChanged() {
targetImageInfo.x = targetImage.x;
}

function onYChanged() {
targetImageInfo.y = targetImage.y;
}

enabled: undefined !== targetImage
Expand All @@ -128,12 +168,13 @@ Item {

// 用于加载大图时的延迟显示效果
Loader {
id: previosLoader
id: previousLoader

property bool needBlur: false

active: needBlur && Image.Loading === baseDelegate.status
anchors.fill: parent
active: needBlur && isCurrentImage && (Image.Loading === baseDelegate.status)
height: parent.height
width: parent.width
z: parent.z + 1

sourceComponent: Item {
Expand All @@ -142,11 +183,12 @@ Item {
Image {
id: loadImage

anchors.fill: parent
// cache会缓存数据(即便Loader重新加载),取消此设置以正确在快速旋转/切换时从正确缓存管理中读取
cache: false
fillMode: Image.PreserveAspectFit
height: parent.height
source: "image://ThumbnailLoad/" + delegate.source + "#frame_" + delegate.frameIndex
width: parent.width
}

MultiEffect {
Expand All @@ -159,20 +201,34 @@ Item {
}
}

onActiveChanged: {
if (active) {
// 应用缓存的图像设置
scale = targetImageInfo.scale <= 0 ? 1 : targetImageInfo.scale;
x = targetImageInfo.x;
y = targetImageInfo.y;
}
}

// 短时间完成加载的图片内无需模糊延迟效果
Timer {
interval: 20
running: Image.Loading === baseDelegate.status

onTriggered: {
previosLoader.needBlur = true;
previousLoader.needBlur = true;
}
}
}

IV.ImageInfo {
id: imageInfo

frameIndex: baseDelegate.frameIndex
source: baseDelegate.source

onInfoChanged: {
inited = false;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,12 @@ BaseImageDelegate {
}

function updateSource() {
// 由于会 resetSource() 破坏绑定,因此重新设置源数据
image.source = "image://ImageLoad/" + delegate.source + "#frame_" + delegate.frameIndex;
if (delegate.source != "") {
// 由于会 resetSource() 破坏绑定,因此重新设置源数据
image.source = "image://ImageLoad/" + delegate.source + "#frame_" + delegate.frameIndex;
} else {
image.source = "";
}
}

inputHandler: imageInput
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ Loader {
property alias frameCount: imageInfo.frameCount
property int frameIndex: model.frameIndex
property url imageSource: model.imageUrl
readonly property int index: model.index

function updateLoaderSource() {
if (active && imageInfo.delegateSource) {
Expand Down
13 changes: 0 additions & 13 deletions src/qml/PreviewImageViewer/ImageViewer.qml
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,6 @@ import "./Utils"
Item {
id: imageViewer

// current rotate
property int currentRotate: 0

// 记录图像缩放,用于在窗口缩放时,根据前后窗口变化保持图片缩放比例
property bool enableChangeDisplay: true
property real lastDisplayScaleWidth: 0
Expand Down Expand Up @@ -274,16 +271,6 @@ Item {
}
}

Shortcut {
enabled: visible && !FileControl.isAlbum()
sequence: "Ctrl+Shift+/"

onActivated: {
var screenPos = mapToGlobal(parent.x, parent.y);
FileControl.showShortcutPanel(screenPos.x + parent.Window.width / 2, screenPos.y + parent.Window.height / 2);
}
}

ParallelAnimation {
id: moveCenterAnimation
property int fromX: 0
Expand Down
14 changes: 12 additions & 2 deletions src/qml/PreviewImageViewer/MainStack.qml
Original file line number Diff line number Diff line change
Expand Up @@ -119,8 +119,7 @@ FadeInoutAnimation {
sourceComponent: FileDialog {
id: fileDialog

currentFolder: shortcuts.pictures
// selectMultiple: true
currentFolder: FileControl.standardPicturesPath()
fileMode: FileDialog.OpenFiles
nameFilters: ["Image files (*.jpg *.png *.bmp *.gif *.ico *.jpe " + "*.jps *.jpeg *.jng *.koala *.koa *.lbm " + "*.iff *.mng *.pbm *.pbmraw *.pcd *.pcx " + "*.pgm *.pgmraw *.ppm *.ppmraw *.ras *.tga " + "*.targa *.tiff *.tif *.wbmp *.psd *.cut *.xbm " + "*.xpm *.dds *.fax *.g3 *.sgi *.exr *.pct *.pic " + "*.pict *.webp *.jxr *.mrw *.raf *.mef *.raw *.orf " + "*.djvu *.or2 *.icns *.dng *.svg *.nef *.pef *.pxm *.pnm)"]
title: qsTr("Select pictures")
Expand Down Expand Up @@ -162,4 +161,15 @@ FadeInoutAnimation {
}
}
}

// show shortcut panel
Shortcut {
enabled: visible && !FileControl.isAlbum()
sequence: "Ctrl+Shift+/"

onActivated: {
var screenPos = mapToGlobal(parent.x, parent.y);
FileControl.showShortcutPanel(screenPos.x + parent.Window.width / 2, screenPos.y + parent.Window.height / 2);
}
}
}
1 change: 1 addition & 0 deletions src/qml/PreviewImageViewer/ThumbnailListView.qml
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,7 @@ Control {
if (ret) {
thumbnailView.deleteCurrentImageImpl(true);
} else {
// 取消删除,恢复删除按钮状态
thumbnailView.imageDeleting = false;
}
// 使用后释放对话框
Expand Down
3 changes: 1 addition & 2 deletions src/src/configsetter.h
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
// Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd.
// SPDX-FileCopyrightText: 2023 UnionTech Software Technology Co., Ltd.
// SPDX-FileCopyrightText: 2020 - 2023 UnionTech Software Technology Co., Ltd.
//
// SPDX-License-Identifier: GPL-3.0-or-later

Expand Down
54 changes: 52 additions & 2 deletions src/src/imagedata/imageinfo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,10 @@ class ImageInfoData
other->size = this->size;
other->frameIndex = this->frameIndex;
other->frameCount = this->frameCount;

other->scale = this->scale;
other->x = this->x;
other->y = this->y;

return other;
}
Expand All @@ -42,6 +46,11 @@ class ImageInfoData
int frameCount = 0; ///< 当前图片总帧数
bool exist = false; ///< 图片是否存在
bool readable = true; ///< 图片是否可读

// runtime property
qreal scale = -1; ///< 图片缩放比值
qreal x = 0; ///< 相对坐标X轴偏移
qreal y = 0; ///< 相对坐标Y轴偏移
};

class LoadImageInfoRunnable : public QRunnable
Expand All @@ -64,7 +73,7 @@ class ImageInfoCache : public QObject
typedef QPair<QString, int> KeyType;

ImageInfoCache();
~ImageInfoCache();
~ImageInfoCache() override;

ImageInfoData::Ptr find(const QString &path, int frameIndex);
void load(const QString &path, int frameIndex, bool reload = false);
Expand Down Expand Up @@ -222,7 +231,7 @@ ImageInfoCache::ImageInfoCache()
localPoolPtr->setMaxThreadCount(qMax(2, QThread::idealThreadCount() / 2));

// 退出时清理线程状态
connect(qApp, &QCoreApplication::aboutToQuit, this, [this](){
connect(qApp, &QCoreApplication::aboutToQuit, this, [this]() {
aboutToQuit = true;
clearCache();

Expand Down Expand Up @@ -325,6 +334,7 @@ void ImageInfoCache::clearCache()
ImageInfo::ImageInfo(QObject *parent)
: QObject(parent)
{
// TODO(renbin): 这种方式效率不佳,应调整为记录文件对应的 ImageInfo 对象进行直接调用(均在同一线程)
connect(CacheInstance(), &ImageInfoCache::imageDataChanged, this, &ImageInfo::onLoadFinished);
connect(CacheInstance(), &ImageInfoCache::imageSizeChanged, this, &ImageInfo::onSizeChanged);
}
Expand Down Expand Up @@ -435,6 +445,46 @@ int ImageInfo::frameCount() const
return data ? data->frameCount : 1;
}

/**
@brief 设置图片运行时属性缩放为 \a s ,除缩放外,还有图片组件在界面上的偏移值 x y 。
这些属性不会用于状态的实时同步或抛出信号,仅在初始化图片展示时取缓存数据复位状态。
*/
void ImageInfo::setScale(qreal s)
{
if (data && data->scale != s) {
data->scale = s;
}
}

qreal ImageInfo::scale() const
{
return data ? data->scale : -1;
}

void ImageInfo::setX(qreal x)
{
if (data) {
data->x = x;
}
}

qreal ImageInfo::x() const
{
return data ? data->x : 0;
}

void ImageInfo::setY(qreal y)
{
if (data) {
data->y = y;
}
}

qreal ImageInfo::y() const
{
return data ? data->y : 0;
}

/**
@return 返回当前图片是否存在,图片可能在展示过程中被销毁
*/
Expand Down
13 changes: 13 additions & 0 deletions src/src/imagedata/imageinfo.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,11 @@ class ImageInfo : public QObject
Q_PROPERTY(bool exists READ exists NOTIFY existsChanged)
Q_PROPERTY(bool hasCachedThumbnail READ hasCachedThumbnail)

// runtime properties
Q_PROPERTY(qreal scale READ scale WRITE setScale FINAL)
Q_PROPERTY(qreal x READ x WRITE setX FINAL)
Q_PROPERTY(qreal y READ y WRITE setY FINAL)

public:
explicit ImageInfo(QObject *parent = nullptr);
explicit ImageInfo(const QUrl &source, QObject *parent = nullptr);
Expand Down Expand Up @@ -52,6 +57,14 @@ class ImageInfo : public QObject
int frameCount() const;
Q_SIGNAL void frameCountChanged();

// runtime properties: scale x y
void setScale(qreal s);
qreal scale() const;
void setX(qreal x);
qreal x() const;
void setY(qreal y);
qreal y() const;

bool exists() const;
Q_SIGNAL void existsChanged();
bool hasCachedThumbnail() const;
Expand Down
Loading

0 comments on commit 6f8899c

Please sign in to comment.