├── .github └── workflows │ ├── Linux.yml │ ├── LinuxDeb.yml │ ├── MacOS10.15.yml │ └── Windows.yml ├── .gitignore ├── .gitmodules ├── 3rdparty └── README.md ├── CMakeLists.txt ├── LICENSE ├── OnlyBuild_x64 .bat ├── PKGBUILD ├── README.md ├── README.zh_CN.md ├── build_Package_x64 .bat ├── debian ├── changelog ├── compat ├── control ├── copyright ├── files ├── flipped.substvars ├── rules └── source │ └── format ├── debian_portable ├── Flipped.sh └── ldd.sh ├── docs ├── .gitignore ├── .rubocop.yml ├── .travis.yml ├── CNAME ├── Gemfile ├── README.md ├── _config.yml ├── _includes │ ├── head-custom-google-analytics.html │ └── head-custom.html ├── _layouts │ └── default.html ├── _sass │ ├── architect.scss │ ├── jekyll-theme-architect.scss │ ├── normalize.scss │ └── rouge-github.scss ├── another-page.md ├── assets │ ├── css │ │ ├── print.scss │ │ └── style.scss │ └── images │ │ ├── body-bg.jpg │ │ ├── download-button.png │ │ ├── github-button.png │ │ ├── header-bg.jpg │ │ ├── highlight-bg.jpg │ │ └── sidebar-bg.jpg ├── docs │ ├── CODE_OF_CONDUCT.md │ ├── CONTRIBUTING.md │ └── SUPPORT.md ├── favicon.ico ├── index.md ├── index.zh_CN.md ├── jekyll-theme-architect.gemspec ├── logo.png ├── script │ ├── bootstrap │ ├── cibuild │ ├── release │ └── validate-html ├── snapshot │ ├── FLIPPED2.jpg │ ├── Flipped.svg │ ├── MacOS13_Cover.jpg │ ├── MacOS13_Cover2.jpg │ ├── MacOS13_Cover23.jpg │ ├── MacOS13_Cover3.jpg │ ├── MacOS13_Cover4.jpg │ ├── MacOS13_Cover5.jpg │ ├── Ubuntu20.04_Cover.jpg │ ├── Windows10_Couer.jpg │ ├── Windows10_Couer10.png │ ├── Windows10_Couer11.png │ ├── Windows10_Couer12.jpg │ ├── Windows10_Couer2.jpg │ ├── Windows10_Couer3.jpg │ ├── Windows10_Couer4.jpg │ ├── Windows10_Couer5.jpg │ ├── Windows10_Couer6.png │ ├── Windows10_Couer7.png │ ├── Windows10_Couer8.png │ └── Windows10_Couer9.png └── thumbnail.png ├── pluginsimpl └── watemark │ ├── CMakeLists.txt │ ├── watemark.json │ ├── watemarkitem.cpp │ ├── watemarkitem.h │ ├── watemarkplugin.cpp │ └── watemarkplugin.h ├── setup-user.iss ├── snapshot ├── FLIPPED2.jpg ├── Flipped.svg ├── Flipped_archived.svg ├── MacOS13_Cover.jpg ├── MacOS13_Cover2.jpg ├── MacOS13_Cover23.jpg ├── MacOS13_Cover3.jpg ├── MacOS13_Cover4.jpg ├── MacOS13_Cover5.jpg ├── Ubuntu20.04_Cover.jpg ├── Windows10_Couer.jpg ├── Windows10_Couer10.png ├── Windows10_Couer11.png ├── Windows10_Couer12.jpg ├── Windows10_Couer2.jpg ├── Windows10_Couer3.jpg ├── Windows10_Couer4.jpg ├── Windows10_Couer5.jpg ├── Windows10_Couer6.png ├── Windows10_Couer7.png ├── Windows10_Couer8.png └── Windows10_Couer9.png ├── src ├── CMakeLists.txt ├── Resources.qrc ├── core │ ├── arrowline.cpp │ ├── arrowline.h │ ├── isingleton.h │ ├── xlog.h │ ├── xqtlog.cpp │ └── xqtlog.h ├── main.cpp ├── platform │ ├── iwininfo.cpp │ ├── iwininfo.h │ ├── wininfo.cpp │ ├── wininfo.h │ ├── wininfo_win.cpp │ ├── wininfo_win.h │ ├── wininfo_x11.cpp │ └── wininfo_x11.h ├── pluginsinterface │ ├── iplugininterface.cpp │ └── iplugininterface.h ├── preference │ ├── appellation.cpp │ ├── appellation.h │ ├── hotkeyswidget.cpp │ ├── hotkeyswidget.h │ ├── prefmanage.cpp │ ├── prefmanage.h │ └── prefmanage.ui ├── resources │ ├── border_style │ │ └── light_blue │ │ │ └── boardPoint.svg │ ├── changelog │ │ └── changelog.txt │ ├── config │ │ ├── Copyright.txt │ │ └── config.ini │ ├── licenses │ │ └── License.md │ ├── logo │ │ ├── logo.ico │ │ ├── logo.png │ │ ├── logo.svg │ │ ├── logo_archive.ico │ │ ├── logo_archive.png │ │ ├── logo_archive.svg │ │ └── resources.rc │ ├── tool │ │ ├── arrow.svg │ │ ├── cancel.svg │ │ ├── custompath.svg │ │ ├── ellipse.svg │ │ ├── finish.svg │ │ ├── gif.svg │ │ ├── mosaic.svg │ │ ├── pin.svg │ │ ├── rectangle.svg │ │ ├── renewal.svg │ │ ├── revocation.svg │ │ ├── save.svg │ │ ├── serialnumber.svg │ │ ├── smooth.svg │ │ └── text.svg │ └── tool_para │ │ ├── arrows │ │ ├── arrow_1.svg │ │ ├── arrow_2.svg │ │ ├── arrow_3.svg │ │ └── arrow_4.svg │ │ ├── ellipses │ │ ├── ellipse.svg │ │ └── ellipse_fill.svg │ │ ├── line_width │ │ ├── line_width_1.svg │ │ ├── line_width_2.svg │ │ └── line_width_3.svg │ │ ├── mosaics │ │ ├── pixelated.svg │ │ └── smooth.svg │ │ ├── rectangles │ │ ├── rectangle.svg │ │ └── rectangle_fill.svg │ │ ├── serialnumber │ │ ├── ellipse_fill.svg │ │ ├── letters.svg │ │ ├── numbers.svg │ │ └── rectangle_fill.svg │ │ └── text │ │ ├── bold.svg │ │ ├── italic.svg │ │ └── outline.svg ├── screen │ ├── datamaid.cpp │ ├── datamaid.h │ ├── drawhelper.cpp │ ├── drawhelper.h │ ├── rectcalcu.cpp │ ├── rectcalcu.h │ ├── screenshot.cpp │ ├── screenshot.h │ ├── tray.cpp │ └── tray.h ├── tool │ ├── base │ │ ├── blurwidget.cpp │ │ ├── blurwidget.h │ │ ├── colorparabar.cpp │ │ ├── colorparabar.h │ │ ├── managebar.cpp │ │ └── managebar.h │ ├── magnifier │ │ ├── magnifier.cpp │ │ └── magnifier.h │ ├── parameterbar.cpp │ ├── parameterbar.h │ ├── pin │ │ ├── pinwidget.cpp │ │ └── pinwidget.h │ ├── selectbar.cpp │ ├── selectbar.h │ └── selectsize │ │ ├── selectsize.cpp │ │ └── selectsize.h ├── translations │ ├── en_US.ts │ ├── zh_CN.ts │ └── zh_TW.ts ├── widget │ ├── xframewidget.cpp │ ├── xframewidget.h │ ├── xhorizontalline.cpp │ ├── xhorizontalline.h │ ├── xkeysequenceedit.cpp │ ├── xkeysequenceedit.h │ ├── xlabel.cpp │ ├── xlabel.h │ ├── xroundwidget.cpp │ ├── xroundwidget.h │ ├── xtextwidget.cpp │ ├── xtextwidget.h │ ├── xverticalline.cpp │ └── xverticalline.h └── xglobal.h ├── tech.xmuli.flipped └── linglong.yaml └── updateI18N.bat /.github/workflows/MacOS10.15.yml: -------------------------------------------------------------------------------- 1 | name: MacOS10.15 2 | on: 3 | push: 4 | paths-ignore: 5 | # - '**' 6 | - 'README.md' 7 | pull_request: 8 | paths-ignore: 9 | - 'README.md' 10 | jobs: 11 | build: 12 | name: Build 13 | runs-on: ${{ matrix.os }} 14 | strategy: 15 | matrix: 16 | os: [macos-10.15] # macos-10.14 macos-10.15, macos-11.0, macos-12.6 # https://github.com/actions/virtual-environments/blob/main/images/macos/macos-11-Readme.md 17 | qt_ver: [5.15.2] # 参考: https://mirrors.cloud.tencent.com/qt/online/qtsdkrepository/mac_x64/desktop/qt5_5111 18 | qt_arch: [clang_64] 19 | env: 20 | targetName: Flipped 21 | targetLowerName: flipped 22 | targetOS: macos 23 | steps: 24 | 25 | # macos 11.0 后默认环境变了,要指定 26 | - name: prepare env 27 | if: ${{ matrix.os >= 'macos-11.0' }} 28 | run: | 29 | softwareupdate --all --install --force 30 | sudo xcode-select --print-path 31 | sudo xcode-select --switch /Library/Developer/CommandLineTools 32 | 33 | - name: Install Qt 34 | # if: steps.cache-qt.outputs.cache-hit != 'true' 35 | uses: jurplel/install-qt-action@v3 36 | with: 37 | version: ${{ matrix.qt_ver }} 38 | # cached: ${{ steps.cache-qt.outputs.cache-hit }} 39 | 40 | - uses: actions/checkout@v2 41 | with: 42 | fetch-depth: 1 43 | 44 | - name: pull 3rdparty code 45 | run: | 46 | git submodule init 47 | git submodule update 48 | 49 | - name: build macos 50 | run: | 51 | mkdir build 52 | cd build 53 | cmake .. 54 | make 55 | 56 | echo "-------------- debug 1 --------------" 57 | pwd 58 | ls -al 59 | 60 | echo "-------------- debug 1 --------------" 61 | cd bin 62 | ls -al 63 | 64 | - name: NameVersion 65 | id: NameVersion 66 | if: startsWith(github.event.ref, 'refs/tags/') 67 | shell: pwsh 68 | run: | 69 | $systemInfo="${{ env.targetOS }}-10.15" 70 | $productVersion="${{ github.ref }}".substring("refs/tags/v".length) 71 | $productName="${{ env.targetLowerName }}-$productVersion-beta-$systemInfo-x64" 72 | 73 | echo "systemInfo=$systemInfo" | Out-File -FilePath $env:GITHUB_ENV -Encoding utf8 -Append 74 | echo "productVersion=$productVersion" | Out-File -FilePath $env:GITHUB_ENV -Encoding utf8 -Append 75 | echo "productName=$productName" | Out-File -FilePath $env:GITHUB_ENV -Encoding utf8 -Append 76 | 77 | # tag打为.zip包 78 | - name: package 79 | id: package 80 | if: startsWith(github.event.ref, 'refs/tags/') 81 | shell: bash 82 | run: | 83 | # 拷贝依赖 84 | mkdir bin 85 | 86 | echo "-------------- debug 1 --------------" 87 | pwd 88 | ls -al 89 | 90 | cp -r build/bin/${{ env.targetName }}.app bin 91 | 92 | echo "-------------- debug 2 --------------" 93 | pwd 94 | ls -al 95 | 96 | echo "-------------- debug 3 --------------" 97 | cd bin 98 | pwd 99 | ls -al 100 | 101 | macdeployqt ${{ env.targetName }}.app -dmg 102 | mv ${{ env.targetName }}.dmg ../${{ env.productName }}.dmg 103 | 104 | 105 | echo "-------------- debug 4 --------------" 106 | pwd 107 | ls -al 108 | 109 | 110 | echo "-------------- debug 5 --------------" 111 | cd ../ 112 | pwd 113 | ls -al 114 | 115 | echo "-------------- debug 6 --------------" 116 | cd bin 117 | ls -al 118 | pwd 119 | 120 | # tag上传Release 121 | - name: uploadRelease 122 | if: startsWith(github.event.ref, 'refs/tags/') 123 | uses: softprops/action-gh-release@v1 124 | env: 125 | GITHUB_TOKEN: ${{ secrets.upload_release }} 126 | with: 127 | draft: false 128 | prerelease: false 129 | files: | 130 | ${{ env.productName }}.dmg 131 | tag: ${{ github.ref }} 132 | overwrite: true -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "3rdparty/QHotkey"] 2 | path = 3rdparty/QHotkey 3 | url = https://github.com/Skycoder42/QHotkey.git 4 | [submodule "3rdparty/spdlog"] 5 | path = 3rdparty/spdlog 6 | url = https://github.com/gabime/spdlog.git 7 | -------------------------------------------------------------------------------- /3rdparty/README.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | ## 计划引入三方库 6 | 7 | 8 | 9 | | 序号 | 库名 | 许可证 | 简介 | 备注 | 10 | | :--: | :-----------------------------------------------: | :----------------------------------------------------------: | :--------------------------------------------------- | :--: | 11 | | 1 | [ QHotkey](https://github.com/Skycoder42/QHotkey) | [BSD 3-Clause](https://github.com/Skycoder42/QHotkey/blob/master/LICENSE) | A global shortcut/hotkey for Desktop Qt-Applications | ✔ | 12 | | 2 | [spdlog](https://github.com/gabime/spdlog) | [MIT](https://github.com/gabime/spdlog/blob/v1.x/LICENSE) | Fast C++ logging library. | ✔ | 13 | 14 | -------------------------------------------------------------------------------- /CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # SPDX-License-Identifier: MIT 2 | # SPDX-FileCopyrightText: 2021-2024 XMuli 3 | # SPDX-GitHub: https://github.com/SunnyScreenshot/FLIPPED 4 | # SPDX-Author: XMuli 5 | 6 | cmake_minimum_required(VERSION 3.5) 7 | project(FILPPE) 8 | add_subdirectory(src) 9 | #add_subdirectory(pluginsimpl/watemark) 10 | add_subdirectory(3rdparty/QHotkey) 11 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2021-2024 Zhang Wengeng 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /OnlyBuild_x64 .bat: -------------------------------------------------------------------------------- 1 | @echo off 2 | 3 | ::delete build dir 4 | if "%1"=="delete" goto _DEL 5 | 6 | if not exist build md build 7 | 8 | cd build 9 | cmake -G "Visual Studio 16 2019" -A x64 .. 10 | goto _END 11 | 12 | :_DEL 13 | rd build/s/q 14 | goto _END 15 | 16 | :_END -------------------------------------------------------------------------------- /PKGBUILD: -------------------------------------------------------------------------------- 1 | # This is an example PKGBUILD file. Use this as a start to creating your own, 2 | # and remove these comments. For more information, see 'man PKGBUILD'. 3 | # NOTE: Please fill out the license field for your package! If it is unknown, 4 | # then please put 'unknown'. 5 | 6 | # Maintainer: XMuli # 包的维护者 7 | pkgname=picshot # 包的名称(由小写字母 @ . _ + - 构成) 8 | _pkgname=PicShot # 自己添加的变量 (因 pkgname 要求全小写,而仓库源码中有大写) 9 | # 亦是最后项目生成的文件名 10 | pkgver=0.1.2 # 包的版本号 (不可有连字符 -) 11 | pkgrel=1 # 包的发布号码 12 | epoch= # 用于强制升级软件包 (一般不允许使用) 13 | pkgdesc="Open source cross-platform screenshots" # 软件包的详细描述 14 | arch=('x86_64') # 包所能够生成并且使用的架构的序列 15 | url="https://github.com/XMuli/PicShot" # 包的官网 16 | license=('MIT') # 采用的许可证 17 | groups=() # 软件包所在的包组 18 | depends=() # 软件包的生成和运行时,必须先行安装的软件列表 19 | makedepends=() # 仅在软件生成时,需要的软件包列表 20 | checkdepends=() # 运行测试组件时需要,而运行时不需要的包列表 21 | optdepends=() # 可选的软件包(可看作本软件的插件) 22 | provides=() # 说明当前包提供的功能 (若使用,则需加上替代版本号) 23 | conflicts=() # 与当前软件包发生冲突的包 与功能的列表 24 | replaces=() # 会因安装当前包而取代的过时的包的列表 25 | backup=() # 当包被升级或卸载时,应当备份的文件(的路径)序列 26 | options=() # 允许重载 makepkg 的部分 (在 /etc/makepkg.conf 中) 27 | install= # .install 脚本的名称 (值应和 pkgname 相同) 28 | changelog= # 软件包的更新日志的文件名 29 | source=("$_pkgname-$pkgver::https://github.com/XMuli/$_pkgname/archive/v$pkgver.tar.gz") # 源码的下载地址 30 | noextract=() # 在 source 中列出,但不应该在运行 makepkg 时被解包的文件列表 31 | md5sums=('5abae73968ea0104e99b816bf0b720fe') # 完整性校验值 32 | validpgpkeys=() # PGP 指纹列表 33 | 34 | 35 | prepare() { # 准备 36 | cd $srcdir 37 | echo $srcdir 38 | } 39 | 40 | build() { # 构建 41 | cd $_pkgname-$pkgver 42 | mkdir bin 43 | cd bin 44 | qmake .. 45 | make -j$(nproc) 46 | } 47 | 48 | check() { # 检查 49 | cd $_pkgname-$pkgver 50 | } 51 | 52 | package() { # 包 53 | cd $_pkgname-$pkgver 54 | # make install 55 | cd bin/ 56 | ./$_pkgname 57 | } 58 | -------------------------------------------------------------------------------- /build_Package_x64 .bat: -------------------------------------------------------------------------------- 1 | @echo off 2 | 3 | ::delete build dir 4 | if "%1"=="delete" goto _DEL 5 | 6 | if not exist build md build 7 | 8 | ::"C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\VC\Auxiliary\Build\vcvarsall.bat" x64 9 | cd build 10 | cmake -G "Visual Studio 16 2019" -A x64 .. 11 | ::devenv Flipped.sln /Build "Release|x64" 12 | ::windeployqt --no-angle --no-opengl-sw bin/Flipped.exe 13 | goto _END 14 | 15 | :_DEL 16 | rd build/s/q 17 | goto _END 18 | 19 | :_END -------------------------------------------------------------------------------- /debian/changelog: -------------------------------------------------------------------------------- 1 | flipped (1.3.2-1) UNRELEASED; urgency=medium 2 | 3 | * fix build Linux and MacOS 4 | * UI refactor 5 | * code open sources https://github.com/SunnyScreenshot/FLIPPED 6 | 7 | -- XMuli Fri, 31 May 2024 22:08:13 +0800 8 | 9 | 10 | flipped (1.1.0-1) UNRELEASED; urgency=medium 11 | 12 | * 重构整个程序和 .ini 交互的逻辑架构,也使用了很多宏;代码清爽了很多 13 | * 功能:Quick save 14 | * 功能:Auto save 15 | * 功能:快捷键冲突检测、系统消息通知 16 | 17 | -- XMuli Sta, 16 Arpil 2023 19:20:13 +0800 18 | 19 | flipped (1.0.1-1) UNRELEASED; urgency=medium 20 | 21 | * 添加开机自启动[Windows] 22 | 23 | -- XMuli Sta, 1 Arpil 2023 18:20:13 +0800 24 | 25 | flipped (1.0.0-1) UNRELEASED; urgency=medium 26 | 27 | * 修复诸多缺陷、屏蔽尚未开发好的部分代码 28 | * 一个较大部分的代码重构、部分架构重新设计 29 | * 整理项目代码规范、添加对应 README 和介绍视频等 30 | 31 | -- XMuli Mon, 31 Oct 2022 19:52:18 +0800 32 | 33 | picshot (0.4.1-1) UNRELEASED; urgency=medium 34 | 35 | picshot (0.4.7-1) UNRELEASED; urgency=medium 36 | 37 | * 重新实现绘画 toolbar 的透明磨砂在跨平台上面实现的效果 38 | * 修复跨平台(MacOS) 下的编译失败失败,低版本 10.15+、12.0+ 都支持 39 | * 完整支持国际化:暂为 English、简体中文、繁体中文 40 | 41 | -- XMuli Mon, 31 Oct 2022 19:52:18 +0800 42 | 43 | picshot (0.4.1-1) UNRELEASED; urgency=medium 44 | 45 | * 修复 MacOS 下的构建 dmg 包 CI 46 | 47 | -- XMuli Sat, 01 Oct 2022 14:17:01 +0800 48 | 49 | picshot (0.4-1) UNRELEASED; urgency=medium 50 | 51 | * 优化 CMake 构建,创建 Linux 下的 install 命令 52 | 53 | -- XMuli Fri, 26 Aug 2022 21:23:01 +0800 54 | 55 | 56 | picshot (0.3.2-1) UNRELEASED; urgency=medium 57 | 58 | * 修复 Linux 构建 *.deb 失败 59 | * 构建包名使用小写 60 | 61 | -- XMuli Mon, 15 Aug 2022 23:13:29 +0800 62 | 63 | picshot (0.3.1-1) UNRELEASED; urgency=medium 64 | 65 | * 修复 Linux 和 MacOS 编译失败 66 | * 修复 MacOS 显示图片区域不正常 67 | * Ubuntu apt 安装 qt 最大 5.12.8,故control 切换回 5.12.0 68 | 69 | -- xmuli Mon, 15 Aug 2022 00:33:46 +0800 70 | 71 | picshot (0.3-1) unstable; urgency=medium 72 | 73 | * 添加贴图功能 74 | * 添加十字线功能 75 | * 添加高亮活动色的支持 76 | * 偏好界面的槽函数实现 77 | * Qt 升级 5.12.11 --> 5.15.2 78 | * 添加国际化支持 79 | * 优化的 1080 和 4K 屏幕下各自的控件大小,优化 UI 显示 80 | * 优化 CMake 的书写 81 | * 优化冗余和注释代码 82 | 83 | -- XMuli Thu, 04 Aug 2022 23:53:03 +0800 84 | 85 | picshot (0.2-1) unstable; urgency=medium 86 | 87 | * 采用全新 UI 设计:截图工具栏和偏好设置界面 88 | * 优化内存,且彻底重构掉旧的架构逻辑(两周重构了半年的代码,好累啊) 89 | * CMake 进步了,采用树形目录结构在 Visual Studio 中展示,便于开发 90 | 91 | -- XMuli Mon, 04 Jul 2022 23:01:03 +0800 92 | 93 | 94 | picshot (0.1.4-1) unstable; urgency=medium 95 | 96 | * 支持智能选中窗口(Linux) 97 | * 绘画工具栏的位置自动改变 98 | * 添加插件机制(水印) 99 | 100 | -- XMuli Sun, 05 Jun 2022 16:50:38 +0800 101 | 102 | 103 | picshot (0.1.3-1) unstable; urgency=medium 104 | 105 | * 支持选中绘画图形后拖曳后移动位置 106 | * 支持智能选中窗口(windows) 107 | * 绘画由“相对坐标”切换为“绝对坐标” 108 | * 优化存储绘画图像的堆栈 109 | * 添加 PKGBUILD 为 Arch 构建脚本 110 | 111 | -- XMuli Thur, 07 Apr 2022 21:24:38 +0800 112 | 113 | 114 | picshot (0.1.2-1) unstable; urgency=medium 115 | 116 | * try build .deb on Linux(ubuntu 20.04) 117 | 118 | -- XMuli Sun, 27 Mar 2022 16:16:38 +0800 119 | -------------------------------------------------------------------------------- /debian/compat: -------------------------------------------------------------------------------- 1 | 11 2 | -------------------------------------------------------------------------------- /debian/control: -------------------------------------------------------------------------------- 1 | Source: flipped 2 | Section: unknown 3 | Priority: optional 4 | Maintainer: XMuli 5 | Build-Depends: 6 | cmake (>= 3.13~), 7 | debhelper (>= 11), 8 | qtbase5-dev (>= 5.12.0~), 9 | libqt5x11extras5-dev 10 | # qt5-default (>= 5.12.0~), 11 | # qttools5-dev (>= 5.12.0), 12 | Standards-Version: 4.4.1 13 | Homepage: https://github.com/XMuli/Flipped 14 | #Vcs-Browser: https://salsa.debian.org/debian/flipped 15 | #Vcs-Git: https://salsa.debian.org/debian/flipped.git 16 | 17 | Package: flipped 18 | Architecture: any 19 | Depends: ${shlibs:Depends}, ${misc:Depends} 20 | Description: Open source cross-platform screenshots 21 | Qt5-based open source cross-platform screenshot tool 22 | -------------------------------------------------------------------------------- /debian/copyright: -------------------------------------------------------------------------------- 1 | Format: https://www.debian.org/doc/packaging-manuals/copyright-format/1.0/ 2 | Upstream-Name: picshot 3 | Upstream-Contact: https://github.com/XMuli/Flipped 4 | Source: https://github.com/XMuli/Flipped 5 | 6 | Files: * 7 | Copyright: 2023 XMuli 8 | License: MIT 9 | 10 | Files: debian/* 11 | Copyright: 2023 XMuli 12 | License: MIT 13 | 14 | License: MIT 15 | Permission is hereby granted, free of charge, to any person obtaining a 16 | copy of this software and associated documentation files (the "Software"), 17 | to deal in the Software without restriction, including without limitation 18 | the rights to use, copy, modify, merge, publish, distribute, sublicense, 19 | and/or sell copies of the Software, and to permit persons to whom the 20 | Software is furnished to do so, subject to the following conditions: 21 | . 22 | The above copyright notice and this permission notice shall be included 23 | in all copies or substantial portions of the Software. 24 | . 25 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 26 | OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 27 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 28 | IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 29 | CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 30 | TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 31 | SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 32 | 33 | # Please also look if there are files or directories which have a 34 | # different copyright/license attached and list them here. 35 | # Please avoid picking licenses with terms that are more restrictive than the 36 | # packaged work, as it may make Debian's contributions unacceptable upstream. 37 | # 38 | # If you need, there are some extra license texts available in two places: 39 | # /usr/share/debhelper/dh_make/licenses/ 40 | # /usr/share/common-licenses/ 41 | -------------------------------------------------------------------------------- /debian/files: -------------------------------------------------------------------------------- 1 | flipped-dbgsym_1.3.2-1_amd64.deb debug optional automatic=yes 2 | flipped_1.3.2-1_amd64.buildinfo unknown optional 3 | flipped_1.3.2-1_amd64.deb unknown optional 4 | -------------------------------------------------------------------------------- /debian/flipped.substvars: -------------------------------------------------------------------------------- 1 | shlibs:Depends=libc6 (>= 2.14), libgcc1 (>= 1:3.0), libqt5core5a (>= 5.15.1), libqt5gui5 (>= 5.14.1) | libqt5gui5-gles (>= 5.14.1), libqt5svg5 (>= 5.6.0~beta), libqt5widgets5 (>= 5.12.0~), libqt5x11extras5 (>= 5.6.0), libqt5xml5 (>= 5.12.0~), libstdc++6 (>= 5.2), libx11-6, libxext6 2 | misc:Depends= 3 | misc:Pre-Depends= 4 | -------------------------------------------------------------------------------- /debian/rules: -------------------------------------------------------------------------------- 1 | #!/usr/bin/make -f 2 | # See debhelper(7) (uncomment to enable) 3 | # output every command that modifies files on the build system. 4 | #export DH_VERBOSE = 1 5 | 6 | 7 | # see FEATURE AREAS in dpkg-buildflags(1) 8 | #export DEB_BUILD_MAINT_OPTIONS = hardening=+all 9 | 10 | # see ENVIRONMENT in dpkg-buildflags(1) 11 | # package maintainers to append CFLAGS 12 | #export DEB_CFLAGS_MAINT_APPEND = -Wall -pedantic 13 | # package maintainers to append LDFLAGS 14 | #export DEB_LDFLAGS_MAINT_APPEND = -Wl,--as-needed 15 | 16 | 17 | %: 18 | dh $@ 19 | 20 | 21 | # dh_make generated override targets 22 | # This is example for Cmake (See https://bugs.debian.org/641051 ) 23 | #override_dh_auto_configure: 24 | # dh_auto_configure -- # -DCMAKE_LIBRARY_PATH=$(DEB_HOST_MULTIARCH) 25 | 26 | -------------------------------------------------------------------------------- /debian/source/format: -------------------------------------------------------------------------------- 1 | 3.0 (quilt) 2 | -------------------------------------------------------------------------------- /debian_portable/Flipped.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | appname=`basename $0 | sed s,\.sh$,,` #获取\和.sh之间的字符串 3 | 4 | dirname=`dirname $0` 5 | tmp="${dirname#?}" 6 | 7 | #绝对路径 8 | if [ "${dirname%$tmp}" != "/" ]; then 9 | dirname=$PWD/$dirname 10 | fi 11 | 12 | LD_LIBRARY_PATH=$dirname 13 | export LD_LIBRARY_PATH 14 | $dirname/$appname "$@" #"$@" 脚本参数 15 | 16 | -------------------------------------------------------------------------------- /debian_portable/ldd.sh: -------------------------------------------------------------------------------- 1 | #! /bin/bash 2 | EXE='Flipped' # 我的程序名 3 | PWD=`pwd` # 打包的路径 4 | files=`ldd $EXE | awk '{ if(match($3,"^/"))printf("%s "),$3 }'` 5 | cp $files $PWD 6 | 7 | -------------------------------------------------------------------------------- /docs/.gitignore: -------------------------------------------------------------------------------- 1 | _site 2 | .sass-cache 3 | Gemfile.lock 4 | *.gem 5 | .jekyll-cache 6 | -------------------------------------------------------------------------------- /docs/.rubocop.yml: -------------------------------------------------------------------------------- 1 | inherit_gem: 2 | rubocop-github: 3 | - config/default.yml 4 | 5 | AllCops: 6 | Exclude: 7 | - _site/**/* 8 | - vendor/**/* 9 | 10 | Layout/LineLength: 11 | Enabled: false 12 | -------------------------------------------------------------------------------- /docs/.travis.yml: -------------------------------------------------------------------------------- 1 | language: ruby 2 | cache: bundler 3 | rvm: 2.6 4 | 5 | install: script/bootstrap 6 | script: script/cibuild 7 | -------------------------------------------------------------------------------- /docs/CNAME: -------------------------------------------------------------------------------- 1 | flipped.xmuli.tech -------------------------------------------------------------------------------- /docs/Gemfile: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | source "https://rubygems.org" 4 | 5 | gemspec 6 | -------------------------------------------------------------------------------- /docs/_config.yml: -------------------------------------------------------------------------------- 1 | title: FLIPPED 2 | description: Simple and beautiful screenshot software for Windows, MacOS and Linux. 3 | show_downloads: true 4 | google_analytics: 5 | theme: jekyll-theme-architect -------------------------------------------------------------------------------- /docs/_includes/head-custom-google-analytics.html: -------------------------------------------------------------------------------- 1 | {% if site.google_analytics %} 2 | 10 | {% endif %} 11 | -------------------------------------------------------------------------------- /docs/_includes/head-custom.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | {% include head-custom-google-analytics.html %} 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /docs/_layouts/default.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 13 | 14 | {% seo %} 15 | 16 | {% include head-custom.html %} 17 | 18 | 19 | 20 |
21 |
22 | 23 |

