From fe51f0f12261534cce4beac6651c7c9e0a0487e3 Mon Sep 17 00:00:00 2001 From: wingsummer <1326224942@qq.com> Date: Sun, 20 Oct 2024 11:26:51 +0800 Subject: [PATCH] =?UTF-8?q?fix:=20=E4=BC=98=E5=8C=96=E5=A4=84=E7=90=86?= =?UTF-8?q?=E7=BB=86=E8=8A=82=EF=BC=9B=E8=A3=81=E5=88=87=E9=80=89=E5=8F=96?= =?UTF-8?q?=E8=BE=B9=E6=A1=86=E4=BC=9A=E8=87=AA=E5=8A=A8=E9=80=89=E6=8B=A9?= =?UTF-8?q?=E5=AF=B9=E6=AF=94=E8=89=B2=EF=BC=9B=E4=BF=AE=E5=A4=8D=E5=A4=9A?= =?UTF-8?q?=E8=AF=AD=E8=A8=80=E6=98=BE=E7=A4=BA=E7=9A=84=20Bug=20=EF=BC=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- images/fitinview.png | Bin 6461 -> 0 bytes lang/WingGifEditor2_zh_CN.ts | 261 ++++++++++++---------- resources.qrc | 1 - src/class/gifcontentmodel.cpp | 4 + src/class/gifcontentmodel.h | 6 + src/class/languagemanager.cpp | 2 +- src/class/picturedelegate.cpp | 24 +- src/class/picturedelegate.h | 20 ++ src/command/cropimagecommand.cpp | 10 +- src/command/rotateframecommand.cpp | 10 +- src/control/gifeditor.cpp | 2 + src/control/gifeditorscene.cpp | 55 ++++- src/control/gifeditorscene.h | 10 + src/control/imagecropper/imagecropper.cpp | 1 - src/dialog/cropgifdialog.cpp | 4 + src/dialog/logdialog.cpp | 2 + src/dialog/mainwindow.cpp | 51 +++-- src/settings/editorsettingdialog.cpp | 1 - 18 files changed, 307 insertions(+), 157 deletions(-) delete mode 100644 images/fitinview.png diff --git a/images/fitinview.png b/images/fitinview.png deleted file mode 100644 index 28c15d54106bf51df1124b7031c02f86f3337356..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 6461 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 CropGifDialog - + Cut 裁切 - + Cancel 取消 - + CropGifDialog 裁切 @@ -239,6 +239,14 @@ 中文(简体) + + LogDialog + + + Log + 日志 + + Logger @@ -300,551 +308,556 @@ MainWindow - + InfoSave 是否保存 - + WingGifEditor 羽云 GIF 编辑器 - + File 文件 - + Edit 编辑 - + View 视图 - + Plugin 插件 - + Setting 设置 - + About 关于 - - - - - - + + + + + + ChooseFile 选择文件 - + Choose to open 选择文件以打开 - + NewFromPicsGif 从图像序列创建动图 - + InvalidGif 无效 GIF 文件 - + SaveGif 保存 GIF - - + + CaneledByUser 被用户取消操作 - + SaveSuccess 保存成功 - + SaveFail 保存失败 - - + + ChooseSaveFile 选择保存文件路径 - + SaveAsGif 另存为 GIF - + SaveAsSuccess 另存为成功 - + SaveAsFail 另存为失败 - + ExportFrames 导出帧 - - + + ExportSuccess 导出成功 - + ExportFail 导出失败 - - + + Goto 跳转 - + PleaseInputIndex 请输入帧索引 - + DelayTime 延迟时间 - - + + (Global) (全局) - + Inputms 输入时间(单位 ms) - + ScaleDelayTime 缩放延迟时间 - + InputPercent 输入百分比 - + Images (*.jpg *.tiff *.png) 图像 (*.jpg *.tiff *.png) - - + + InsertPics 插入图片序列 - + InsertPicsSuccess 插入图片序列成功 - + InsertGifs 插入动图 - + InsertGifsSuccess 插入动图成功 - + NoSelection 无选择 - + InvalidModel 无效模型 - + Basic 基础 - + NewFromPics 从图序新建 - + NewFromGifs 从动图创建 - + Open 打开 - + Close 关闭 - + RecentFiles 最近文件 - + NewFromGifsGif 从动图创建中 - - + + Save 保存 - + SaveAs 另存为 - + Export 导出 - + FileInfo 文件信息 - - + + General 基本 - + Undo 撤销 - + Redo 重做 - + Cut 剪切 - + Copy 复制 - + Paste 粘贴 - + Delete 删除 - + Frame - + ReduceFrame 降低帧率 - + DeleteBefore 删除之前帧 - + DeleteAfter 删除之后帧 - + MoveLeft 左移帧 - + MoveRight 右移帧 - + Reverse 反转 - + SetDelay 设置延时 - + Image 图像 - + ScaleGif 缩放 GIF - + CutGif 裁切 GIF - + FilpH 水平反转 - + FlipV 垂直翻转 - + RotateLeft 逆时针旋转 - + RotateR 顺时针旋转 - + Effect 效果 - + ExportBlank 导出模板 - + ApplyModel 应用模型 - + CreateReverse 创建逆向帧动画 - + ScaleDelay 缩放延时 - + Merge 合并 - + MergeGIfs 合并动图 - + Player 播放 - + FirstFrame 第一帧 - + LastFrame 上一帧 - + Play 播放 - + Stop 停止 - + NextFrame 下一帧 - + EndFrame 最后帧 - + LoopUp 查找 - + FitInView 适合编辑区 - + SelectAll 全选 - + Deselect 取消选择 - + ReverseSelection 反选 - + Log 日志 - - + + Info 信息 - + Scale 缩放 - + PlgInfo 插件信息 - + Settings 设置 - + Software 软件 - + Sponsor 赞助 - + Wiki WIKI - + AboutQT 关于 QT - + + OpenedGif + 该 GIF 文件已被打开 + + + ReadingGif 读取 GIF 中 - + WritingGif 写入 GIF 中 - + ExportingGif 导出 GIF 中 - + ConfirmClose 确认退出 - + ConfirmSave 你确认未保存就退出软件吗? - + Untitled 未命名 - + Frame: %1/%2 帧:%1/%2 - + NewFrame 新帧 - + InputNewFrameInterval(keep10ms) 请设置新帧延时(时间只保留十位) diff --git a/resources.qrc b/resources.qrc index b25296c..64450b2 100644 --- a/resources.qrc +++ b/resources.qrc @@ -16,7 +16,6 @@ images/export.png images/file.png images/first.png - images/fitinview.png images/fliph.png images/flipv.png images/foreword.png diff --git a/src/class/gifcontentmodel.cpp b/src/class/gifcontentmodel.cpp index 3f6d19e..d537245 100644 --- a/src/class/gifcontentmodel.cpp +++ b/src/class/gifcontentmodel.cpp @@ -18,8 +18,12 @@ void GifContentModel::setLinkedListView(QListView *view) { _view = view; } +void GifContentModel::setLinkedEditor(GifEditor *editor) { _editor = editor; } + QListView *GifContentModel::linkedListView() const { return _view; } +GifEditor *GifContentModel::linkedGifEditor() const { return _editor; } + void GifContentModel::updateLinkedListViewCurrent() const { if (_view) { auto i = _view->currentIndex(); diff --git a/src/class/gifcontentmodel.h b/src/class/gifcontentmodel.h index 2d74677..6fb58b9 100644 --- a/src/class/gifcontentmodel.h +++ b/src/class/gifcontentmodel.h @@ -7,6 +7,7 @@ #include #include +#include "control/gifeditor.h" #include "utilities.h" class GifContentModel : public QAbstractListModel { @@ -19,8 +20,12 @@ class GifContentModel : public QAbstractListModel { void setLinkedListView(QListView *view); + void setLinkedEditor(GifEditor *editor); + QListView *linkedListView() const; + GifEditor *linkedGifEditor() const; + QImage image(qsizetype index) const; int delay(qsizetype index) const; @@ -105,6 +110,7 @@ public slots: QVector _delays; QListView *_view = nullptr; + GifEditor *_editor = nullptr; }; #endif // GIFCONTENTMODEL_H diff --git a/src/class/languagemanager.cpp b/src/class/languagemanager.cpp index e037a14..94f8691 100644 --- a/src/class/languagemanager.cpp +++ b/src/class/languagemanager.cpp @@ -63,7 +63,7 @@ LanguageManager::LanguageManager() { #else if (p->country() == _defaultLocale.country() && #endif - p->language() == p->language() && + p->language() == _defaultLocale.language() && p->script() == _defaultLocale.script()) { found = true; break; diff --git a/src/class/picturedelegate.cpp b/src/class/picturedelegate.cpp index 2937a7c..5402eac 100644 --- a/src/class/picturedelegate.cpp +++ b/src/class/picturedelegate.cpp @@ -3,9 +3,7 @@ #include const unsigned int BANNER_HEIGHT = 20; -const unsigned int BANNER_COLOR = 0x303030; const unsigned int BANNER_ALPHA = 200; -const unsigned int BANNER_TEXT_COLOR = 0xffffff; const unsigned int HIGHLIGHT_ALPHA = 100; PictureDelegate::PictureDelegate(QObject *parent) @@ -29,13 +27,13 @@ void PictureDelegate::paint(QPainter *painter, QRect bannerRectBottom = bannerRectTop; bannerRectBottom.moveBottom(option.rect.bottom()); - QColor bannerColor = QColor(BANNER_COLOR); + QColor bannerColor = this->bannerColor; bannerColor.setAlpha(BANNER_ALPHA); painter->fillRect(bannerRectTop, bannerColor); painter->fillRect(bannerRectBottom, bannerColor); QString filename = index.model()->data(index, Qt::DisplayRole).toString(); - painter->setPen(BANNER_TEXT_COLOR); + painter->setPen(this->bannerTextColor); painter->drawText(bannerRectTop, Qt::AlignCenter, QString::number(index.row() + 1)); painter->drawText(bannerRectBottom, Qt::AlignCenter, filename); @@ -54,3 +52,21 @@ QSize PictureDelegate::sizeHint(const QStyleOptionViewItem &option, auto s = option.widget->height() - 40; return QSize(s * 5 / 4, s); } + +QColor PictureDelegate::getBannerTextColor() const { return bannerTextColor; } + +void PictureDelegate::setBannerTextColor(const QColor &newBannerTextColor) { + if (bannerTextColor == newBannerTextColor) + return; + bannerTextColor = newBannerTextColor; + emit bannerTextColorChanged(); +} + +QColor PictureDelegate::getBannerColor() const { return bannerColor; } + +void PictureDelegate::setBannerColor(const QColor &newBannerColor) { + if (bannerColor == newBannerColor) + return; + bannerColor = newBannerColor; + emit bannerColorChanged(); +} diff --git a/src/class/picturedelegate.h b/src/class/picturedelegate.h index afa428b..1309374 100644 --- a/src/class/picturedelegate.h +++ b/src/class/picturedelegate.h @@ -5,6 +5,11 @@ class PictureDelegate : public QStyledItemDelegate { Q_OBJECT + + Q_PROPERTY(QColor bannerTextColor READ getBannerTextColor WRITE + setBannerTextColor NOTIFY bannerTextColorChanged FINAL) + Q_PROPERTY(QColor bannerColor READ getBannerColor WRITE setBannerColor + NOTIFY bannerColorChanged FINAL) public: PictureDelegate(QObject *parent = nullptr); @@ -12,6 +17,21 @@ class PictureDelegate : public QStyledItemDelegate { const QModelIndex &index) const override; QSize sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const override; + + QColor getBannerTextColor() const; + void setBannerTextColor(const QColor &newBannerTextColor); + + QColor getBannerColor() const; + void setBannerColor(const QColor &newBannerColor); + +signals: + void bannerTextColorChanged(); + + void bannerColorChanged(); + +private: + QColor bannerTextColor = 0xffffff; + QColor bannerColor = 0x303030; }; #endif // PICTUREDELEGATE_H diff --git a/src/command/cropimagecommand.cpp b/src/command/cropimagecommand.cpp index 087ca28..cba2b3c 100644 --- a/src/command/cropimagecommand.cpp +++ b/src/command/cropimagecommand.cpp @@ -7,6 +7,12 @@ CropImageCommand::CropImageCommand(GifContentModel *helper, const QRect &rect, buffer = helper->images(); } -void CropImageCommand::undo() { gif->swapFrames(buffer); } +void CropImageCommand::undo() { + gif->swapFrames(buffer); + gif->linkedGifEditor()->fitOpenSize(); +} -void CropImageCommand::redo() { gif->cropFrames(_rect); } +void CropImageCommand::redo() { + gif->cropFrames(_rect); + gif->linkedGifEditor()->fitOpenSize(); +} diff --git a/src/command/rotateframecommand.cpp b/src/command/rotateframecommand.cpp index b159ff9..3315d5b 100644 --- a/src/command/rotateframecommand.cpp +++ b/src/command/rotateframecommand.cpp @@ -4,6 +4,12 @@ RotateFrameCommand::RotateFrameCommand(GifContentModel *helper, bool isclockwise, QUndoCommand *parent) : QUndoCommand(parent), gif(helper), clockwise(isclockwise) {} -void RotateFrameCommand::undo() { gif->rotateFrames(!clockwise); } +void RotateFrameCommand::undo() { + gif->rotateFrames(!clockwise); + gif->linkedGifEditor()->fitOpenSize(); +} -void RotateFrameCommand::redo() { gif->rotateFrames(clockwise); } +void RotateFrameCommand::redo() { + gif->rotateFrames(clockwise); + gif->linkedGifEditor()->fitOpenSize(); +} diff --git a/src/control/gifeditor.cpp b/src/control/gifeditor.cpp index c2c1ed7..e6ad667 100644 --- a/src/control/gifeditor.cpp +++ b/src/control/gifeditor.cpp @@ -19,6 +19,8 @@ void GifEditor::fitOpenSize() { if (imgSize.width() > wSize.width() || imgSize.height() > wSize.height()) { fitInEditorView(); } else { + auto r = scene->contentBounding(); + setSceneRect(r); resetTransform(); } } diff --git a/src/control/gifeditorscene.cpp b/src/control/gifeditorscene.cpp index eb128b2..98b0b52 100644 --- a/src/control/gifeditorscene.cpp +++ b/src/control/gifeditorscene.cpp @@ -2,13 +2,22 @@ #include #include +#include +#include +#include + +size_t qHash(const QColor &color, size_t seed = 0) noexcept { + return qHash(qMakePair(color.rgba(), color.spec()), seed); +} + GifEditorScene::GifEditorScene(const QImage &img, QObject *parent) : QGraphicsScene(parent) { sel = new ImageCropper(); sel->setAttribute(Qt::WA_TranslucentBackground); sel->setBackgroundColor(Qt::transparent); sel->setCropperVisible(false); - sel->setImage(img); + sel->setCroppingRectBorderColor(Qt::gray); + setFrameImg(img); gw = addWidget(sel); connect(sel, &ImageCropper::sizeChanged, gw, [=] { // call the internal updateProxyGeometryFromWidget @@ -30,7 +39,13 @@ void GifEditorScene::setCuttingMode(bool value) { sel->setCropperVisible(value); } -void GifEditorScene::setFrameImg(const QImage &img) { sel->setImage(img); } +void GifEditorScene::setFrameImg(const QImage &img) { + sel->setImage(img); + auto mainColor = getMainThemeColor(img); + if (!img.isNull()) { + sel->setCroppingRectBorderColor(getContrastingColor(mainColor)); + } +} QRectF GifEditorScene::contentBounding() const { return gw->boundingRect(); } @@ -41,3 +56,39 @@ QRectF GifEditorScene::selRect() const { return sel->selRect(); } void GifEditorScene::setSelRect(int x, int y, int w, int h) { sel->setSelRect(x, y, w, h); } + +double GifEditorScene::getLuminance(const QColor &color) { + return 0.299 * color.red() + 0.587 * color.green() + 0.114 * color.blue(); +} + +QColor GifEditorScene::getContrastingColor(const QColor &color) { + double luminance = getLuminance(color); + return (luminance > 128) ? QColor(Qt::black) : QColor(Qt::white); +} + +QColor GifEditorScene::getMainThemeColor(const QImage &image) { + QHash colorCount; + + // Reduce the image size to speed up the process + QImage scaledImage = image.scaled(50, 50); + + // Count each pixel's color + for (int y = 0; y < scaledImage.height(); ++y) { + for (int x = 0; x < scaledImage.width(); ++x) { + QColor color = scaledImage.pixelColor(x, y); + colorCount[color]++; + } + } + + // Find the most frequent color + QColor dominantColor; + int maxCount = 0; + for (auto it = colorCount.constBegin(); it != colorCount.constEnd(); ++it) { + if (it.value() > maxCount) { + maxCount = it.value(); + dominantColor = it.key(); + } + } + + return dominantColor; +} diff --git a/src/control/gifeditorscene.h b/src/control/gifeditorscene.h index a47df2a..1006614 100644 --- a/src/control/gifeditorscene.h +++ b/src/control/gifeditorscene.h @@ -27,6 +27,16 @@ public slots: signals: void selRectChanged(const QRectF &rect); +private: + // Function to calculate luminance of a color + double getLuminance(const QColor &color); + + // Function to get the contrasting color (white or black) + QColor getContrastingColor(const QColor &color); + + // Function to get the main theme color from the image + QColor getMainThemeColor(const QImage &image); + private: ImageCropper *sel; QPointF oldpos; diff --git a/src/control/imagecropper/imagecropper.cpp b/src/control/imagecropper/imagecropper.cpp index f96e98f..583028c 100644 --- a/src/control/imagecropper/imagecropper.cpp +++ b/src/control/imagecropper/imagecropper.cpp @@ -41,7 +41,6 @@ void ImageCropper::setSelRect(int x, int y, int w, int h) { void ImageCropper::setImage(const QImage &_image) { pimpl->imageForCropping = _image; setFixedSize(_image.size()); - update(); } diff --git a/src/dialog/cropgifdialog.cpp b/src/dialog/cropgifdialog.cpp index 3385e88..a88db66 100644 --- a/src/dialog/cropgifdialog.cpp +++ b/src/dialog/cropgifdialog.cpp @@ -3,6 +3,8 @@ #include CropGifDialog::CropGifDialog(QWidget *parent) : FramelessDialogBase(parent) { + setAttribute(Qt::WA_ShowWithoutActivating); + auto widget = new QWidget(this); auto layout = new QVBoxLayout(widget); @@ -64,6 +66,8 @@ CropGifDialog::CropGifDialog(QWidget *parent) : FramelessDialogBase(parent) { layout->addWidget(btnBox); setFocusPolicy(Qt::StrongFocus); + widget->setMinimumWidth(300); + buildUpContent(widget); setWindowTitle(tr("CropGifDialog")); diff --git a/src/dialog/logdialog.cpp b/src/dialog/logdialog.cpp index 6735ddb..22ebeab 100644 --- a/src/dialog/logdialog.cpp +++ b/src/dialog/logdialog.cpp @@ -6,6 +6,8 @@ LogDialog::LogDialog(QWidget *parent) : FramelessDialogBase(parent) { _log->setOpenExternalLinks(true); _log->setUndoRedoEnabled(false); + setWindowTitle(tr("Log")); + buildUpContent(_log); } diff --git a/src/dialog/mainwindow.cpp b/src/dialog/mainwindow.cpp index a798030..391b250 100644 --- a/src/dialog/mainwindow.cpp +++ b/src/dialog/mainwindow.cpp @@ -78,6 +78,7 @@ MainWindow::MainWindow(QWidget *parent) : FramelessMainWindow(parent) { splitter->addWidget(_gallery); _model = new GifContentModel(_gallery); _model->setLinkedListView(_gallery); + _model->setLinkedEditor(_editor); _gallery->setSelectionMode(QAbstractItemView::ExtendedSelection); _gallery->setMaximumHeight(300); connect(_gallery->selectionModel(), &QItemSelectionModel::currentRowChanged, @@ -147,6 +148,10 @@ MainWindow::MainWindow(QWidget *parent) : FramelessMainWindow(parent) { }); _cuttingdlg = new CropGifDialog(this); + + auto w = qApp->primaryScreen()->availableSize().width(); + _cuttingdlg->move(w - _cuttingdlg->width(), 0); + connect(_cuttingdlg, &CropGifDialog::selRectChanged, _editor, &GifEditor::setSelRect); connect(_cuttingdlg, &CropGifDialog::crop, this, @@ -218,17 +223,19 @@ void MainWindow::buildUpRibbonBar() { _playDisWidgets << buildAboutPage(m_ribbon->addTab(tr("About"))); connect(m_ribbon, &Ribbon::onDragDropFiles, this, [=](const QStringList &files) { - if (files.size() == 1) { - readGif(files.first()); - return; - } - bool ok; - auto f = WingInputDialog::getItem(this, tr("ChooseFile"), - tr("Choose to open"), files, - 0, false, &ok); - if (ok) { - readGif(f); + QString f; + + if (files.size() > 1) { + bool ok; + f = WingInputDialog::getItem(this, tr("ChooseFile"), + tr("Choose to open"), files, 0, + false, &ok); + if (!ok) { + return; + } } + + openGif(f); }); } @@ -384,6 +391,7 @@ void MainWindow::on_close() { _model->clearData(); _curfilename.clear(); undo.clear(); + _editor->fitOpenSize(); setEditModeEnabled(false); } } @@ -1013,12 +1021,16 @@ RibbonTabContent *MainWindow::buildViewPage(RibbonTabContent *tab) { auto pannel = tab->addGroup(tr("LoopUp")); auto menu = new QMenu(this); + + menu->addAction( + newAction(tr("FitInView"), [this] { _editor->fitInEditorView(); })); + menu->addAction(newAction(QStringLiteral("100%"), + [this] { _editor->setZoom(100); })); + menu->addSeparator(); menu->addAction( newAction(QStringLiteral("80%"), [this] { _editor->setZoom(80); })); menu->addAction( newAction(QStringLiteral("90%"), [this] { _editor->setZoom(90); })); - menu->addAction(newAction(QStringLiteral("100%"), - [this] { _editor->setZoom(100); })); menu->addSeparator(); menu->addAction(newAction(QStringLiteral("120%"), [this] { _editor->setZoom(120); })); @@ -1030,11 +1042,6 @@ RibbonTabContent *MainWindow::buildViewPage(RibbonTabContent *tab) { [this] { _editor->setZoom(250); })); menu->addAction(newAction(QStringLiteral("300%"), [this] { _editor->setZoom(300); })); - menu->addSeparator(); - auto a = - newAction(tr("FitInView"), [this] { _editor->fitInEditorView(); }); - a->setIcon(ICONRES("fitinview")); - menu->addAction(a); addPannelAction(pannel, QStringLiteral("scaleview"), tr("Scale"), EMPTY_FUNC, {}, menu); @@ -1092,6 +1099,7 @@ RibbonTabContent *MainWindow::buildAboutPage(RibbonTabContent *tab) { void MainWindow::openGif(const QString &filename) { if (filename == _curfilename) { + Toast::toast(this, QStringLiteral("open"), tr("OpenedGif")); return; } @@ -1119,7 +1127,12 @@ bool MainWindow::readGif(const QString &gif) { } _comment = reader.comment(); _model->readGifReader(&reader); - _gallery->setCurrentIndex(_model->index(0)); + if (_gallery->currentIndex().row() == 0) { + auto index = _model->index(0); + emit _gallery->selectionModel()->currentRowChanged(index, index); + } else { + _gallery->setCurrentIndex(_model->index(0)); + } _editor->fitOpenSize(); return true; } @@ -1284,7 +1297,7 @@ void MainWindow::loadCacheIcon() { void MainWindow::updateGifMessage() { if (_curfilename.isEmpty()) { - m_status->showMessage(QStringLiteral("-")); + m_status->showMessage({}); } else { m_status->showMessage(tr("Frame: %1/%2") .arg(_gallery->currentIndex().row() + 1) diff --git a/src/settings/editorsettingdialog.cpp b/src/settings/editorsettingdialog.cpp index 607644a..3bfbaf2 100644 --- a/src/settings/editorsettingdialog.cpp +++ b/src/settings/editorsettingdialog.cpp @@ -40,7 +40,6 @@ void EditorSettingDialog::reload() { auto &set = SettingManager::instance(); auto langs = LanguageManager::instance().langsDisplay(); - ui->cbLanguage->addItems(langs); auto lang = set.defaultLang(); if (lang.isEmpty()) { ui->cbLanguage->setCurrentIndex(0);