{{ site.title | default: site.github.repository_name }}

24 |
25 |

{{ site.description | default: site.github.project_tagline }}

26 | {% if site.github.is_project_page %} 27 | View project on GitHub 28 | {% endif %} 29 | {% if site.github.is_user_page %} 30 | Follow me on GitHub 31 | {% endif %} 32 |
33 |
34 | 35 |
36 |
37 |
38 | {{ content }} 39 |
40 | 41 | 59 |
60 |
61 | 62 | 63 | 64 | -------------------------------------------------------------------------------- /docs/_sass/architect.scss: -------------------------------------------------------------------------------- 1 | // Placeholder file. If your site uses 2 | // @import "{{ site.theme }}"; 3 | // Then using this theme with jekyll-remote-theme will work fine. 4 | @import "jekyll-theme-architect"; 5 | -------------------------------------------------------------------------------- /docs/_sass/rouge-github.scss: -------------------------------------------------------------------------------- 1 | .highlight table td { padding: 5px; } 2 | .highlight table pre { margin: 0; } 3 | .highlight .cm { 4 | color: #999988; 5 | font-style: italic; 6 | } 7 | .highlight .cp { 8 | color: #999999; 9 | font-weight: bold; 10 | } 11 | .highlight .c1 { 12 | color: #999988; 13 | font-style: italic; 14 | } 15 | .highlight .cs { 16 | color: #999999; 17 | font-weight: bold; 18 | font-style: italic; 19 | } 20 | .highlight .c, .highlight .cd { 21 | color: #999988; 22 | font-style: italic; 23 | } 24 | .highlight .err { 25 | color: #a61717; 26 | background-color: #e3d2d2; 27 | } 28 | .highlight .gd { 29 | color: #000000; 30 | background-color: #ffdddd; 31 | } 32 | .highlight .ge { 33 | color: #000000; 34 | font-style: italic; 35 | } 36 | .highlight .gr { 37 | color: #aa0000; 38 | } 39 | .highlight .gh { 40 | color: #999999; 41 | } 42 | .highlight .gi { 43 | color: #000000; 44 | background-color: #ddffdd; 45 | } 46 | .highlight .go { 47 | color: #888888; 48 | } 49 | .highlight .gp { 50 | color: #555555; 51 | } 52 | .highlight .gs { 53 | font-weight: bold; 54 | } 55 | .highlight .gu { 56 | color: #aaaaaa; 57 | } 58 | .highlight .gt { 59 | color: #aa0000; 60 | } 61 | .highlight .kc { 62 | color: #000000; 63 | font-weight: bold; 64 | } 65 | .highlight .kd { 66 | color: #000000; 67 | font-weight: bold; 68 | } 69 | .highlight .kn { 70 | color: #000000; 71 | font-weight: bold; 72 | } 73 | .highlight .kp { 74 | color: #000000; 75 | font-weight: bold; 76 | } 77 | .highlight .kr { 78 | color: #000000; 79 | font-weight: bold; 80 | } 81 | .highlight .kt { 82 | color: #445588; 83 | font-weight: bold; 84 | } 85 | .highlight .k, .highlight .kv { 86 | color: #000000; 87 | font-weight: bold; 88 | } 89 | .highlight .mf { 90 | color: #009999; 91 | } 92 | .highlight .mh { 93 | color: #009999; 94 | } 95 | .highlight .il { 96 | color: #009999; 97 | } 98 | .highlight .mi { 99 | color: #009999; 100 | } 101 | .highlight .mo { 102 | color: #009999; 103 | } 104 | .highlight .m, .highlight .mb, .highlight .mx { 105 | color: #009999; 106 | } 107 | .highlight .sb { 108 | color: #d14; 109 | } 110 | .highlight .sc { 111 | color: #d14; 112 | } 113 | .highlight .sd { 114 | color: #d14; 115 | } 116 | .highlight .s2 { 117 | color: #d14; 118 | } 119 | .highlight .se { 120 | color: #d14; 121 | } 122 | .highlight .sh { 123 | color: #d14; 124 | } 125 | .highlight .si { 126 | color: #d14; 127 | } 128 | .highlight .sx { 129 | color: #d14; 130 | } 131 | .highlight .sr { 132 | color: #009926; 133 | } 134 | .highlight .s1 { 135 | color: #d14; 136 | } 137 | .highlight .ss { 138 | color: #990073; 139 | } 140 | .highlight .s { 141 | color: #d14; 142 | } 143 | .highlight .na { 144 | color: #008080; 145 | } 146 | .highlight .bp { 147 | color: #999999; 148 | } 149 | .highlight .nb { 150 | color: #0086B3; 151 | } 152 | .highlight .nc { 153 | color: #445588; 154 | font-weight: bold; 155 | } 156 | .highlight .no { 157 | color: #008080; 158 | } 159 | .highlight .nd { 160 | color: #3c5d5d; 161 | font-weight: bold; 162 | } 163 | .highlight .ni { 164 | color: #800080; 165 | } 166 | .highlight .ne { 167 | color: #990000; 168 | font-weight: bold; 169 | } 170 | .highlight .nf { 171 | color: #990000; 172 | font-weight: bold; 173 | } 174 | .highlight .nl { 175 | color: #990000; 176 | font-weight: bold; 177 | } 178 | .highlight .nn { 179 | color: #555555; 180 | } 181 | .highlight .nt { 182 | color: #000080; 183 | } 184 | .highlight .vc { 185 | color: #008080; 186 | } 187 | .highlight .vg { 188 | color: #008080; 189 | } 190 | .highlight .vi { 191 | color: #008080; 192 | } 193 | .highlight .nv { 194 | color: #008080; 195 | } 196 | .highlight .ow { 197 | color: #000000; 198 | font-weight: bold; 199 | } 200 | .highlight .o { 201 | color: #000000; 202 | font-weight: bold; 203 | } 204 | .highlight .w { 205 | color: #bbbbbb; 206 | } 207 | .highlight { 208 | background-color: #f8f8f8; 209 | } 210 | -------------------------------------------------------------------------------- /docs/another-page.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: default 3 | --- 4 | 5 | ## Welcome to another page 6 | 7 | _yay_ 8 | 9 | [back](./) 10 | -------------------------------------------------------------------------------- /docs/assets/css/print.scss: -------------------------------------------------------------------------------- 1 | --- 2 | --- 3 | 4 | html, body, div, span, applet, object, iframe, 5 | h1, h2, h3, h4, h5, h6, p, blockquote, pre, 6 | a, abbr, acronym, address, big, cite, code, 7 | del, dfn, em, img, ins, kbd, q, s, samp, 8 | small, strike, strong, sub, sup, tt, var, 9 | b, u, i, center, 10 | dl, dt, dd, ol, ul, li, 11 | fieldset, form, label, legend, 12 | table, caption, tbody, tfoot, thead, tr, th, td, 13 | article, aside, canvas, details, embed, 14 | figure, figcaption, footer, header, hgroup, 15 | menu, nav, output, ruby, section, summary, 16 | time, mark, audio, video { 17 | padding: 0; 18 | margin: 0; 19 | font: inherit; 20 | font-size: 100%; 21 | vertical-align: baseline; 22 | border: 0; 23 | } 24 | /* HTML5 display-role reset for older browsers */ 25 | article, aside, details, figcaption, figure, 26 | footer, header, hgroup, menu, nav, section { 27 | display: block; 28 | } 29 | body { 30 | line-height: 1; 31 | } 32 | ol, ul { 33 | list-style: none; 34 | } 35 | blockquote, q { 36 | quotes: none; 37 | } 38 | blockquote:before, blockquote:after, 39 | q:before, q:after { 40 | content: ''; 41 | content: none; 42 | } 43 | table { 44 | border-spacing: 0; 45 | border-collapse: collapse; 46 | } 47 | body { 48 | font-family: 'Helvetica Neue', Helvetica, Arial, serif; 49 | font-size: 13px; 50 | line-height: 1.5; 51 | color: #000; 52 | } 53 | 54 | a { 55 | font-weight: bold; 56 | color: #d5000d; 57 | } 58 | 59 | header { 60 | padding-top: 35px; 61 | padding-bottom: 10px; 62 | } 63 | 64 | header h1 { 65 | font-size: 48px; 66 | font-weight: bold; 67 | line-height: 1.2; 68 | color: #303030; 69 | letter-spacing: -1px; 70 | } 71 | 72 | header h2 { 73 | font-size: 24px; 74 | font-weight: normal; 75 | line-height: 1.3; 76 | color: #aaa; 77 | letter-spacing: -1px; 78 | } 79 | #downloads { 80 | display: none; 81 | } 82 | #main_content { 83 | padding-top: 20px; 84 | } 85 | 86 | code, pre { 87 | margin-bottom: 30px; 88 | font-family: Monaco, "Bitstream Vera Sans Mono", "Lucida Console", Terminal; 89 | font-size: 12px; 90 | color: #222; 91 | } 92 | 93 | code { 94 | padding: 0 3px; 95 | } 96 | 97 | pre { 98 | padding: 20px; 99 | overflow: auto; 100 | border: solid 1px #ddd; 101 | } 102 | pre code { 103 | padding: 0; 104 | } 105 | 106 | ul, ol, dl { 107 | margin-bottom: 20px; 108 | } 109 | 110 | 111 | /* COMMON STYLES */ 112 | 113 | table { 114 | width: 100%; 115 | border: 1px solid #ebebeb; 116 | } 117 | 118 | th { 119 | font-weight: 500; 120 | } 121 | 122 | td { 123 | font-weight: 300; 124 | text-align: center; 125 | border: 1px solid #ebebeb; 126 | } 127 | 128 | form { 129 | padding: 20px; 130 | background: #f2f2f2; 131 | 132 | } 133 | 134 | 135 | /* GENERAL ELEMENT TYPE STYLES */ 136 | 137 | h1 { 138 | font-size: 2.8em; 139 | } 140 | 141 | h2 { 142 | margin-bottom: 8px; 143 | font-size: 22px; 144 | font-weight: bold; 145 | color: #303030; 146 | } 147 | 148 | h3 { 149 | margin-bottom: 8px; 150 | font-size: 18px; 151 | font-weight: bold; 152 | color: #d5000d; 153 | } 154 | 155 | h4 { 156 | font-size: 16px; 157 | font-weight: bold; 158 | color: #303030; 159 | } 160 | 161 | h5 { 162 | font-size: 1em; 163 | color: #303030; 164 | } 165 | 166 | h6 { 167 | font-size: .8em; 168 | color: #303030; 169 | } 170 | 171 | p { 172 | margin-bottom: 20px; 173 | font-weight: 300; 174 | } 175 | 176 | a { 177 | text-decoration: none; 178 | } 179 | 180 | p a { 181 | font-weight: 400; 182 | } 183 | 184 | blockquote { 185 | padding: 0 0 0 30px; 186 | margin-bottom: 20px; 187 | font-size: 1.6em; 188 | border-left: 10px solid #e9e9e9; 189 | } 190 | 191 | ul li { 192 | padding-left: 20px; 193 | list-style-position: inside; 194 | list-style: disc; 195 | } 196 | 197 | ol li { 198 | padding-left: 3px; 199 | list-style-position: inside; 200 | list-style: decimal; 201 | } 202 | 203 | dl dd { 204 | font-style: italic; 205 | font-weight: 100; 206 | } 207 | 208 | footer { 209 | padding-top: 20px; 210 | padding-bottom: 30px; 211 | margin-top: 40px; 212 | font-size: 13px; 213 | color: #aaa; 214 | } 215 | 216 | footer a { 217 | color: #666; 218 | } 219 | 220 | /* MISC */ 221 | .clearfix:after { 222 | display: block; 223 | height: 0; 224 | clear: both; 225 | visibility: hidden; 226 | content: '.'; 227 | } 228 | 229 | .clearfix {display: inline-block;} 230 | * html .clearfix {height: 1%;} 231 | .clearfix {display: block;} 232 | -------------------------------------------------------------------------------- /docs/assets/css/style.scss: -------------------------------------------------------------------------------- 1 | --- 2 | --- 3 | 4 | @import 'jekyll-theme-architect'; 5 | -------------------------------------------------------------------------------- /docs/assets/images/body-bg.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SunnyCapturer/FLIPPED/1c936be8e407535363d7e6239b953eb196bbf84e/docs/assets/images/body-bg.jpg -------------------------------------------------------------------------------- /docs/assets/images/download-button.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SunnyCapturer/FLIPPED/1c936be8e407535363d7e6239b953eb196bbf84e/docs/assets/images/download-button.png -------------------------------------------------------------------------------- /docs/assets/images/github-button.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SunnyCapturer/FLIPPED/1c936be8e407535363d7e6239b953eb196bbf84e/docs/assets/images/github-button.png -------------------------------------------------------------------------------- /docs/assets/images/header-bg.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SunnyCapturer/FLIPPED/1c936be8e407535363d7e6239b953eb196bbf84e/docs/assets/images/header-bg.jpg -------------------------------------------------------------------------------- /docs/assets/images/highlight-bg.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SunnyCapturer/FLIPPED/1c936be8e407535363d7e6239b953eb196bbf84e/docs/assets/images/highlight-bg.jpg -------------------------------------------------------------------------------- /docs/assets/images/sidebar-bg.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SunnyCapturer/FLIPPED/1c936be8e407535363d7e6239b953eb196bbf84e/docs/assets/images/sidebar-bg.jpg -------------------------------------------------------------------------------- /docs/docs/CODE_OF_CONDUCT.md: -------------------------------------------------------------------------------- 1 | # Contributor Covenant Code of Conduct 2 | 3 | ## Our Pledge 4 | 5 | In the interest of fostering an open and welcoming environment, we as contributors and maintainers pledge to making participation in our project and our community a harassment-free experience for everyone, regardless of age, body size, disability, ethnicity, gender identity and expression, level of experience, nationality, personal appearance, race, religion, or sexual identity and orientation. 6 | 7 | ## Our Standards 8 | 9 | Examples of behavior that contributes to creating a positive environment include: 10 | 11 | * Using welcoming and inclusive language 12 | * Being respectful of differing viewpoints and experiences 13 | * Gracefully accepting constructive criticism 14 | * Focusing on what is best for the community 15 | * Showing empathy towards other community members 16 | 17 | Examples of unacceptable behavior by participants include: 18 | 19 | * The use of sexualized language or imagery and unwelcome sexual attention or advances 20 | * Trolling, insulting/derogatory comments, and personal or political attacks 21 | * Public or private harassment 22 | * Publishing others' private information, such as a physical or electronic address, without explicit permission 23 | * Other conduct which could reasonably be considered inappropriate in a professional setting 24 | 25 | ## Our Responsibilities 26 | 27 | Project maintainers are responsible for clarifying the standards of acceptable behavior and are expected to take appropriate and fair corrective action in response to any instances of unacceptable behavior. 28 | 29 | Project maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct, or to ban temporarily or permanently any contributor for other behaviors that they deem inappropriate, threatening, offensive, or harmful. 30 | 31 | ## Scope 32 | 33 | This Code of Conduct applies both within project spaces and in public spaces when an individual is representing the project or its community. Examples of representing a project or community include using an official project e-mail address, posting via an official social media account, or acting as an appointed representative at an online or offline event. Representation of a project may be further defined and clarified by project maintainers. 34 | 35 | ## Enforcement 36 | 37 | Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by contacting the project team at opensource@github.com. The project team will review and investigate all complaints, and will respond in a way that it deems appropriate to the circumstances. The project team is obligated to maintain confidentiality with regard to the reporter of an incident. Further details of specific enforcement policies may be posted separately. 38 | 39 | Project maintainers who do not follow or enforce the Code of Conduct in good faith may face temporary or permanent repercussions as determined by other members of the project's leadership. 40 | 41 | ## Attribution 42 | 43 | This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, available at [http://contributor-covenant.org/version/1/4][version] 44 | 45 | [homepage]: http://contributor-covenant.org 46 | [version]: http://contributor-covenant.org/version/1/4/ 47 | -------------------------------------------------------------------------------- /docs/docs/SUPPORT.md: -------------------------------------------------------------------------------- 1 | ## Where to get help 2 | 3 | If you think you've found a bug in the Architect theme, please [check the existing issues](https://github.com/pages-themes/architect/issues), and if no one has reported the problem, [open a new issue](https://github.com/pages-themes/architect/issues/new). 4 | 5 | If you have a general question about the theme, how to implement it, or how to customize it for your site you have two options: 6 | 7 | 1. Search for your query on [`support.github.com`](https://support.github.com/?q=pages+Architect+theme), which will also look for similar topics on [`github.community`](https://github.community/search?q=pages+Architect+theme) 8 | 2. Ask your question of the Jekyll community on [talk.jekyllrb.com](https://talk.jekyllrb.com/) 9 | 3. [Contact GitHub Support](https://github.com/contact?form%5Bsubject%5D=GitHub%20Pages%20theme%20pages-themes/architect) 10 | -------------------------------------------------------------------------------- /docs/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SunnyCapturer/FLIPPED/1c936be8e407535363d7e6239b953eb196bbf84e/docs/favicon.ico -------------------------------------------------------------------------------- /docs/index.zh_CN.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: default 3 | --- 4 | 5 | 6 | 7 |
8 |

9 |

10 | 11 | FLIPPED 12 | 13 |
14 | FLIPPED 15 |

16 |
17 |

Simple and beautiful screenshot software tool for Windows, MacOS and Linux

18 |

简洁且漂亮的截图的软件工具,支持 Windows,MacOS,Linux 平台

19 |

簡潔且漂亮的截圖的軟件工具,支持 Windows,MacOS,Linux 平臺

20 |

21 |

22 | 23 | code-size 24 | 25 | 26 | Docs 27 | 28 |

29 |
30 | 31 | 32 | 33 | > Time: 2024-06-01 34 | > Featured new screenshot project: Sunny, supports screenshot & pinning, OCR text extraction and image translation! 35 | > FLIPPED has adopted MIT loose agreement, open source all the code, help newcomers to lower the threshold of C++ / Qt, can easily write a screenshot project! 36 | 37 |
38 | 39 | 40 | ## Preview 41 | 42 | **MACOS:** 43 | 44 | 45 | 46 | **WINDOWS:** 47 | 48 | 49 | 50 | - **LINUX:** 51 | 52 | 53 | 54 | - **Other:** 55 | 56 | More snapshoot effects can be → [here](https://github.com/XMuli/FILPPED/tree/master/snapshot) preview 57 | 58 | 59 | 60 |
61 | 62 | ## 截图作品系列 63 | 64 | 很久之前就想些一个软件截图的软件,目前一共写如下三个层级的难度作品,提供大家参考 65 | 66 | - **Ⅰ. 新手之作 ShotX** 67 | - 项目地址:[ShotX](https://github.com/XMuli/ShotX) \| [镜像](https://gitee.com/XMuli/ShotX) 68 | - 功 能:①基本的截图功能,复制和保存,②右键托盘及菜单,③支持 Window,MacOS,Linux,④攥写 Github-Action 的 CI/CD 自动脚本 .yml;实现自动打包和发布,⑤更多见 README 和 源码 69 | - 描 述:新手级的截图,适合初学 Qt/C++ 入门者 70 | - **Ⅱ. 高级之作 FLIPPED** 71 | - 官 网:[flipped.xmuli.tech](https://flipped.xmuli.tech/) 72 | - 项目地址:[FLIPPED](https://github.com/SunnyScreenshot/FLIPPED) \| [镜像](https://gitee.com/SunnyScreenshot/FLIPPED) 73 | - 功 能:①贴图和钉图,②多屏截图,延时截图,自定义截图,③智能检测窗口矩形(Windows & Linux),④矩形、椭圆、箭头、画笔、马赛克、文本、序号,⑤撤销、重做(多级)、保存、取消、拷贝到剪切板,⑥截图框样式三套,且主题色提供自定义;屏幕十字线样式自定义,⑦国际化:英文、简体中文、繁体中文;字体和字号自定义,⑧支持设置窗口,托盘,截图区域之间的流畅切换,⑨更多见 README 和 源码 74 | - 描 述:高级难度,适合已学习 Qt/C++ 数年经验进阶,需同类型软件的代码借鉴,但可探索中独立写一个大的软件。出发于隐私安全,无任何联网功能。 75 | - **Ⅲ. 商业级别的成熟之作 Sunny (推荐)** 76 | - 官 网:[sunny.xmuli.tech](https://sunny.xmuli.tech/) 77 | - 项目地址:[Sunny](https://github.com/XMuli/sunnypages) \| [镜像](https://gitee.com/XMuli/SunnyPages) 78 | - 功 能:是 FLIPPED 作品的超集合,常见截图功能都都包含。还包含额外的功能:① "图片翻译" (中/英/日/韩/俄等),和"OCR 提取文字",也支持用户私人token 的额度使用 ,② .iss 脚本和 CMake 来提供便携版,安装版,③ 绘画工具栏的亚克力效果,且支持跨平台(毛玻璃效果),④编辑文本支持富文本,同一个注释可采用多个字体和颜色等(暂未遇到其它同类软件也能做到),⑤全新的 UI/UE 设计交互,“设置窗口” 无任何缝隙拼接感,颜值达到简约美观,⑥优化截屏完成后的内存释放;⑦国际化翻译更方便,⑧CMake 重写拆分为 EXE + DLL 隔离,⑨进行代码签名,方便下载校验和防篡改,⑩成功上架 Window 的微软商店,Linux 的 深度/统信商店,以及三方的星火商店等;麒麟商店也在上架待审核 79 | - 描 述:基于前两个的项目经验和不足,直接重写了一套新的框架和UI界面;目前个人从代码功能和产品体验来说,已经达到 工程代码整洁、规范、稳定和健壮性,优秀的解耦机制,漂亮简约得 UI / UX 设计,可以随时应对变化的实际需求,很久之内都无需重构了。定位为 漂亮和简洁,功能实用为主。 80 | 81 | | 项目 | 描述 | 开发经验 | 82 | | :-----: | :----------------------------------------------------------: | :----------------------------------------------------------: | 83 | | ShotX | 功能极简的截图工具 | 简易,新手级的截图,适合初学 Qt/C++ 入门 | 84 | | FLIPPED | 简洁且漂亮,功能完整的截图软件;隐私安全,无任何联网功能 | 高级难度,属 Qt/C++ 数年经验的进阶作品,在借鉴同类作品的代码时,可于探索中独立完成的一个大的软件 | 85 | | Sunny | 一款简洁且漂亮的截图的软件工具。亦支持图片翻译和OCR;已上架微软商店,深度/统信商店,及三方的星火商店等 | 专业级作品,适合已多年沉浸研究 Qt/C++ 经验,随心所欲写任意所需功能,**属于商业级的成熟作品,是本截图系列的最高水准之作** | 86 | 87 | 88 | 89 | > **注:** ShotX,FLIPPED,Sunny 这三款均支持跨平台 Windows / MacOS / Linux。 90 | > 91 | > **笔记:** Sunny = FLIPPED的功能重构 + 代码重构 + UI重构 + 网络功能(图片翻译+OCR)+ 上架应用商店 + 后续新功能;而 ShotX 是最早的练手探索 92 | 93 |
-------------------------------------------------------------------------------- /docs/jekyll-theme-architect.gemspec: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | Gem::Specification.new do |s| 4 | s.name = "jekyll-theme-architect" 5 | s.version = "0.2.0" 6 | s.license = "CC0-1.0" 7 | s.authors = ["Jason Long", "GitHub, Inc."] 8 | s.email = ["opensource+jekyll-theme-architect@github.com"] 9 | s.homepage = "https://github.com/pages-themes/architect" 10 | s.summary = "Architect is a Jekyll theme for GitHub Pages" 11 | 12 | s.files = `git ls-files -z`.split("\x0").select do |f| 13 | f.match(%r{^((_includes|_layouts|_sass|assets)/|(LICENSE|README)((\.(txt|md|markdown)|$)))}i) 14 | end 15 | 16 | s.required_ruby_version = ">= 2.4.0" 17 | 18 | s.platform = Gem::Platform::RUBY 19 | s.add_runtime_dependency "jekyll", "> 3.5", "< 5.0" 20 | s.add_runtime_dependency "jekyll-seo-tag", "~> 2.0" 21 | s.add_development_dependency "html-proofer", "~> 3.0" 22 | s.add_development_dependency "rubocop-github", "~> 0.16" 23 | s.add_development_dependency "w3c_validators", "~> 1.3" 24 | end 25 | -------------------------------------------------------------------------------- /docs/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SunnyCapturer/FLIPPED/1c936be8e407535363d7e6239b953eb196bbf84e/docs/logo.png -------------------------------------------------------------------------------- /docs/script/bootstrap: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | set -e 4 | 5 | gem install bundler 6 | bundle install 7 | -------------------------------------------------------------------------------- /docs/script/cibuild: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | set -e 4 | 5 | bundle exec jekyll build 6 | bundle exec htmlproofer ./_site --check-html --check-sri 7 | bundle exec rubocop -D --config .rubocop.yml 8 | bundle exec script/validate-html 9 | gem build jekyll-theme-architect.gemspec 10 | -------------------------------------------------------------------------------- /docs/script/release: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # Tag and push a release. 3 | 4 | set -e 5 | 6 | # Make sure we're in the project root. 7 | 8 | cd $(dirname "$0")/.. 9 | 10 | # Make sure the darn thing works 11 | 12 | bundle update 13 | 14 | # Build a new gem archive. 15 | 16 | rm -rf jekyll-theme-architect-*.gem 17 | gem build -q jekyll-theme-architect.gemspec 18 | 19 | # Make sure we're on the master branch. 20 | 21 | (git branch | grep -q 'master') || { 22 | echo "Only release from the master branch." 23 | exit 1 24 | } 25 | 26 | # Figure out what version we're releasing. 27 | 28 | tag=v`ls jekyll-theme-architect-*.gem | sed 's/^jekyll-theme-architect-\(.*\)\.gem$/\1/'` 29 | 30 | # Make sure we haven't released this version before. 31 | 32 | git fetch -t origin 33 | 34 | (git tag -l | grep -q "$tag") && { 35 | echo "Whoops, there's already a '${tag}' tag." 36 | exit 1 37 | } 38 | 39 | # Tag it and bag it. 40 | 41 | gem push jekyll-theme-architect-*.gem && git tag "$tag" && 42 | git push origin master && git push origin "$tag" 43 | -------------------------------------------------------------------------------- /docs/script/validate-html: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | # frozen_string_literal: true 3 | 4 | require "w3c_validators" 5 | 6 | def validator(file) 7 | extension = File.extname(file) 8 | if extension == ".html" 9 | W3CValidators::NuValidator.new 10 | elsif extension == ".css" 11 | W3CValidators::CSSValidator.new 12 | end 13 | end 14 | 15 | def validate(file) 16 | puts "Checking #{file}..." 17 | 18 | path = File.expand_path "../_site/#{file}", __dir__ 19 | results = validator(file).validate_file(path) 20 | 21 | return puts "Valid!" if results.errors.empty? 22 | 23 | results.errors.each { |err| puts err.to_s } 24 | exit 1 25 | end 26 | 27 | validate "index.html" 28 | validate File.join "assets", "css", "style.css" 29 | -------------------------------------------------------------------------------- /docs/snapshot/FLIPPED2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SunnyCapturer/FLIPPED/1c936be8e407535363d7e6239b953eb196bbf84e/docs/snapshot/FLIPPED2.jpg -------------------------------------------------------------------------------- /docs/snapshot/MacOS13_Cover.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SunnyCapturer/FLIPPED/1c936be8e407535363d7e6239b953eb196bbf84e/docs/snapshot/MacOS13_Cover.jpg -------------------------------------------------------------------------------- /docs/snapshot/MacOS13_Cover2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SunnyCapturer/FLIPPED/1c936be8e407535363d7e6239b953eb196bbf84e/docs/snapshot/MacOS13_Cover2.jpg -------------------------------------------------------------------------------- /docs/snapshot/MacOS13_Cover23.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SunnyCapturer/FLIPPED/1c936be8e407535363d7e6239b953eb196bbf84e/docs/snapshot/MacOS13_Cover23.jpg -------------------------------------------------------------------------------- /docs/snapshot/MacOS13_Cover3.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SunnyCapturer/FLIPPED/1c936be8e407535363d7e6239b953eb196bbf84e/docs/snapshot/MacOS13_Cover3.jpg -------------------------------------------------------------------------------- /docs/snapshot/MacOS13_Cover4.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SunnyCapturer/FLIPPED/1c936be8e407535363d7e6239b953eb196bbf84e/docs/snapshot/MacOS13_Cover4.jpg -------------------------------------------------------------------------------- /docs/snapshot/MacOS13_Cover5.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SunnyCapturer/FLIPPED/1c936be8e407535363d7e6239b953eb196bbf84e/docs/snapshot/MacOS13_Cover5.jpg -------------------------------------------------------------------------------- /docs/snapshot/Ubuntu20.04_Cover.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SunnyCapturer/FLIPPED/1c936be8e407535363d7e6239b953eb196bbf84e/docs/snapshot/Ubuntu20.04_Cover.jpg -------------------------------------------------------------------------------- /docs/snapshot/Windows10_Couer.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SunnyCapturer/FLIPPED/1c936be8e407535363d7e6239b953eb196bbf84e/docs/snapshot/Windows10_Couer.jpg -------------------------------------------------------------------------------- /docs/snapshot/Windows10_Couer10.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SunnyCapturer/FLIPPED/1c936be8e407535363d7e6239b953eb196bbf84e/docs/snapshot/Windows10_Couer10.png -------------------------------------------------------------------------------- /docs/snapshot/Windows10_Couer11.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SunnyCapturer/FLIPPED/1c936be8e407535363d7e6239b953eb196bbf84e/docs/snapshot/Windows10_Couer11.png -------------------------------------------------------------------------------- /docs/snapshot/Windows10_Couer12.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SunnyCapturer/FLIPPED/1c936be8e407535363d7e6239b953eb196bbf84e/docs/snapshot/Windows10_Couer12.jpg -------------------------------------------------------------------------------- /docs/snapshot/Windows10_Couer2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SunnyCapturer/FLIPPED/1c936be8e407535363d7e6239b953eb196bbf84e/docs/snapshot/Windows10_Couer2.jpg -------------------------------------------------------------------------------- /docs/snapshot/Windows10_Couer3.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SunnyCapturer/FLIPPED/1c936be8e407535363d7e6239b953eb196bbf84e/docs/snapshot/Windows10_Couer3.jpg -------------------------------------------------------------------------------- /docs/snapshot/Windows10_Couer4.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SunnyCapturer/FLIPPED/1c936be8e407535363d7e6239b953eb196bbf84e/docs/snapshot/Windows10_Couer4.jpg -------------------------------------------------------------------------------- /docs/snapshot/Windows10_Couer5.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SunnyCapturer/FLIPPED/1c936be8e407535363d7e6239b953eb196bbf84e/docs/snapshot/Windows10_Couer5.jpg -------------------------------------------------------------------------------- /docs/snapshot/Windows10_Couer6.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SunnyCapturer/FLIPPED/1c936be8e407535363d7e6239b953eb196bbf84e/docs/snapshot/Windows10_Couer6.png -------------------------------------------------------------------------------- /docs/snapshot/Windows10_Couer7.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SunnyCapturer/FLIPPED/1c936be8e407535363d7e6239b953eb196bbf84e/docs/snapshot/Windows10_Couer7.png -------------------------------------------------------------------------------- /docs/snapshot/Windows10_Couer8.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SunnyCapturer/FLIPPED/1c936be8e407535363d7e6239b953eb196bbf84e/docs/snapshot/Windows10_Couer8.png -------------------------------------------------------------------------------- /docs/snapshot/Windows10_Couer9.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SunnyCapturer/FLIPPED/1c936be8e407535363d7e6239b953eb196bbf84e/docs/snapshot/Windows10_Couer9.png -------------------------------------------------------------------------------- /docs/thumbnail.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SunnyCapturer/FLIPPED/1c936be8e407535363d7e6239b953eb196bbf84e/docs/thumbnail.png -------------------------------------------------------------------------------- /pluginsimpl/watemark/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | 2 | set(PLUGIN_NAME "watemark") 3 | project(${PLUGIN_NAME}) 4 | 5 | set(EXECUTABLE_OUTPUT_PATH ${CMAKE_CURRENT_SOURCE_DIR}/../bin) # 更改二进制输出路径 6 | 7 | # Sources files 8 | set(SRCS_FILES 9 | "watemarkplugin.h" 10 | "watemarkplugin.cpp" 11 | "watemarkitem.h" 12 | "watemarkitem.cpp") 13 | 14 | set(CMAKE_CXX_STANDARD 17) 15 | set(CMAKE_AUTOMOC ON) 16 | set(CMAKE_AUTORCC ON) 17 | set(CMAKE_AUTOUIC ON) 18 | set(QT5_LIBS_LINK 19 | Qt5::Core 20 | Qt5::Gui 21 | Qt5::Widgets) 22 | 23 | find_package(Qt5 COMPONENTS 24 | Core 25 | Gui 26 | Widgets 27 | REQUIRED) 28 | 29 | add_library(${PLUGIN_NAME} SHARED ${SRCS_FILES}) 30 | 31 | #add_definitions("${QT_DEFINITIONS} -DQT_PLUGIN") 32 | #set_target_properties(${PLUGIN_NAME} PROPERTIES LIBRARY_OUTPUT_DIRECTORY ../) 33 | #target_include_directories(${PLUGIN_NAME} PUBLIC 34 | # ${DtkWidget_INCLUDE_DIRS} 35 | # ${DFrameworkDBus_INCLUDE_DIRS} 36 | # ${QGSettings_INCLUDE_DIRS} 37 | # ../../src/pluginsinterface) 38 | 39 | set(_src_root_path ${CMAKE_CURRENT_SOURCE_DIR}) # default root path curr path (CMakeList.txt) 40 | file(GLOB_RECURSE _source_list LIST_DIRECTORIES false 41 | "${_src_root_path}/*.cpp" 42 | "${_src_root_path}/*.h") 43 | source_group(TREE ${_src_root_path} FILES ${_source_list}) 44 | 45 | target_link_libraries(${PLUGIN_NAME} PRIVATE 46 | ${QT5_LIBS_LINK}) 47 | 48 | #install(TARGETS ${PLUGIN_NAME} LIBRARY DESTINATION plugins) 49 | -------------------------------------------------------------------------------- /pluginsimpl/watemark/watemark.json: -------------------------------------------------------------------------------- 1 | { 2 | "api": "0.1" 3 | } 4 | -------------------------------------------------------------------------------- /pluginsimpl/watemark/watemarkitem.cpp: -------------------------------------------------------------------------------- 1 | #include "watemarkitem.h" 2 | 3 | WateMarkItem::WateMarkItem() 4 | { 5 | 6 | } 7 | -------------------------------------------------------------------------------- /pluginsimpl/watemark/watemarkitem.h: -------------------------------------------------------------------------------- 1 | #ifndef WATEMARKITEM_H 2 | #define WATEMARKITEM_H 3 | 4 | #include 5 | 6 | class WateMarkItem : public QWidget 7 | { 8 | Q_OBJECT 9 | public: 10 | WateMarkItem(); 11 | }; 12 | 13 | #endif // WATEMARKITEM_H 14 | -------------------------------------------------------------------------------- /pluginsimpl/watemark/watemarkplugin.cpp: -------------------------------------------------------------------------------- 1 | #include "watemarkplugin.h" 2 | #include 3 | 4 | 5 | WateMarkPlugin::WateMarkPlugin(QObject *parent) 6 | { 7 | int a = 0; 8 | 9 | } 10 | 11 | const QString WateMarkPlugin::plugName() const 12 | { 13 | return "WateMark"; 14 | } 15 | 16 | QWidget *WateMarkPlugin::itemWidget() 17 | { 18 | return new QLabel("test label"); 19 | } 20 | -------------------------------------------------------------------------------- /pluginsimpl/watemark/watemarkplugin.h: -------------------------------------------------------------------------------- 1 | #ifndef WATEMARKPLUGIN_H 2 | #define WATEMARKPLUGIN_H 3 | 4 | #include 5 | #include "../../src/pluginsinterface/iplugininterface.h" 6 | 7 | class WateMarkPlugin : public QObject, IPluginInterface // 必须多继承自 QObject 和抽象类; 8 | { 9 | Q_OBJECT 10 | // Q_INTERFACES 的作用是将所实现的插件接口通知给元类型系统,参数是抽象类类名; 11 | // Q_PLUGIN_METADATA 用于声明元数据,IID 是必须且唯一的,FILE 是可选的,后面跟着一个json文件,用于描述插件的相关数据信息; 12 | Q_INTERFACES(IPluginInterface) 13 | Q_PLUGIN_METADATA(IID "XMuli.PicShot.PluginsInterface" FILE "watemark.json") 14 | public: 15 | explicit WateMarkPlugin(QObject *parent = nullptr); 16 | 17 | public: 18 | virtual const QString plugName() const override; 19 | virtual QWidget *itemWidget() override; 20 | }; 21 | 22 | #endif // WATEMARKPLUGIN_H 23 | -------------------------------------------------------------------------------- /setup-user.iss: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SunnyCapturer/FLIPPED/1c936be8e407535363d7e6239b953eb196bbf84e/setup-user.iss -------------------------------------------------------------------------------- /snapshot/FLIPPED2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SunnyCapturer/FLIPPED/1c936be8e407535363d7e6239b953eb196bbf84e/snapshot/FLIPPED2.jpg -------------------------------------------------------------------------------- /snapshot/Flipped.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /snapshot/MacOS13_Cover.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SunnyCapturer/FLIPPED/1c936be8e407535363d7e6239b953eb196bbf84e/snapshot/MacOS13_Cover.jpg -------------------------------------------------------------------------------- /snapshot/MacOS13_Cover2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SunnyCapturer/FLIPPED/1c936be8e407535363d7e6239b953eb196bbf84e/snapshot/MacOS13_Cover2.jpg -------------------------------------------------------------------------------- /snapshot/MacOS13_Cover23.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SunnyCapturer/FLIPPED/1c936be8e407535363d7e6239b953eb196bbf84e/snapshot/MacOS13_Cover23.jpg -------------------------------------------------------------------------------- /snapshot/MacOS13_Cover3.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SunnyCapturer/FLIPPED/1c936be8e407535363d7e6239b953eb196bbf84e/snapshot/MacOS13_Cover3.jpg -------------------------------------------------------------------------------- /snapshot/MacOS13_Cover4.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SunnyCapturer/FLIPPED/1c936be8e407535363d7e6239b953eb196bbf84e/snapshot/MacOS13_Cover4.jpg -------------------------------------------------------------------------------- /snapshot/MacOS13_Cover5.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SunnyCapturer/FLIPPED/1c936be8e407535363d7e6239b953eb196bbf84e/snapshot/MacOS13_Cover5.jpg -------------------------------------------------------------------------------- /snapshot/Ubuntu20.04_Cover.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SunnyCapturer/FLIPPED/1c936be8e407535363d7e6239b953eb196bbf84e/snapshot/Ubuntu20.04_Cover.jpg -------------------------------------------------------------------------------- /snapshot/Windows10_Couer.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SunnyCapturer/FLIPPED/1c936be8e407535363d7e6239b953eb196bbf84e/snapshot/Windows10_Couer.jpg -------------------------------------------------------------------------------- /snapshot/Windows10_Couer10.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SunnyCapturer/FLIPPED/1c936be8e407535363d7e6239b953eb196bbf84e/snapshot/Windows10_Couer10.png -------------------------------------------------------------------------------- /snapshot/Windows10_Couer11.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SunnyCapturer/FLIPPED/1c936be8e407535363d7e6239b953eb196bbf84e/snapshot/Windows10_Couer11.png -------------------------------------------------------------------------------- /snapshot/Windows10_Couer12.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SunnyCapturer/FLIPPED/1c936be8e407535363d7e6239b953eb196bbf84e/snapshot/Windows10_Couer12.jpg -------------------------------------------------------------------------------- /snapshot/Windows10_Couer2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SunnyCapturer/FLIPPED/1c936be8e407535363d7e6239b953eb196bbf84e/snapshot/Windows10_Couer2.jpg -------------------------------------------------------------------------------- /snapshot/Windows10_Couer3.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SunnyCapturer/FLIPPED/1c936be8e407535363d7e6239b953eb196bbf84e/snapshot/Windows10_Couer3.jpg -------------------------------------------------------------------------------- /snapshot/Windows10_Couer4.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SunnyCapturer/FLIPPED/1c936be8e407535363d7e6239b953eb196bbf84e/snapshot/Windows10_Couer4.jpg -------------------------------------------------------------------------------- /snapshot/Windows10_Couer5.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SunnyCapturer/FLIPPED/1c936be8e407535363d7e6239b953eb196bbf84e/snapshot/Windows10_Couer5.jpg -------------------------------------------------------------------------------- /snapshot/Windows10_Couer6.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SunnyCapturer/FLIPPED/1c936be8e407535363d7e6239b953eb196bbf84e/snapshot/Windows10_Couer6.png -------------------------------------------------------------------------------- /snapshot/Windows10_Couer7.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SunnyCapturer/FLIPPED/1c936be8e407535363d7e6239b953eb196bbf84e/snapshot/Windows10_Couer7.png -------------------------------------------------------------------------------- /snapshot/Windows10_Couer8.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SunnyCapturer/FLIPPED/1c936be8e407535363d7e6239b953eb196bbf84e/snapshot/Windows10_Couer8.png -------------------------------------------------------------------------------- /snapshot/Windows10_Couer9.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SunnyCapturer/FLIPPED/1c936be8e407535363d7e6239b953eb196bbf84e/snapshot/Windows10_Couer9.png -------------------------------------------------------------------------------- /src/Resources.qrc: -------------------------------------------------------------------------------- 1 | 2 | 3 | resources/tool/arrow.svg 4 | resources/tool/cancel.svg 5 | resources/tool/ellipse.svg 6 | resources/tool/finish.svg 7 | resources/tool/gif.svg 8 | resources/tool/mosaic.svg 9 | resources/tool/rectangle.svg 10 | resources/tool/renewal.svg 11 | resources/tool/revocation.svg 12 | resources/tool/save.svg 13 | resources/tool/smooth.svg 14 | resources/tool/text.svg 15 | resources/tool/serialnumber.svg 16 | resources/tool_para/ellipses/ellipse.svg 17 | resources/tool_para/ellipses/ellipse_fill.svg 18 | resources/tool_para/mosaics/pixelated.svg 19 | resources/tool_para/mosaics/smooth.svg 20 | resources/tool_para/rectangles/rectangle.svg 21 | resources/tool_para/rectangles/rectangle_fill.svg 22 | resources/tool_para/arrows/arrow_1.svg 23 | resources/tool_para/arrows/arrow_2.svg 24 | resources/tool_para/arrows/arrow_3.svg 25 | resources/tool_para/line_width/line_width_1.svg 26 | resources/tool_para/line_width/line_width_2.svg 27 | resources/tool_para/line_width/line_width_3.svg 28 | resources/tool_para/arrows/arrow_4.svg 29 | resources/tool/pin.svg 30 | resources/tool_para/serialnumber/ellipse_fill.svg 31 | resources/tool_para/serialnumber/letters.svg 32 | resources/tool_para/serialnumber/numbers.svg 33 | resources/tool_para/serialnumber/rectangle_fill.svg 34 | resources/tool_para/text/bold.svg 35 | resources/tool_para/text/italic.svg 36 | resources/tool_para/text/outline.svg 37 | resources/tool/custompath.svg 38 | resources/border_style/light_blue/boardPoint.svg 39 | resources/logo/logo.ico 40 | resources/logo/logo.png 41 | resources/logo/logo.svg 42 | resources/logo/resources.rc 43 | 44 | 45 | -------------------------------------------------------------------------------- /src/core/arrowline.cpp: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | // SPDX-FileCopyrightText: 2021-2024 XMuli 3 | // SPDX-GitHub: https://github.com/SunnyScreenshot/FLIPPED 4 | // SPDX-Author: XMuli 5 | 6 | #include "arrowline.h" 7 | 8 | ArrowLine::ArrowLine(double lineWidth, const QPointF &p1, const QPointF &p2) 9 | : m_lineWidth(lineWidth) 10 | , m_p1(p1) 11 | , m_p2(p2) 12 | { 13 | } 14 | 15 | const QPainterPath ArrowLine::arrowLine() const 16 | { 17 | QPointF p1; 18 | QPointF p2; 19 | calcVertexes(p1, p2); 20 | 21 | QPolygonF polygon; 22 | polygon << m_p2 << p1 << p2; 23 | 24 | QPainterPath path; 25 | path.addPolygon(polygon); 26 | path.closeSubpath(); 27 | 28 | const QLineF l1(p1, p2); 29 | const QLineF l2(l1.center(), m_p2); 30 | // const double vertLine( + pow(l2.center().x() - m_p2.x(), 2))); 31 | // const QPointF tEnd(m_p2 - qAbs(l2.center().y() - m_p2.y()) / 3); //三角形垂线的 1/3 处 32 | path.moveTo(m_p1); 33 | path.lineTo(l2.center()); 34 | return path; 35 | } 36 | 37 | const QPainterPath ArrowLine::arrowLineOpen() const 38 | { 39 | QPointF p1; 40 | QPointF p2; 41 | calcVertexes(p1, p2); 42 | 43 | QPainterPath path; 44 | path.moveTo(m_p1); 45 | path.lineTo(m_p2); 46 | path.lineTo(p1); 47 | path.moveTo(m_p2); 48 | path.lineTo(p2); 49 | return path; 50 | } 51 | const QPainterPath ArrowLine::circleLine() const 52 | { 53 | QPainterPath path; 54 | path.moveTo(m_p1); 55 | path.lineTo(m_p2); 56 | const double mix = 2; 57 | const double max = 100; 58 | const double r = qBound(mix, m_lineWidth * 1.2, max); 59 | path.addEllipse(m_p2, r, r); 60 | return path; 61 | } 62 | 63 | const QPainterPath ArrowLine::line() const 64 | { 65 | QPainterPath path; 66 | path.moveTo(m_p1); 67 | path.lineTo(m_p2); 68 | return path; 69 | } 70 | 71 | void ArrowLine::calcVertexes(QPointF &p1, QPointF &p2) const 72 | { 73 | double lenght = 12; // 箭头边线长度 74 | double degrees = 0.4; // 箭头夹角 75 | // const double baseLine = sqrt(pow(m_p2.y() - m_p1.y(), 2) + pow(m_p2.x() - m_p1.x(), 2)); 76 | lenght = qBound(30, lenght + m_lineWidth * 2, 200); 77 | 78 | double angle = atan2(m_p2.y() - m_p1.y(), m_p2.x() - m_p1.x()) + M_PI; 79 | 80 | p1.setX(m_p2.x() + lenght * cos(angle - degrees)); 81 | p1.setY(m_p2.y() + lenght * sin(angle - degrees)); 82 | p2.setX(m_p2.x() + lenght * cos(angle + degrees)); 83 | p2.setY(m_p2.y() + lenght * sin(angle + degrees)); 84 | } 85 | -------------------------------------------------------------------------------- /src/core/arrowline.h: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | // SPDX-FileCopyrightText: 2021-2024 XMuli 3 | // SPDX-GitHub: https://github.com/SunnyScreenshot/FLIPPED 4 | // SPDX-Author: XMuli 5 | 6 | #ifndef ARROWLINE_H 7 | #define ARROWLINE_H 8 | 9 | #include 10 | #include 11 | #include 12 | #include 13 | 14 | class ArrowLine 15 | { 16 | public: 17 | ArrowLine(double lineWidth, const QPointF& p1, const QPointF& p2); 18 | ~ArrowLine() = default; 19 | 20 | const QPainterPath arrowLineOpen() const; 21 | const QPainterPath arrowLine() const; 22 | const QPainterPath circleLine() const; 23 | const QPainterPath line() const; 24 | 25 | private: 26 | void calcVertexes(QPointF& p1, QPointF& p2) const; 27 | 28 | private: 29 | double m_lineWidth; 30 | const QPointF m_p1; 31 | const QPointF m_p2; 32 | }; 33 | 34 | #endif // ARROWLINE_H 35 | -------------------------------------------------------------------------------- /src/core/isingleton.h: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | // SPDX-FileCopyrightText: 2021-2024 XMuli 3 | // SPDX-GitHub: https://github.com/SunnyScreenshot/FLIPPED 4 | // SPDX-Author: XMuli 5 | 6 | #ifndef TSINGLETON_H 7 | #define TSINGLETON_H 8 | 9 | template 10 | class ISingleton 11 | { 12 | public: 13 | static T& instance() { 14 | static T instance; 15 | return instance; 16 | } 17 | 18 | ISingleton(const T&) = delete; 19 | T& operator=(const T&) = delete; 20 | ISingleton(T&&) = delete; 21 | T& operator=(T&&) = delete; 22 | 23 | protected: 24 | ISingleton() = default; 25 | virtual ~ISingleton() = default; 26 | }; 27 | 28 | #define FRIEND_CREAT_SINGLETION(_name) friend class ISingleton<_name>; 29 | 30 | #endif // TSINGLETON_H 31 | -------------------------------------------------------------------------------- /src/core/xlog.h: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | // SPDX-FileCopyrightText: 2021-2024 XMuli 3 | // SPDX-GitHub: https://github.com/SunnyScreenshot/FLIPPED 4 | // SPDX-Author: XMuli 5 | 6 | #ifndef XLOG_H 7 | #define XLOG_H 8 | 9 | #include 10 | #ifdef _WIN32 11 | #define SPDLOG_WCHAR_TO_UTF8_SUPPORT // needs to be defined before spdlog to support the output of wchar_t 12 | #endif 13 | 14 | #include 15 | #include 16 | #include 17 | #include 18 | #include "spdlog/sinks/rotating_file_sink.h" 19 | 20 | class XLog 21 | { 22 | public: 23 | static XLog* instance() { 24 | static XLog instance; 25 | return &instance; 26 | } 27 | 28 | std::shared_ptr getLogger() { return m_logger; } 29 | void setLevel(const std::string val) { m_level = val; } 30 | 31 | private: 32 | XLog() { 33 | std::string path = QStandardPaths::standardLocations(QStandardPaths::TempLocation).first().toStdString() + "/flipped_debug.log"; 34 | 35 | qDebug()<< "Log Path:" << QString::fromStdString(path); 36 | m_logger = spdlog::rotating_logger_mt("fileLogger", path, 1024 * 1024 * 20, 10, true); 37 | m_logger->set_pattern("%Y-%m-%d %H:%M:%S %t %l [%!] %v"); 38 | 39 | setLevel("debug"); 40 | spdlog::level::level_enum logLevel(spdlog::level::n_levels); 41 | if (m_level == "trace") { 42 | logLevel = spdlog::level::trace; 43 | } else if (m_level == "debug") { 44 | logLevel = spdlog::level::debug; 45 | } else if (m_level == "info") { 46 | logLevel = spdlog::level::info; 47 | } else if (m_level == "warn") { 48 | logLevel = spdlog::level::warn; 49 | } else if (m_level == "error") { 50 | logLevel = spdlog::level::err; 51 | } else if (m_level == "critical") { 52 | logLevel = spdlog::level::critical; 53 | } else if (m_level == "off") { 54 | logLevel = spdlog::level::off; 55 | } else { 56 | m_logger->set_level(spdlog::level::n_levels); 57 | } 58 | 59 | m_logger->set_level(logLevel); 60 | m_logger->flush_on(logLevel); 61 | } 62 | 63 | ~XLog() { spdlog::drop_all();} // must do this 64 | XLog(XLog&&) = delete; 65 | XLog(const XLog&) = delete; 66 | void operator= (const XLog&) = delete; 67 | 68 | private: 69 | std::string m_level; 70 | std::shared_ptr m_logger; 71 | }; 72 | 73 | // use embedded macro to support file and line number 74 | #define XLOG_TRACE(...) SPDLOG_LOGGER_CALL(XLog::instance()->getLogger().get(), spdlog::level::trace, __VA_ARGS__) 75 | #define XLOG_DEBUG(...) SPDLOG_LOGGER_CALL(XLog::instance()->getLogger().get(), spdlog::level::debug, __VA_ARGS__) 76 | #define XLOG_INFO(...) SPDLOG_LOGGER_CALL(XLog::instance()->getLogger().get(), spdlog::level::info, __VA_ARGS__) 77 | #define XLOG_WARN(...) SPDLOG_LOGGER_CALL(XLog::instance()->getLogger().get(), spdlog::level::warn, __VA_ARGS__) 78 | #define XLOG_ERROR(...) SPDLOG_LOGGER_CALL(XLog::instance()->getLogger().get(), spdlog::level::err, __VA_ARGS__) 79 | #define XLOG_CRITICAL(...) SPDLOG_LOGGER_CALL(XLog::instance()->getLogger().get(), spdlog::level::critical, __VA_ARGS__) 80 | #define XLOG_OFF(...) SPDLOG_LOGGER_CALL(XLog::instance()->getLogger().get(), spdlog::level::off, __VA_ARGS__) 81 | 82 | #endif // XLOG_H 83 | -------------------------------------------------------------------------------- /src/core/xqtlog.cpp: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | // SPDX-FileCopyrightText: 2021-2024 XMuli 3 | // SPDX-GitHub: https://github.com/SunnyScreenshot/FLIPPED 4 | // SPDX-Author: XMuli 5 | 6 | #include "xqtlog.h" 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | #include 18 | #include 19 | #include 20 | 21 | #define LOG_FILE_KEEP_NUM 7 22 | 23 | // https://blog.csdn.net/lileiyu1/article/details/78279514 24 | // https://blog.csdn.net/liang19890820/article/details/51838379 25 | // https://www.coologic.cn/2018/01/880/ 26 | void CustomOutputMessage(QtMsgType type, const QMessageLogContext& context, const QString& msg) 27 | { 28 | // Lock to prevent qdebug from crashing too often in multiple threads 29 | static QMutex mutex; 30 | QMutexLocker locker(&mutex); 31 | 32 | QString curTime = QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss"); 33 | QString msgType; 34 | switch (type) { 35 | case QtDebugMsg: { 36 | msgType = "Debug"; 37 | break; 38 | } 39 | case QtInfoMsg: { 40 | msgType = "Info"; 41 | break; 42 | } 43 | case QtWarningMsg: { 44 | msgType = "Warning"; 45 | break; 46 | } 47 | case QtCriticalMsg: { 48 | msgType = "Critical"; 49 | break; 50 | } 51 | case QtFatalMsg: { 52 | msgType = "Fatal"; 53 | QMessageBox::critical(nullptr, msgType, QString("[%1] [%2] [%3] Function: %4 File: %5 Line: %6\n").arg(curTime).arg(msgType).arg(msg).arg(context.function).arg(context.file).arg(context.line)); 54 | abort(); 55 | break; 56 | } 57 | default: 58 | break; 59 | } 60 | 61 | QString logMsg = QString("[%1] [%2] [%3] Function: %4 File: %5 Line: %6\n").arg(curTime).arg(msgType).arg(msg).arg(context.function).arg(context.file).arg(context.line); 62 | if (logMsg.isEmpty()) 63 | return; 64 | 65 | // Create and write files 66 | // QString path = QString::fromStdString(QStandardPaths::standardLocations(QStandardPaths::TempLocation).first().toStdString()) + "/flipped_log"; 67 | QString path = qApp->applicationDirPath(); 68 | 69 | QDir dir(path); 70 | if (!dir.exists()) 71 | dir.mkdir(path); 72 | 73 | QString currentDate = QDateTime::currentDateTime().toString("yyyyMMdd"); 74 | QString logName = "log_flipped_" + currentDate + ".txt"; 75 | QString logFileName = path + "/" + logName; 76 | 77 | static std::once_flag flag1; 78 | std::call_once(flag1, [logFileName](){ qDebug() << "log path:" << logFileName; }); 79 | 80 | if (!QFile::exists(logFileName)) { 81 | QFileInfoList fileList = dir.entryInfoList(QStringList() << "*.txt", QDir::NoFilter, QDir::Time); 82 | if (fileList.size() >= LOG_FILE_KEEP_NUM) { 83 | int i = 1; 84 | foreach(QFileInfo fileInfo, fileList) { 85 | if (i >= LOG_FILE_KEEP_NUM) { 86 | QString fileName = fileInfo.absoluteFilePath(); 87 | QFile::remove(fileName); 88 | } 89 | i++; 90 | } 91 | } 92 | } 93 | 94 | QFile file(logFileName); 95 | if (!file.open(QIODevice::WriteOnly | QIODevice::Append /*QIODevice::Truncate*/ | QIODevice::Text)) { 96 | file.close(); 97 | return; 98 | } 99 | 100 | QTextStream ts(&file); 101 | ts << logMsg; 102 | file.close(); 103 | } 104 | 105 | XQtLog::XQtLog(QObject *parent) 106 | : QObject{parent} 107 | { 108 | 109 | } 110 | -------------------------------------------------------------------------------- /src/core/xqtlog.h: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | // SPDX-FileCopyrightText: 2021-2024 XMuli 3 | // SPDX-GitHub: https://github.com/SunnyScreenshot/FLIPPED 4 | // SPDX-Author: XMuli 5 | 6 | #ifndef XQTLOG_H 7 | #define XQTLOG_H 8 | 9 | #include 10 | 11 | void CustomOutputMessage(QtMsgType type, const QMessageLogContext& context, const QString& msg); 12 | 13 | class XQtLog : public QObject 14 | { 15 | Q_OBJECT 16 | public: 17 | explicit XQtLog(QObject *parent = nullptr); 18 | }; 19 | 20 | #endif // XQTLOG_H 21 | -------------------------------------------------------------------------------- /src/main.cpp: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | // SPDX-FileCopyrightText: 2021-2024 XMuli 3 | // SPDX-GitHub: https://github.com/SunnyScreenshot/FLIPPED 4 | // SPDX-Author: XMuli 5 | 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | 16 | // test 17 | #include 18 | #include 19 | #include 20 | #include 21 | #include 22 | #include 23 | #include 24 | #include 25 | #include 26 | #include "./screen/tray.h" 27 | #include "preference/prefmanage.h" 28 | #include "qmetaobject.h" 29 | #include "tool/pin/pinwidget.h" 30 | #include "widget/xroundwidget.h" 31 | #include "tool/parameterbar.h" 32 | #include "tool/selectbar.h" 33 | #include "core/xlog.h" 34 | #include "tool/base/blurwidget.h" 35 | #include "screen/datamaid.h" 36 | 37 | int main(int argc, char *argv[]) 38 | { 39 | //qInstallMessageHandler(CustomOutputMessage); 40 | qInstallMessageHandler(nullptr); 41 | 42 | // 高分屏四种方案 https://blog.csdn.net/qq_33154343/article/details/108905279 43 | #if(QT_VERSION > QT_VERSION_CHECK(5,6,0)) 44 | // QGuiApplication::setAttribute(Qt::AA_EnableHighDpiScaling); // 2K、4K 2@ 倍;获取的分辨率 4K 下实际为 /2 后。 此行需在 QApplication a(argc,argv);前面 45 | // QCoreApplication::setAttribute(Qt::AA_UseHighDpiPixmaps); // 控制图片缩放质量,svg 的图片不会模糊在 4K 上。 此行无需在 QApplication a(argc,argv);前面 46 | qApp->setAttribute(Qt::AA_UseHighDpiPixmaps); // 上面一行没有生效,但是此行可以生效 47 | #endif 48 | 49 | // 因多处使用 QSettings,故声明组织等信息 50 | QCoreApplication::setOrganizationName(QStringLiteral("XMuli")); 51 | QCoreApplication::setOrganizationDomain(QStringLiteral("github.com/XMuli")); 52 | QCoreApplication::setApplicationName(QStringLiteral(_PROJECT_NAME)); 53 | QCoreApplication::setApplicationVersion(_PROJECT_VERSION); 54 | 55 | QApplication a(argc, argv); 56 | a.setQuitOnLastWindowClosed(false); 57 | qApp->setAttribute(Qt::AA_DontCreateNativeWidgetSiblings, true); 58 | 59 | QString filePath = QApplication::applicationDirPath() + "/Flipped.temp.lock"; 60 | QLockFile* lockFile = new QLockFile(filePath); 61 | bool isLock = lockFile->isLocked(); 62 | qDebug() << "filePath:" << filePath << " isLock:" << isLock; 63 | 64 | if (!lockFile->tryLock(100)) { 65 | QMessageBox msgBox(QMessageBox::Warning, QObject::tr("Warning"), QObject::tr("The application is already running.\nAllowed to run only one instance of the application.")); 66 | msgBox.exec(); 67 | return 0; 68 | } 69 | 70 | if (lockFile) 71 | delete lockFile; 72 | 73 | DATAMAID->setRunLanguage(); 74 | 75 | Tray::instance(); 76 | 77 | 78 | // QStringList listStyle = QStyleFactory::keys(); 79 | // foreach(QString val, listStyle) 80 | // qDebug()<setWindowFlags(Qt::FramelessWindowHint); 91 | //// t1 ->setBlurBackground(QPixmap("D:/projects/Flipped/src/p1.jpg"), 4); 92 | // t1->move(200, 100); 93 | // t1->show(); 94 | 95 | // ParameterBar* t2 = new ParameterBar(Qt::Horizontal); 96 | //// t2->setBlurBackground(QPixmap("D:/projects/Flipped/src/p2.jpg"), 5); 97 | // t2->move(200, 200); 98 | // t2->show(); 99 | 100 | // ColorParaBar* t3 = new ColorParaBar(ColorParaBarMode::CPB_ParaBar, Qt::Horizontal); 101 | //// t3->resize(400, 300); 102 | // t3->move(200, 300); 103 | // t3->show(); 104 | 105 | // ColorParaBar* t3_1 = new ColorParaBar(ColorParaBarMode::CPB_HighLight, Qt::Horizontal); 106 | // // t3->resize(400, 300); 107 | // t3_1->move(200, 400); 108 | // t3_1->show(); 109 | 110 | //// ExWidget* t4 = new ExWidget(); 111 | //// // t3->resize(400, 300); 112 | //// t4->move(100, 200); 113 | //// t4->show(); 114 | 115 | // PinWidget* w5 = new PinWidget(QPixmap("C:/Users/xmuli/Desktop/Snipaste_2022-07-16_02-13-39.png"), QRect(100, 100, 400, 400)); 116 | // w5->show(); 117 | 118 | return QApplication::exec(); 119 | } 120 | -------------------------------------------------------------------------------- /src/platform/iwininfo.cpp: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | // SPDX-FileCopyrightText: 2021-2024 XMuli 3 | // SPDX-GitHub: https://github.com/SunnyScreenshot/FLIPPED 4 | // SPDX-Author: XMuli 5 | 6 | #include "iwininfo.h" 7 | 8 | std::vector IWinInfo::m_vWinData; 9 | std::vector IWinInfo::m_vWinIdFilter; 10 | 11 | -------------------------------------------------------------------------------- /src/platform/iwininfo.h: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | // SPDX-FileCopyrightText: 2021-2024 XMuli 3 | // SPDX-GitHub: https://github.com/SunnyScreenshot/FLIPPED 4 | // SPDX-Author: XMuli 5 | 6 | #ifndef IWININFO_H 7 | #define IWININFO_H 8 | 9 | #include 10 | #include 11 | #include 12 | #include 13 | 14 | union WinID { 15 | void* _hWnd; // NT OS 16 | unsigned long _xWindow; // X11 OS 17 | }; 18 | 19 | struct WinData 20 | { 21 | WinData(WinID tId 22 | , bool bTFilter 23 | , QRect tRect 24 | , QString tPath 25 | , QString tName 26 | , QString tTitle 27 | , QString tReserved 28 | , int tLevel 29 | , int tCurIndex 30 | , int tTotalIndex) 31 | : id(tId) 32 | , bFilter(bTFilter) 33 | , rect(tRect) 34 | , path(tPath) 35 | , name(tName) 36 | , title(tTitle) 37 | , reserved(tReserved) 38 | , level(tLevel) 39 | , curIndex(tCurIndex) 40 | , totalIndex(tTotalIndex){} 41 | 42 | WinData() 43 | : id() // todo 44 | , bFilter(false) 45 | , rect(0, 0, 0, 0) 46 | , path("") 47 | , name("") 48 | , title("") 49 | , reserved("") 50 | , level(0) 51 | , curIndex(0) 52 | , totalIndex(0) {} 53 | 54 | WinID id; 55 | bool bFilter; 56 | QRect rect; 57 | QString path; 58 | QString name; 59 | QString title; 60 | QString reserved; 61 | int level; // 等级 62 | int curIndex; // 当前等级的序号 63 | int totalIndex; // 总的累计个数(横跨等级累计) 64 | }; 65 | 66 | class IWinInfo 67 | { 68 | public: 69 | IWinInfo() = default; 70 | virtual ~IWinInfo() = default; 71 | 72 | virtual void setWinIdFilter(WinID target) = 0; 73 | virtual WinData* getWinInfoFromPoint(QPoint pt, bool bPrevCache = false) = 0; 74 | 75 | //protected: 76 | static std::vector m_vWinData; 77 | static std::vector m_vWinIdFilter; 78 | }; 79 | 80 | #endif // IWININFO_H 81 | 82 | -------------------------------------------------------------------------------- /src/platform/wininfo.cpp: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | // SPDX-FileCopyrightText: 2021-2024 XMuli 3 | // SPDX-GitHub: https://github.com/SunnyScreenshot/FLIPPED 4 | // SPDX-Author: XMuli 5 | 6 | #include "wininfo.h" 7 | 8 | #include 9 | #include 10 | 11 | #ifdef _WIN32 12 | //define something for Windows (32-bit and 64-bit, this part is common) 13 | #include "wininfo_win.h" 14 | #elif __APPLE__ 15 | #elif __linux__ 16 | #include "wininfo_x11.h" 17 | #else 18 | # error "Unknown compiler" 19 | #endif 20 | 21 | // pt 光标当前位置;bPrevCache: true 获取所有窗口模式: false 实时获取窗口模式 22 | const WinData* WinInfo::targWinInfo(WinID hWnd, bool bPrevCache) 23 | { 24 | if (!m_pWinList) 25 | return nullptr; 26 | 27 | WinData* pData = nullptr; 28 | QPoint pt = QCursor::pos(); 29 | 30 | #ifdef _WIN32 31 | POINT pos; 32 | ::GetCursorPos(&pos); 33 | pt = QPoint(pos.x, pos.y); 34 | #elif __APPLE__ 35 | #elif __linux__ 36 | #else 37 | #endif 38 | 39 | if (m_pWinList) { 40 | m_pWinList->setWinIdFilter(hWnd); 41 | pData = m_pWinList->getWinInfoFromPoint(pt, bPrevCache); 42 | } 43 | 44 | return pData; 45 | } 46 | 47 | const QRect WinInfo::targWinRect(WinID hWnd, bool bPrevCache) 48 | { 49 | const WinData* pDate = targWinInfo(hWnd, bPrevCache); 50 | 51 | if (pDate) 52 | return pDate->rect; 53 | else 54 | return QRect(); 55 | } 56 | 57 | void WinInfo::winInfoAllCache() 58 | { 59 | } 60 | 61 | void WinInfo::winInfoRealTime() 62 | { 63 | } 64 | 65 | WinInfo::WinInfo() 66 | : m_bGetAllCache(false) 67 | , m_pWinList(nullptr) 68 | { 69 | #ifdef _WIN32 70 | m_pWinList = new WinInfo_Win(); 71 | #elif __APPLE__ 72 | #elif __linux__ 73 | m_pWinList = new WinInfo_x11(); 74 | #else 75 | #endif 76 | } 77 | -------------------------------------------------------------------------------- /src/platform/wininfo.h: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | // SPDX-FileCopyrightText: 2021-2024 XMuli 3 | // SPDX-GitHub: https://github.com/SunnyScreenshot/FLIPPED 4 | // SPDX-Author: XMuli 5 | 6 | #ifndef WININFO_H 7 | #define WININFO_H 8 | 9 | #include "../core/isingleton.h" 10 | #include "iwininfo.h" 11 | 12 | class WinInfo : public ISingleton 13 | { 14 | FRIEND_CREAT_SINGLETION(WinInfo); 15 | 16 | public: 17 | const WinData* targWinInfo(WinID hWnd, bool bPrevCache); 18 | const QRect targWinRect(WinID hWnd, bool bPrevCache = false); 19 | 20 | private: 21 | void winInfoAllCache(); 22 | void winInfoRealTime(); 23 | 24 | private: 25 | WinInfo(); 26 | virtual ~WinInfo() = default; 27 | 28 | private: 29 | bool m_bGetAllCache; 30 | IWinInfo* m_pWinList; 31 | }; 32 | 33 | #endif // WININFO_H 34 | -------------------------------------------------------------------------------- /src/platform/wininfo_win.h: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | // SPDX-FileCopyrightText: 2021-2024 XMuli 3 | // SPDX-GitHub: https://github.com/SunnyScreenshot/FLIPPED 4 | // SPDX-Author: XMuli 5 | 6 | #ifndef WININFO_WIN_H 7 | #define WININFO_WIN_H 8 | #include "iwininfo.h" 9 | 10 | #include 11 | #include 12 | 13 | class WinInfo_Win : public IWinInfo 14 | { 15 | public: 16 | WinInfo_Win(); 17 | virtual ~WinInfo_Win(); 18 | 19 | public: 20 | virtual void setWinIdFilter(WinID target) override; 21 | virtual WinData* getWinInfoFromPoint(QPoint pt, bool bPrevCache = false) override; 22 | 23 | private: 24 | void getAllWinInfoCache(); 25 | HWND getAllWinInfoRealTime(POINT pt); 26 | 27 | public: 28 | static BOOL CALLBACK EnumRealTimeWindowsProc(HWND hWnd, LPARAM lParam); 29 | static BOOL CALLBACK EnumChildRealTimeWindowsProc(HWND hWnd, LPARAM lParam); 30 | 31 | static BOOL CALLBACK EnumWindowsProc(HWND hWnd, LPARAM lParam); 32 | static BOOL CALLBACK EnumChildWindowsProc(HWND hWnd, LPARAM lParam); 33 | 34 | static BOOL WindowsContainsPoint(HWND hWnd, POINT pt); 35 | static HWND getWinInfoFromCache(POINT pt); 36 | static BOOL WindowsFilter(HWND hWnd); 37 | static std::wstring getWindowPath(DWORD processId); 38 | static std::wstring windowPath2Name(std::wstring path); 39 | 40 | // error: LNK2005: "protected: static struct HWND__ * WinInfoWin::m_hWndTarget" (?m_hWndTarget@WinInfoWin@@1PAUHWND__@@A) already defined in mocs_compilation.cpp.obj 41 | // 静态成员变量只能在 cpp 中初始化,坑了一会 https://stackoverflow.com/questions/40991522 42 | public: 43 | static HWND m_hWndTarget; 44 | static int m_level; 45 | static int m_curIndex; 46 | static int m_totalIndex; 47 | }; 48 | 49 | #endif // WININFO_WIN_H 50 | -------------------------------------------------------------------------------- /src/platform/wininfo_x11.h: -------------------------------------------------------------------------------- 1 | /******************************************************************* 2 | * Copyright (c) 2021-2022 偕臧 All rights reserved. 3 | * 4 | * Author: XMuli 5 | * GitHub: https://github.com/XMuli 6 | * Blog: https://xmuli.tech 7 | * 8 | * Date: 2022.05.11 9 | * Description: Linux 系统下智能窗口识别 10 | ******************************************************************/ 11 | #ifndef WININFO_X11_H 12 | #define WININFO_X11_H 13 | 14 | #include "iwininfo.h" 15 | #include 16 | #include 17 | #include 18 | #include 19 | 20 | #include 21 | #include 22 | #include 23 | #include 24 | 25 | #include 26 | #include 27 | 28 | 29 | class WinInfo_x11 : public IWinInfo 30 | { 31 | public: 32 | virtual void setWinIdFilter(WinID target) override; 33 | virtual WinData* getWinInfoFromPoint(QPoint pt, bool bPrevCache) override; 34 | 35 | public: 36 | WinInfo_x11(); 37 | ~WinInfo_x11(); 38 | 39 | void getAllWinInfo(); 40 | 41 | private: 42 | void getWinIdList(std::list& vec); 43 | 44 | bool bSupportQuery(); 45 | std::string getWindowAtom(Window win, const char *atom); 46 | inline std::string getWindowName(Window win); 47 | 48 | private: 49 | Display* m_pDisplay; 50 | }; 51 | 52 | #endif // WININFO_X11_H 53 | -------------------------------------------------------------------------------- /src/pluginsinterface/iplugininterface.cpp: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | // SPDX-FileCopyrightText: 2021-2024 XMuli 3 | // SPDX-GitHub: https://github.com/SunnyScreenshot/FLIPPED 4 | // SPDX-Author: XMuli 5 | 6 | #include "iplugininterface.h" 7 | -------------------------------------------------------------------------------- /src/pluginsinterface/iplugininterface.h: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | // SPDX-FileCopyrightText: 2021-2024 XMuli 3 | // SPDX-GitHub: https://github.com/SunnyScreenshot/FLIPPED 4 | // SPDX-Author: XMuli 5 | 6 | #ifndef IPLUGININTERFACE_H 7 | #define IPLUGININTERFACE_H 8 | 9 | #include 10 | #include 11 | 12 | class IPluginInterface 13 | { 14 | public: 15 | virtual ~IPluginInterface() {}; 16 | 17 | virtual const QString plugName() const { return QString("test plugName");} 18 | virtual QWidget*itemWidget() { return nullptr;} 19 | }; 20 | 21 | 22 | QT_BEGIN_NAMESPACE 23 | #define IPluginInterface_iid "XMuli.Flipped.PluginsInterface" // 唯一标识符 24 | Q_DECLARE_INTERFACE(IPluginInterface, IPluginInterface_iid) 25 | QT_END_NAMESPACE 26 | 27 | #endif // IPLUGININTERFACE_H 28 | 29 | 30 | -------------------------------------------------------------------------------- /src/preference/appellation.cpp: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | // SPDX-FileCopyrightText: 2021-2024 XMuli 3 | // SPDX-GitHub: https://github.com/SunnyScreenshot/FLIPPED 4 | // SPDX-Author: XMuli 5 | #include "appellation.h" 6 | 7 | 8 | -------------------------------------------------------------------------------- /src/preference/appellation.h: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | // SPDX-FileCopyrightText: 2021-2024 XMuli 3 | // SPDX-GitHub: https://github.com/SunnyScreenshot/FLIPPED 4 | // SPDX-Author: XMuli 5 | 6 | #ifndef APPELLATION_H 7 | #define APPELLATION_H 8 | 9 | #include 10 | 11 | // Description: 统一存放 class PrefManage 中新建的对象的 objectName 12 | // perference UI config 13 | //const QString INIT_GENERAL("General"); // 初始化 常规 14 | //const QString INIT_INTERFACE("Interface"); // 初始化 界面 15 | //const QString INIT_OUTPUT("Output"); // 初始化 输出 16 | //const QString INIT_PIN("Pin"); // 初始化 贴图 17 | //const QString INIT_HOTKEYS("Hotkeys"); // 初始化 快捷键 18 | 19 | namespace XC { 20 | 21 | //tabGeneral 常规 22 | const QString tgFirstRun("firstRun"); 23 | const QString tgLanuage("lanuage"); 24 | const QString tgFont("font"); 25 | const QString tgAutoRun("autoRun"); 26 | const QString tgAsAdmin("asAdmin"); 27 | const QString tgLogLevel("logLevel"); 28 | const QString tgAutoCheckUpdate("autoCheck"); // TODO 带 _ 都是没修改的 29 | const QString tgAutoUpdate("autoUpdate"); 30 | const QString tgReset("tg_reset"); // 单独添加 tg, 下同 31 | 32 | //tabInterface() 界面 33 | const QString tiBorderStyle("borderStyle"); 34 | const QString tiBorderColor("borderColor"); 35 | const QString tiBorderWidth("borderWidth"); 36 | const QString tiCrosshairColor("crosshairColor"); 37 | const QString tiCrosshairWidth("crosshairWidth"); 38 | const QString tiSmartWindow("smartWindow"); 39 | const QString tiCrosshair("crosshair"); 40 | const QString tiShowCursor("showCursor"); 41 | const QString tiAutoCopy2Clipboard("autoCopy2Clipboard"); 42 | const QString tiReset("ti_reset"); 43 | 44 | //tabOutput() 输出 45 | const QString toImageQuailty("imageQuailty"); 46 | const QString toFileName("fileName"); 47 | const QString toConfigPath("configPath"); 48 | const QString toQuickSave("quickSave"); 49 | const QString toAutoSave("autoSave"); 50 | const QString toQuickSavePath("quickSavePath"); 51 | const QString toAutoSavePath("autoSavePath"); 52 | const QString toReset("to_reset"); 53 | 54 | //tabPin() 贴图 55 | const QString tpWindowShadow("windowShadow"); 56 | const QString tpOpacity("opacity"); 57 | const QString tpMaxSize("maxSize"); 58 | const QString tpReset("tp_reset"); 59 | 60 | //tabHotkeys() 快捷键 61 | const QString thScrnCapture("scrnCapture"); 62 | //const QString thScrollingWindow("scrolling_window"); 63 | const QString thDelayCapture("delayCapture"); 64 | const QString thFullScreen("fullScrnCapture"); 65 | //const QString thFixdSize_Region("fixd_size_region"); 66 | //const QString thPaste("paste"); 67 | //const QString thHide_ShowAllImages("hide_show_all_images"); 68 | //const QString thSwitchCurGroup("switch_current_group"); 69 | const QString thReset("th_reset"); 70 | 71 | //tabAbout() 关于 72 | } 73 | 74 | using namespace XC; 75 | 76 | // 对象名、类型、命名的对象名称 77 | #define NEW_OBJECT(_object, _type, _objectName) \ 78 | auto _object = new _type(this); \ 79 | if (_object) \ 80 | _object->setObjectName(_objectName); 81 | 82 | // 对象名、类型、命名的对象名称、可能需要显示的文本 83 | #define NEW_OBJECT_AND_TEXT(_object, _type, _objectName, _text) \ 84 | auto _object = new _type(_text, this); \ 85 | if (_object) \ 86 | _object->setObjectName(_objectName); 87 | 88 | //// 写入配置文件 .ini 的内容 89 | //#define WRITE_CONFIG_INI(group, key, value) \ 90 | // SETTINGINI->beginGroup(group); \ 91 | // SETTINGINI->setValue(key, value); \ 92 | // SETTINGINI->endGroup(); 93 | 94 | //// 读取配置文件 .ini 的内容 95 | //#define READ_CONFIG_INI(group, key, defValue) \ 96 | // SETTINGINI->value("/" + group + "/" + key, defValue) 97 | 98 | #endif // APPELLATION_H 99 | -------------------------------------------------------------------------------- /src/preference/hotkeyswidget.cpp: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | // SPDX-FileCopyrightText: 2021-2024 XMuli 3 | // SPDX-GitHub: https://github.com/SunnyScreenshot/FLIPPED 4 | // SPDX-Author: XMuli 5 | 6 | #include "hotkeyswidget.h" 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include "../xglobal.h" 13 | #include "../screen/tray.h" 14 | #include "../widget/xkeysequenceedit.h" 15 | #include "../screen/drawhelper.h" 16 | #include "../screen/datamaid.h" 17 | #include "appellation.h" 18 | #include "../screen/tray.h" 19 | 20 | HotkeysWidget::HotkeysWidget(QWidget *parent) : QWidget(parent) 21 | { 22 | double m_scale = DATAMAID->scale(); 23 | 24 | setContentsMargins(0, 0, 0, 0); 25 | QVBoxLayout* vLay = new QVBoxLayout(this); 26 | vLay->setContentsMargins(THV_MARGIN_HOR, THV_MARGIN_VER_TOP, THV_MARGIN_HOR, THV_MARGIN_VER_BOTTOM); 27 | 28 | int i = 0; 29 | int j = 0; 30 | QGridLayout* grid = new QGridLayout(); 31 | grid->setMargin(0); 32 | grid->setVerticalSpacing(THG_SPACING_VER); 33 | grid->setHorizontalSpacing(THG_SPACING_HOR); 34 | grid->setColumnStretch(0, 8); 35 | grid->setColumnStretch(1, 9); 36 | 37 | QStringList list = { DATAMAID->paraValue(thScrnCapture).toString() 38 | ,DATAMAID->paraValue(thFullScreen).toString() 39 | ,DATAMAID->paraValue(thDelayCapture).toString()}; 40 | std::map vHkEdit; 41 | int idx = 0; 42 | for (auto& it : Tray::instance().getVHotKeys()) { 43 | auto& hk = std::get<0>(it); 44 | QString& hotkey = std::get<1>(it); 45 | QString& describe = std::get<2>(it); 46 | qDebug() << "----->t0:" << hk << " hotkey:" << hotkey << " describe:" << describe; 47 | 48 | XKeySequenceEdit* pEdit = new XKeySequenceEdit(QKeySequence(hotkey)); 49 | vHkEdit.insert(std::make_pair(pEdit, list.at(idx++))); 50 | pEdit->setObjectName(describe); 51 | pEdit->setMinimumWidth(110 * m_scale); 52 | const bool reg = hk->isRegistered(); 53 | if (reg) { 54 | pEdit->setStyleSheet("background-color: #98fb98;"); 55 | } else { 56 | pEdit->setStyleSheet("background-color: #ff7f50;"); 57 | } 58 | 59 | grid->addWidget(new QLabel(describe + ":"), i, j, 1, 1, Qt::AlignRight); 60 | grid->addWidget(pEdit, i++, j + 1, 1, 1, Qt::AlignLeft); 61 | connect(pEdit, &XKeySequenceEdit::sigKeySeqChanged, &(Tray::instance()), &Tray::onKeySequenceChanged); 62 | 63 | // if (std::get<3>(it) == Tray::ScrnShotType::SST_FullScreen) 64 | // grid->addWidget(new XHorizontalLine(contentsRect().width() * 3 / 4 - THV_MARGIN_HOR * m_scale * 2), i++, j, 1, grid->columnCount(), Qt::AlignCenter); 65 | } 66 | // qDebug() << "tabHotkeys:grid->rowCount():" << grid->rowCount(); 67 | vLay->addLayout(grid, grid->rowCount()); 68 | vLay->addStretch(3); 69 | 70 | QHBoxLayout* hLay = new QHBoxLayout(); 71 | hLay->setContentsMargins(0, 0, 0, 0); 72 | hLay->addSpacing(0); 73 | hLay->addStretch(7); 74 | auto btn = new QPushButton(tr("Reset"), this); 75 | if (btn) { 76 | btn->setObjectName(thReset); 77 | hLay->addWidget(btn, 1, Qt::AlignRight); 78 | 79 | connect(btn, &QPushButton::released, this, [vHkEdit]() { 80 | for (auto& it : vHkEdit) { 81 | it.first->setKeySequence(it.second); 82 | emit it.first->sigKeySeqChanged(it.first->keySequence()); 83 | }}); 84 | } 85 | vLay->addLayout(hLay, 1); 86 | 87 | 88 | 89 | } 90 | 91 | void HotkeysWidget::mousePressEvent(QMouseEvent *event) 92 | { 93 | if (event->button() != Qt::LeftButton) 94 | return; 95 | 96 | // 点击 快捷键编辑框 之外,焦点消失 97 | QList list = findChildren(); 98 | for (const auto& it : list) { 99 | if (!it->geometry().contains(mapFromGlobal(QCursor::pos()))) 100 | it->clearFocus(); 101 | } 102 | } 103 | -------------------------------------------------------------------------------- /src/preference/hotkeyswidget.h: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | // SPDX-FileCopyrightText: 2021-2024 XMuli 3 | // SPDX-GitHub: https://github.com/SunnyScreenshot/FLIPPED 4 | // SPDX-Author: XMuli 5 | 6 | #ifndef HOTKEYSWIDGET_H 7 | #define HOTKEYSWIDGET_H 8 | 9 | #include 10 | #include 11 | #include 12 | 13 | // Description: 偏好设置界面的 hotkeys UI;为了规避掉 编辑框 鼠标点击外面却仍有焦点 14 | class HotkeysWidget : public QWidget 15 | { 16 | Q_OBJECT 17 | public: 18 | explicit HotkeysWidget(QWidget *parent = nullptr); 19 | virtual ~HotkeysWidget() = default; 20 | 21 | protected: 22 | void mousePressEvent(QMouseEvent *event) override; 23 | }; 24 | 25 | #endif // HOTKEYSWIDGET_H 26 | -------------------------------------------------------------------------------- /src/preference/prefmanage.h: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | // SPDX-FileCopyrightText: 2021-2024 XMuli 3 | // SPDX-GitHub: https://github.com/SunnyScreenshot/FLIPPED 4 | // SPDX-Author: XMuli 5 | 6 | #ifndef PREFMANAGE_H 7 | #define PREFMANAGE_H 8 | 9 | #include 10 | #include 11 | 12 | namespace Ui { 13 | class PrefManage; 14 | } 15 | 16 | class PrefManage : public QWidget 17 | { 18 | Q_OBJECT 19 | 20 | public: 21 | explicit PrefManage(QWidget *parent = nullptr); 22 | ~PrefManage(); 23 | 24 | private: 25 | void initUIGeneral(); 26 | void initUIInterface(); 27 | void initUIOutput(); 28 | void initUIPin(); 29 | void initUIHotkeys(); 30 | void initUIAbout(); 31 | void initUI(); 32 | 33 | inline bool cbState2Bool(int state); 34 | 35 | private slots: 36 | // tabGeneral 37 | void on_cbLanuage_currentTextChanged(const QString &language); 38 | void on_btnFont_released(); 39 | void on_cbAutoRun_stateChanged(int sta); 40 | void on_cbLogLevel_currentTextChanged(const QString &level); 41 | 42 | // tabInterface 43 | void onBorderColor(const QColor& color); 44 | void onCrosshairColor(const QColor& color); 45 | void on_cbBorderStyle_currentTextChanged(const QString &style); 46 | void on_spBorderWidth_valueChanged(int val); 47 | void on_spCrosshairWidth_valueChanged(int val); 48 | void on_cbAutoDetectWindows_stateChanged(int val); 49 | void on_cbCrosshair_stateChanged(int val); 50 | void on_cbAutoCopy2clipboard_stateChanged(int val); 51 | 52 | // tabOutput 53 | void on_cbQuickSave_clicked(bool checked); 54 | void on_cbAutoSave_clicked(bool checked); 55 | void on_sbImageQuailty_valueChanged(int val); 56 | void on_leFileName_textChanged(const QString &name); 57 | void on_leConfig_textChanged(const QString &path); 58 | void on_leQuickSave_textChanged(const QString &path); 59 | void on_leAutoSave_textChanged(const QString &path); 60 | QString onSelectPath(); 61 | 62 | // tabPin 63 | void on_sbOpacity_valueChanged(int val); 64 | void on_spMaxSize_valueChanged(int val); 65 | 66 | // tabAbout 67 | 68 | // Reset 69 | void on_generalReset_released(); 70 | void on_interfaceReset_released(); 71 | void on_outputReset_released(); 72 | void on_pinReset_released(); 73 | void on_hotkeysReset_released(); 74 | 75 | private: 76 | Ui::PrefManage *ui; 77 | std::map m_lanuages; 78 | std::map m_borderStyle; 79 | }; 80 | 81 | #endif // PREFMANAGE_H 82 | -------------------------------------------------------------------------------- /src/resources/border_style/light_blue/boardPoint.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Oval 8 5 | Created with Sketch. 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /src/resources/changelog/changelog.txt: -------------------------------------------------------------------------------- 1 | FLIPPED (1.3.0) UNRELEASED; urgency=medium 2 | 3 | * Refactor the entire UI, and CMakelist. 4 | 5 | flipped (1.2.3) UNRELEASED; urgency=medium 6 | 7 | * fix build Linux and MacOS 8 | * UI refactor 9 | 10 | -- XMuli Sun, 23 Arpil 2023 22:08:13 +0800 11 | 12 | flipped (1.1.0) UNRELEASED; urgency=medium 13 | 14 | * 重构整个程序和 .ini 交互的逻辑架构,也使用了很多宏;代码清爽了很多 15 | * 功能:Quick save 16 | * 功能:Auto save 17 | * 功能:快捷键冲突检测、系统消息通知 18 | 19 | -- XMuli Sta, 16 Arpil 2023 19:20:13 +0800 20 | 21 | flipped (1.0.1) UNRELEASED; urgency=medium 22 | 23 | * 添加开机自启动[Windows] 24 | 25 | -- XMuli Sta, 1 Arpil 2023 18:20:13 +0800 26 | 27 | flipped (1.0.0) UNRELEASED; urgency=medium 28 | 29 | * 修复诸多缺陷、屏蔽尚未开发好的部分代码 30 | * 一个较大部分的代码重构、部分架构重新设计 31 | * 整理项目代码规范、添加对应 README 和介绍视频等 32 | 33 | -- XMuli Mon, 31 Oct 2022 19:52:18 +0800 34 | 35 | picshot (0.4.1) UNRELEASED; urgency=medium 36 | 37 | picshot (0.4.7) UNRELEASED; urgency=medium 38 | 39 | * 重新实现绘画 toolbar 的透明磨砂在跨平台上面实现的效果 40 | * 修复跨平台(MacOS) 下的编译失败失败,低版本 10.15+、12.0+ 都支持 41 | * 完整支持国际化:暂为 English、简体中文、繁体中文 42 | 43 | -- XMuli Mon, 31 Oct 2022 19:52:18 +0800 44 | 45 | picshot (0.4.1) UNRELEASED; urgency=medium 46 | 47 | * 修复 MacOS 下的构建 dmg 包 CI 48 | 49 | -- XMuli Sat, 01 Oct 2022 14:17:01 +0800 50 | 51 | picshot (0.4) UNRELEASED; urgency=medium 52 | 53 | * 优化 CMake 构建,创建 Linux 下的 install 命令 54 | 55 | -- XMuli Fri, 26 Aug 2022 21:23:01 +0800 56 | 57 | 58 | picshot (0.3.2) UNRELEASED; urgency=medium 59 | 60 | * 修复 Linux 构建 *.deb 失败 61 | * 构建包名使用小写 62 | 63 | -- XMuli Mon, 15 Aug 2022 23:13:29 +0800 64 | 65 | picshot (0.3.1) UNRELEASED; urgency=medium 66 | 67 | * 修复 Linux 和 MacOS 编译失败 68 | * 修复 MacOS 显示图片区域不正常 69 | * Ubuntu apt 安装 qt 最大 5.12.8,故control 切换回 5.12.0 70 | 71 | -- xmuli Mon, 15 Aug 2022 00:33:46 +0800 72 | 73 | picshot (0.3-1) unstable; urgency=medium 74 | 75 | * 添加贴图功能 76 | * 添加十字线功能 77 | * 添加高亮活动色的支持 78 | * 偏好界面的槽函数实现 79 | * Qt 升级 5.12.11 --> 5.15.2 80 | * 添加国际化支持 81 | * 优化的 1080 和 4K 屏幕下各自的控件大小,优化 UI 显示 82 | * 优化 CMake 的书写 83 | * 优化冗余和注释代码 84 | 85 | -- XMuli Thu, 04 Aug 2022 23:53:03 +0800 86 | 87 | picshot (0.2-1) unstable; urgency=medium 88 | 89 | * 采用全新 UI 设计:截图工具栏和偏好设置界面 90 | * 优化内存,且彻底重构掉旧的架构逻辑(两周重构了半年的代码,好累啊) 91 | * CMake 进步了,采用树形目录结构在 Visual Studio 中展示,便于开发 92 | 93 | -- XMuli Mon, 04 Jul 2022 23:01:03 +0800 94 | 95 | 96 | picshot (0.1.4-1) unstable; urgency=medium 97 | 98 | * 支持智能选中窗口(Linux) 99 | * 绘画工具栏的位置自动改变 100 | * 添加插件机制(水印) 101 | 102 | -- XMuli Sun, 05 Jun 2022 16:50:38 +0800 103 | 104 | 105 | picshot (0.1.3-1) unstable; urgency=medium 106 | 107 | * 支持选中绘画图形后拖曳后移动位置 108 | * 支持智能选中窗口(windows) 109 | * 绘画由“相对坐标”切换为“绝对坐标” 110 | * 优化存储绘画图像的堆栈 111 | * 添加 PKGBUILD 为 Arch 构建脚本 112 | 113 | -- XMuli Thur, 07 Apr 2022 21:24:38 +0800 114 | 115 | 116 | picshot (0.1.2-1) unstable; urgency=medium 117 | 118 | * try build .deb on Linux(ubuntu 20.04) 119 | 120 | -- XMuli Sun, 27 Mar 2022 16:16:38 +0800 121 | -------------------------------------------------------------------------------- /src/resources/config/Copyright.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SunnyCapturer/FLIPPED/1c936be8e407535363d7e6239b953eb196bbf84e/src/resources/config/Copyright.txt -------------------------------------------------------------------------------- /src/resources/config/config.ini: -------------------------------------------------------------------------------- 1 | [%General] 2 | firstRun=true 3 | font="Microsoft YaHei,9" 4 | autoRun=true 5 | asAdmin=false 6 | logLevel=debug 7 | autoUpdate=false 8 | 9 | [Interface] 10 | borderStyle=Flipped 11 | borderColor=#0e70ff 12 | borderWidth=2 13 | crosshairColor=#db000f 14 | crosshairWidth=1 15 | smartWindow=true 16 | crosshair=false 17 | showCursor=false 18 | autoCopy2Clipboard=true 19 | 20 | [Output] 21 | imageQuailty=-1 22 | fileName=Flipped_$yyyyMMdd_hhmmss$.png 23 | quickSave=true 24 | autoSave=false 25 | 26 | [Pin] 27 | windowShadow=false 28 | opacity=100 29 | maxSize=100000 30 | 31 | [Hotkeys] 32 | scrnCapture=F6 33 | delayCapture=F7 34 | fullScrnCapture=F8 35 | -------------------------------------------------------------------------------- /src/resources/licenses/License.md: -------------------------------------------------------------------------------- 1 | ## FLIPPED - Licensing and Disclaimer 2 | 3 | ### Copyright (c) 2023 https://github.com/XMuli/FILPPED 4 | 5 | Unless otherwise stated, all documents and software included in the FLIPPED installation package are the property of https://github.com/XMuli/FILPPED. 6 | 7 | This software is provided as-is, without any express or implied warranties. In no event shall the author be liable for any damages arising from the use of this software. 8 | 9 | ### Scope of Use 10 | 11 | 1. This software is allowed for personal use free of charge. 12 | 2. This software is allowed for commercial use by teams or companies, but prior authorization through email contact is required. 13 | 3. For any custom features or other business collaborations, feel free to reach out to us via email. 14 | 15 | ### Software Distribution 16 | 17 | Under the following conditions, anyone is allowed to redistribute this software: 18 | 19 | 1. All texts, logo images, website content, and styles must be distributed with all existing copyright notices and this list of conditions, without any modifications. 20 | 2. All binary redistributions must retain all instances of the above copyright notice and the website address: 21 | - Website address (e.g., in an "About" box). 22 | - Modifications, cracking, or any alterations to the binary form are prohibited, including any tampering with information prompts inside. 23 | - Misrepresenting the origin of this software is prohibited; you may not claim that you wrote the original software. 24 | - If you use this software to publish a product, please acknowledge it in the product documentation. 25 | - If you use this software to publish a product or work, acknowledging it in the product documentation is appreciated but not required. 26 | 27 | 3. For any modifications made with individual authorization, modified versions in text documents, image resources, and binary form must be clearly marked as such and may not be misrepresented as the original software. 28 | 29 | ## Disclaimer 30 | 31 | Welcome to FLIPPED! Before using the FLIPPED client, please carefully read and understand the following disclaimer to fully comprehend your rights and responsibilities. By using the FLIPPED client, you accept the following disclaimer and agree to comply with its terms and conditions. If you do not agree with the content below, please stop using this software. 32 | 33 | 1. **Service Provision** 34 | 35 | FLIPPED provides the ability to take screenshots and edit them, please refer to the official website for more details. 36 | 37 | 2. **Data Sources** 38 | 39 | FLIPPED has no networking capabilities and does not collect any information from the user. 40 | 41 | 3. **Personal Privacy** 42 | 43 | We highly value your personal privacy and will take reasonable measures to protect your personal information. During the use of the FLIPPED client, it may involve the collection and processing of some personal data. We will strictly comply with relevant laws and regulations to safeguard your privacy. For specific policies regarding personal privacy, please refer to our privacy policy. 44 | 45 | 4. **Liability Terms** 46 | 47 | - Users are solely responsible for any results generated using the FLIPPED client. We are not liable for any losses or damages arising from the use of this software. 48 | - We are not liable for any interruptions, delays, or errors caused by force majeure, accidents, or failures of third-party service providers. 49 | - We are not liable for any difficulties or errors caused by users' own devices or network environments. 50 | 51 | 5. **Intellectual Property** 52 | 53 | All contents of the FLIPPED client, including but not limited to text, images, logos, icons, software, audio, and video, are protected by intellectual property laws. Without authorization, it is forbidden to use any content of the FLIPPED client for commercial purposes, distribution, or replication. 54 | 55 | 6. **Usage Restrictions** 56 | 57 | The FLIPPED client is for personal use only and should not be used for commercial purposes. Users under the age of 18 must use this software under the supervision of their parents or guardians. 58 | 59 | 7. **Other Terms** 60 | 61 | - We reserve the right to change and modify this disclaimer at any time without prior notice. 62 | - In case of any disputes arising from the use of the FLIPPED client, the local laws shall apply. 63 | 64 | Please read and understand the above disclaimer carefully before using the FLIPPED client. If you have any questions or opinions about the disclaimer, please contact us: 65 | 66 | FLIPPED 67 | xmulitech@gmail.com 68 | https://https://github.com/XMuli/FILPPED 69 | 70 | Thank you for choosing the FLIPPED client; we will continue to provide quality service and respect your rights. -------------------------------------------------------------------------------- /src/resources/logo/logo.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SunnyCapturer/FLIPPED/1c936be8e407535363d7e6239b953eb196bbf84e/src/resources/logo/logo.ico -------------------------------------------------------------------------------- /src/resources/logo/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SunnyCapturer/FLIPPED/1c936be8e407535363d7e6239b953eb196bbf84e/src/resources/logo/logo.png -------------------------------------------------------------------------------- /src/resources/logo/logo.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/resources/logo/logo_archive.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SunnyCapturer/FLIPPED/1c936be8e407535363d7e6239b953eb196bbf84e/src/resources/logo/logo_archive.ico -------------------------------------------------------------------------------- /src/resources/logo/logo_archive.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SunnyCapturer/FLIPPED/1c936be8e407535363d7e6239b953eb196bbf84e/src/resources/logo/logo_archive.png -------------------------------------------------------------------------------- /src/resources/logo/resources.rc: -------------------------------------------------------------------------------- 1 | IDI_ICON1 ICON DISCARDABLE "logo.ico" -------------------------------------------------------------------------------- /src/resources/tool/arrow.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 箭头 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /src/resources/tool/cancel.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 取消 4 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /src/resources/tool/custompath.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 画笔 4 | 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /src/resources/tool/ellipse.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 圆形 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /src/resources/tool/finish.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 确定 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /src/resources/tool/gif.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | gif 4 | 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /src/resources/tool/mosaic.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 马赛克 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /src/resources/tool/pin.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 钉住 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /src/resources/tool/rectangle.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 矩形 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /src/resources/tool/renewal.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 恢复 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /src/resources/tool/revocation.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 撤回 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /src/resources/tool/save.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 保存 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /src/resources/tool/serialnumber.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 标注 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /src/resources/tool/smooth.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 模糊 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /src/resources/tool/text.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 文字 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /src/resources/tool_para/arrows/arrow_1.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 箭头2 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /src/resources/tool_para/arrows/arrow_2.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 箭头1 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /src/resources/tool_para/arrows/arrow_3.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 箭头3 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /src/resources/tool_para/arrows/arrow_4.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 线条 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /src/resources/tool_para/ellipses/ellipse.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 圆形-线 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /src/resources/tool_para/ellipses/ellipse_fill.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 圆形-面 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /src/resources/tool_para/line_width/line_width_1.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 粗细1 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /src/resources/tool_para/line_width/line_width_2.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 粗细2 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /src/resources/tool_para/line_width/line_width_3.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 粗细3 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /src/resources/tool_para/mosaics/pixelated.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 马赛克 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /src/resources/tool_para/mosaics/smooth.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 模糊 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /src/resources/tool_para/rectangles/rectangle.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 矩形-线 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /src/resources/tool_para/rectangles/rectangle_fill.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 矩形-面 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /src/resources/tool_para/serialnumber/ellipse_fill.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 圆形-面 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /src/resources/tool_para/serialnumber/letters.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 标注-字母 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /src/resources/tool_para/serialnumber/numbers.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 标注-数字 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /src/resources/tool_para/serialnumber/rectangle_fill.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 矩形-面 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /src/resources/tool_para/text/bold.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 文字-加粗 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /src/resources/tool_para/text/italic.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 文字-斜体 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /src/resources/tool_para/text/outline.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 文字-描边 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /src/screen/drawhelper.cpp: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | // SPDX-FileCopyrightText: 2021-2024 XMuli 3 | // SPDX-GitHub: https://github.com/SunnyScreenshot/FLIPPED 4 | // SPDX-Author: XMuli 5 | 6 | #include "drawhelper.h" 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | #include 18 | #include 19 | #include 20 | #include 21 | #include 22 | #include 23 | #include 24 | #include 25 | #include 26 | #include "../xglobal.h" 27 | #include "../preference/appellation.h" 28 | 29 | QString XDrawStep::serialText = "0_0_0_0"; 30 | 31 | void XDrawStep::showDebug() const 32 | { 33 | const auto& t = pen.widthF(); 34 | qDebug() << "showDebug(): this:" << this; 35 | qDebug() << "p1:" << p1 << " p2:" << p2 << " rt:" << rt << " shape:" << int(shape) << " shapePara:" << int(shapePara); 36 | qDebug() << &pen << " " << pen << " " << pen.color().name() << " " << pen.widthF() << " t:" << &t << " " << t; 37 | qDebug() << &brush << " " << brush << " " << brush.color().name(); 38 | qDebug() << &text << " " << text << " font:" << font << " textParas:" << textParas << " serialText:" << serialText << Qt::endl; 39 | } 40 | 41 | void XDrawStep::partClear() 42 | { 43 | p1 = QPoint(); 44 | p2 = QPoint(); 45 | rt = QRect(); 46 | custPath.clear(); 47 | } 48 | 49 | void XDrawStep::destroyClear() 50 | { 51 | p1 = QPoint(); 52 | p2 = QPoint(); 53 | rt = QRect(); 54 | shape = DrawShape::NoDraw; 55 | shapePara = ShapePara::SP_0; 56 | custPath.clear(); 57 | text.clear(); 58 | 59 | font.setBold(false); 60 | font.setItalic(false); 61 | textParas = TextPara(0); 62 | } 63 | 64 | -------------------------------------------------------------------------------- /src/screen/drawhelper.h: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | // SPDX-FileCopyrightText: 2021-2024 XMuli 3 | // SPDX-GitHub: https://github.com/SunnyScreenshot/FLIPPED 4 | // SPDX-Author: XMuli 5 | 6 | #ifndef XDRAW_H 7 | #define XDRAW_H 8 | 9 | #include "../preference/appellation.h" 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | #include 18 | #include 19 | #include 20 | #include 21 | #include 22 | #include 23 | 24 | class QLine; 25 | class QPoint; 26 | class QDomElement; 27 | 28 | namespace XC { 29 | // C++11 新增带作用域的枚举,用 enum class 或enum struct(两者等价)声明。 30 | // https://blog.csdn.net/luckysym/article/details/1666114 31 | enum class DrawShape { 32 | NoDraw, 33 | LineWidth, 34 | Rectangles, 35 | Ellipses, 36 | Arrows, 37 | CustomPath, 38 | Mosaics, 39 | Text, 40 | SerialNumberShape, 41 | SerialNumberType 42 | }; 43 | 44 | enum class ToolBarOffset { 45 | TBO_Left, 46 | TBO_Middle, 47 | TBO_Right, 48 | 49 | TBO_Top = TBO_Left, 50 | TBO_Bottom = TBO_Right 51 | }; 52 | 53 | enum class LineEnds { 54 | EmptyToEmpty, 55 | EmptyToRecesedArrow, 56 | DotToRecesedArrow, 57 | EmptyToArrow, 58 | DotToArrow, 59 | EmptyToDot, 60 | DotToEmpty, 61 | DotToDot, 62 | RecesedArrowToRecesedArrow, 63 | ArrowToArrow 64 | }; 65 | 66 | enum class ShapePara { // 某种具体图形,互斥的参数的第一个 67 | SP_0, 68 | SP_1, 69 | SP_2, 70 | SP_3 71 | }; 72 | 73 | enum class TextPara { 74 | TP_Bold = 0x01, 75 | TP_Italic = 0x02, 76 | TP_Outline = 0x04 77 | }; 78 | Q_DECLARE_FLAGS(TextParas, TextPara) // 枚举 TextPara 生成宏 TextParas 79 | Q_DECLARE_OPERATORS_FOR_FLAGS(TextParas) // 重载宏 TextParas 的 |() 函数 80 | 81 | enum class ScrnType { 82 | ST_Primary = 1 << 0, // 显示器主屏幕: qGuiApp->primaryScreen() 83 | ST_Current = 1 << 1, // 截图时光标所在的屏幕 84 | ST_Associated = 1 << 2, // 关联的屏幕: qGuiApp->screens() 85 | ST_FullScreen = 1 << 3 // 全屏窗口 86 | }; 87 | Q_DECLARE_FLAGS(ScrnTypes, ScrnType) 88 | Q_DECLARE_OPERATORS_FOR_FLAGS(ScrnTypes) 89 | } 90 | 91 | using namespace XC; 92 | 93 | class CaptureHelper : public QObject 94 | { 95 | Q_OBJECT 96 | public: 97 | enum CaptureType { 98 | SST_ScrnCapture, 99 | SST_ScrollingWindow, 100 | SST_DelayCapture, 101 | SST_FullScrnCapture, 102 | SST_FixdSizeRegion, 103 | SST_Paste, 104 | SST_HideShowAllImages, 105 | SST_SwitchCurrentGroup, 106 | SST_Unknow 107 | }; 108 | Q_ENUM(CaptureType) 109 | }; 110 | 111 | // rectangle | ellipse | arrow | custompath | mosaic、smooth | text | serialnumber | pin | [gif] | revocation | renewal | save | cancel | finish 112 | struct XDrawStep 113 | { 114 | QPoint p1; // 起点 115 | QPoint p2; // 终点 116 | QRect rt; // 初始绘画位置: 由 p1、p2 构成 117 | DrawShape shape = DrawShape::NoDraw; // 绘画形状 118 | ShapePara shapePara = ShapePara::SP_0; // 图形的样式类型:Rectangles、Ellipses、Arrows、Mosaics 119 | 120 | /*『pen.width』rect/ellipses/line/arrows/custPath/SerialNumber 的绘画宽度,单位px; | Mosaics 模糊参数,单位px 121 | * 『pen.color』rect/ellipses/line/arrows/custPath/SerialNumber 的实际[轮廓]颜色 122 | * 『brush.width』rect/ellipses/line/arrows/custPath/SerialNumber 的绘画宽度,单位px; 123 | * 『brush.color』rect/ellipses/line/arrows/custPath/SerialNumber 的[填充]颜色 124 | * 125 | * 『Text』pa.drawPath: 遇到 \n 不会换行,自行分割解决; 可以实现描边效果 -> QPen 是描边颜色, Brush 是字体颜色;【采用此方案】 126 | * 其 Tip 显示是 font.pointSize 127 | * 『SerialNumber』pa.drawText: 遇到 \n 会换行; 无描边效果 -> QPen 是字体颜色;其字体大小由 pa.font.pointSize 控制,而非 pa.pen.width 128 | */ 129 | QPen pen = QPen(Qt::red, 2, Qt::SolidLine, Qt::RoundCap, Qt::RoundJoin); 130 | QBrush brush = QBrush(Qt::red, Qt::SolidPattern); 131 | QVector custPath; // 手绘路径 132 | 133 | // Mosaics / Text 134 | QString text; // 文字内容; SerialNumberShape 135 | QFont font = QFont("KaiTi", 14); // 字体 136 | TextParas textParas; 137 | 138 | // SerialNumberShape 139 | static QString serialText; 140 | 141 | public: 142 | void showDebug() const; 143 | void partClear(); 144 | void destroyClear(); 145 | }; 146 | 147 | #endif // XDRAW_H 148 | -------------------------------------------------------------------------------- /src/screen/rectcalcu.h: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | // SPDX-FileCopyrightText: 2021-2024 XMuli 3 | // SPDX-GitHub: https://github.com/SunnyScreenshot/FLIPPED 4 | // SPDX-Author: XMuli 5 | 6 | #ifndef PICSHOT_RECTCALCU_H 7 | #define PICSHOT_RECTCALCU_H 8 | 9 | #include "../xglobal.h" 10 | #include 11 | #include 12 | #include 13 | 14 | QT_BEGIN_NAMESPACE 15 | class QRect; 16 | class QPoint; 17 | QT_END_NAMESPACE 18 | 19 | namespace XC { 20 | enum class ScrnOperate { 21 | SO_Wait, // 基础的等待状态(未有,和已有矩形局域) 22 | SO_Select, // 基础的选中状态 23 | SO_Move, // 基础的移动状态 24 | SO_Draw, // 基础的绘画状态 25 | SO_Stretch, // 基础的拉伸状态 26 | }; 27 | 28 | enum class CursorArea { 29 | Left = 0x00000001, 30 | Top = 0x00000002, 31 | Right = 0x00000004, 32 | Bottom = 0x00000008, 33 | Horizontal = Left | Right, 34 | Vertical = Top | Bottom, 35 | Edga = Horizontal | Vertical, 36 | 37 | TopLeft = 0x00000010, 38 | TopRight = 0x00000020, 39 | BottomLeft = 0x00000040, 40 | BottomRight = 0x00000080, 41 | TLAndBR = TopLeft | BottomRight, 42 | TRAndBL = TopRight | BottomLeft, 43 | Corner = TLAndBR | TRAndBL, 44 | 45 | Border = Edga | Corner, // 边框 46 | External = 0x00000100, // 外部 47 | Internal = 0x00000200, // 内部 48 | Unknow 49 | }; 50 | } 51 | 52 | // ** 方便使用枚举 ** 53 | using namespace XC; 54 | 55 | 56 | class ScreenShot; 57 | // 矩形计算 58 | class RectCalcu 59 | { 60 | public: 61 | RectCalcu(ScreenShot* pSrnShot); 62 | ~RectCalcu(); 63 | 64 | static QRect getRect(QPoint pos1, QPoint pos2); 65 | const QRect getSelRect() const; 66 | 67 | void clear(); 68 | void setClear(bool clear); 69 | bool isClear(); 70 | const CursorArea getCursorArea(const QPoint pos, bool details = false) const; 71 | 72 | QRect& limitBound(QRect& rt, QRect maxRt); 73 | 74 | const QRect calcurRsultOnce(); 75 | void setRtSel(const QRect rt); 76 | 77 | private: 78 | const QRect getStretchRect() const; // 仅拉伸时使用 79 | 80 | public: 81 | QRect getExteRect(QRect& rect, int interval = HAIF_INTERVAL) const; // 获取外部矩形 82 | QRect getInteRect(QRect& rect, int interval = HAIF_INTERVAL) const; // 获取内部矩形 83 | 84 | public: 85 | QPoint pos1; 86 | QPoint pos2; 87 | ScrnOperate scrnType; // 程序状态(对应此时鼠标的操作类型) 88 | 89 | private: 90 | QRect rtSel; // 由 pos1, pos2 所得 91 | bool m_bClear; // 当前清理状态 92 | CursorArea cursArea; // 光标对应区域 93 | ScreenShot* m_scrnShot; // 用来判定 当前选中 移动 形状 94 | }; 95 | 96 | #endif //PICSHOT_RECTCALCU_H 97 | -------------------------------------------------------------------------------- /src/screen/tray.h: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | // SPDX-FileCopyrightText: 2021-2024 XMuli 3 | // SPDX-GitHub: https://github.com/SunnyScreenshot/FLIPPED 4 | // SPDX-Author: XMuli 5 | 6 | #ifndef TRAY_H 7 | #define TRAY_H 8 | 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include "screenshot.h" 14 | 15 | class QSystemTrayIcon; 16 | class QAction; 17 | class QMenu; 18 | class QHotkey; 19 | class PrefManage; 20 | 21 | class Tray : public QObject 22 | { 23 | Q_OBJECT 24 | public: 25 | static Tray& instance(); 26 | std::vector> getVHotKeys() const; 27 | 28 | private: 29 | explicit Tray(QObject* parent = nullptr); 30 | virtual ~Tray(); 31 | void init(); 32 | void initGlobalHotKeys(); 33 | 34 | public slots: 35 | void onScrnShot(); 36 | void onPreference(bool checked); 37 | void onKeySequenceChanged(const QKeySequence& keySequence); 38 | 39 | void onNotificQuickSave(const bool bSaveOk, const QString& pathName); 40 | void onNotificHotkeyRegisteredFail(std::map map); 41 | 42 | void onActivated(QSystemTrayIcon::ActivationReason reason); 43 | // tabGeneral 44 | //void onLanuageChange(const QString& language); 45 | //void onSelfStart(int sta); 46 | //void onAsAdmin(int sta); 47 | //void onAutoCheck(int sta); 48 | //void onUpdate(); 49 | 50 | private: 51 | QPointer m_scrnShot; // 前台截图 UI 52 | QPointer m_prefManage; // 偏好设置 UI 53 | QPointer m_trayMenu; 54 | QPointer m_trayIcon; 55 | 56 | // hkPtr, "F6", tr("Active Window"), objectName/tupe: SST_ActionWindow 57 | std::vector> m_vHotKeys; 58 | }; 59 | 60 | #endif // TARY_H 61 | -------------------------------------------------------------------------------- /src/tool/base/blurwidget.cpp: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | // SPDX-FileCopyrightText: 2021-2024 XMuli 3 | // SPDX-GitHub: https://github.com/SunnyScreenshot/FLIPPED 4 | // SPDX-Author: XMuli 5 | 6 | #include "blurwidget.h" 7 | #include "../../xglobal.h" 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | 17 | QT_BEGIN_NAMESPACE 18 | extern Q_WIDGETS_EXPORT void qt_blurImage(QPainter *p, QImage &blurImage, qreal radius, bool quality, bool alphaOnly, int transposed = 0); 19 | QT_END_NAMESPACE 20 | 21 | BlurWidget::BlurWidget(QWidget *parent) 22 | : QWidget(parent) 23 | , m_pix() 24 | // , m_pBlurEffect(std::make_unique()) 25 | { 26 | // m_pBlurEffect->setBlurRadius(5); 27 | // m_pBlurEffect->setBlurHints(QGraphicsBlurEffect::QualityHint); 28 | // setGraphicsEffect(m_pBlurEffect.get()); 29 | // setWindowFlags(Qt::FramelessWindowHint); 30 | } 31 | 32 | void BlurWidget::setPixmap(const QPixmap &pix, int blurRadius) 33 | { 34 | if (!pix.isNull()) { 35 | // m_pix = std::move(pix); 36 | QImage img = pix.toImage(); 37 | QPixmap tPix(pix.size()); 38 | tPix.setDevicePixelRatio(qApp->primaryScreen()->devicePixelRatio()); // fix: macos dpi is 2 39 | QPainter painter(&tPix); 40 | qt_blurImage(&painter, img, blurRadius, true, false); 41 | m_pix = std::move(tPix); 42 | } 43 | 44 | 45 | // if (m_pBlurEffect) 46 | // m_pBlurEffect->setBlurRadius(blurRadius); 47 | } 48 | 49 | void BlurWidget::paintEvent(QPaintEvent *event) 50 | { 51 | Q_UNUSED(event) 52 | const int margin = 1; 53 | QPainter pa(this); 54 | pa.setRenderHints(QPainter::Antialiasing | QPainter::SmoothPixmapTransform); 55 | if (!m_pix.isNull()) { 56 | QPainterPath clipPath; 57 | clipPath.addRoundedRect(contentsRect(), B_RADIRS, B_RADIRS); 58 | pa.setClipPath(clipPath); 59 | pa.drawPixmap(rect(), m_pix); 60 | } 61 | 62 | pa.setRenderHints(QPainter::Antialiasing); 63 | QColor colBrush(19, 19, 19, 0.6 * 255); 64 | QColor colPen(255, 255, 255, 0.1 * 255); 65 | pa.setBrush(colBrush); 66 | QPen pen(colPen, 1); 67 | pa.setPen(pen); 68 | pa.drawRoundedRect(contentsRect().adjusted(margin, margin, -margin, -margin), B_RADIRS, B_RADIRS); 69 | 70 | colPen = QColor(0, 0, 0, 0.1 * 255); 71 | pa.setPen(colPen); 72 | pa.setBrush(Qt::NoBrush); 73 | pa.drawRoundedRect(contentsRect(), B_RADIRS, B_RADIRS); 74 | 75 | // QPainterPath path; 76 | // path.addRect(contentsRect()); 77 | // path.addRoundedRect(contentsRect().adjusted(margin, margin, -margin, -margin), B_RADIRS, B_RADIRS); 78 | // path.setFillRule(Qt::OddEvenFill); 79 | // pa.setPen(colPen); 80 | // pa.setBrush(colPen); 81 | // pa.drawPath(path); 82 | } 83 | -------------------------------------------------------------------------------- /src/tool/base/blurwidget.h: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | // SPDX-FileCopyrightText: 2021-2024 XMuli 3 | // SPDX-GitHub: https://github.com/SunnyScreenshot/FLIPPED 4 | // SPDX-Author: XMuli 5 | 6 | #ifndef BLURWIDGET_H 7 | #define BLURWIDGET_H 8 | 9 | #include 10 | #include 11 | #include 12 | 13 | // 模拟 亚克力/透明磨砂 效果(此处取巧) 14 | class QPixmap; 15 | class BlurWidget : public QWidget 16 | { 17 | Q_OBJECT 18 | public: 19 | explicit BlurWidget(QWidget *parent = nullptr); 20 | virtual ~BlurWidget() = default; 21 | void setPixmap(const QPixmap& pix, int blurRadius); 22 | 23 | protected: 24 | void paintEvent(QPaintEvent *event) override; 25 | 26 | private: 27 | QPixmap m_pix; 28 | // std::unique_ptr m_pBlurEffect; 29 | }; 30 | 31 | #endif // BLURWIDGET_H 32 | -------------------------------------------------------------------------------- /src/tool/base/colorparabar.h: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | // SPDX-FileCopyrightText: 2021-2024 XMuli 3 | // SPDX-GitHub: https://github.com/SunnyScreenshot/FLIPPED 4 | // SPDX-Author: XMuli 5 | #ifndef COLORPARABAR_H 6 | #define COLORPARABAR_H 7 | 8 | #include 9 | #include 10 | #include 11 | #include 12 | 13 | enum class ColorParaBarMode 14 | { 15 | CPB_ParaBar, // 默认的 GridLayout 布局,用途为 draw bar 的取色器 16 | CPB_HighLight // QHBoxLayout 的水平布局,为活动色选择 17 | }; 18 | 19 | class XLabel; 20 | class QLayout; 21 | class ColorParaBar : public QWidget 22 | { 23 | Q_OBJECT 24 | public: 25 | ColorParaBar(ColorParaBarMode mode = ColorParaBarMode::CPB_ParaBar, Qt::Orientations orien = Qt::Horizontal, QWidget *parent = nullptr); 26 | virtual ~ColorParaBar() = default; 27 | 28 | void setOrientations(Qt::Orientations orien = Qt::Horizontal); 29 | QColor setCurColor(const QColor col); 30 | const QColor getCurColor(); 31 | 32 | signals: 33 | void sigColorChange(const QColor&); 34 | 35 | private: 36 | void onUpdateSel(const QColor& col); 37 | 38 | public: 39 | bool eventFilter(QObject *watched, QEvent *event) override; 40 | 41 | protected: 42 | void paintEvent(QPaintEvent *event) override; 43 | 44 | private: 45 | double m_scal; 46 | Qt::Orientations m_orien; 47 | QLayout* m_layout; 48 | QMap m_labMap; 49 | XLabel* m_curXLab; 50 | QColor m_curCol; 51 | }; 52 | 53 | #endif // COLORPARABAR_H 54 | -------------------------------------------------------------------------------- /src/tool/base/managebar.cpp: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | // SPDX-FileCopyrightText: 2021-2024 XMuli 3 | // SPDX-GitHub: https://github.com/SunnyScreenshot/FLIPPED 4 | // SPDX-Author: XMuli 5 | 6 | #include "managebar.h" 7 | #include 8 | #include "../../xglobal.h" 9 | #include "../../widget/xhorizontalline.h" 10 | #include "../../widget/xverticalline.h" 11 | #include "../../screen/drawhelper.h" 12 | #include "../../screen/datamaid.h" 13 | 14 | ManageBar::ManageBar(Qt::Orientations orien /*= Qt::Horizontal*/, QWidget* parent /*= nullptr*/) 15 | : QWidget(parent) 16 | , m_scal(DATAMAID->scale()) 17 | , m_orien(orien) 18 | , m_layout(nullptr) 19 | { 20 | if (m_orien == Qt::Horizontal) 21 | m_layout = new QHBoxLayout(this); 22 | else 23 | m_layout = new QVBoxLayout(this); 24 | 25 | setContentsMargins(MB_MARGIN_HOR, MB_MARGIN_VER, MB_MARGIN_HOR, MB_MARGIN_VER); 26 | setLayout(m_layout); 27 | m_layout->setMargin(0); 28 | m_layout->setSpacing(0); 29 | } 30 | 31 | void ManageBar::addWidget(QWidget* w) 32 | { 33 | if (w) 34 | m_layout->addWidget(w); 35 | } 36 | 37 | void ManageBar::addSpacer() 38 | { 39 | if (m_orien == Qt::Horizontal) 40 | m_layout->addWidget(new XVerticalLine(B_SPACER_LINE_HEIGHT * m_scal, this)); 41 | else 42 | m_layout->addWidget(new XHorizontalLine(B_SPACER_LINE_HEIGHT * m_scal, this)); 43 | } 44 | -------------------------------------------------------------------------------- /src/tool/base/managebar.h: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | // SPDX-FileCopyrightText: 2021-2024 XMuli 3 | // SPDX-GitHub: https://github.com/SunnyScreenshot/FLIPPED 4 | // SPDX-Author: XMuli 5 | #ifndef MANAGEBAR_H 6 | #define MANAGEBAR_H 7 | 8 | #include 9 | 10 | class QBoxLayout; 11 | class ManageBar : public QWidget 12 | { 13 | Q_OBJECT 14 | public: 15 | explicit ManageBar(Qt::Orientations orien = Qt::Horizontal, QWidget* parent = nullptr); 16 | virtual ~ManageBar() = default; 17 | void addWidget(QWidget* w); 18 | void addSpacer(); 19 | 20 | private: 21 | double m_scal; 22 | Qt::Orientations m_orien; 23 | QBoxLayout* m_layout; 24 | }; 25 | 26 | #endif // MANAGEBAR_H 27 | -------------------------------------------------------------------------------- /src/tool/magnifier/magnifier.cpp: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | // SPDX-FileCopyrightText: 2021-2024 XMuli 3 | // SPDX-GitHub: https://github.com/SunnyScreenshot/FLIPPED 4 | // SPDX-Author: XMuli 5 | #include "magnifier.h" 6 | 7 | Magnifier::Magnifier(QWidget *parent) 8 | : QWidget(parent) 9 | { 10 | 11 | } 12 | -------------------------------------------------------------------------------- /src/tool/magnifier/magnifier.h: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | // SPDX-FileCopyrightText: 2021-2024 XMuli 3 | // SPDX-GitHub: https://github.com/SunnyScreenshot/FLIPPED 4 | // SPDX-Author: XMuli 5 | #ifndef MAGNIFIER_H 6 | #define MAGNIFIER_H 7 | 8 | #include 9 | 10 | class Magnifier : public QWidget 11 | { 12 | Q_OBJECT 13 | public: 14 | explicit Magnifier(QWidget* parent = nullptr); 15 | ~Magnifier() = default; 16 | }; 17 | 18 | #endif // MAGNIFIER_H 19 | -------------------------------------------------------------------------------- /src/tool/parameterbar.h: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | // SPDX-FileCopyrightText: 2021-2024 XMuli 3 | // SPDX-GitHub: https://github.com/SunnyScreenshot/FLIPPED 4 | // SPDX-Author: XMuli 5 | 6 | #ifndef PARAMETERBAR_H 7 | #define PARAMETERBAR_H 8 | 9 | #include "../screen/drawhelper.h" 10 | #include 11 | #include 12 | #include "base/colorparabar.h" 13 | #include "base/managebar.h" 14 | 15 | class BlurWidget; 16 | class QBoxLayout; 17 | class QAbstractButton; 18 | class QToolButton; 19 | 20 | class ParameterBar : public QWidget 21 | { 22 | Q_OBJECT 23 | public: 24 | explicit ParameterBar(Qt::Orientations orien = Qt::Horizontal, QWidget *parent = nullptr); 25 | virtual ~ParameterBar(); 26 | void setBlurBackground(const QPixmap& pix, double blurRadius); 27 | 28 | private: 29 | void initUI(); 30 | void addWidget(QWidget *w); 31 | void addSpacer(); 32 | QString amendSvgShow(QString path); 33 | 34 | void creatorParaBar(QPointer& manageBar, const QString& path, const QStringList& items, const bool exclusive = true, const int defaultCheck = 0); 35 | void initRectBar(); 36 | void initEllipseBar(); 37 | void initArrowBar(); 38 | void initMosaicBar(); 39 | void initTextBar(); 40 | void initSerialnumberBar(); 41 | void initLineWidthBar(); 42 | void removeAllBar(); 43 | 44 | signals: 45 | void sigParaBtnId(DrawShape shap, QToolButton* tb); // ToolButton 发射的信号 46 | void sigSelColor(QColor); // XLabel 发射的信号 47 | 48 | public slots: 49 | void onTBReleased(QAbstractButton* btn); 50 | void onEnableDraw(bool enable); 51 | void onSelShape(DrawShape shape, bool checked); 52 | 53 | protected: 54 | void enterEvent(QEvent* event) override; 55 | void resizeEvent(QResizeEvent *event) override; 56 | 57 | private: 58 | double m_scal; 59 | Qt::Orientations m_orien; 60 | QBoxLayout* m_layout; 61 | std::unique_ptr m_blur; 62 | 63 | QPointer m_rectBar; // 矩形 64 | QPointer m_ellipseBar; // 圆形 65 | QPointer m_arrowBar; // 箭头 66 | QPointer m_mosaicBar; // 马赛克 67 | QPointer m_textBar; // 文本 68 | QPointer m_serialnumberShape; // 序号图形 69 | QPointer m_serialnumberType; // 序号类型 70 | QPointer m_lienWidthBar; // 线宽 71 | QPointer m_colorBar; // 取色板 72 | }; 73 | 74 | #endif // PARAMETERBAR_H 75 | -------------------------------------------------------------------------------- /src/tool/pin/pinwidget.h: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | // SPDX-FileCopyrightText: 2021-2024 XMuli 3 | // SPDX-GitHub: https://github.com/SunnyScreenshot/FLIPPED 4 | // SPDX-Author: XMuli 5 | 6 | #ifndef XFRAMELESSWIDGET_H 7 | #define XFRAMELESSWIDGET_H 8 | 9 | #include 10 | #include 11 | 12 | class QMenu; 13 | class QLabel; 14 | class QPoint; 15 | class QPixmap; 16 | class QMouseEvent; 17 | class QWheelEvent; 18 | class QGraphicsDropShadowEffect; 19 | 20 | class PinWidget : public QWidget 21 | { 22 | Q_OBJECT 23 | public: 24 | explicit PinWidget(const QPixmap& pixmap, const QRect& geometry, QWidget* parent = nullptr); 25 | 26 | private: 27 | void initUI(); 28 | void setScaledPixmapToLabel(const QSize& newSize, const qreal scale, const bool expanding); 29 | void createShadowEffect(); 30 | 31 | protected: 32 | void mousePressEvent(QMouseEvent *e) override; 33 | void mouseMoveEvent(QMouseEvent *e) override; 34 | void mouseReleaseEvent(QMouseEvent *e) override; 35 | void mouseDoubleClickEvent(QMouseEvent *e) override; 36 | void wheelEvent(QWheelEvent *event) override; 37 | void contextMenuEvent(QContextMenuEvent* event) override; 38 | 39 | private slots: 40 | void onCopy(); 41 | void onSave(); 42 | 43 | void onWindowShadow(bool enable); 44 | void onOpacity(int opacity); 45 | void onMaxSize(double val); 46 | 47 | private: 48 | QPoint m_p; // 窗口的左上角 49 | QPoint m_p1; 50 | QPoint m_p2; 51 | 52 | QPixmap m_pixmap; 53 | QLabel* m_label; 54 | QPointer m_shadowEffect; 55 | 56 | QMenu* m_menu; 57 | }; 58 | 59 | #endif // XFRAMELESSWIDGET_H 60 | -------------------------------------------------------------------------------- /src/tool/selectbar.h: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | // SPDX-FileCopyrightText: 2021-2024 XMuli 3 | // SPDX-GitHub: https://github.com/SunnyScreenshot/FLIPPED 4 | // SPDX-Author: XMuli 5 | 6 | #ifndef SELECTBAR_H 7 | #define SELECTBAR_H 8 | 9 | #include 10 | #include "../screen/drawhelper.h" 11 | #include "base/blurwidget.h" 12 | 13 | class BlurWidget; 14 | class QToolButton; 15 | class QStringList; 16 | class QBoxLayout; 17 | class QAbstractButton; 18 | class QButtonGroup; 19 | 20 | class SelectBar : public QWidget 21 | { 22 | Q_OBJECT 23 | public: 24 | SelectBar(Qt::Orientations orien = Qt::Horizontal, QWidget *parent = nullptr); 25 | virtual ~SelectBar() = default; 26 | void setBlurBackground(const QPixmap& pix, int blurRadius); 27 | 28 | private: 29 | void initUI(); 30 | void addWidget(QWidget *w); 31 | void addSpacer(); 32 | inline bool isEnableDraw(); 33 | 34 | public slots: 35 | void onToolBtn(); 36 | 37 | signals: 38 | void sigEnableDraw(bool enable); 39 | void sigSelShape(DrawShape shape, bool checked); 40 | void sigRevocation(); 41 | void sigRenewal(); 42 | void sigPin(); 43 | void sigSave(); 44 | void sigCancel(); 45 | void sigFinish(); 46 | void sigInterruptEdit(const QPoint& pos); 47 | 48 | protected: 49 | void enterEvent(QEvent* event) override; 50 | void resizeEvent(QResizeEvent *event) override; 51 | 52 | private: 53 | double m_scal; 54 | Qt::Orientations m_orien; 55 | QBoxLayout* m_layout; 56 | std::unique_ptr m_blur; 57 | std::vector> m_vBtns; // pTb, btnName, tr(), bCheckable, bAddSpacer 58 | }; 59 | 60 | #endif // SELECTBAR_H 61 | -------------------------------------------------------------------------------- /src/tool/selectsize/selectsize.cpp: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | // SPDX-FileCopyrightText: 2021-2024 XMuli 3 | // SPDX-GitHub: https://github.com/SunnyScreenshot/FLIPPED 4 | // SPDX-Author: XMuli 5 | 6 | #include "selectsize.h" 7 | #include 8 | #include "../../xglobal.h" 9 | #include "../../screen/datamaid.h" 10 | 11 | SelectSize::SelectSize(QWidget* parent, Qt::WindowFlags f) 12 | : QLabel(parent, f) 13 | { 14 | initUI(); 15 | } 16 | 17 | SelectSize::SelectSize(const QString& text, QWidget* parent, Qt::WindowFlags f) 18 | : QLabel(text, parent, f) 19 | { 20 | initUI(); 21 | } 22 | 23 | void SelectSize::onTextChanged(QString text) 24 | { 25 | text = this->text(); 26 | QFontMetrics fm(font()); 27 | QRect bound = fm.boundingRect(QRect(), Qt::AlignCenter, text); 28 | resize(bound.size() + QSize(2, 2)); // fix: 1080 和 2K 屏幕下,字体被遮挡 29 | } 30 | 31 | void SelectSize::initUI() 32 | { 33 | setContentsMargins(SS_MARGIN_LEFT, SS_MARGIN_TOP, SS_MARGIN_RIGHT, SS_MARGIN_BOTTOM); 34 | connect(this, &SelectSize::sigTextChanged, this, &SelectSize::onTextChanged); 35 | } 36 | 37 | void SelectSize::paintEvent(QPaintEvent* e) 38 | { 39 | QPainter pa(this); 40 | pa.setRenderHints(QPainter::Antialiasing | QPainter::SmoothPixmapTransform); 41 | 42 | QColor col(DATAMAID->paraValue("borderColor").toString()); 43 | pa.setPen(Qt::NoPen); 44 | pa.setBrush(col); 45 | pa.drawRoundedRect(rect(), SS_RADIRS, SS_RADIRS); 46 | 47 | pa.setPen("#FFFFFF"); 48 | pa.setBrush(Qt::NoBrush); 49 | pa.drawText(contentsRect(), Qt::AlignCenter, text()); 50 | } 51 | 52 | -------------------------------------------------------------------------------- /src/tool/selectsize/selectsize.h: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | // SPDX-FileCopyrightText: 2021-2024 XMuli 3 | // SPDX-GitHub: https://github.com/SunnyScreenshot/FLIPPED 4 | // SPDX-Author: XMuli 5 | 6 | #ifndef SELECTSIZE_H 7 | #define SELECTSIZE_H 8 | 9 | #include 10 | 11 | // 选中矩形区域的尺寸大小,显示在左上角、尺寸位置的显示 12 | class SelectSize : public QLabel 13 | { 14 | Q_OBJECT 15 | public: 16 | explicit SelectSize(QWidget* parent = nullptr, Qt::WindowFlags f = Qt::WindowFlags()); 17 | explicit SelectSize(const QString& text, QWidget* parent = nullptr, Qt::WindowFlags f = Qt::WindowFlags()); 18 | ~SelectSize() = default; 19 | 20 | signals: 21 | void sigTextChanged(QString text); 22 | 23 | public slots: 24 | void onTextChanged(QString text); 25 | 26 | private: 27 | void initUI(); 28 | 29 | protected: 30 | // void showEvent(QShowEvent *e) override; 31 | void paintEvent(QPaintEvent* e) override; 32 | }; 33 | 34 | #endif // SELECTSIZE_H 35 | -------------------------------------------------------------------------------- /src/widget/xframewidget.cpp: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | // SPDX-FileCopyrightText: 2021-2024 XMuli 3 | // SPDX-GitHub: https://github.com/SunnyScreenshot/FLIPPED 4 | // SPDX-Author: XMuli 5 | 6 | #include "xframewidget.h" 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include "../xglobal.h" 12 | 13 | XFrameWidget::XFrameWidget(QWidget *parent) 14 | : QWidget(parent) 15 | { 16 | setWindowFlags(Qt::FramelessWindowHint); // 去掉标题栏 17 | setAttribute(Qt::WA_TranslucentBackground); // 设置透明,自绘画为圆角矩形 18 | //setWindowOpacity(0.7); 19 | //PerformanceHint = 0x00, 20 | // QualityHint = 0x01, 21 | // AnimationHint = 0x02 22 | 23 | //QGraphicsBlurEffect* blureffect = new QGraphicsBlurEffect(this); 24 | //blureffect->setBlurRadius(1); //数值越大,越模糊 25 | //blureffect->setBlurHints(QGraphicsBlurEffect::QualityHint); 26 | //this->setGraphicsEffect(blureffect); 27 | 28 | //setWindowFlags(Qt::FramelessWindowHint); 29 | 30 | //HWND hMoudle = (HWND)(winId()); 31 | //HMODULE hDLL = LoadLibrary(L"Acrylic"); 32 | 33 | //using fun = void (*)(HWND hWnd); 34 | 35 | //fun pSetBlur = (fun)GetProcAddress(hDLL, "setBlur"); 36 | //pSetBlur((HWND)(winId())); 37 | 38 | 39 | // 仅支持 windows 7 的毛玻璃 磨砂 透明 Aero Glass 效果 40 | //#ifdef Q_OS_WIN 41 | // // 添加 winextras 42 | // #include 43 | // this->setAttribute(Qt::WA_TranslucentBackground); 44 | // QtWin::enableBlurBehindWindow(this); 45 | // QtWin::extendFrameIntoClientArea(this, -1, -1, -1, -1); 46 | //#endif 47 | 48 | 49 | } 50 | 51 | void XFrameWidget::paintEvent(QPaintEvent *event) 52 | { 53 | Q_UNUSED(event) 54 | 55 | QPainter pa(this); 56 | pa.setRenderHints(QPainter::Antialiasing | QPainter::SmoothPixmapTransform); 57 | QColor colBrush("#131313"); 58 | colBrush.setAlphaF(0.6); 59 | pa.setBrush(colBrush); 60 | QColor colPen("#FFFFFF"); 61 | colPen.setAlphaF(0.1); 62 | QPen pen(colPen, 1); 63 | pa.setPen(pen); 64 | 65 | const int margin1 = 1; 66 | pa.drawRoundedRect(contentsRect().adjusted(margin1, margin1, -margin1, -margin1), B_RADIRS, B_RADIRS); 67 | 68 | colPen.setNamedColor("#000000"); 69 | colPen.setAlphaF(0.1); 70 | pa.setPen(colPen); 71 | pa.setBrush(Qt::NoBrush); 72 | const int margin2 = 0; 73 | pa.drawRoundedRect(contentsRect().adjusted(margin2, margin2, -margin2, -margin2), B_RADIRS, B_RADIRS); 74 | } 75 | -------------------------------------------------------------------------------- /src/widget/xframewidget.h: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | // SPDX-FileCopyrightText: 2021-2024 XMuli 3 | // SPDX-GitHub: https://github.com/SunnyScreenshot/FLIPPED 4 | // SPDX-Author: XMuli 5 | 6 | #ifndef XFRAMEWIDGET_H 7 | #define XFRAMEWIDGET_H 8 | 9 | #include 10 | 11 | class XFrameWidget : public QWidget 12 | { 13 | Q_OBJECT 14 | public: 15 | explicit XFrameWidget(QWidget *parent = nullptr); 16 | virtual ~XFrameWidget() = default; 17 | 18 | protected: 19 | void paintEvent(QPaintEvent *event) override; 20 | }; 21 | 22 | #endif // XFRAMEWIDGET_H 23 | -------------------------------------------------------------------------------- /src/widget/xhorizontalline.cpp: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | // SPDX-FileCopyrightText: 2021-2024 XMuli 3 | // SPDX-GitHub: https://github.com/SunnyScreenshot/FLIPPED 4 | // SPDX-Author: XMuli 5 | 6 | #include "xhorizontalline.h" 7 | 8 | XHorizontalLine::XHorizontalLine(int width, QWidget *parent, Qt::WindowFlags f) 9 | : QFrame(parent, f) 10 | { 11 | setFrameShape(HLine); 12 | setFrameShadow(Sunken); 13 | setLineWidth(0); 14 | setMidLineWidth(2); 15 | setFixedWidth(width); 16 | } 17 | -------------------------------------------------------------------------------- /src/widget/xhorizontalline.h: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | // SPDX-FileCopyrightText: 2021-2024 XMuli 3 | // SPDX-GitHub: https://github.com/SunnyScreenshot/FLIPPED 4 | // SPDX-Author: XMuli 5 | 6 | #ifndef XHORIZONTALLINE_H 7 | #define XHORIZONTALLINE_H 8 | 9 | #include 10 | 11 | // 水平分割线 12 | class XHorizontalLine : public QFrame 13 | { 14 | Q_OBJECT 15 | public: 16 | XHorizontalLine(int width, QWidget* parent = nullptr, Qt::WindowFlags f = Qt::WindowFlags()); 17 | }; 18 | 19 | #endif // XHORIZONTALLINE_H 20 | -------------------------------------------------------------------------------- /src/widget/xkeysequenceedit.cpp: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | // SPDX-FileCopyrightText: 2021-2024 XMuli 3 | // SPDX-GitHub: https://github.com/SunnyScreenshot/FLIPPED 4 | // SPDX-Author: XMuli 5 | 6 | #include "xkeysequenceedit.h" 7 | #include 8 | #include 9 | #include 10 | 11 | /*! 12 | * \brief The XKeySequenceEdit class 设置仅接受一个快捷键组合;删除清空 13 | */ 14 | 15 | XKeySequenceEdit::XKeySequenceEdit(QWidget *parent) 16 | : QKeySequenceEdit(parent) 17 | { 18 | initUI(); 19 | } 20 | 21 | XKeySequenceEdit::XKeySequenceEdit(const QKeySequence &keySequence, QWidget *parent) 22 | : QKeySequenceEdit(keySequence, parent) 23 | { 24 | initUI(); 25 | } 26 | 27 | void XKeySequenceEdit::initUI() 28 | { 29 | //setWindowFlags(Qt::FramelessWindowHint | Qt::Popup); 30 | } 31 | 32 | //void XKeySequenceEdit::test() 33 | //{ 34 | // connect(this, &XKeySequenceEdit::keySequenceChanged, this, &XKeySequenceEdit::onKeySequenceChanged); 35 | 36 | // connect(this, &XKeySequenceEdit::editingFinished, this, &XKeySequenceEdit::onEditingFinished); 37 | //} 38 | 39 | //void XKeySequenceEdit::onEditingFinished() 40 | //{ 41 | // qInfo() << "editingFinished ------------>" << keySequence() << keySequence().count(); 42 | //} 43 | 44 | //void XKeySequenceEdit::onKeySequenceChanged(const QKeySequence & keySequence) 45 | //{ 46 | // qInfo() << "keySequenceChanged ------------>" << keySequence << keySequence.count(); 47 | //} 48 | 49 | // Ref: https://jishurizhi.com/p-74.html 50 | void XKeySequenceEdit::keyPressEvent(QKeyEvent *event) 51 | { 52 | QKeySequenceEdit::keyPressEvent(event); 53 | 54 | QKeySequence keySeq = keySequence(); 55 | qInfo() << "keySeq:" << keySeq << "keySeq.count():" << keySeq.count(); 56 | 57 | // Fix: 按下相同快捷键编辑框为空白 58 | if ( keySeq.count() <= 0) 59 | return; 60 | 61 | int key = keySeq[0]; 62 | qDebug()<<"keySeq[0]:"<button() != Qt::LeftButton) 74 | // return; 75 | // 76 | // if (!geometry().contains(mapFromGlobal(QCursor::pos()))) 77 | // clearFocus(); 78 | //} 79 | -------------------------------------------------------------------------------- /src/widget/xkeysequenceedit.h: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | // SPDX-FileCopyrightText: 2021-2024 XMuli 3 | // SPDX-GitHub: https://github.com/SunnyScreenshot/FLIPPED 4 | // SPDX-Author: XMuli 5 | #ifndef XKEYSEQUENCEEDIT_H 6 | #define XKEYSEQUENCEEDIT_H 7 | 8 | #include 9 | 10 | class XKeySequenceEdit : public QKeySequenceEdit 11 | { 12 | Q_OBJECT 13 | public: 14 | explicit XKeySequenceEdit(QWidget *parent = nullptr); 15 | explicit XKeySequenceEdit(const QKeySequence &keySequence, QWidget *parent = nullptr); 16 | virtual ~XKeySequenceEdit() = default; 17 | 18 | private: 19 | void initUI(); 20 | 21 | // void test(); 22 | 23 | signals: 24 | void sigKeySeqChanged(const QKeySequence &keySequence); 25 | 26 | //public slots: 27 | //void onEditingFinished(); 28 | //void onKeySequenceChanged(const QKeySequence &keySequence); 29 | 30 | protected: 31 | void keyPressEvent(QKeyEvent *event) override; 32 | //void mousePressEvent(QMouseEvent* event) override; 33 | }; 34 | 35 | 36 | 37 | #endif // XKEYSEQUENCEEDIT_H 38 | -------------------------------------------------------------------------------- /src/widget/xlabel.cpp: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | // SPDX-FileCopyrightText: 2021-2024 XMuli 3 | // SPDX-GitHub: https://github.com/SunnyScreenshot/FLIPPED 4 | // SPDX-Author: XMuli 5 | #include "xlabel.h" 6 | #include "../xglobal.h" 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | 15 | XLabel::XLabel(QWidget *parent, Qt::WindowFlags f) 16 | : QToolButton(parent) 17 | { 18 | initUI(); 19 | } 20 | 21 | void XLabel::setChecked(const bool &checked) 22 | { 23 | m_bChecked = checked; 24 | } 25 | 26 | void XLabel::setColor(QColor c, double alpha) 27 | { 28 | m_color = c; 29 | m_alpha = alpha; 30 | } 31 | 32 | // 构造一个锥向渐变(center, angle) https://blog.csdn.net/weixin_37818081/article/details/118879134 33 | void XLabel::setConicalGradientColor(QPainter& pa) 34 | { 35 | QConicalGradient conicalGradient(QPointF(contentsRect().center()), 300); 36 | 37 | conicalGradient.setColorAt(0, QColor("#EB004A")); 38 | conicalGradient.setColorAt(1 / 7.0, QColor("#FF0000")); 39 | conicalGradient.setColorAt(2 / 7.0, QColor("#F800FC")); 40 | conicalGradient.setColorAt(3 / 7.0, QColor("#4D00F3")); 41 | conicalGradient.setColorAt(4 / 7.0, QColor("#1BB8F2")); 42 | conicalGradient.setColorAt(5 / 7.0, QColor("#46EA48")); 43 | conicalGradient.setColorAt(6 / 7.0, QColor("#FFDB34")); 44 | conicalGradient.setColorAt(1, QColor("#EB004A")); 45 | 46 | pa.save(); 47 | QColor colPen("#6B6B6B"); 48 | colPen.setAlphaF(0.5); 49 | pa.setPen(colPen); 50 | pa.setBrush(conicalGradient); 51 | pa.drawRect(rect()); 52 | pa.restore(); 53 | } 54 | 55 | void XLabel::setRainbow(bool bRainbow) 56 | { 57 | m_bRainbow = bRainbow; 58 | } 59 | 60 | void XLabel::initUI() 61 | { 62 | m_color = "#DB000F"; 63 | m_alpha = 1; 64 | m_bRainbow = false; 65 | m_bChecked = false; 66 | 67 | // 此两行也可以注释掉,亲测不影响,可能是由于后面有一个 ColorParaBar 作为父类 68 | //setWindowFlags(Qt::FramelessWindowHint); // 去掉标题栏 69 | setAttribute(Qt::WA_TranslucentBackground); // 设置透明,自绘画为圆角矩形 70 | // setAutoFillBackground(false); 71 | 72 | QColor col = this->palette().window().color(); 73 | } 74 | 75 | 76 | void XLabel::paintEvent(QPaintEvent *event) 77 | { 78 | Q_UNUSED(event) 79 | QPainter pa(this); 80 | pa.setRenderHints(QPainter::Antialiasing | QPainter::SmoothPixmapTransform); 81 | // 矩形和内切圆此部分不用绘画 避免出现 拖曳时刻出现残影和交叉部分显示黑色 82 | 83 | if (m_bRainbow) { 84 | setConicalGradientColor(pa); 85 | } else { 86 | QColor colBrush(m_color); 87 | colBrush.setAlphaF(m_alpha); 88 | QColor colPen("#6B6B6B"); 89 | colPen.setAlphaF(0.5); 90 | pa.setPen(colPen); 91 | pa.setBrush(colBrush); 92 | pa.drawRect(rect()); 93 | } 94 | 95 | if (m_bChecked) { 96 | int centerX = width() / 2; 97 | int centerY = height() / 2; 98 | const int side = rect().size().width() * 2 / 3; 99 | const QRect rt(centerX - side / 2, centerY - side / 2, side, side); 100 | 101 | pa.setPen(QPen(QColor("#FFFFFF"), 2)); 102 | pa.setBrush(Qt::NoBrush); 103 | pa.drawRect(rt); 104 | } 105 | } 106 | -------------------------------------------------------------------------------- /src/widget/xlabel.h: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | // SPDX-FileCopyrightText: 2021-2024 XMuli 3 | // SPDX-GitHub: https://github.com/SunnyScreenshot/FLIPPED 4 | // SPDX-Author: XMuli 5 | 6 | #ifndef XLABEL_H 7 | #define XLABEL_H 8 | 9 | #include 10 | #include 11 | #include 12 | 13 | class QWidget; 14 | class QString; 15 | class QWidget; 16 | class QPainter; 17 | class QMouseEvent; 18 | 19 | class XLabel : public QToolButton 20 | { 21 | Q_OBJECT 22 | public: 23 | explicit XLabel(QWidget *parent=nullptr, Qt::WindowFlags f=Qt::WindowFlags()); 24 | virtual ~XLabel() = default; 25 | 26 | void setChecked(const bool& checked = false); 27 | void setColor(QColor c, double alpha = 1); 28 | void setRainbow(bool bRainbow = false); 29 | private: 30 | void initUI(); 31 | void setConicalGradientColor(QPainter &pa); 32 | 33 | protected: 34 | void paintEvent(QPaintEvent *event) override; 35 | 36 | private: 37 | QColor m_color; 38 | double m_alpha; 39 | bool m_bChecked; // 当前被选中否? 40 | bool m_bRainbow; // false:纯色 true:彩色 41 | }; 42 | 43 | Q_DECLARE_METATYPE(XLabel*); // 提供给 QVariant 使用; // 另外自定义类型中一定要有默认构造函数 44 | 45 | #endif // XLABEL_H 46 | -------------------------------------------------------------------------------- /src/widget/xroundwidget.cpp: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | // SPDX-FileCopyrightText: 2021-2024 XMuli 3 | // SPDX-GitHub: https://github.com/SunnyScreenshot/FLIPPED 4 | // SPDX-Author: XMuli 5 | 6 | #include "xroundwidget.h" 7 | #include "../xglobal.h" 8 | #include 9 | #include 10 | #include 11 | 12 | XRoundWidget::XRoundWidget(QWidget *parent) 13 | : QWidget(parent) 14 | { 15 | initUI(); 16 | } 17 | 18 | XRoundWidget::~XRoundWidget() 19 | { 20 | } 21 | 22 | void XRoundWidget::initUI() 23 | { 24 | setWindowFlags(Qt::FramelessWindowHint); // 去掉标题栏 25 | setAttribute(Qt::WA_TranslucentBackground); // 设置透明,自绘画为圆角矩形 26 | } 27 | 28 | void XRoundWidget::paintEvent(QPaintEvent *event) 29 | { 30 | Q_UNUSED(event) 31 | 32 | QPainter pa(this); 33 | pa.setRenderHints(QPainter::Antialiasing | QPainter::SmoothPixmapTransform); 34 | pa.setPen(Qt::NoPen); 35 | pa.setBrush(QColor(255, 255, 255, 0.8 * 255)); 36 | pa.drawRoundedRect(contentsRect(), B_RADIRS, B_RADIRS); 37 | } 38 | -------------------------------------------------------------------------------- /src/widget/xroundwidget.h: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | // SPDX-FileCopyrightText: 2021-2024 XMuli 3 | // SPDX-GitHub: https://github.com/SunnyScreenshot/FLIPPED 4 | // SPDX-Author: XMuli 5 | 6 | #ifndef XROUNDWIDGET_H 7 | #define XROUNDWIDGET_H 8 | 9 | #include 10 | #include 11 | 12 | class XRoundWidget : public QWidget 13 | { 14 | Q_OBJECT 15 | public: 16 | explicit XRoundWidget(QWidget *parent = nullptr); 17 | virtual ~XRoundWidget(); 18 | 19 | void initUI(); 20 | 21 | protected: 22 | virtual void paintEvent(QPaintEvent *event) override; 23 | }; 24 | 25 | #endif // XROUNDWIDGET_H 26 | -------------------------------------------------------------------------------- /src/widget/xtextwidget.cpp: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | // SPDX-FileCopyrightText: 2021-2024 XMuli 3 | // SPDX-GitHub: https://github.com/SunnyScreenshot/FLIPPED 4 | // SPDX-Author: XMuli 5 | 6 | #include "xtextwidget.h" 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include "../core/xlog.h" 12 | 13 | XTextWidget::XTextWidget(QWidget *parent) 14 | : QTextEdit(parent) 15 | , m_baseSize() 16 | , m_minSize() 17 | { 18 | //qDebug() << "XTextWidget::XTextWidget()" << Qt::endl << "--a1--rect:" << rect() << " size:" << size(); 19 | 20 | //setStyleSheet(QStringLiteral("XTextWidget { background: transparent; }")); 21 | connect(this, &XTextWidget::textChanged, this, &XTextWidget::adjustSize); 22 | connect(this, &XTextWidget::textChanged, this, &XTextWidget::emitTextUpdated); 23 | setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff); 24 | setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); 25 | setContextMenuPolicy(Qt::NoContextMenu); 26 | } 27 | 28 | XTextWidget::~XTextWidget() 29 | { 30 | //qDebug() << "XTextWidget::~XTextWidget()" << Qt::endl << "rect:" << rect() << " size:" << size(); 31 | } 32 | 33 | // https://blog.csdn.net/kenfan1647/article/details/115171891 34 | void XTextWidget::adjustSize() 35 | { 36 | //qDebug() << "XTextWidget::adjustSize()" << Qt::endl << "--a1--rect:" << rect(); 37 | 38 | QString&& text = this->toPlainText(); 39 | QFontMetrics fm(font()); 40 | QRect bound = fm.boundingRect(QRect(), Qt::AlignLeft, text); // 需要再研究下 41 | int pixelsWidth = qMax(bound.width() + fm.lineSpacing(), m_minSize.width()) ; 42 | int pixelsHigh = qMax(bound.height() * 1.15 + fm.lineSpacing(), m_minSize.height()); 43 | this->setFixedSize(pixelsWidth, pixelsHigh); 44 | //qDebug() << "--a3--rect:" << rect(); 45 | //qDebug() << "bounds:" << bounds << " fm.lineSpacing:" << fm.lineSpacing() 46 | // << " pixelsWide:" << pixelsWide << " pixelsHigh:" << pixelsHigh << " m_minSize:" << m_minSize; 47 | } 48 | 49 | void XTextWidget::setFont(const QFont & font) 50 | { 51 | //qDebug() << "XTextWidget::setFont()" << Qt::endl << "rect:" << rect(); 52 | QTextEdit::setFont(font); 53 | adjustSize(); 54 | } 55 | 56 | void XTextWidget::showEvent(QShowEvent *e) 57 | { 58 | QFont font; 59 | QFontMetrics fm(font); // 赋值一个初始的宽高 60 | 61 | //qDebug() << "XTextWidget::showEvent()" << Qt::endl << "--a1--rect:" << rect() << " fm.lineSpacing:" << fm.lineSpacing() << " size:" << size(); 62 | setFixedWidth(fm.lineSpacing() * 6); 63 | setFixedHeight(fm.lineSpacing() * 2.5); 64 | m_baseSize = size(); 65 | m_minSize = m_baseSize; 66 | 67 | QTextEdit::showEvent(e); 68 | adjustSize(); 69 | 70 | //qDebug() << "--a2--rect:" << rect() << " fm.lineSpacing:" << fm.lineSpacing() << " size:" << size(); 71 | } 72 | 73 | // 当 widget 大小被重新设置的时候就会被调用 74 | void XTextWidget::resizeEvent(QResizeEvent *e) 75 | { 76 | //qDebug() << "XTextWidget::showEvent()" << Qt::endl << "--a1--rect:" << rect() << " size:" << size(); 77 | m_minSize.setHeight(qMin(m_baseSize.height(), height())); 78 | m_minSize.setWidth(qMin(m_baseSize.width(), width())); 79 | QTextEdit::resizeEvent(e); 80 | 81 | //qDebug() << "--a2--rect:" << rect() << " size:" << size(); 82 | } 83 | 84 | void XTextWidget::setTextColor(const QColor & c) 85 | { 86 | QString s(QStringLiteral("XTextWidget { background: transparent; color: %1; }")); 87 | setStyleSheet(s.arg(c.name())); 88 | } 89 | 90 | void XTextWidget::setAlignment(Qt::AlignmentFlag alignment) 91 | { 92 | QTextEdit::setAlignment(alignment); 93 | adjustSize(); 94 | } 95 | 96 | void XTextWidget::emitTextUpdated() 97 | { 98 | //qDebug() << "XTextWidget::showEvent()" << Qt::endl << "--a1--rect:" << rect() << " size:" << size(); 99 | emit textUpdated(this->toPlainText()); 100 | 101 | //qDebug() << "--a2--rect:" << rect() << " size:" << size(); 102 | } 103 | -------------------------------------------------------------------------------- /src/widget/xtextwidget.h: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | // SPDX-FileCopyrightText: 2021-2024 XMuli 3 | // SPDX-GitHub: https://github.com/SunnyScreenshot/FLIPPED 4 | // SPDX-Author: XMuli 5 | 6 | #ifndef XTEXTWIDGET_H 7 | #define XTEXTWIDGET_H 8 | 9 | #include 10 | 11 | class XTextWidget : public QTextEdit 12 | { 13 | Q_OBJECT 14 | public: 15 | explicit XTextWidget(QWidget *parent = nullptr); 16 | ~XTextWidget(); 17 | 18 | void adjustSize(); 19 | void setFont(const QFont& font); 20 | 21 | protected: 22 | void showEvent(QShowEvent *e) override; 23 | void resizeEvent(QResizeEvent *e) override; 24 | 25 | signals: 26 | void textUpdated(const QString& s); 27 | 28 | public /*slots*/: 29 | void setTextColor(const QColor& c); 30 | void setAlignment(Qt::AlignmentFlag alignment); 31 | 32 | private slots: 33 | void emitTextUpdated(); 34 | 35 | private: 36 | QSize m_baseSize; 37 | QSize m_minSize; 38 | }; 39 | 40 | #endif // XTEXTWIDGET_H 41 | -------------------------------------------------------------------------------- /src/widget/xverticalline.cpp: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: 2 | // SPDX-FileCopyrightText: 2021-2023 XMuli 3 | // 4 | // Source: https://github.com/XMuli/FlippedCode 5 | 6 | #include "xverticalline.h" 7 | 8 | //frameRect : QRect//控件矩形 9 | //frameWidth : const int//框架的宽度 10 | //frameShadow : Shadow//有无阴影 11 | //lineWidth : int//线宽度 12 | //frameShape : Shape//框架形状 13 | //midLineWidth : int//中间线的宽度 14 | 15 | XVerticalLine::XVerticalLine(int height, QWidget *parent, Qt::WindowFlags f) 16 | : QFrame(parent, f) 17 | { 18 | setFrameShape(VLine); 19 | setFrameShadow(Sunken); 20 | setLineWidth(0); 21 | setMidLineWidth(2); 22 | setFixedHeight(height); 23 | } 24 | -------------------------------------------------------------------------------- /src/widget/xverticalline.h: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | // SPDX-FileCopyrightText: 2021-2024 XMuli 3 | // SPDX-GitHub: https://github.com/SunnyScreenshot/FLIPPED 4 | // SPDX-Author: XMuli 5 | #ifndef XVERTICALLINE_H 6 | #define XVERTICALLINE_H 7 | 8 | #include 9 | 10 | class XVerticalLine : public QFrame 11 | { 12 | Q_OBJECT 13 | public: 14 | XVerticalLine(int height, QWidget* parent = nullptr, Qt::WindowFlags f = Qt::WindowFlags()); 15 | }; 16 | 17 | #endif // XVERTICALLINE_H 18 | -------------------------------------------------------------------------------- /tech.xmuli.flipped/linglong.yaml: -------------------------------------------------------------------------------- 1 | package: 2 | id: tech.xmuli.flipped 3 | name: flipped 4 | version: 1.5.0 5 | kind: app 6 | description: | 7 | Simple and beautiful cross-platform screenshot software. 8 | 9 | runtime: 10 | id: org.deepin.Runtime 11 | version: 23.0.0 12 | 13 | depends: 14 | - id: icu 15 | version: 63.1 16 | type: runtime 17 | 18 | source: 19 | kind: git 20 | url: "https://github.com/XMuli/Flipped.git" 21 | commit: efbb6a5769b2d1c638fa95a2cfcd656580b99ab7 22 | 23 | build: 24 | kind: cmake 25 | -------------------------------------------------------------------------------- /updateI18N.bat: -------------------------------------------------------------------------------- 1 | set PROJECT_DIR=%~dp0 2 | 3 | lupdate -recursive %PROJECT_DIR%src -ts %PROJECT_DIR%src\data\translations\en_US.ts 4 | ::linguist %PROJECT_DIR%src\data\translations\en_US.ts 5 | 6 | lupdate -recursive %PROJECT_DIR%src -ts %PROJECT_DIR%src\data\translations\zh_CN.ts 7 | ::linguist %PROJECT_DIR%src\data\translations\zh_CN.ts 8 | 9 | lupdate -recursive %PROJECT_DIR%src -ts %PROJECT_DIR%src\data\translations\zh_TW.ts 10 | ::linguist %PROJECT_DIR%src\data\translations\zh_TW.ts 11 | 12 | pause --------------------------------------------------------------------------------