add KGC APP
|
@ -0,0 +1,45 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>CFBundleInfoDictionaryVersion</key>
|
||||
<string>6.0</string>
|
||||
<key>CFBundlePackageType</key>
|
||||
<string>APPL</string>
|
||||
|
||||
<key>CFBundleName</key>
|
||||
<string>${MACOSX_BUNDLE_BUNDLE_NAME}</string>
|
||||
<key>CFBundleIdentifier</key>
|
||||
<string>${MACOSX_BUNDLE_GUI_IDENTIFIER}</string>
|
||||
<key>CFBundleExecutable</key>
|
||||
<string>${MACOSX_BUNDLE_EXECUTABLE_NAME}</string>
|
||||
|
||||
<key>CFBundleVersion</key>
|
||||
<string>${MACOSX_BUNDLE_BUNDLE_VERSION}</string>
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>${MACOSX_BUNDLE_SHORT_VERSION_STRING}</string>
|
||||
|
||||
<key>LSMinimumSystemVersion</key>
|
||||
<string>${CMAKE_OSX_DEPLOYMENT_TARGET}</string>
|
||||
|
||||
<key>NSHumanReadableCopyright</key>
|
||||
<string>${MACOSX_BUNDLE_COPYRIGHT}</string>
|
||||
|
||||
<key>CFBundleIconFile</key>
|
||||
<string>${MACOSX_BUNDLE_ICON_FILE}</string>
|
||||
|
||||
<key>CFBundleDevelopmentRegion</key>
|
||||
<string>${MACOSX_BUNDLE_DEVELOPMENT_REGION}</string>
|
||||
<key>CFBundleAllowMixedLocalizations</key>
|
||||
<true/>
|
||||
|
||||
<key>NSHighResolutionCapable</key>
|
||||
<true/>
|
||||
|
||||
<key>NSPrincipalClass</key>
|
||||
<string>NSApplication</string>
|
||||
|
||||
<key>NSSupportsAutomaticGraphicsSwitching</key>
|
||||
<true/>
|
||||
</dict>
|
||||
</plist>
|
|
@ -0,0 +1,37 @@
|
|||
#include <windows.h>
|
||||
|
||||
IDI_ICON1 ICON "${PROJECT_SOURCE_DIR}/resources/imgs/icon.ico"
|
||||
|
||||
VS_VERSION_INFO VERSIONINFO
|
||||
FILEVERSION ${version_str}
|
||||
PRODUCTVERSION ${version_str}
|
||||
FILEFLAGSMASK 0x3fL
|
||||
#ifdef _DEBUG
|
||||
FILEFLAGS VS_FF_DEBUG
|
||||
#else
|
||||
FILEFLAGS 0x0L
|
||||
#endif
|
||||
FILEOS VOS_NT_WINDOWS32
|
||||
FILETYPE VFT_APP
|
||||
FILESUBTYPE VFT2_UNKNOWN
|
||||
BEGIN
|
||||
BLOCK "StringFileInfo"
|
||||
BEGIN
|
||||
BLOCK "040904b0"
|
||||
BEGIN
|
||||
VALUE "Comments", "Made by Mentalflow."
|
||||
VALUE "CompanyName", "${PROJECT_COMPANY}"
|
||||
VALUE "FileDescription", "${PROJECT_BUNDLE_NAME}"
|
||||
VALUE "FileVersion", "${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR}.${PROJECT_VERSION_PATCH}"
|
||||
VALUE "InternalName", "${PROJECT_BUNDLE_NAME}.exe"
|
||||
VALUE "LegalCopyright", "${PROJECT_COPYRIGHT}"
|
||||
VALUE "OriginalFilename", "${PROJECT_BUNDLE_NAME}.exe"
|
||||
VALUE "ProductName", "${PROJECT_BUNDLE_NAME}"
|
||||
VALUE "ProductVersion", "${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR}.${PROJECT_VERSION_PATCH}"
|
||||
END
|
||||
END
|
||||
BLOCK "VarFileInfo"
|
||||
BEGIN
|
||||
VALUE "Translation", 0x409, 1200
|
||||
END
|
||||
END
|
|
@ -0,0 +1,75 @@
|
|||
name: MacOS (Shared Library)
|
||||
on:
|
||||
push:
|
||||
paths:
|
||||
- '*.txt'
|
||||
- 'include/**'
|
||||
- 'source/**'
|
||||
- 'scripts/**'
|
||||
- '.github/workflows/macos-shared.yml'
|
||||
pull_request:
|
||||
paths:
|
||||
- '*.txt'
|
||||
- 'include/**'
|
||||
- 'source/**'
|
||||
- 'scripts/**'
|
||||
- '.github/workflows/macos-shared.yml'
|
||||
|
||||
jobs:
|
||||
build:
|
||||
name: Build
|
||||
runs-on: ${{ matrix.os }}
|
||||
strategy:
|
||||
matrix:
|
||||
os: [macos-14]
|
||||
qt_ver: [6.6.3]
|
||||
qt_arch: [clang_64]
|
||||
env:
|
||||
targetName: KGCAPP
|
||||
steps:
|
||||
- name: Check out repository
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
submodules: recursive
|
||||
|
||||
- name: Install Qt
|
||||
uses: jurplel/install-qt-action@v3
|
||||
with:
|
||||
version: ${{ matrix.qt_ver }}
|
||||
arch: ${{ matrix.qt_arch }}
|
||||
modules: 'qt5compat qtmultimedia qtshadertools qtimageformats'
|
||||
|
||||
- name: Set up Ninja
|
||||
uses: seanmiddleditch/gha-setup-ninja@v4
|
||||
with:
|
||||
version: 1.10.2
|
||||
|
||||
- name: build macos
|
||||
run: |
|
||||
cmake --version
|
||||
mkdir build
|
||||
cd build
|
||||
cmake -DCMAKE_MESSAGE_LOG_LEVEL=STATUS -DCMAKE_PREFIX_PATH=/Users/runner/work/KGCAPP/Qt/${{ matrix.qt_ver }}/macos -DCMAKE_C_COMPILER=clang -DCMAKE_CXX_COMPILER=clang++ -DCMAKE_BUILD_TYPE=Release -GNinja ..
|
||||
cmake --build . --target all --config Release --parallel
|
||||
|
||||
- name: package
|
||||
run: |
|
||||
# 先删除所有dSYM文件,减少包的体积
|
||||
sudo find /Users/runner/work/KGCAPP/Qt/${{ matrix.qt_ver }}/macos/qml -name "*.dSYM" | xargs rm -r
|
||||
# 拷贝依赖
|
||||
sudo macdeployqt /Users/runner/work/KGCAPP/KGCAPP/build/output/release/${targetName}.app -qmldir=. -verbose=1 -dmg
|
||||
|
||||
- uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: ${{ env.targetName }}_${{ matrix.os }}_${{matrix.qt_ver}}_shared.zip
|
||||
path: /Users/runner/work/KGCAPP/KGCAPP/build/output/release/${{ env.targetName }}.dmg
|
||||
|
||||
- name: uploadRelease
|
||||
if: startsWith(github.event.ref, 'refs/tags/')
|
||||
uses: svenstaro/upload-release-action@v2
|
||||
with:
|
||||
repo_token: ${{ secrets.GITHUB_TOKEN }}
|
||||
file: /Users/runner/work/KGCAPP/KGCAPP/build/output/release/${{ env.targetName }}.dmg
|
||||
asset_name: ${{ env.targetName }}_${{ github.ref_name }}_${{ matrix.os }}_Qt${{ matrix.qt_ver }}_shared.dmg
|
||||
tag: ${{ github.ref }}
|
||||
overwrite: true
|
|
@ -0,0 +1,75 @@
|
|||
name: MacOS (Static Library)
|
||||
on:
|
||||
push:
|
||||
paths:
|
||||
- '*.txt'
|
||||
- 'include/**'
|
||||
- 'source/**'
|
||||
- 'scripts/**'
|
||||
- '.github/workflows/macos-static.yml'
|
||||
pull_request:
|
||||
paths:
|
||||
- '*.txt'
|
||||
- 'include/**'
|
||||
- 'source/**'
|
||||
- 'scripts/**'
|
||||
- '.github/workflows/macos-static.yml'
|
||||
|
||||
jobs:
|
||||
build:
|
||||
name: Build
|
||||
runs-on: ${{ matrix.os }}
|
||||
strategy:
|
||||
matrix:
|
||||
os: [macos-14]
|
||||
qt_ver: [6.6.3]
|
||||
qt_arch: [clang_64]
|
||||
env:
|
||||
targetName: KGCAPP
|
||||
steps:
|
||||
- name: Check out repository
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
submodules: recursive
|
||||
|
||||
- name: Install Qt
|
||||
uses: jurplel/install-qt-action@v3
|
||||
with:
|
||||
version: ${{ matrix.qt_ver }}
|
||||
arch: ${{ matrix.qt_arch }}
|
||||
modules: 'qt5compat qtmultimedia qtshadertools qtimageformats'
|
||||
|
||||
- name: Set up Ninja
|
||||
uses: seanmiddleditch/gha-setup-ninja@v4
|
||||
with:
|
||||
version: 1.10.2
|
||||
|
||||
- name: build macos
|
||||
run: |
|
||||
cmake --version
|
||||
mkdir build
|
||||
cd build
|
||||
cmake -DCMAKE_MESSAGE_LOG_LEVEL=STATUS -DCMAKE_PREFIX_PATH=/Users/runner/work/KGCAPP/Qt/${{ matrix.qt_ver }}/macos -DCMAKE_C_COMPILER=clang -DCMAKE_CXX_COMPILER=clang++ -DCMAKE_BUILD_TYPE=Release -DKGCAPP_BUILD_STATIC_LIB=ON -GNinja ..
|
||||
cmake --build . --target all --config Release --parallel
|
||||
|
||||
- name: package
|
||||
run: |
|
||||
# 先删除所有dSYM文件,减少包的体积
|
||||
sudo find /Users/runner/work/KGCAPP/Qt/${{ matrix.qt_ver }}/macos/qml -name "*.dSYM" | xargs rm -r
|
||||
# 拷贝依赖
|
||||
sudo macdeployqt /Users/runner/work/KGCAPP/KGCAPP/build/output/release/${targetName}.app -qmldir=. -verbose=1 -dmg
|
||||
|
||||
- uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: ${{ env.targetName }}_${{ matrix.os }}_${{matrix.qt_ver}}_static.zip
|
||||
path: /Users/runner/work/KGCAPP/KGCAPP/build/output/release/${{ env.targetName }}.dmg
|
||||
|
||||
- name: uploadRelease
|
||||
if: startsWith(github.event.ref, 'refs/tags/')
|
||||
uses: svenstaro/upload-release-action@v2
|
||||
with:
|
||||
repo_token: ${{ secrets.GITHUB_TOKEN }}
|
||||
file: /Users/runner/work/KGCAPP/KGCAPP/build/output/release/${{ env.targetName }}.dmg
|
||||
asset_name: ${{ env.targetName }}_${{ github.ref_name }}_${{ matrix.os }}_Qt${{ matrix.qt_ver }}_static.dmg
|
||||
tag: ${{ github.ref }}
|
||||
overwrite: true
|
|
@ -0,0 +1,92 @@
|
|||
name: Ubuntu (Shared Library)
|
||||
on:
|
||||
workflow_dispatch:
|
||||
push:
|
||||
paths:
|
||||
- '*.txt'
|
||||
- 'include/**'
|
||||
- 'source/**'
|
||||
- 'scripts/**'
|
||||
- '.github/workflows/ubuntu-shared.yml'
|
||||
pull_request:
|
||||
paths:
|
||||
- '*.txt'
|
||||
- 'include/**'
|
||||
- 'source/**'
|
||||
- 'scripts/**'
|
||||
- '.github/workflows/ubuntu-shared.yml'
|
||||
|
||||
jobs:
|
||||
build:
|
||||
name: Build
|
||||
runs-on: ${{ matrix.os }}
|
||||
strategy:
|
||||
matrix:
|
||||
os: [ubuntu-latest]
|
||||
qt_ver: [6.6.3]
|
||||
qt_arch: [gcc_64]
|
||||
env:
|
||||
targetName: KGCAPP
|
||||
steps:
|
||||
- name: Check out repository
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
submodules: recursive
|
||||
|
||||
- name: Install Qt
|
||||
uses: jurplel/install-qt-action@v3
|
||||
with:
|
||||
version: ${{ matrix.qt_ver }}
|
||||
arch: ${{ matrix.qt_arch }}
|
||||
modules: 'qt5compat qtmultimedia qtshadertools qtimageformats'
|
||||
|
||||
- name: Set up Ninja
|
||||
uses: seanmiddleditch/gha-setup-ninja@v4
|
||||
with:
|
||||
version: 1.10.2
|
||||
|
||||
- name: ubuntu install GL library
|
||||
run: sudo apt install -y libxcb-cursor0 libgl1-mesa-dev libxcb1-dev libgtk-3-dev libxkbcommon-x11-dev libxcb-icccm4-dev libxcb-image0-dev libxcb-keysyms1-dev libxcb-randr0-dev libxcb-shape0-dev libxcb-xfixes0-dev libxcb-xinerama0-dev libxcb-sync-dev libxcb-render-util0-dev libxcb-shm0-dev
|
||||
|
||||
- name: ubuntu install libfuse2
|
||||
run: sudo apt install libfuse2
|
||||
|
||||
- name: build ubuntu
|
||||
run: |
|
||||
ninja --version
|
||||
cmake --version
|
||||
mkdir build
|
||||
cd build
|
||||
cmake -DCMAKE_MESSAGE_LOG_LEVEL=STATUS -DCMAKE_PREFIX_PATH=/home/runner/work/KGCAPP/Qt/${{ matrix.qt_ver }}/gcc_64 -DCMAKE_C_COMPILER=gcc -DCMAKE_CXX_COMPILER=g++ -DCMAKE_BUILD_TYPE=Release -GNinja ..
|
||||
cmake --build . --target all --config Release --parallel
|
||||
|
||||
- name: install QT linux deploy
|
||||
uses: miurahr/install-linuxdeploy-action@v1
|
||||
with:
|
||||
plugins: qt appimage
|
||||
|
||||
- name: Check if svg file exists
|
||||
run: if [ ! -f "${targetName}.svg" ]; then echo "File not found, creating..."; touch ${targetName}.svg; fi
|
||||
|
||||
- name: package
|
||||
run: |
|
||||
# make sure Qt plugin finds QML sources so it can deploy the imported files
|
||||
export QML_SOURCES_PATHS=./
|
||||
# 拷贝依赖
|
||||
linuxdeploy-x86_64.AppImage --plugin=qt --output=appimage --create-desktop-file --icon-file=${targetName}.svg --executable=/home/runner/work/KGCAPP/KGCAPP/build/output/release/${targetName} --appdir /home/runner/work/KGCAPP/KGCAPP/build/output/release/
|
||||
mv ${{ env.targetName }}-*.AppImage ${{ env.targetName }}_${{ matrix.os }}_${{matrix.qt_ver}}_shared.AppImage
|
||||
|
||||
- uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: ${{ env.targetName }}_${{ matrix.os }}_${{matrix.qt_ver}}_shared
|
||||
path: ${{ env.targetName }}_${{ matrix.os }}_${{matrix.qt_ver}}_shared.AppImage
|
||||
|
||||
- name: uploadRelease
|
||||
if: startsWith(github.event.ref, 'refs/tags/')
|
||||
uses: svenstaro/upload-release-action@v2
|
||||
with:
|
||||
repo_token: ${{ secrets.GITHUB_TOKEN }}
|
||||
file: ${{ env.targetName }}_${{ matrix.os }}_${{matrix.qt_ver}}_shared.AppImage
|
||||
asset_name: ${{ env.targetName }}_${{ github.ref_name }}_${{ matrix.os }}_Qt${{ matrix.qt_ver }}_shared.AppImage
|
||||
tag: ${{ github.ref }}
|
||||
overwrite: true
|
|
@ -0,0 +1,92 @@
|
|||
name: Ubuntu (Static Library)
|
||||
on:
|
||||
workflow_dispatch:
|
||||
push:
|
||||
paths:
|
||||
- '*.txt'
|
||||
- 'include/**'
|
||||
- 'source/**'
|
||||
- 'scripts/**'
|
||||
- '.github/workflows/ubuntu-static.yml'
|
||||
pull_request:
|
||||
paths:
|
||||
- '*.txt'
|
||||
- 'include/**'
|
||||
- 'source/**'
|
||||
- 'scripts/**'
|
||||
- '.github/workflows/ubuntu-static.yml'
|
||||
|
||||
jobs:
|
||||
build:
|
||||
name: Build
|
||||
runs-on: ${{ matrix.os }}
|
||||
strategy:
|
||||
matrix:
|
||||
os: [ubuntu-latest]
|
||||
qt_ver: [6.6.3]
|
||||
qt_arch: [gcc_64]
|
||||
env:
|
||||
targetName: KGCAPP
|
||||
steps:
|
||||
- name: Check out repository
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
submodules: recursive
|
||||
|
||||
- name: Install Qt
|
||||
uses: jurplel/install-qt-action@v3
|
||||
with:
|
||||
version: ${{ matrix.qt_ver }}
|
||||
arch: ${{ matrix.qt_arch }}
|
||||
modules: 'qt5compat qtmultimedia qtshadertools qtimageformats'
|
||||
|
||||
- name: Set up Ninja
|
||||
uses: seanmiddleditch/gha-setup-ninja@v4
|
||||
with:
|
||||
version: 1.10.2
|
||||
|
||||
- name: ubuntu install GL library
|
||||
run: sudo apt-get install -y libxcb-cursor0 libgl1-mesa-dev libxcb1-dev libgtk-3-dev libxkbcommon-x11-dev libxcb-icccm4-dev libxcb-image0-dev libxcb-keysyms1-dev libxcb-randr0-dev libxcb-shape0-dev libxcb-xfixes0-dev libxcb-xinerama0-dev libxcb-sync-dev libxcb-render-util0-dev libxcb-shm0-dev
|
||||
|
||||
- name: ubuntu install libfuse2
|
||||
run: sudo apt install libfuse2
|
||||
|
||||
- name: build ubuntu
|
||||
run: |
|
||||
ninja --version
|
||||
cmake --version
|
||||
mkdir build
|
||||
cd build
|
||||
cmake -DCMAKE_MESSAGE_LOG_LEVEL=STATUS -DCMAKE_PREFIX_PATH=/home/runner/work/KGCAPP/Qt/${{ matrix.qt_ver }}/gcc_64 -DCMAKE_C_COMPILER=gcc -DCMAKE_CXX_COMPILER=g++ -DCMAKE_BUILD_TYPE=Release -DKGCAPP_BUILD_STATIC_LIB=ON -GNinja ..
|
||||
cmake --build . --target all --config Release --parallel
|
||||
|
||||
- name: install QT linux deploy
|
||||
uses: miurahr/install-linuxdeploy-action@v1
|
||||
with:
|
||||
plugins: qt appimage
|
||||
|
||||
- name: Check if svg file exists
|
||||
run: if [ ! -f "${targetName}.svg" ]; then echo "File not found, creating..."; touch ${targetName}.svg; fi
|
||||
|
||||
- name: package
|
||||
run: |
|
||||
# make sure Qt plugin finds QML sources so it can deploy the imported files
|
||||
export QML_SOURCES_PATHS=./
|
||||
# 拷贝依赖
|
||||
linuxdeploy-x86_64.AppImage --plugin=qt --output=appimage --create-desktop-file --icon-file=${targetName}.svg --executable=/home/runner/work/KGCAPP/KGCAPP/build/output/release/${targetName} --appdir /home/runner/work/KGCAPP/KGCAPP/build/output/release/
|
||||
mv ${{ env.targetName }}-*.AppImage ${{ env.targetName }}_${{ matrix.os }}_Qt${{ matrix.qt_ver }}_static.AppImage
|
||||
|
||||
- uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: ${{ env.targetName }}_${{ matrix.os }}_Qt${{ matrix.qt_ver }}_static
|
||||
path: ${{ env.targetName }}_${{ matrix.os }}_Qt${{ matrix.qt_ver }}_static.AppImage
|
||||
|
||||
- name: uploadRelease
|
||||
if: startsWith(github.event.ref, 'refs/tags/')
|
||||
uses: svenstaro/upload-release-action@v2
|
||||
with:
|
||||
repo_token: ${{ secrets.GITHUB_TOKEN }}
|
||||
file: ${{ env.targetName }}_${{ matrix.os }}_Qt${{ matrix.qt_ver }}_static.AppImage
|
||||
asset_name: ${{ env.targetName }}_${{ github.ref_name }}_${{ matrix.os }}_Qt${{ matrix.qt_ver }}_static.AppImage
|
||||
tag: ${{ github.ref }}
|
||||
overwrite: true
|
|
@ -0,0 +1,95 @@
|
|||
name: Windows MinGW (Shared Library)
|
||||
on:
|
||||
push:
|
||||
paths:
|
||||
- '*.txt'
|
||||
- 'include/**'
|
||||
- 'source/**'
|
||||
- 'scripts/**'
|
||||
- '.github/workflows/windows-mingw-shared.yml'
|
||||
pull_request:
|
||||
paths:
|
||||
- '*.txt'
|
||||
- 'include/**'
|
||||
- 'source/**'
|
||||
- 'scripts/**'
|
||||
- '.github/workflows/windows-mingw-shared.yml'
|
||||
|
||||
jobs:
|
||||
build:
|
||||
name: Build
|
||||
runs-on: windows-latest
|
||||
strategy:
|
||||
matrix:
|
||||
include:
|
||||
- qt_arch: win64_mingw
|
||||
qt_ver: 6.6.3
|
||||
qt_tools: "tools_mingw,9.0.0-1-202203221220,qt.tools.win64_mingw900"
|
||||
qt_tools_mingw_install: mingw900_64
|
||||
env:
|
||||
targetName: KGCAPP.exe
|
||||
fileName: KGCAPP
|
||||
steps:
|
||||
- name: Check out repository
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
submodules: recursive
|
||||
|
||||
- name: Setup ninja
|
||||
uses: seanmiddleditch/gha-setup-ninja@v4
|
||||
with:
|
||||
version: 1.10.2
|
||||
|
||||
- name: Install Qt
|
||||
uses: jurplel/install-qt-action@v3
|
||||
with:
|
||||
version: ${{ matrix.qt_ver }}
|
||||
arch: ${{ matrix.qt_arch }}
|
||||
modules: 'qt5compat qtmultimedia qtshadertools qtimageformats'
|
||||
|
||||
- name: Qt6 environment configuration
|
||||
if: ${{ startsWith( matrix.qt_ver, 6 ) }}
|
||||
shell: pwsh
|
||||
run: |
|
||||
Write-Output "${{ env.Qt6_DIR }}/bin" | Out-File -FilePath $env:GITHUB_PATH -Encoding utf8 -Append
|
||||
Write-Output "${{ env.Qt6_DIR }}/../../Tools/${{ matrix.qt_tools_mingw_install }}/bin" | Out-File -FilePath $env:GITHUB_PATH -Encoding utf8 -Append
|
||||
|
||||
- name: where is cmake & where is mingw32-make
|
||||
shell: pwsh
|
||||
run: |
|
||||
Get-Command -Name 'cmake' | Format-List
|
||||
Get-Command -Name 'mingw32-make' | Format-List
|
||||
|
||||
- name: mingw-build
|
||||
id: build
|
||||
shell: cmd
|
||||
run: |
|
||||
mkdir build
|
||||
cd build
|
||||
cmake -DCMAKE_MESSAGE_LOG_LEVEL=STATUS -DCMAKE_PREFIX_PATH=D:\a\KGCAPP\Qt\${{ matrix.qt_ver }}\mingw_64 -DCMAKE_C_COMPILER=gcc -DCMAKE_CXX_COMPILER=g++ -DCMAKE_BUILD_TYPE=Release -GNinja ..
|
||||
cmake --build . --target all --config Release --parallel
|
||||
|
||||
- name: package
|
||||
id: package
|
||||
env:
|
||||
archiveName: ${{ env.fileName }}-${{ matrix.qt_arch }}-${{ matrix.qt_ver }}-shared
|
||||
shell: pwsh
|
||||
run: |
|
||||
& scripts\windows-mingw-publish.ps1 ${env:archiveName} ${env:targetName}
|
||||
$name = ${env:archiveName}
|
||||
echo "packageName=$name" >> $env:GITHUB_OUTPUT
|
||||
|
||||
- uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: ${{ steps.package.outputs.packageName }}
|
||||
path: ${{ steps.package.outputs.packageName }}
|
||||
|
||||
- name: uploadRelease
|
||||
if: startsWith(github.event.ref, 'refs/tags/')
|
||||
uses: svenstaro/upload-release-action@v2
|
||||
with:
|
||||
repo_token: ${{ secrets.GITHUB_TOKEN }}
|
||||
file: ${{ steps.package.outputs.packageName }}.zip
|
||||
asset_name: ${{ env.fileName }}_${{ github.ref_name }}_${{ matrix.qt_arch }}_Qt${{ matrix.qt_ver }}_shared.zip
|
||||
tag: ${{ github.ref }}
|
||||
overwrite: true
|
|
@ -0,0 +1,95 @@
|
|||
name: Windows MinGW (Static Library)
|
||||
on:
|
||||
push:
|
||||
paths:
|
||||
- '*.txt'
|
||||
- 'include/**'
|
||||
- 'source/**'
|
||||
- 'scripts/**'
|
||||
- '.github/workflows/windows-mingw-static.yml'
|
||||
pull_request:
|
||||
paths:
|
||||
- '*.txt'
|
||||
- 'include/**'
|
||||
- 'source/**'
|
||||
- 'scripts/**'
|
||||
- '.github/workflows/windows-mingw-static.yml'
|
||||
|
||||
jobs:
|
||||
build:
|
||||
name: Build
|
||||
runs-on: windows-latest
|
||||
strategy:
|
||||
matrix:
|
||||
include:
|
||||
- qt_arch: win64_mingw
|
||||
qt_ver: 6.6.3
|
||||
qt_tools: "tools_mingw,9.0.0-1-202203221220,qt.tools.win64_mingw900"
|
||||
qt_tools_mingw_install: mingw900_64
|
||||
env:
|
||||
targetName: KGCAPP.exe
|
||||
fileName: KGCAPP
|
||||
steps:
|
||||
- name: Check out repository
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
submodules: recursive
|
||||
|
||||
- name: Setup ninja
|
||||
uses: seanmiddleditch/gha-setup-ninja@v4
|
||||
with:
|
||||
version: 1.10.2
|
||||
|
||||
- name: Install Qt
|
||||
uses: jurplel/install-qt-action@v3
|
||||
with:
|
||||
version: ${{ matrix.qt_ver }}
|
||||
arch: ${{ matrix.qt_arch }}
|
||||
modules: 'qt5compat qtmultimedia qtshadertools qtimageformats'
|
||||
|
||||
- name: Qt6 environment configuration
|
||||
if: ${{ startsWith( matrix.qt_ver, 6 ) }}
|
||||
shell: pwsh
|
||||
run: |
|
||||
Write-Output "${{ env.Qt6_DIR }}/bin" | Out-File -FilePath $env:GITHUB_PATH -Encoding utf8 -Append
|
||||
Write-Output "${{ env.Qt6_DIR }}/../../Tools/${{ matrix.qt_tools_mingw_install }}/bin" | Out-File -FilePath $env:GITHUB_PATH -Encoding utf8 -Append
|
||||
|
||||
- name: where is cmake & where is mingw32-make
|
||||
shell: pwsh
|
||||
run: |
|
||||
Get-Command -Name 'cmake' | Format-List
|
||||
Get-Command -Name 'mingw32-make' | Format-List
|
||||
|
||||
- name: mingw-build
|
||||
id: build
|
||||
shell: cmd
|
||||
run: |
|
||||
mkdir build
|
||||
cd build
|
||||
cmake -DCMAKE_MESSAGE_LOG_LEVEL=STATUS -DCMAKE_PREFIX_PATH=D:\a\KGCAPP\Qt\${{ matrix.qt_ver }}\mingw_64 -DCMAKE_C_COMPILER=gcc -DCMAKE_CXX_COMPILER=g++ -DCMAKE_BUILD_TYPE=Release -DKGCAPP_BUILD_STATIC_LIB=ON -GNinja ..
|
||||
cmake --build . --target all --config Release --parallel
|
||||
|
||||
- name: package
|
||||
id: package
|
||||
env:
|
||||
archiveName: ${{ env.fileName }}-${{ matrix.qt_arch }}-${{ matrix.qt_ver }}-static
|
||||
shell: pwsh
|
||||
run: |
|
||||
& scripts\windows-mingw-publish.ps1 ${env:archiveName} ${env:targetName}
|
||||
$name = ${env:archiveName}
|
||||
echo "packageName=$name" >> $env:GITHUB_OUTPUT
|
||||
|
||||
- uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: ${{ steps.package.outputs.packageName }}
|
||||
path: ${{ steps.package.outputs.packageName }}
|
||||
|
||||
- name: uploadRelease
|
||||
if: startsWith(github.event.ref, 'refs/tags/')
|
||||
uses: svenstaro/upload-release-action@v2
|
||||
with:
|
||||
repo_token: ${{ secrets.GITHUB_TOKEN }}
|
||||
file: ${{ steps.package.outputs.packageName }}.zip
|
||||
asset_name: ${{ env.fileName }}_${{ github.ref_name }}_${{ matrix.qt_arch }}_Qt${{ matrix.qt_ver }}_static.zip
|
||||
tag: ${{ github.ref }}
|
||||
overwrite: true
|
|
@ -0,0 +1,89 @@
|
|||
name: Windows MSVC (Shared Library)
|
||||
on:
|
||||
push:
|
||||
paths:
|
||||
- '*.txt'
|
||||
- 'include/**'
|
||||
- 'source/**'
|
||||
- 'scripts/**'
|
||||
- '.github/workflows/windows-msvc-shared.yml'
|
||||
pull_request:
|
||||
paths:
|
||||
- '*.txt'
|
||||
- 'include/**'
|
||||
- 'source/**'
|
||||
- 'scripts/**'
|
||||
- '.github/workflows/windows-msvc-shared.yml'
|
||||
|
||||
jobs:
|
||||
build:
|
||||
name: Build
|
||||
runs-on: ${{ matrix.os }}
|
||||
strategy:
|
||||
matrix:
|
||||
os: [windows-latest]
|
||||
include:
|
||||
- qt_ver: 6.6.3
|
||||
qt_arch: win64_msvc2019_64
|
||||
msvc_arch: x64
|
||||
qt_arch_install: msvc2019_64
|
||||
env:
|
||||
targetName: KGCAPP.exe
|
||||
fileName: KGCAPP
|
||||
steps:
|
||||
- name: Check out repository
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
submodules: recursive
|
||||
|
||||
- name: Setup ninja
|
||||
uses: seanmiddleditch/gha-setup-ninja@v4
|
||||
with:
|
||||
version: 1.10.2
|
||||
|
||||
- name: Install Qt
|
||||
uses: jurplel/install-qt-action@v3
|
||||
with:
|
||||
version: ${{ matrix.qt_ver }}
|
||||
arch: ${{ matrix.qt_arch }}
|
||||
modules: 'qt5compat qtmultimedia qtshadertools qtimageformats'
|
||||
|
||||
- name: msvc-build
|
||||
id: build
|
||||
shell: cmd
|
||||
run: |
|
||||
call "C:\Program Files\Microsoft Visual Studio\2022\Enterprise\VC\Auxiliary\Build\vcvarsall.bat" ${{ matrix.msvc_arch }}
|
||||
mkdir build
|
||||
cd build
|
||||
cmake -DCMAKE_MESSAGE_LOG_LEVEL=STATUS -DCMAKE_PREFIX_PATH=D:\a\KGCAPP\Qt\${{ matrix.qt_ver }}\msvc2019_64 -DCMAKE_C_COMPILER=cl -DCMAKE_CXX_COMPILER=cl -DCMAKE_BUILD_TYPE=Release -GNinja ..
|
||||
cmake --build . --target all --config Release --parallel
|
||||
echo winSdkDir=%WindowsSdkDir% >> %GITHUB_ENV%
|
||||
echo winSdkVer=%WindowsSdkVersion% >> %GITHUB_ENV%
|
||||
echo vcToolsInstallDir=%VCToolsInstallDir% >> %GITHUB_ENV%
|
||||
echo vcToolsRedistDir=%VCToolsRedistDir% >> %GITHUB_ENV%
|
||||
|
||||
- name: package
|
||||
id: package
|
||||
env:
|
||||
archiveName: ${{ env.fileName }}-${{ matrix.qt_arch }}-${{ matrix.qt_ver }}-shared
|
||||
msvcArch: ${{ matrix.msvc_arch }}
|
||||
shell: pwsh
|
||||
run: |
|
||||
& scripts\windows-publish.ps1 ${env:archiveName} ${env:targetName}
|
||||
$name = ${env:archiveName}
|
||||
echo "packageName=$name" >> $env:GITHUB_OUTPUT
|
||||
|
||||
- uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: ${{ steps.package.outputs.packageName }}
|
||||
path: ${{ steps.package.outputs.packageName }}
|
||||
|
||||
- name: uploadRelease
|
||||
if: startsWith(github.event.ref, 'refs/tags/')
|
||||
uses: svenstaro/upload-release-action@v2
|
||||
with:
|
||||
repo_token: ${{ secrets.GITHUB_TOKEN }}
|
||||
file: ${{ steps.package.outputs.packageName }}.zip
|
||||
asset_name: ${{ env.fileName }}_${{ github.ref_name }}_${{ matrix.qt_arch }}_Qt${{ matrix.qt_ver }}_shared.zip
|
||||
tag: ${{ github.ref }}
|
||||
overwrite: true
|
|
@ -0,0 +1,89 @@
|
|||
name: Windows MSVC (Static Library)
|
||||
on:
|
||||
push:
|
||||
paths:
|
||||
- '*.txt'
|
||||
- 'include/**'
|
||||
- 'source/**'
|
||||
- 'scripts/**'
|
||||
- '.github/workflows/windows-msvc-static.yml'
|
||||
pull_request:
|
||||
paths:
|
||||
- '*.txt'
|
||||
- 'include/**'
|
||||
- 'source/**'
|
||||
- 'scripts/**'
|
||||
- '.github/workflows/windows-msvc-static.yml'
|
||||
|
||||
jobs:
|
||||
build:
|
||||
name: Build
|
||||
runs-on: ${{ matrix.os }}
|
||||
strategy:
|
||||
matrix:
|
||||
os: [windows-latest]
|
||||
include:
|
||||
- qt_ver: 6.6.3
|
||||
qt_arch: win64_msvc2019_64
|
||||
msvc_arch: x64
|
||||
qt_arch_install: msvc2019_64
|
||||
env:
|
||||
targetName: KGCAPP.exe
|
||||
fileName: KGCAPP
|
||||
steps:
|
||||
- name: Check out repository
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
submodules: recursive
|
||||
|
||||
- name: Setup ninja
|
||||
uses: seanmiddleditch/gha-setup-ninja@v4
|
||||
with:
|
||||
version: 1.10.2
|
||||
|
||||
- name: Install Qt
|
||||
uses: jurplel/install-qt-action@v3
|
||||
with:
|
||||
version: ${{ matrix.qt_ver }}
|
||||
arch: ${{ matrix.qt_arch }}
|
||||
modules: 'qt5compat qtmultimedia qtshadertools qtimageformats'
|
||||
|
||||
- name: msvc-build
|
||||
id: build
|
||||
shell: cmd
|
||||
run: |
|
||||
call "C:\Program Files\Microsoft Visual Studio\2022\Enterprise\VC\Auxiliary\Build\vcvarsall.bat" ${{ matrix.msvc_arch }}
|
||||
mkdir build
|
||||
cd build
|
||||
cmake -DCMAKE_MESSAGE_LOG_LEVEL=STATUS -DCMAKE_PREFIX_PATH=D:\a\KGCAPP\Qt\${{ matrix.qt_ver }}\msvc2019_64 -DCMAKE_C_COMPILER=cl -DCMAKE_CXX_COMPILER=cl -DCMAKE_BUILD_TYPE=Release -DKGCAPP_BUILD_STATIC_LIB=ON -GNinja ..
|
||||
cmake --build . --target all --config Release --parallel
|
||||
echo winSdkDir=%WindowsSdkDir% >> %GITHUB_ENV%
|
||||
echo winSdkVer=%WindowsSdkVersion% >> %GITHUB_ENV%
|
||||
echo vcToolsInstallDir=%VCToolsInstallDir% >> %GITHUB_ENV%
|
||||
echo vcToolsRedistDir=%VCToolsRedistDir% >> %GITHUB_ENV%
|
||||
|
||||
- name: package
|
||||
id: package
|
||||
env:
|
||||
archiveName: ${{ env.fileName }}-${{ matrix.qt_arch }}-${{ matrix.qt_ver }}-static
|
||||
msvcArch: ${{ matrix.msvc_arch }}
|
||||
shell: pwsh
|
||||
run: |
|
||||
& scripts\windows-publish.ps1 ${env:archiveName} ${env:targetName}
|
||||
$name = ${env:archiveName}
|
||||
echo "packageName=$name" >> $env:GITHUB_OUTPUT
|
||||
|
||||
- uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: ${{ steps.package.outputs.packageName }}
|
||||
path: ${{ steps.package.outputs.packageName }}
|
||||
|
||||
- name: uploadRelease
|
||||
if: startsWith(github.event.ref, 'refs/tags/')
|
||||
uses: svenstaro/upload-release-action@v2
|
||||
with:
|
||||
repo_token: ${{ secrets.GITHUB_TOKEN }}
|
||||
file: ${{ steps.package.outputs.packageName }}.zip
|
||||
asset_name: ${{ env.fileName }}_${{ github.ref_name }}_${{ matrix.qt_arch }}_Qt${{ matrix.qt_ver }}_static.zip
|
||||
tag: ${{ github.ref }}
|
||||
overwrite: true
|
|
@ -0,0 +1,87 @@
|
|||
# C++ objects and libs
|
||||
*.slo
|
||||
*.lo
|
||||
*.o
|
||||
*.a
|
||||
*.la
|
||||
*.lai
|
||||
#*.so
|
||||
#*.so.*
|
||||
#*.dll
|
||||
#*.dylib
|
||||
|
||||
# Qt-es
|
||||
object_script.*.Release
|
||||
object_script.*.Debug
|
||||
*_plugin_import.cpp
|
||||
/.qmake.cache
|
||||
/.qmake.stash
|
||||
*.pro.user
|
||||
*.pro.user.*
|
||||
*.qbs.user
|
||||
*.qbs.user.*
|
||||
*.moc
|
||||
moc_*.cpp
|
||||
moc_*.h
|
||||
qrc_*.cpp
|
||||
ui_*.h
|
||||
*.qmlc
|
||||
*.jsc
|
||||
Makefile*
|
||||
*build-*
|
||||
*.qm
|
||||
*.prl
|
||||
|
||||
# Qt unit tests
|
||||
target_wrapper.*
|
||||
|
||||
# QtCreator
|
||||
*.autosave
|
||||
|
||||
# QtCreator Qml
|
||||
*.qmlproject.user
|
||||
*.qmlproject.user.*
|
||||
|
||||
# QtCreator CMake
|
||||
CMakeLists.txt.user*
|
||||
|
||||
# QtCreator 4.8< compilation database
|
||||
compile_commands.json
|
||||
|
||||
# QtCreator local machine specific files for imported projects
|
||||
*creator.user*
|
||||
|
||||
*_qmlcache.qrc
|
||||
|
||||
# ---> macOS
|
||||
# General
|
||||
.DS_Store
|
||||
.AppleDouble
|
||||
.LSOverride
|
||||
|
||||
# Icon must end with two \r
|
||||
Icon
|
||||
|
||||
|
||||
# Thumbnails
|
||||
._*
|
||||
|
||||
# Files that might appear in the root of a volume
|
||||
.DocumentRevisions-V100
|
||||
.fseventsd
|
||||
.Spotlight-V100
|
||||
.TemporaryItems
|
||||
.Trashes
|
||||
.VolumeIcon.icns
|
||||
.com.apple.timemachine.donotpresent
|
||||
|
||||
# Directories potentially created on remote AFP share
|
||||
.AppleDB
|
||||
.AppleDesktop
|
||||
Network Trash Folder
|
||||
Temporary Items
|
||||
.apdisk
|
||||
|
||||
# macOS
|
||||
.DS_Store
|
||||
*/.DS_Store
|
|
@ -0,0 +1,75 @@
|
|||
name: MacOS (Shared Library)
|
||||
on:
|
||||
push:
|
||||
paths:
|
||||
- '*.txt'
|
||||
- 'example/**'
|
||||
- 'lib_source/**'
|
||||
- 'scripts/**'
|
||||
- '.github/workflows/macos-shared.yml'
|
||||
pull_request:
|
||||
paths:
|
||||
- '*.txt'
|
||||
- 'example/**'
|
||||
- 'lib_source/**'
|
||||
- 'scripts/**'
|
||||
- '.github/workflows/macos-shared.yml'
|
||||
|
||||
jobs:
|
||||
build:
|
||||
name: Build
|
||||
runs-on: ${{ matrix.os }}
|
||||
strategy:
|
||||
matrix:
|
||||
os: [macos-14]
|
||||
qt_ver: [6.6.3]
|
||||
qt_arch: [clang_64]
|
||||
env:
|
||||
targetName: RibbonUI-APP
|
||||
steps:
|
||||
- name: Check out repository
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
submodules: recursive
|
||||
|
||||
- name: Install Qt
|
||||
uses: jurplel/install-qt-action@v3
|
||||
with:
|
||||
version: ${{ matrix.qt_ver }}
|
||||
arch: ${{ matrix.qt_arch }}
|
||||
modules: 'qt5compat qtmultimedia qtshadertools qtimageformats'
|
||||
|
||||
- name: Set up Ninja
|
||||
uses: seanmiddleditch/gha-setup-ninja@v4
|
||||
with:
|
||||
version: 1.10.2
|
||||
|
||||
- name: build macos
|
||||
run: |
|
||||
cmake --version
|
||||
mkdir build
|
||||
cd build
|
||||
cmake -DCMAKE_MESSAGE_LOG_LEVEL=STATUS -DCMAKE_PREFIX_PATH=/Users/runner/work/RibbonUI/Qt/${{ matrix.qt_ver }}/macos -DCMAKE_C_COMPILER=clang -DCMAKE_CXX_COMPILER=clang++ -DCMAKE_BUILD_TYPE=Release -GNinja ..
|
||||
cmake --build . --target all --config Release --parallel
|
||||
|
||||
- name: package
|
||||
run: |
|
||||
# 先删除所有dSYM文件,减少包的体积
|
||||
sudo find /Users/runner/work/RibbonUI/Qt/${{ matrix.qt_ver }}/macos/qml -name "*.dSYM" | xargs rm -r
|
||||
# 拷贝依赖
|
||||
sudo macdeployqt /Users/runner/work/RibbonUI/RibbonUI/build/app/release/${targetName}.app -qmldir=. -verbose=1 -dmg
|
||||
|
||||
- uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: ${{ env.targetName }}_${{ matrix.os }}_${{matrix.qt_ver}}_shared.zip
|
||||
path: /Users/runner/work/RibbonUI/RibbonUI/build/app/release/${{ env.targetName }}.dmg
|
||||
|
||||
- name: uploadRelease
|
||||
if: startsWith(github.event.ref, 'refs/tags/')
|
||||
uses: svenstaro/upload-release-action@v2
|
||||
with:
|
||||
repo_token: ${{ secrets.GITHUB_TOKEN }}
|
||||
file: /Users/runner/work/RibbonUI/RibbonUI/build/app/release/${{ env.targetName }}.dmg
|
||||
asset_name: ${{ env.targetName }}_${{ github.ref_name }}_${{ matrix.os }}_Qt${{ matrix.qt_ver }}_shared.dmg
|
||||
tag: ${{ github.ref }}
|
||||
overwrite: true
|
|
@ -0,0 +1,75 @@
|
|||
name: MacOS (Static Library)
|
||||
on:
|
||||
push:
|
||||
paths:
|
||||
- '*.txt'
|
||||
- 'example/**'
|
||||
- 'lib_source/**'
|
||||
- 'scripts/**'
|
||||
- '.github/workflows/macos-static.yml'
|
||||
pull_request:
|
||||
paths:
|
||||
- '*.txt'
|
||||
- 'example/**'
|
||||
- 'lib_source/**'
|
||||
- 'scripts/**'
|
||||
- '.github/workflows/macos-static.yml'
|
||||
|
||||
jobs:
|
||||
build:
|
||||
name: Build
|
||||
runs-on: ${{ matrix.os }}
|
||||
strategy:
|
||||
matrix:
|
||||
os: [macos-14]
|
||||
qt_ver: [6.6.3]
|
||||
qt_arch: [clang_64]
|
||||
env:
|
||||
targetName: RibbonUI-APP
|
||||
steps:
|
||||
- name: Check out repository
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
submodules: recursive
|
||||
|
||||
- name: Install Qt
|
||||
uses: jurplel/install-qt-action@v3
|
||||
with:
|
||||
version: ${{ matrix.qt_ver }}
|
||||
arch: ${{ matrix.qt_arch }}
|
||||
modules: 'qt5compat qtmultimedia qtshadertools qtimageformats'
|
||||
|
||||
- name: Set up Ninja
|
||||
uses: seanmiddleditch/gha-setup-ninja@v4
|
||||
with:
|
||||
version: 1.10.2
|
||||
|
||||
- name: build macos
|
||||
run: |
|
||||
cmake --version
|
||||
mkdir build
|
||||
cd build
|
||||
cmake -DCMAKE_MESSAGE_LOG_LEVEL=STATUS -DCMAKE_PREFIX_PATH=/Users/runner/work/RibbonUI/Qt/${{ matrix.qt_ver }}/macos -DCMAKE_C_COMPILER=clang -DCMAKE_CXX_COMPILER=clang++ -DCMAKE_BUILD_TYPE=Release -DRIBBONUI_BUILD_STATIC_LIB=ON -GNinja ..
|
||||
cmake --build . --target all --config Release --parallel
|
||||
|
||||
- name: package
|
||||
run: |
|
||||
# 先删除所有dSYM文件,减少包的体积
|
||||
sudo find /Users/runner/work/RibbonUI/Qt/${{ matrix.qt_ver }}/macos/qml -name "*.dSYM" | xargs rm -r
|
||||
# 拷贝依赖
|
||||
sudo macdeployqt /Users/runner/work/RibbonUI/RibbonUI/build/app/release/${targetName}.app -qmldir=. -verbose=1 -dmg
|
||||
|
||||
- uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: ${{ env.targetName }}_${{ matrix.os }}_${{matrix.qt_ver}}_static.zip
|
||||
path: /Users/runner/work/RibbonUI/RibbonUI/build/app/release/${{ env.targetName }}.dmg
|
||||
|
||||
- name: uploadRelease
|
||||
if: startsWith(github.event.ref, 'refs/tags/')
|
||||
uses: svenstaro/upload-release-action@v2
|
||||
with:
|
||||
repo_token: ${{ secrets.GITHUB_TOKEN }}
|
||||
file: /Users/runner/work/RibbonUI/RibbonUI/build/app/release/${{ env.targetName }}.dmg
|
||||
asset_name: ${{ env.targetName }}_${{ github.ref_name }}_${{ matrix.os }}_Qt${{ matrix.qt_ver }}_static.dmg
|
||||
tag: ${{ github.ref }}
|
||||
overwrite: true
|
|
@ -0,0 +1,92 @@
|
|||
name: Ubuntu (Shared Library)
|
||||
on:
|
||||
workflow_dispatch:
|
||||
push:
|
||||
paths:
|
||||
- '*.txt'
|
||||
- 'lib_source/**'
|
||||
- 'example/**'
|
||||
- 'scripts/**'
|
||||
- '.github/workflows/ubuntu-shared.yml'
|
||||
pull_request:
|
||||
paths:
|
||||
- '*.txt'
|
||||
- 'lib_source/**'
|
||||
- 'example/**'
|
||||
- 'scripts/**'
|
||||
- '.github/workflows/ubuntu-shared.yml'
|
||||
|
||||
jobs:
|
||||
build:
|
||||
name: Build
|
||||
runs-on: ${{ matrix.os }}
|
||||
strategy:
|
||||
matrix:
|
||||
os: [ubuntu-latest]
|
||||
qt_ver: [6.6.3]
|
||||
qt_arch: [gcc_64]
|
||||
env:
|
||||
targetName: RibbonUI-APP
|
||||
steps:
|
||||
- name: Check out repository
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
submodules: recursive
|
||||
|
||||
- name: Install Qt
|
||||
uses: jurplel/install-qt-action@v3
|
||||
with:
|
||||
version: ${{ matrix.qt_ver }}
|
||||
arch: ${{ matrix.qt_arch }}
|
||||
modules: 'qt5compat qtmultimedia qtshadertools qtimageformats'
|
||||
|
||||
- name: Set up Ninja
|
||||
uses: seanmiddleditch/gha-setup-ninja@v4
|
||||
with:
|
||||
version: 1.10.2
|
||||
|
||||
- name: ubuntu install GL library
|
||||
run: sudo apt install -y libxcb-cursor0 libgl1-mesa-dev libxcb1-dev libgtk-3-dev libxkbcommon-x11-dev libxcb-icccm4-dev libxcb-image0-dev libxcb-keysyms1-dev libxcb-randr0-dev libxcb-shape0-dev libxcb-xfixes0-dev libxcb-xinerama0-dev libxcb-sync-dev libxcb-render-util0-dev libxcb-shm0-dev
|
||||
|
||||
- name: ubuntu install libfuse2
|
||||
run: sudo apt install libfuse2
|
||||
|
||||
- name: build ubuntu
|
||||
run: |
|
||||
ninja --version
|
||||
cmake --version
|
||||
mkdir build
|
||||
cd build
|
||||
cmake -DCMAKE_MESSAGE_LOG_LEVEL=STATUS -DCMAKE_PREFIX_PATH=/home/runner/work/RibbonUI/Qt/${{ matrix.qt_ver }}/gcc_64 -DCMAKE_C_COMPILER=gcc -DCMAKE_CXX_COMPILER=g++ -DCMAKE_BUILD_TYPE=Release -GNinja ..
|
||||
cmake --build . --target all --config Release --parallel
|
||||
|
||||
- name: install QT linux deploy
|
||||
uses: miurahr/install-linuxdeploy-action@v1
|
||||
with:
|
||||
plugins: qt appimage
|
||||
|
||||
- name: Check if svg file exists
|
||||
run: if [ ! -f "${targetName}.svg" ]; then echo "File not found, creating..."; touch ${targetName}.svg; fi
|
||||
|
||||
- name: package
|
||||
run: |
|
||||
# make sure Qt plugin finds QML sources so it can deploy the imported files
|
||||
export QML_SOURCES_PATHS=./
|
||||
# 拷贝依赖
|
||||
linuxdeploy-x86_64.AppImage --plugin=qt --output=appimage --create-desktop-file --icon-file=${targetName}.svg --executable=/home/runner/work/RibbonUI/RibbonUI/build/app/release/${targetName} --appdir /home/runner/work/RibbonUI/RibbonUI/build/app/release/
|
||||
mv ${{ env.targetName }}-*.AppImage ${{ env.targetName }}_${{ matrix.os }}_${{matrix.qt_ver}}_shared.AppImage
|
||||
|
||||
- uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: ${{ env.targetName }}_${{ matrix.os }}_${{matrix.qt_ver}}_shared
|
||||
path: ${{ env.targetName }}_${{ matrix.os }}_${{matrix.qt_ver}}_shared.AppImage
|
||||
|
||||
- name: uploadRelease
|
||||
if: startsWith(github.event.ref, 'refs/tags/')
|
||||
uses: svenstaro/upload-release-action@v2
|
||||
with:
|
||||
repo_token: ${{ secrets.GITHUB_TOKEN }}
|
||||
file: ${{ env.targetName }}_${{ matrix.os }}_${{matrix.qt_ver}}_shared.AppImage
|
||||
asset_name: ${{ env.targetName }}_${{ github.ref_name }}_${{ matrix.os }}_Qt${{ matrix.qt_ver }}_shared.AppImage
|
||||
tag: ${{ github.ref }}
|
||||
overwrite: true
|
|
@ -0,0 +1,92 @@
|
|||
name: Ubuntu (Static Library)
|
||||
on:
|
||||
workflow_dispatch:
|
||||
push:
|
||||
paths:
|
||||
- '*.txt'
|
||||
- 'lib_source/**'
|
||||
- 'example/**'
|
||||
- 'scripts/**'
|
||||
- '.github/workflows/ubuntu-static.yml'
|
||||
pull_request:
|
||||
paths:
|
||||
- '*.txt'
|
||||
- 'lib_source/**'
|
||||
- 'example/**'
|
||||
- 'scripts/**'
|
||||
- '.github/workflows/ubuntu-static.yml'
|
||||
|
||||
jobs:
|
||||
build:
|
||||
name: Build
|
||||
runs-on: ${{ matrix.os }}
|
||||
strategy:
|
||||
matrix:
|
||||
os: [ubuntu-latest]
|
||||
qt_ver: [6.6.3]
|
||||
qt_arch: [gcc_64]
|
||||
env:
|
||||
targetName: RibbonUI-APP
|
||||
steps:
|
||||
- name: Check out repository
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
submodules: recursive
|
||||
|
||||
- name: Install Qt
|
||||
uses: jurplel/install-qt-action@v3
|
||||
with:
|
||||
version: ${{ matrix.qt_ver }}
|
||||
arch: ${{ matrix.qt_arch }}
|
||||
modules: 'qt5compat qtmultimedia qtshadertools qtimageformats'
|
||||
|
||||
- name: Set up Ninja
|
||||
uses: seanmiddleditch/gha-setup-ninja@v4
|
||||
with:
|
||||
version: 1.10.2
|
||||
|
||||
- name: ubuntu install GL library
|
||||
run: sudo apt-get install -y libxcb-cursor0 libgl1-mesa-dev libxcb1-dev libgtk-3-dev libxkbcommon-x11-dev libxcb-icccm4-dev libxcb-image0-dev libxcb-keysyms1-dev libxcb-randr0-dev libxcb-shape0-dev libxcb-xfixes0-dev libxcb-xinerama0-dev libxcb-sync-dev libxcb-render-util0-dev libxcb-shm0-dev
|
||||
|
||||
- name: ubuntu install libfuse2
|
||||
run: sudo apt install libfuse2
|
||||
|
||||
- name: build ubuntu
|
||||
run: |
|
||||
ninja --version
|
||||
cmake --version
|
||||
mkdir build
|
||||
cd build
|
||||
cmake -DCMAKE_MESSAGE_LOG_LEVEL=STATUS -DCMAKE_PREFIX_PATH=/home/runner/work/RibbonUI/Qt/${{ matrix.qt_ver }}/gcc_64 -DCMAKE_C_COMPILER=gcc -DCMAKE_CXX_COMPILER=g++ -DCMAKE_BUILD_TYPE=Release -DRIBBONUI_BUILD_STATIC_LIB=ON -GNinja ..
|
||||
cmake --build . --target all --config Release --parallel
|
||||
|
||||
- name: install QT linux deploy
|
||||
uses: miurahr/install-linuxdeploy-action@v1
|
||||
with:
|
||||
plugins: qt appimage
|
||||
|
||||
- name: Check if svg file exists
|
||||
run: if [ ! -f "${targetName}.svg" ]; then echo "File not found, creating..."; touch ${targetName}.svg; fi
|
||||
|
||||
- name: package
|
||||
run: |
|
||||
# make sure Qt plugin finds QML sources so it can deploy the imported files
|
||||
export QML_SOURCES_PATHS=./
|
||||
# 拷贝依赖
|
||||
linuxdeploy-x86_64.AppImage --plugin=qt --output=appimage --create-desktop-file --icon-file=${targetName}.svg --executable=/home/runner/work/RibbonUI/RibbonUI/build/app/release/${targetName} --appdir /home/runner/work/RibbonUI/RibbonUI/build/app/release/
|
||||
mv ${{ env.targetName }}-*.AppImage ${{ env.targetName }}_${{ matrix.os }}_Qt${{ matrix.qt_ver }}_static.AppImage
|
||||
|
||||
- uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: ${{ env.targetName }}_${{ matrix.os }}_Qt${{ matrix.qt_ver }}_static
|
||||
path: ${{ env.targetName }}_${{ matrix.os }}_Qt${{ matrix.qt_ver }}_static.AppImage
|
||||
|
||||
- name: uploadRelease
|
||||
if: startsWith(github.event.ref, 'refs/tags/')
|
||||
uses: svenstaro/upload-release-action@v2
|
||||
with:
|
||||
repo_token: ${{ secrets.GITHUB_TOKEN }}
|
||||
file: ${{ env.targetName }}_${{ matrix.os }}_Qt${{ matrix.qt_ver }}_static.AppImage
|
||||
asset_name: ${{ env.targetName }}_${{ github.ref_name }}_${{ matrix.os }}_Qt${{ matrix.qt_ver }}_static.AppImage
|
||||
tag: ${{ github.ref }}
|
||||
overwrite: true
|
|
@ -0,0 +1,95 @@
|
|||
name: Windows MinGW (Shared Library)
|
||||
on:
|
||||
push:
|
||||
paths:
|
||||
- '*.txt'
|
||||
- 'lib_source/**'
|
||||
- 'example/**'
|
||||
- 'scripts/**'
|
||||
- '.github/workflows/windows-mingw-shared.yml'
|
||||
pull_request:
|
||||
paths:
|
||||
- '*.txt'
|
||||
- 'example/**'
|
||||
- 'lib_source/**'
|
||||
- 'scripts/**'
|
||||
- '.github/workflows/windows-mingw-shared.yml'
|
||||
|
||||
jobs:
|
||||
build:
|
||||
name: Build
|
||||
runs-on: windows-latest
|
||||
strategy:
|
||||
matrix:
|
||||
include:
|
||||
- qt_arch: win64_mingw
|
||||
qt_ver: 6.6.3
|
||||
qt_tools: "tools_mingw,9.0.0-1-202203221220,qt.tools.win64_mingw900"
|
||||
qt_tools_mingw_install: mingw900_64
|
||||
env:
|
||||
targetName: RibbonUI-APP.exe
|
||||
fileName: RibbonUI-APP
|
||||
steps:
|
||||
- name: Check out repository
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
submodules: recursive
|
||||
|
||||
- name: Setup ninja
|
||||
uses: seanmiddleditch/gha-setup-ninja@v4
|
||||
with:
|
||||
version: 1.10.2
|
||||
|
||||
- name: Install Qt
|
||||
uses: jurplel/install-qt-action@v3
|
||||
with:
|
||||
version: ${{ matrix.qt_ver }}
|
||||
arch: ${{ matrix.qt_arch }}
|
||||
modules: 'qt5compat qtmultimedia qtshadertools qtimageformats'
|
||||
|
||||
- name: Qt6 environment configuration
|
||||
if: ${{ startsWith( matrix.qt_ver, 6 ) }}
|
||||
shell: pwsh
|
||||
run: |
|
||||
Write-Output "${{ env.Qt6_DIR }}/bin" | Out-File -FilePath $env:GITHUB_PATH -Encoding utf8 -Append
|
||||
Write-Output "${{ env.Qt6_DIR }}/../../Tools/${{ matrix.qt_tools_mingw_install }}/bin" | Out-File -FilePath $env:GITHUB_PATH -Encoding utf8 -Append
|
||||
|
||||
- name: where is cmake & where is mingw32-make
|
||||
shell: pwsh
|
||||
run: |
|
||||
Get-Command -Name 'cmake' | Format-List
|
||||
Get-Command -Name 'mingw32-make' | Format-List
|
||||
|
||||
- name: mingw-build
|
||||
id: build
|
||||
shell: cmd
|
||||
run: |
|
||||
mkdir build
|
||||
cd build
|
||||
cmake -DCMAKE_MESSAGE_LOG_LEVEL=STATUS -DCMAKE_PREFIX_PATH=D:\a\RibbonUI\Qt\${{ matrix.qt_ver }}\mingw_64 -DCMAKE_C_COMPILER=gcc -DCMAKE_CXX_COMPILER=g++ -DCMAKE_BUILD_TYPE=Release -GNinja ..
|
||||
cmake --build . --target all --config Release --parallel
|
||||
|
||||
- name: package
|
||||
id: package
|
||||
env:
|
||||
archiveName: ${{ env.fileName }}-${{ matrix.qt_arch }}-${{ matrix.qt_ver }}-shared
|
||||
shell: pwsh
|
||||
run: |
|
||||
& scripts\windows-mingw-publish.ps1 ${env:archiveName} ${env:targetName}
|
||||
$name = ${env:archiveName}
|
||||
echo "packageName=$name" >> $env:GITHUB_OUTPUT
|
||||
|
||||
- uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: ${{ steps.package.outputs.packageName }}
|
||||
path: ${{ steps.package.outputs.packageName }}
|
||||
|
||||
- name: uploadRelease
|
||||
if: startsWith(github.event.ref, 'refs/tags/')
|
||||
uses: svenstaro/upload-release-action@v2
|
||||
with:
|
||||
repo_token: ${{ secrets.GITHUB_TOKEN }}
|
||||
file: ${{ steps.package.outputs.packageName }}.zip
|
||||
asset_name: ${{ env.fileName }}_${{ github.ref_name }}_${{ matrix.qt_arch }}_Qt${{ matrix.qt_ver }}_shared.zip
|
||||
tag: ${{ github.ref }}
|
||||
overwrite: true
|
|
@ -0,0 +1,95 @@
|
|||
name: Windows MinGW (Static Library)
|
||||
on:
|
||||
push:
|
||||
paths:
|
||||
- '*.txt'
|
||||
- 'lib_source/**'
|
||||
- 'example/**'
|
||||
- 'scripts/**'
|
||||
- '.github/workflows/windows-mingw-static.yml'
|
||||
pull_request:
|
||||
paths:
|
||||
- '*.txt'
|
||||
- 'example/**'
|
||||
- 'lib_source/**'
|
||||
- 'scripts/**'
|
||||
- '.github/workflows/windows-mingw-static.yml'
|
||||
|
||||
jobs:
|
||||
build:
|
||||
name: Build
|
||||
runs-on: windows-latest
|
||||
strategy:
|
||||
matrix:
|
||||
include:
|
||||
- qt_arch: win64_mingw
|
||||
qt_ver: 6.6.3
|
||||
qt_tools: "tools_mingw,9.0.0-1-202203221220,qt.tools.win64_mingw900"
|
||||
qt_tools_mingw_install: mingw900_64
|
||||
env:
|
||||
targetName: RibbonUI-APP.exe
|
||||
fileName: RibbonUI-APP
|
||||
steps:
|
||||
- name: Check out repository
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
submodules: recursive
|
||||
|
||||
- name: Setup ninja
|
||||
uses: seanmiddleditch/gha-setup-ninja@v4
|
||||
with:
|
||||
version: 1.10.2
|
||||
|
||||
- name: Install Qt
|
||||
uses: jurplel/install-qt-action@v3
|
||||
with:
|
||||
version: ${{ matrix.qt_ver }}
|
||||
arch: ${{ matrix.qt_arch }}
|
||||
modules: 'qt5compat qtmultimedia qtshadertools qtimageformats'
|
||||
|
||||
- name: Qt6 environment configuration
|
||||
if: ${{ startsWith( matrix.qt_ver, 6 ) }}
|
||||
shell: pwsh
|
||||
run: |
|
||||
Write-Output "${{ env.Qt6_DIR }}/bin" | Out-File -FilePath $env:GITHUB_PATH -Encoding utf8 -Append
|
||||
Write-Output "${{ env.Qt6_DIR }}/../../Tools/${{ matrix.qt_tools_mingw_install }}/bin" | Out-File -FilePath $env:GITHUB_PATH -Encoding utf8 -Append
|
||||
|
||||
- name: where is cmake & where is mingw32-make
|
||||
shell: pwsh
|
||||
run: |
|
||||
Get-Command -Name 'cmake' | Format-List
|
||||
Get-Command -Name 'mingw32-make' | Format-List
|
||||
|
||||
- name: mingw-build
|
||||
id: build
|
||||
shell: cmd
|
||||
run: |
|
||||
mkdir build
|
||||
cd build
|
||||
cmake -DCMAKE_MESSAGE_LOG_LEVEL=STATUS -DCMAKE_PREFIX_PATH=D:\a\RibbonUI\Qt\${{ matrix.qt_ver }}\mingw_64 -DCMAKE_C_COMPILER=gcc -DCMAKE_CXX_COMPILER=g++ -DCMAKE_BUILD_TYPE=Release -DRIBBONUI_BUILD_STATIC_LIB=ON -GNinja ..
|
||||
cmake --build . --target all --config Release --parallel
|
||||
|
||||
- name: package
|
||||
id: package
|
||||
env:
|
||||
archiveName: ${{ env.fileName }}-${{ matrix.qt_arch }}-${{ matrix.qt_ver }}-static
|
||||
shell: pwsh
|
||||
run: |
|
||||
& scripts\windows-mingw-publish.ps1 ${env:archiveName} ${env:targetName}
|
||||
$name = ${env:archiveName}
|
||||
echo "packageName=$name" >> $env:GITHUB_OUTPUT
|
||||
|
||||
- uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: ${{ steps.package.outputs.packageName }}
|
||||
path: ${{ steps.package.outputs.packageName }}
|
||||
|
||||
- name: uploadRelease
|
||||
if: startsWith(github.event.ref, 'refs/tags/')
|
||||
uses: svenstaro/upload-release-action@v2
|
||||
with:
|
||||
repo_token: ${{ secrets.GITHUB_TOKEN }}
|
||||
file: ${{ steps.package.outputs.packageName }}.zip
|
||||
asset_name: ${{ env.fileName }}_${{ github.ref_name }}_${{ matrix.qt_arch }}_Qt${{ matrix.qt_ver }}_static.zip
|
||||
tag: ${{ github.ref }}
|
||||
overwrite: true
|
|
@ -0,0 +1,89 @@
|
|||
name: Windows MSVC (Shared Library)
|
||||
on:
|
||||
push:
|
||||
paths:
|
||||
- '*.txt'
|
||||
- 'lib_source/**'
|
||||
- 'example/**'
|
||||
- 'scripts/**'
|
||||
- '.github/workflows/windows-msvc-shared.yml'
|
||||
pull_request:
|
||||
paths:
|
||||
- '*.txt'
|
||||
- 'example/**'
|
||||
- 'lib_source/**'
|
||||
- 'scripts/**'
|
||||
- '.github/workflows/windows-msvc-shared.yml'
|
||||
|
||||
jobs:
|
||||
build:
|
||||
name: Build
|
||||
runs-on: ${{ matrix.os }}
|
||||
strategy:
|
||||
matrix:
|
||||
os: [windows-latest]
|
||||
include:
|
||||
- qt_ver: 6.6.3
|
||||
qt_arch: win64_msvc2019_64
|
||||
msvc_arch: x64
|
||||
qt_arch_install: msvc2019_64
|
||||
env:
|
||||
targetName: RibbonUI-APP.exe
|
||||
fileName: RibbonUI-APP
|
||||
steps:
|
||||
- name: Check out repository
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
submodules: recursive
|
||||
|
||||
- name: Setup ninja
|
||||
uses: seanmiddleditch/gha-setup-ninja@v4
|
||||
with:
|
||||
version: 1.10.2
|
||||
|
||||
- name: Install Qt
|
||||
uses: jurplel/install-qt-action@v3
|
||||
with:
|
||||
version: ${{ matrix.qt_ver }}
|
||||
arch: ${{ matrix.qt_arch }}
|
||||
modules: 'qt5compat qtmultimedia qtshadertools qtimageformats'
|
||||
|
||||
- name: msvc-build
|
||||
id: build
|
||||
shell: cmd
|
||||
run: |
|
||||
call "C:\Program Files\Microsoft Visual Studio\2022\Enterprise\VC\Auxiliary\Build\vcvarsall.bat" ${{ matrix.msvc_arch }}
|
||||
mkdir build
|
||||
cd build
|
||||
cmake -DCMAKE_MESSAGE_LOG_LEVEL=STATUS -DCMAKE_PREFIX_PATH=D:\a\RibbonUI\Qt\${{ matrix.qt_ver }}\msvc2019_64 -DCMAKE_C_COMPILER=cl -DCMAKE_CXX_COMPILER=cl -DCMAKE_BUILD_TYPE=Release -GNinja ..
|
||||
cmake --build . --target all --config Release --parallel
|
||||
echo winSdkDir=%WindowsSdkDir% >> %GITHUB_ENV%
|
||||
echo winSdkVer=%WindowsSdkVersion% >> %GITHUB_ENV%
|
||||
echo vcToolsInstallDir=%VCToolsInstallDir% >> %GITHUB_ENV%
|
||||
echo vcToolsRedistDir=%VCToolsRedistDir% >> %GITHUB_ENV%
|
||||
|
||||
- name: package
|
||||
id: package
|
||||
env:
|
||||
archiveName: ${{ env.fileName }}-${{ matrix.qt_arch }}-${{ matrix.qt_ver }}-shared
|
||||
msvcArch: ${{ matrix.msvc_arch }}
|
||||
shell: pwsh
|
||||
run: |
|
||||
& scripts\windows-publish.ps1 ${env:archiveName} ${env:targetName}
|
||||
$name = ${env:archiveName}
|
||||
echo "packageName=$name" >> $env:GITHUB_OUTPUT
|
||||
|
||||
- uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: ${{ steps.package.outputs.packageName }}
|
||||
path: ${{ steps.package.outputs.packageName }}
|
||||
|
||||
- name: uploadRelease
|
||||
if: startsWith(github.event.ref, 'refs/tags/')
|
||||
uses: svenstaro/upload-release-action@v2
|
||||
with:
|
||||
repo_token: ${{ secrets.GITHUB_TOKEN }}
|
||||
file: ${{ steps.package.outputs.packageName }}.zip
|
||||
asset_name: ${{ env.fileName }}_${{ github.ref_name }}_${{ matrix.qt_arch }}_Qt${{ matrix.qt_ver }}_shared.zip
|
||||
tag: ${{ github.ref }}
|
||||
overwrite: true
|
|
@ -0,0 +1,89 @@
|
|||
name: Windows MSVC (Static Library)
|
||||
on:
|
||||
push:
|
||||
paths:
|
||||
- '*.txt'
|
||||
- 'lib_source/**'
|
||||
- 'example/**'
|
||||
- 'scripts/**'
|
||||
- '.github/workflows/windows-msvc-static.yml'
|
||||
pull_request:
|
||||
paths:
|
||||
- '*.txt'
|
||||
- 'example/**'
|
||||
- 'lib_source/**'
|
||||
- 'scripts/**'
|
||||
- '.github/workflows/windows-msvc-static.yml'
|
||||
|
||||
jobs:
|
||||
build:
|
||||
name: Build
|
||||
runs-on: ${{ matrix.os }}
|
||||
strategy:
|
||||
matrix:
|
||||
os: [windows-latest]
|
||||
include:
|
||||
- qt_ver: 6.6.3
|
||||
qt_arch: win64_msvc2019_64
|
||||
msvc_arch: x64
|
||||
qt_arch_install: msvc2019_64
|
||||
env:
|
||||
targetName: RibbonUI-APP.exe
|
||||
fileName: RibbonUI-APP
|
||||
steps:
|
||||
- name: Check out repository
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
submodules: recursive
|
||||
|
||||
- name: Setup ninja
|
||||
uses: seanmiddleditch/gha-setup-ninja@v4
|
||||
with:
|
||||
version: 1.10.2
|
||||
|
||||
- name: Install Qt
|
||||
uses: jurplel/install-qt-action@v3
|
||||
with:
|
||||
version: ${{ matrix.qt_ver }}
|
||||
arch: ${{ matrix.qt_arch }}
|
||||
modules: 'qt5compat qtmultimedia qtshadertools qtimageformats'
|
||||
|
||||
- name: msvc-build
|
||||
id: build
|
||||
shell: cmd
|
||||
run: |
|
||||
call "C:\Program Files\Microsoft Visual Studio\2022\Enterprise\VC\Auxiliary\Build\vcvarsall.bat" ${{ matrix.msvc_arch }}
|
||||
mkdir build
|
||||
cd build
|
||||
cmake -DCMAKE_MESSAGE_LOG_LEVEL=STATUS -DCMAKE_PREFIX_PATH=D:\a\RibbonUI\Qt\${{ matrix.qt_ver }}\msvc2019_64 -DCMAKE_C_COMPILER=cl -DCMAKE_CXX_COMPILER=cl -DCMAKE_BUILD_TYPE=Release -DRIBBONUI_BUILD_STATIC_LIB=ON -GNinja ..
|
||||
cmake --build . --target all --config Release --parallel
|
||||
echo winSdkDir=%WindowsSdkDir% >> %GITHUB_ENV%
|
||||
echo winSdkVer=%WindowsSdkVersion% >> %GITHUB_ENV%
|
||||
echo vcToolsInstallDir=%VCToolsInstallDir% >> %GITHUB_ENV%
|
||||
echo vcToolsRedistDir=%VCToolsRedistDir% >> %GITHUB_ENV%
|
||||
|
||||
- name: package
|
||||
id: package
|
||||
env:
|
||||
archiveName: ${{ env.fileName }}-${{ matrix.qt_arch }}-${{ matrix.qt_ver }}-static
|
||||
msvcArch: ${{ matrix.msvc_arch }}
|
||||
shell: pwsh
|
||||
run: |
|
||||
& scripts\windows-publish.ps1 ${env:archiveName} ${env:targetName}
|
||||
$name = ${env:archiveName}
|
||||
echo "packageName=$name" >> $env:GITHUB_OUTPUT
|
||||
|
||||
- uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: ${{ steps.package.outputs.packageName }}
|
||||
path: ${{ steps.package.outputs.packageName }}
|
||||
|
||||
- name: uploadRelease
|
||||
if: startsWith(github.event.ref, 'refs/tags/')
|
||||
uses: svenstaro/upload-release-action@v2
|
||||
with:
|
||||
repo_token: ${{ secrets.GITHUB_TOKEN }}
|
||||
file: ${{ steps.package.outputs.packageName }}.zip
|
||||
asset_name: ${{ env.fileName }}_${{ github.ref_name }}_${{ matrix.qt_arch }}_Qt${{ matrix.qt_ver }}_static.zip
|
||||
tag: ${{ github.ref }}
|
||||
overwrite: true
|
|
@ -0,0 +1,87 @@
|
|||
# C++ objects and libs
|
||||
*.slo
|
||||
*.lo
|
||||
*.o
|
||||
*.a
|
||||
*.la
|
||||
*.lai
|
||||
*.so
|
||||
*.so.*
|
||||
#*.dll
|
||||
*.dylib
|
||||
|
||||
# Qt-es
|
||||
object_script.*.Release
|
||||
object_script.*.Debug
|
||||
*_plugin_import.cpp
|
||||
/.qmake.cache
|
||||
/.qmake.stash
|
||||
*.pro.user
|
||||
*.pro.user.*
|
||||
*.qbs.user
|
||||
*.qbs.user.*
|
||||
*.moc
|
||||
moc_*.cpp
|
||||
moc_*.h
|
||||
qrc_*.cpp
|
||||
ui_*.h
|
||||
*.qmlc
|
||||
*.jsc
|
||||
Makefile*
|
||||
*build-*
|
||||
*.qm
|
||||
*.prl
|
||||
|
||||
# Qt unit tests
|
||||
target_wrapper.*
|
||||
|
||||
# QtCreator
|
||||
*.autosave
|
||||
|
||||
# QtCreator Qml
|
||||
*.qmlproject.user
|
||||
*.qmlproject.user.*
|
||||
|
||||
# QtCreator CMake
|
||||
CMakeLists.txt.user*
|
||||
|
||||
# QtCreator 4.8< compilation database
|
||||
compile_commands.json
|
||||
|
||||
# QtCreator local machine specific files for imported projects
|
||||
*creator.user*
|
||||
|
||||
*_qmlcache.qrc
|
||||
|
||||
# ---> macOS
|
||||
# General
|
||||
.DS_Store
|
||||
.AppleDouble
|
||||
.LSOverride
|
||||
|
||||
# Icon must end with two \r
|
||||
Icon
|
||||
|
||||
|
||||
# Thumbnails
|
||||
._*
|
||||
|
||||
# Files that might appear in the root of a volume
|
||||
.DocumentRevisions-V100
|
||||
.fseventsd
|
||||
.Spotlight-V100
|
||||
.TemporaryItems
|
||||
.Trashes
|
||||
.VolumeIcon.icns
|
||||
.com.apple.timemachine.donotpresent
|
||||
|
||||
# Directories potentially created on remote AFP share
|
||||
.AppleDB
|
||||
.AppleDesktop
|
||||
Network Trash Folder
|
||||
Temporary Items
|
||||
.apdisk
|
||||
|
||||
# macOS
|
||||
.DS_Store
|
||||
*/.DS_Store
|
|
@ -0,0 +1,3 @@
|
|||
[submodule "lib_source/3rdparty/qwindowkit"]
|
||||
path = lib_source/3rdparty/qwindowkit
|
||||
url = https://github.com/stdware/qwindowkit.git
|
|
@ -0,0 +1,28 @@
|
|||
cmake_minimum_required(VERSION 3.16)
|
||||
|
||||
project(RibbonUI_Project VERSION 1.0.3 LANGUAGES CXX)
|
||||
|
||||
find_package(Qt6 REQUIRED COMPONENTS Core)
|
||||
set(QT_SDK_DIR ${Qt6_DIR}/../../..)
|
||||
cmake_path(SET QT_SDK_DIR NORMALIZE ${QT_SDK_DIR})
|
||||
|
||||
option(RIBBONUI_BUILD_EXAMPLES "Build RibbonUI APP." ON)
|
||||
option(RIBBONUI_BUILD_QWINDOWKIT "Build QWindowKit." ON)
|
||||
option(RIBBONUI_BUILD_STATIC_LIB "Build RibbonUI static library." OFF)
|
||||
|
||||
if(NOT RIBBONUI_QML_PLUGIN_DIRECTORY)
|
||||
set(RIBBONUI_QML_PLUGIN_DIRECTORY ${QT_SDK_DIR}/qml/RibbonUI CACHE PATH "RibbonUI Plugin Path")
|
||||
endif()
|
||||
|
||||
add_subdirectory(lib_source)
|
||||
|
||||
if (RIBBONUI_BUILD_EXAMPLES)
|
||||
add_subdirectory(example)
|
||||
endif()
|
||||
|
||||
message("---------------------------- RibbonUI ----------------------------")
|
||||
message("Build RibbonUI APP: ${RIBBONUI_BUILD_EXAMPLES}")
|
||||
message("Build RibbonUI static library: ${RIBBONUI_BUILD_STATIC_LIB}")
|
||||
message("Build QWindowKit: ${RIBBONUI_BUILD_QWINDOWKIT}")
|
||||
message("RibbonUI QML Plugin Path: ${RIBBONUI_QML_PLUGIN_DIRECTORY}")
|
||||
message("------------------------------------------------------------------")
|
|
@ -0,0 +1,21 @@
|
|||
MIT License
|
||||
|
||||
Copyright (c) 2023 Dylan Liu
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
|
@ -0,0 +1,128 @@
|
|||
# RibbonUI
|
||||
|
||||
<div align="center">
|
||||
<img src="lib_source/resources/imgs/icon.png" alt="Logo" style="width:40%; height:auto;">
|
||||
</div>
|
||||
|
||||
<h1 align="center">Qt RibbonUI </h1>
|
||||
|
||||
- [RibbonUI](#ribbonui)
|
||||
- [1. 介绍](#1-介绍)
|
||||
- [2. 组件列表](#2-组件列表)
|
||||
- [3. 支持平台](#3-支持平台)
|
||||
- [Qt 6 分支 (main 分支)](#qt-6-分支-main-分支)
|
||||
- [Qt 5 分支 (***TODO***)](#qt-5-分支-todo)
|
||||
- [4. 如何使用?](#4-如何使用)
|
||||
- [5. 鸣谢](#5-鸣谢)
|
||||
- [6. 与我联系](#6-与我联系)
|
||||
|
||||
## 1. 介绍
|
||||
RibbonUI是一个参考微软Ribbon风格(即Office 2016后的风格)设计的轻量级、简约且优雅的Qt组件库,用QML写就。
|
||||
|
||||
***[Click to view English README](README.md)***
|
||||
|
||||
<div align="center">
|
||||
<div align="center">
|
||||
<img src="documents/pictures/home-light-classic.png" alt="Home Light Classic" style="width:45%; height:auto;">
|
||||
<img src="documents/pictures/home-dark-classic.png" alt="Home Light Classic" style="width:45%; height:auto;">
|
||||
</div>
|
||||
<p align="center">主界面浅色/深色主题 (经典风格) </p>
|
||||
</div>
|
||||
<div align="center">
|
||||
<div align="center">
|
||||
<img src="documents/pictures/home-light-modern.png" alt="Home Light Modern" style="width:45%; height:auto;">
|
||||
<img src="documents/pictures/home-dark-modern.png" alt="Home Light Modern" style="width:45%; height:auto;">
|
||||
</div>
|
||||
<p align="center">主界面浅色/深色主题 (现代风格) </p>
|
||||
</div>
|
||||
|
||||
## 2. 组件列表
|
||||
目前支持***30***种组件,后续会添加更多。
|
||||
| 名称 | 介绍 | 展示图片|
|
||||
|:----:|:----:|:----:|
|
||||
| RibbonWindow | 基于framelesshelper实现的无边框窗口,支持退出确认弹窗及模糊/亚克力化背景。||
|
||||
| RibbonTabBar | 支持多分组页面切换、自定义右上角工具栏、自由收放的工具栏,如同Word的。|  |
|
||||
| RibbonTitleBar | 支持自定义背景色、自由添加工具按钮的窗口标题栏,针对Windows和macOS有不同的窗口按钮设计。|  |
|
||||
| RibbonBottomBar | 支持添加自定义工具的底栏。 | |
|
||||
| RibbonBlur | 为各种组件提供模糊化效果 |  |
|
||||
| RibbonButton | 支持有/无背景的纯文字/纯图标/图标加文字的按钮,支持鼠标覆盖显示提示信息 |  |
|
||||
| RibbonPushButton | 支持弹出菜单的大图标按钮,可以使用内置图标库或用户自选图片 |  |
|
||||
| RibbonSlider | 支持水平或垂直放置的滑动控制条 |  |
|
||||
| RibbonIcon | 图标组件,内置图标数百个来自微软的精美图标 |  |
|
||||
| RibbonText | 文字组件,可以允许/禁止选中文字或复制 |  |
|
||||
| RibbonCheckBox | 选择框组件,可自定义是否显示文字、文字显示位置(左/右) |  |
|
||||
| RibbonSwitchButton | 开关按钮,支持自定义背景颜色、是否显示提示文字或按钮文字,可自由调整文字显示位置(左/右) |  |
|
||||
| RibbonTheme | 主题支持浅色、深色、跟随系统三种模式 |  |
|
||||
| RibbonMenu | 菜单组件,支持二元选择及子菜单 |  |
|
||||
| RibbonPopup | 自动居中的弹出式窗口 |  |
|
||||
| RibbonPopDialog | 支持二元或三元选择的弹出式窗口 |  |
|
||||
| RibbonLineEdit | 支持设置图标和一键清除的单行文本输入控件 |  |
|
||||
| RibbonTextEdit | 支持设置图标和一键清除的多行文本输入控件,可随文本输入自动换行/滚动 |  |
|
||||
| RibbonTextEdit | 支持设置图标和一键清除的多行文本输入控件,可随文本输入自动换行/滚动 |  |
|
||||
| RibbonComboBox | 支持设置图标的下拉菜单选择控件,菜单支持用户输入添加 |  |
|
||||
| RibbonSpinBox | 支持设置图标的旋钮控件 |  |
|
||||
| RibbonSpinBox | 支持设置图标的旋钮控件 |  |
|
||||
| RibbonView | 与TabBar和BottomBar搭配使用的可滑动组件,两组件模糊化的背景均来源于它 |  |
|
||||
| RibbonPaperView | 类似Word中纸张的组件 |  |
|
||||
|
||||
其他组件的介绍会陆续更新。
|
||||
|
||||
## 3. 支持平台
|
||||
目前是基于Qt 6 设计的,之后有时间会加入Qt 5的支持, ***因此目前仅支持Qt 6支持的平台***。
|
||||
### Qt 6 分支 (main 分支)
|
||||
+ Windows: Windows 10 (1809+), Windows 11.(X86/AMD64, aarch64)
|
||||
+ macOS: macOS 11+.(AMD64, aarch64)
|
||||
+ Linux: Ubuntu 22.04+ (X86/AMD64)
|
||||
### Qt 5 分支 (***TODO***)
|
||||
+ Windows: Windows 7+.(X86/AMD64)
|
||||
+ macOS: MacOS X 10.13 - 10.15, macOS 11+.(AMD64, aarch64)
|
||||
+ Linux: Ubuntu 18.04+ (X86/AMD64)
|
||||
|
||||
## 4. 如何使用?
|
||||
+ 安装前准备
|
||||
|
||||
安装Qt 6,推荐通过官方在线安装器安装**Qt 6.6.3版本**,**通过brew等方式安装可能会出现问题**。**Qt Quick相关模块**和**qt5compat qtshadertools qtimageformats**组件是必要的。
|
||||
|
||||
+ 编译例程和库
|
||||
- 下载仓库并进入
|
||||
```shell
|
||||
git clone https://github.com/mentalfl0w/RibbonUI.git --recursive
|
||||
cd RibbonUI
|
||||
```
|
||||
- 创建并进入build文件夹
|
||||
```shell
|
||||
mkdir build
|
||||
cd build
|
||||
```
|
||||
- 编译
|
||||
```shell
|
||||
# 如果想进行Debug编译, 请配置 -DCMAKE_BUILD_TYPE=Debug和--config Debug参数
|
||||
# 如果想编译静态库, 请在cmake参数中加入-DRIBBONUI_BUILD_STATIC_LIB=ON
|
||||
cmake -DCMAKE_MESSAGE_LOG_LEVEL=STATUS -DCMAKE_PREFIX_PATH=/Users/runner/work/RibbonUI/Qt/6.6.3/macos -DCMAKE_C_COMPILER=clang -DCMAKE_CXX_COMPILER=clang++ -DCMAKE_BUILD_TYPE=Release -GNinja ..
|
||||
# -DCMAKE_PREFIX_PATH={你的Qt安装目录}
|
||||
cmake --build . --target all --config Release --parallel
|
||||
```
|
||||
+ 在其他项目中使用RibbonUI
|
||||
- 遵循***编译例程和库***的下载仓库和进入build目录步骤
|
||||
- 在CMakeLists.txt中加入以下语句
|
||||
```camke
|
||||
add_subdirectory(RibbonUI) # RibbonUI在你文件系统中的相对路径
|
||||
```
|
||||
- 编译
|
||||
```shell
|
||||
# 如果想进行Debug编译, 请配置 -DCMAKE_BUILD_TYPE=Debug和--config Debug参数
|
||||
# 如果想编译静态库, 请在cmake参数中加入-DRIBBONUI_BUILD_STATIC_LIB=ON
|
||||
cmake -DCMAKE_MESSAGE_LOG_LEVEL=STATUS -DCMAKE_PREFIX_PATH=/Users/runner/work/RibbonUI/Qt/6.6.3/macos -DCMAKE_C_COMPILER=clang -DCMAKE_CXX_COMPILER=clang++ -DCMAKE_BUILD_TYPE=Release -DRIBBONUI_BUILD_EXAMPLES=OFF -GNinja ..
|
||||
# -DCMAKE_PREFIX_PATH={你的Qt安装目录}
|
||||
cmake --build . --target all --config Release --parallel
|
||||
```
|
||||
|
||||
## 5. 鸣谢
|
||||
+ 感谢[@wangwenx190](https://github.com/wangwenx190)的[framelesshelper](https://github.com/wangwenx190/framelesshelper)让RibbonWindow能实现无边框。
|
||||
+ [@Microsoft](https://github.com/microsoft)的[fluentui-system-icons](https://github.com/microsoft/fluentui-system-icons)提供的漂亮图标库.
|
||||
+ 感谢[@zhuzichu520](https://github.com/zhuzichu520)的[FluentUI](https://github.com/zhuzichu520/FluentUI) 为我提供的灵感和参考。
|
||||
|
||||
## 6. 与我联系
|
||||
+ Email: mentalflow@ourdocs.cn
|
||||
+ Blog: [菜鸟技术猿的折腾史.](https://blog.ourdocs.cn)
|
||||
+ ***欢迎发起PR或Issues,我会在空余时间尽快完善功能或修复bug,希望能一起让RibbonUI变得更好,尽情享受吧🎉!***
|
|
@ -0,0 +1,126 @@
|
|||
# RibbonUI
|
||||
|
||||
<div align="center">
|
||||
<img src="lib_source/resources/imgs/icon.png" alt="Logo" style="width:40%; height:auto;">
|
||||
</div>
|
||||
<h1 align="center">Qt RibbonUI </h1>
|
||||
|
||||
- [RibbonUI](#ribbonui)
|
||||
- [1. Introduction](#1-introduction)
|
||||
- [2. Included Components](#2-included-components)
|
||||
- [3. Supported platforms](#3-supported-platforms)
|
||||
- [Qt 6 branch (main branch)](#qt-6-branch-main-branch)
|
||||
- [Qt 5 branch (***TODO***)](#qt-5-branch-todo)
|
||||
- [4. How to use it?](#4-how-to-use-it)
|
||||
- [5. Acknowledgement](#5-acknowledgement)
|
||||
- [6. Get in touch with me](#6-get-in-touch-with-me)
|
||||
|
||||
|
||||
## 1. Introduction
|
||||
RibbonUI is a lightweight, minimalist and elegant Qt component library written in QML and designed with reference to the Microsoft Ribbon style.
|
||||
|
||||
***[点击查看中文文档](README(zh-cn).md)***
|
||||
|
||||
<div align="center">
|
||||
<div align="center">
|
||||
<img src="documents/pictures/home-light-classic.png" alt="Home Light Classic" style="width:45%; height:auto;">
|
||||
<img src="documents/pictures/home-dark-classic.png" alt="Home Light Classic" style="width:45%; height:auto;">
|
||||
</div>
|
||||
<p align="center">Home Light/Dark Theme (Classic Style) </p>
|
||||
</div>
|
||||
<div align="center">
|
||||
<div align="center">
|
||||
<img src="documents/pictures/home-light-modern.png" alt="Home Light Modern" style="width:45%; height:auto;">
|
||||
<img src="documents/pictures/home-dark-modern.png" alt="Home Light Modern" style="width:45%; height:auto;">
|
||||
</div>
|
||||
<p align="center">Home Light/Dark Theme (Modern Style) </p>
|
||||
</div>
|
||||
|
||||
## 2. Included Components
|
||||
Currently supports ***30*** components, more will be added later.
|
||||
| Components | Introduction | Demo Picture|
|
||||
|:----:|:----:|:----:|
|
||||
| RibbonWindow | A Window component that relies on framelesshelper to support exit confirmation popups and blur style backgrounds. ||
|
||||
| RibbonTabBar | A toolbar with support for page switching and retracting, and support for placing customized buttons in the upper right corner, just like Microsoft Word's. |  |
|
||||
| RibbonTitleBar | A window title bar that supports custom colors and the free addition of secondary buttons, with different designs for Windows and macOS. |  |
|
||||
| RibbonBottomBar | A bottom bar that supports adding custom tools. | |
|
||||
| RibbonBlur | Provides blurring effects for various components |  |
|
||||
| RibbonButton | A button that supports plain text/plain icons/icons and text with/without backgrounds, with mouse overlay support for displaying alert messages |  |
|
||||
| RibbonPushButton | A large icon button that supports pop-up menus, either using the built-in icon library or a user-selected image |  |
|
||||
| RibbonSlider | Support for horizontally or vertically placed slider |  |
|
||||
| RibbonIcon | Icon component, built-in hundreds of beautiful icons from Microsoft |  |
|
||||
| RibbonText | Text component that allows/disallows selection of text or copying |  |
|
||||
| RibbonCheckBox | Checkbox component, customizable whether to display text, where to display text (left/right) |  |
|
||||
| RibbonSwitchButton | Switch button, support for customizing the background color, whether to display the prompt text or button text, free to adjust the text display position (left/right) |  |
|
||||
| RibbonTheme | Theme support light color, dark color, follow system three modes |  |
|
||||
| RibbonMenu | Menu component with binary selection and submenu support |  |
|
||||
| RibbonPopup | Auto-centered pop-ups |  |
|
||||
| RibbonPopDialog | Popups supporting binary or ternary selection |  |
|
||||
| RibbonLineEdit | Single-line text input control with support for icons and one-click clearing |  |
|
||||
| RibbonTextEdit | Multi-line text input control with support for icons and one-click clearing, automatic line feed/scrolling as text is entered |  |
|
||||
| RibbonComboBox | Supports drop-down menu selection controls with icons, and menus can be added with user input. |  |
|
||||
| RibbonSpinBox | SpinBox with support for setting icons |  |
|
||||
| RibbonView | Slidable component for use with TabBar and BottomBar, from which the blurred backgrounds of both components are derived. |  |
|
||||
| RibbonPaperView | Components similar to paper in Word |  |
|
||||
|
||||
***The introduction of other components will be updated later.***
|
||||
|
||||
## 3. Supported platforms
|
||||
The current design is based on Qt 6, and support for Qt 5 will be added sometime later, ***so the current support list is consistent with Qt 6***.
|
||||
### Qt 6 branch (main branch)
|
||||
+ Windows: Windows 10 (1809+), Windows 11.(X86/AMD64, aarch64)
|
||||
+ macOS: macOS 11+.(AMD64, aarch64)
|
||||
+ Linux: Ubuntu 22.04+ (X86/AMD64)
|
||||
### Qt 5 branch (***TODO***)
|
||||
+ Windows: Windows 7+.(X86/AMD64)
|
||||
+ macOS: MacOS X 10.13 - 10.15, macOS 11+.(AMD64, aarch64)
|
||||
+ Linux: Ubuntu 18.04+ (X86/AMD64)
|
||||
|
||||
## 4. How to use it?
|
||||
+ Before Install
|
||||
|
||||
To install Qt 6, it is recommended to install the **Qt 6.6.3** version via the official online installer, **installing via brew, etc. may cause problems**. **Qt Quick related modules** and the **qt5compat qtshadertools qtimageformats** component are required
|
||||
|
||||
+ Compile the example and library
|
||||
- Clone and enter the library folder
|
||||
```shell
|
||||
git clone https://github.com/mentalfl0w/RibbonUI.git --recursive
|
||||
cd RibbonUI
|
||||
```
|
||||
- Create and enter the build folder
|
||||
```shell
|
||||
mkdir build
|
||||
cd build
|
||||
```
|
||||
- Build
|
||||
```shell
|
||||
# if you want to make a Debug build, just let -DCMAKE_BUILD_TYPE=Debug, --config Debug
|
||||
# if you want a static build, add -DRIBBONUI_BUILD_STATIC_LIB=ON into command
|
||||
cmake -DCMAKE_MESSAGE_LOG_LEVEL=STATUS -DCMAKE_PREFIX_PATH=/Users/runner/work/RibbonUI/Qt/6.6.3/macos -DCMAKE_C_COMPILER=clang -DCMAKE_CXX_COMPILER=clang++ -DCMAKE_BUILD_TYPE=Release -GNinja ..
|
||||
# -DCMAKE_PREFIX_PATH={YOUR QT INSTALL FOLDER}
|
||||
cmake --build . --target all --config Release --parallel
|
||||
```
|
||||
+ Use library with other project
|
||||
- Follow the same steps like clone and enter build folder as ***Compile the example and library***
|
||||
- Add the following code to your CMakeLists.txt
|
||||
```camke
|
||||
add_subdirectory(RibbonUI) # RibbonUI's path in your project file system
|
||||
```
|
||||
- Build
|
||||
```shell
|
||||
# if you want to make a Debug build, just let -DCMAKE_BUILD_TYPE=Debug, --config Debug
|
||||
# if you want a static build, add -DRIBBONUI_BUILD_STATIC_LIB=ON into command
|
||||
cmake -DCMAKE_MESSAGE_LOG_LEVEL=STATUS -DCMAKE_PREFIX_PATH=/Users/runner/work/RibbonUI/Qt/6.6.3/macos -DCMAKE_C_COMPILER=clang -DCMAKE_CXX_COMPILER=clang++ -DCMAKE_BUILD_TYPE=Release -DRIBBONUI_BUILD_EXAMPLES=OFF -GNinja ..
|
||||
# -DCMAKE_PREFIX_PATH={YOUR QT INSTALL FOLDER}
|
||||
cmake --build . --target all --config Release --parallel
|
||||
```
|
||||
|
||||
## 5. Acknowledgement
|
||||
+ [@wangwenx190](https://github.com/wangwenx190)'s [framelesshelper](https://github.com/wangwenx190/framelesshelper) for frameless window (aka RibbonWindow's base).
|
||||
+ [@Microsoft](https://github.com/microsoft)'s [fluentui-system-icons](https://github.com/microsoft/fluentui-system-icons) for beautifully designed icons.
|
||||
+ [@zhuzichu520](https://github.com/zhuzichu520)'s [FluentUI](https://github.com/zhuzichu520/FluentUI) for inspiration and reference.
|
||||
|
||||
## 6. Get in touch with me
|
||||
+ Email: mentalflow@ourdocs.cn
|
||||
+ Blog: [The Tossed History of a Rookie Technician.](https://blog.ourdocs.cn)
|
||||
+ ***And PRs and Issues are welcome, I'll try to improve features or fix bugs as soon as I can in my spare time, let's make RibbonUI better together, enjoy!***
|
After Width: | Height: | Size: 272 KiB |
After Width: | Height: | Size: 46 KiB |
After Width: | Height: | Size: 70 KiB |
After Width: | Height: | Size: 26 KiB |
After Width: | Height: | Size: 30 KiB |
After Width: | Height: | Size: 193 KiB |
After Width: | Height: | Size: 34 KiB |
After Width: | Height: | Size: 64 KiB |
After Width: | Height: | Size: 154 KiB |
After Width: | Height: | Size: 102 KiB |
After Width: | Height: | Size: 26 KiB |
After Width: | Height: | Size: 38 KiB |
After Width: | Height: | Size: 25 KiB |
After Width: | Height: | Size: 17 KiB |
After Width: | Height: | Size: 41 KiB |
After Width: | Height: | Size: 199 KiB |
After Width: | Height: | Size: 28 KiB |
After Width: | Height: | Size: 35 KiB |
After Width: | Height: | Size: 18 KiB |
After Width: | Height: | Size: 31 KiB |
After Width: | Height: | Size: 502 KiB |
After Width: | Height: | Size: 518 KiB |
After Width: | Height: | Size: 669 KiB |
After Width: | Height: | Size: 550 KiB |
After Width: | Height: | Size: 630 KiB |
|
@ -0,0 +1,45 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>CFBundleInfoDictionaryVersion</key>
|
||||
<string>6.0</string>
|
||||
<key>CFBundlePackageType</key>
|
||||
<string>APPL</string>
|
||||
|
||||
<key>CFBundleName</key>
|
||||
<string>${MACOSX_BUNDLE_BUNDLE_NAME}</string>
|
||||
<key>CFBundleIdentifier</key>
|
||||
<string>${MACOSX_BUNDLE_GUI_IDENTIFIER}</string>
|
||||
<key>CFBundleExecutable</key>
|
||||
<string>${MACOSX_BUNDLE_EXECUTABLE_NAME}</string>
|
||||
|
||||
<key>CFBundleVersion</key>
|
||||
<string>${MACOSX_BUNDLE_BUNDLE_VERSION}</string>
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>${MACOSX_BUNDLE_SHORT_VERSION_STRING}</string>
|
||||
|
||||
<key>LSMinimumSystemVersion</key>
|
||||
<string>${CMAKE_OSX_DEPLOYMENT_TARGET}</string>
|
||||
|
||||
<key>NSHumanReadableCopyright</key>
|
||||
<string>${MACOSX_BUNDLE_COPYRIGHT}</string>
|
||||
|
||||
<key>CFBundleIconFile</key>
|
||||
<string>${MACOSX_BUNDLE_ICON_FILE}</string>
|
||||
|
||||
<key>CFBundleDevelopmentRegion</key>
|
||||
<string>${MACOSX_BUNDLE_DEVELOPMENT_REGION}</string>
|
||||
<key>CFBundleAllowMixedLocalizations</key>
|
||||
<true/>
|
||||
|
||||
<key>NSHighResolutionCapable</key>
|
||||
<true/>
|
||||
|
||||
<key>NSPrincipalClass</key>
|
||||
<string>NSApplication</string>
|
||||
|
||||
<key>NSSupportsAutomaticGraphicsSwitching</key>
|
||||
<true/>
|
||||
</dict>
|
||||
</plist>
|
|
@ -0,0 +1,37 @@
|
|||
#include <windows.h>
|
||||
|
||||
IDI_ICON1 ICON "${PROJECT_SOURCE_DIR}/resources/imgs/icon.ico"
|
||||
|
||||
VS_VERSION_INFO VERSIONINFO
|
||||
FILEVERSION ${version_str}
|
||||
PRODUCTVERSION ${version_str}
|
||||
FILEFLAGSMASK 0x3fL
|
||||
#ifdef _DEBUG
|
||||
FILEFLAGS VS_FF_DEBUG
|
||||
#else
|
||||
FILEFLAGS 0x0L
|
||||
#endif
|
||||
FILEOS VOS_NT_WINDOWS32
|
||||
FILETYPE VFT_APP
|
||||
FILESUBTYPE VFT2_UNKNOWN
|
||||
BEGIN
|
||||
BLOCK "StringFileInfo"
|
||||
BEGIN
|
||||
BLOCK "040904b0"
|
||||
BEGIN
|
||||
VALUE "Comments", "Made by Mentalflow."
|
||||
VALUE "CompanyName", "${PROJECT_COMPANY}"
|
||||
VALUE "FileDescription", "${PROJECT_BUNDLE_NAME}"
|
||||
VALUE "FileVersion", "${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR}.${PROJECT_VERSION_PATCH}"
|
||||
VALUE "InternalName", "${PROJECT_BUNDLE_NAME}.exe"
|
||||
VALUE "LegalCopyright", "${PROJECT_COPYRIGHT}"
|
||||
VALUE "OriginalFilename", "${PROJECT_BUNDLE_NAME}.exe"
|
||||
VALUE "ProductName", "${PROJECT_BUNDLE_NAME}"
|
||||
VALUE "ProductVersion", "${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR}.${PROJECT_VERSION_PATCH}"
|
||||
END
|
||||
END
|
||||
BLOCK "VarFileInfo"
|
||||
BEGIN
|
||||
VALUE "Translation", 0x409, 1200
|
||||
END
|
||||
END
|
|
@ -0,0 +1,134 @@
|
|||
cmake_minimum_required(VERSION 3.21)
|
||||
|
||||
project(RibbonUIAPP VERSION ${PROJECT_VERSION} LANGUAGES CXX)
|
||||
|
||||
set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
||||
|
||||
list(APPEND CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/.cmake/)
|
||||
|
||||
if(QT_VERSION VERSION_GREATER_EQUAL "6.3")
|
||||
qt_standard_project_setup()
|
||||
qt_policy(SET QTP0001 NEW)
|
||||
else()
|
||||
set(CMAKE_AUTOMOC ON)
|
||||
set(CMAKE_AUTORCC ON)
|
||||
set(CMAKE_AUTOUIC ON)
|
||||
endif()
|
||||
|
||||
if(APPLE)
|
||||
set(CMAKE_OSX_ARCHITECTURES "arm64;x86_64" CACHE STRING "" FORCE)
|
||||
endif()
|
||||
|
||||
string(TIMESTAMP TIME_YEAR %Y)
|
||||
set(PROJECT_COMPANY "Mentalflow's Lab")
|
||||
set(PROJECT_COPYRIGHT "Copyright (c) ${TIME_YEAR} Mentalflow's Lab. All rights reserved.")
|
||||
set(PROJECT_DOMAIN "dev.ourdocs.cn.ribbonuiapp")
|
||||
set(PROJECT_BUNDLE_NAME RibbonUI-APP)
|
||||
|
||||
set(version_str "${PROJECT_VERSION_MAJOR},${PROJECT_VERSION_MINOR},${PROJECT_VERSION_PATCH}")
|
||||
add_definitions(-DRIBBONUIAPP_VERSION=${version_str})
|
||||
|
||||
find_package(Qt6 COMPONENTS Quick REQUIRED)
|
||||
|
||||
set(sources_files example.cpp)
|
||||
|
||||
if(CMAKE_BUILD_TYPE STREQUAL "Debug")
|
||||
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/app/debug)
|
||||
else()
|
||||
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/app/release)
|
||||
endif()
|
||||
|
||||
if (WIN32)
|
||||
configure_file(.cmake/win_app.rc.in ${CMAKE_BINARY_DIR}/win_app.rc)
|
||||
set(app_icon_resource_windows ${CMAKE_BINARY_DIR}/win_app.rc)
|
||||
qt_add_executable(${PROJECT_NAME}
|
||||
${sources_files}
|
||||
${app_icon_resource_windows}
|
||||
)
|
||||
file(TO_CMAKE_PATH "/" PATH_SEPARATOR)
|
||||
if(MSVC)
|
||||
set(DLLPATH ${CMAKE_SOURCE_DIR}/3rdparty/msvc/*.dll)
|
||||
else()
|
||||
set(DLLPATH ${CMAKE_SOURCE_DIR}/3rdparty/mingw/*.dll)
|
||||
endif()
|
||||
string(REPLACE "/" ${PATH_SEPARATOR} DLLPATH "${DLLPATH}")
|
||||
file(GLOB DLL_FILES ${DLLPATH})
|
||||
add_custom_command(TARGET ${PROJECT_NAME} POST_BUILD
|
||||
COMMAND ${CMAKE_COMMAND} -E copy
|
||||
${DLL_FILES}
|
||||
${CMAKE_RUNTIME_OUTPUT_DIRECTORY}
|
||||
)
|
||||
elseif(APPLE)
|
||||
set(MACOSX_BUNDLE_GUI_IDENTIFIER ${PROJECT_DOMAIN})
|
||||
set(MACOSX_BUNDLE_BUNDLE_VERSION ${PROJECT_VERSION})
|
||||
set(MACOSX_BUNDLE_SHORT_VERSION_STRING ${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR})
|
||||
set(MACOSX_BUNDLE_BUNDLE_NAME ${PROJECT_BUNDLE_NAME})
|
||||
set(MACOSX_BUNDLE_COPYRIGHT ${PROJECT_COPYRIGHT})
|
||||
set(MACOSX_BUNDLE_DEVELOPMENT_REGION "Chinese")
|
||||
set(CMAKE_OSX_DEPLOYMENT_TARGET "11.0" CACHE STRING "Minimum OS X deployment version" FORCE)
|
||||
set(MACOSX_BUNDLE_EXECUTABLE_NAME ${PROJECT_BUNDLE_NAME})
|
||||
set(MACOSX_BUNDLE_ICON_FILE AppIcon)
|
||||
configure_file(.cmake/MacOSXBundleInfo.plist.in ${CMAKE_BINARY_DIR}/Info.plist)
|
||||
set(App_ICON "${PROJECT_SOURCE_DIR}/resources/imgs/AppIcon.icns")
|
||||
set_source_files_properties(${App_ICON} PROPERTIES MACOSX_PACKAGE_LOCATION "Resources")
|
||||
qt_add_executable(${PROJECT_NAME}
|
||||
${sources_files}
|
||||
${App_ICON}
|
||||
)
|
||||
else()
|
||||
qt_add_executable(${PROJECT_NAME}
|
||||
${sources_files}
|
||||
)
|
||||
endif()
|
||||
|
||||
qt_add_qml_module(${PROJECT_NAME}
|
||||
URI ${PROJECT_NAME}
|
||||
VERSION ${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR}
|
||||
RESOURCE_PREFIX "/qt/qml/"
|
||||
QML_FILES example.qml about.qml components/RibbonMessageListViewExample.qml
|
||||
RESOURCES resources/imgs/heart.png resources/imgs/search.png
|
||||
)
|
||||
|
||||
set_target_properties(${PROJECT_NAME} PROPERTIES
|
||||
MACOSX_BUNDLE_INFO_PLIST ${CMAKE_BINARY_DIR}/Info.plist
|
||||
MACOSX_BUNDLE TRUE
|
||||
WIN32_EXECUTABLE TRUE
|
||||
OUTPUT_NAME ${PROJECT_BUNDLE_NAME}
|
||||
)
|
||||
|
||||
if(RIBBONUI_BUILD_STATIC_LIB)
|
||||
target_link_libraries(${PROJECT_NAME} PRIVATE
|
||||
RibbonUIplugin
|
||||
)
|
||||
target_compile_definitions(${PROJECT_NAME} PRIVATE
|
||||
RIBBONUI_BUILD_STATIC_LIB
|
||||
)
|
||||
else()
|
||||
if(WIN32)
|
||||
if (MINGW)
|
||||
add_custom_command(TARGET ${PROJECT_NAME} POST_BUILD
|
||||
COMMAND ${CMAKE_COMMAND} -E copy_if_different
|
||||
"${RIBBONUI_QML_PLUGIN_DIRECTORY}/RibbonUI.dll"
|
||||
${CMAKE_RUNTIME_OUTPUT_DIRECTORY})
|
||||
else()
|
||||
if (NOT RIBBONUI_BUILD_STATIC_LIB)
|
||||
if (CMAKE_BUILD_TYPE MATCHES "Debug")
|
||||
set(DEBUG_POSTFIX "d")
|
||||
endif()
|
||||
add_custom_command(TARGET ${PROJECT_NAME} POST_BUILD
|
||||
COMMAND ${CMAKE_COMMAND} -E copy_if_different
|
||||
"${RIBBONUI_QML_PLUGIN_DIRECTORY}/RibbonUI${DEBUG_POSTFIX}.dll"
|
||||
${CMAKE_RUNTIME_OUTPUT_DIRECTORY})
|
||||
endif()
|
||||
endif()
|
||||
endif()
|
||||
endif()
|
||||
|
||||
target_link_libraries(${PROJECT_NAME} PRIVATE
|
||||
Qt::Quick
|
||||
RibbonUI
|
||||
)
|
||||
|
||||
target_compile_definitions(${PROJECT_NAME} PRIVATE $<$<OR:$<CONFIG:Debug>,$<CONFIG:RelWithDebInfo>>:QT_QML_DEBUG>)
|
||||
target_include_directories(${PROJECT_NAME} PUBLIC ${PROJECT_SOURCE_DIR})
|
||||
|
|
@ -0,0 +1,46 @@
|
|||
import QtQuick
|
||||
import QtQuick.Layouts
|
||||
import QtQuick.Controls
|
||||
import RibbonUI
|
||||
|
||||
RibbonWindow {
|
||||
id: window
|
||||
width: Math.max(content.width, content.height + title_bar.height, title_bar.minimumWidth) + content.anchors.margins * 2
|
||||
minimumWidth: title_bar.minimumWidth
|
||||
minimumHeight: content.height + title_bar.height + content.anchors.margins * 2
|
||||
title: qsTr("About")
|
||||
title_bar.show_darkmode_btn: false
|
||||
title_bar.show_style_switch: false
|
||||
windowStatus: RibbonWindow.Status.SingleInstance
|
||||
|
||||
ColumnLayout{
|
||||
id: content
|
||||
anchors{
|
||||
centerIn: parent
|
||||
margins: 10
|
||||
}
|
||||
spacing: 5
|
||||
Image {
|
||||
source: "qrc:/qt/qml/RibbonUI/resources/imgs/icon.png"
|
||||
fillMode:Image.PreserveAspectFit
|
||||
Layout.preferredHeight: 120
|
||||
Layout.preferredWidth: height
|
||||
Layout.alignment: Qt.AlignHCenter
|
||||
layer.enabled: true
|
||||
layer.effect: RibbonShadow{}
|
||||
}
|
||||
RibbonText{
|
||||
Layout.alignment: Qt.AlignHCenter
|
||||
text: "RibbonUI"
|
||||
font.pixelSize: 16
|
||||
}
|
||||
RibbonText{
|
||||
Layout.alignment: Qt.AlignHCenter
|
||||
text: `©${new Date().getFullYear()} mentalfl0w`
|
||||
}
|
||||
RibbonText{
|
||||
Layout.alignment: Qt.AlignHCenter
|
||||
text: `Version: V${RibbonUI.version}`
|
||||
}
|
||||
}
|
||||
}
|
60
KGCAPP/3rdparty/RibbonUI/example/components/RibbonMessageListViewExample.qml
vendored
Normal file
|
@ -0,0 +1,60 @@
|
|||
import QtQuick
|
||||
import QtQuick.Layouts
|
||||
import QtQuick.Controls
|
||||
import RibbonUI
|
||||
|
||||
Item {
|
||||
id: root
|
||||
implicitHeight: layout.height + layout.anchors.margins * 2
|
||||
implicitWidth: 500
|
||||
ColumnLayout{
|
||||
id: layout
|
||||
width: parent.width - anchors.margins * 2
|
||||
anchors.centerIn: parent
|
||||
anchors.margins: 30
|
||||
RibbonText{
|
||||
Layout.alignment: Qt.AlignHCenter
|
||||
text: qsTr("Message List View Example")
|
||||
font.pixelSize: 20
|
||||
}
|
||||
RibbonMessageListView{
|
||||
id: view
|
||||
auto_scroll_to_bottom: true
|
||||
Layout.preferredHeight: 500
|
||||
Layout.preferredWidth: parent.width
|
||||
delegate: RibbonMessage{
|
||||
id: msg
|
||||
sender_text: `${model.time} ${model.recieved ? qsTr('Recieved') : qsTr('Sent')}`
|
||||
RibbonText{
|
||||
font.pixelSize: msg.font_size
|
||||
color: RibbonTheme.dark_mode ? "white" : !model.recieved ? "white" : "black"
|
||||
text: model.text ? model.text : ""
|
||||
visible: model.text ? true : false
|
||||
Layout.preferredWidth: implicitWidth < (view.width / 2 - padding) ? implicitWidth : (view.width / 2 - padding)
|
||||
wrapMode: RibbonText.Wrap
|
||||
}
|
||||
}
|
||||
}
|
||||
RowLayout{
|
||||
Layout.alignment: Qt.AlignHCenter
|
||||
RibbonButton{
|
||||
icon_source: RibbonIcons.AddCircle
|
||||
text: qsTr('Add Message')
|
||||
onClicked: {
|
||||
view.message_model.append({
|
||||
time: Qt.formatDateTime(new Date(), "yyyy-MM-dd hh:mm:ss.zzz"),
|
||||
text: String(Math.random()*10),
|
||||
recieved: (Math.floor(Math.random()*10))%2===0,
|
||||
})
|
||||
}
|
||||
}
|
||||
RibbonButton{
|
||||
icon_source: RibbonIcons.DismissCircle
|
||||
text: qsTr('Clear Message')
|
||||
onClicked: {
|
||||
view.message_model.clear()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,24 @@
|
|||
#include <QGuiApplication>
|
||||
#include <QQmlApplicationEngine>
|
||||
#include <QtQml/qqmlextensionplugin.h>
|
||||
#include "ribbonui.h"
|
||||
|
||||
#ifdef RIBBONUI_BUILD_STATIC_LIB
|
||||
Q_IMPORT_QML_PLUGIN(RibbonUIPlugin)
|
||||
#endif
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
RibbonUI::init(); // Must set before QGuiApplication
|
||||
QGuiApplication app(argc, argv);
|
||||
QQmlApplicationEngine engine;
|
||||
RibbonUI::registerTypes(&engine);
|
||||
const QUrl url(u"qrc:/qt/qml/RibbonUIAPP/example.qml"_qs);
|
||||
QObject::connect(&engine, &QQmlApplicationEngine::objectCreated,
|
||||
&app, [url](QObject *obj, const QUrl &objUrl) {
|
||||
if (!obj && url == objUrl)
|
||||
QCoreApplication::exit(-1);
|
||||
}, Qt::QueuedConnection);
|
||||
engine.load(url);
|
||||
|
||||
return app.exec();
|
||||
}
|
|
@ -0,0 +1,766 @@
|
|||
import QtQuick
|
||||
import QtQuick.Layouts
|
||||
import QtQuick.Controls
|
||||
import RibbonUI
|
||||
|
||||
RibbonWindow {
|
||||
id:root
|
||||
width: 1200
|
||||
height: 800
|
||||
title: qsTr("RibbonUI APP")
|
||||
comfirmed_quit: true
|
||||
property bool modern_style: RibbonTheme.modern_style
|
||||
RibbonTabBar {
|
||||
id: tab_bar
|
||||
modern_style: root.modern_style
|
||||
right_tool_bar: RowLayout{
|
||||
spacing: 10
|
||||
RibbonButton{
|
||||
text:"Test Button 1"
|
||||
icon_source: RibbonIcons.Alert
|
||||
checkable: true
|
||||
}
|
||||
RibbonButton{
|
||||
text:"Test Button 2"
|
||||
}
|
||||
}
|
||||
|
||||
RibbonTabPage{
|
||||
id: basic_page
|
||||
title: qsTr("Basic")
|
||||
RibbonTabGroup{
|
||||
width: slider_layout.width + 20
|
||||
text: qsTr("Slider")
|
||||
RowLayout{
|
||||
id: slider_layout
|
||||
anchors.centerIn: parent
|
||||
height: parent.height
|
||||
spacing: 0
|
||||
RibbonSlider{
|
||||
Layout.alignment: Qt.AlignVCenter
|
||||
slide_width: 40
|
||||
horizontal: false
|
||||
value: 20
|
||||
}
|
||||
RibbonSlider{
|
||||
Layout.alignment: Qt.AlignVCenter
|
||||
slide_width: 40
|
||||
horizontal: false
|
||||
show_button: false
|
||||
value: 40
|
||||
}
|
||||
ColumnLayout{
|
||||
spacing: 0
|
||||
Layout.alignment: Qt.AlignVCenter
|
||||
RibbonSlider{
|
||||
Layout.alignment: Qt.AlignHCenter
|
||||
slide_width: 40
|
||||
value: 60
|
||||
}
|
||||
RibbonSlider{
|
||||
Layout.alignment: Qt.AlignHCenter
|
||||
slide_width: 40
|
||||
show_button: false
|
||||
value: 80
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
RibbonTabGroup{
|
||||
width: switch_layout.width + 30
|
||||
text: qsTr("Switch Button")
|
||||
RowLayout{
|
||||
id: switch_layout
|
||||
anchors.centerIn: parent
|
||||
height: parent.height
|
||||
spacing: 0
|
||||
ColumnLayout{
|
||||
spacing: 5
|
||||
RibbonSwitchButton{
|
||||
text: "Button"
|
||||
grabber_checked_color: "red"
|
||||
checked: true
|
||||
}
|
||||
RibbonSwitchButton{
|
||||
text: "Button"
|
||||
text_on_left: true
|
||||
grabber_checked_color: "orange"
|
||||
checked: true
|
||||
}
|
||||
RibbonSwitchButton{
|
||||
grabber_checked_color: "blue"
|
||||
}
|
||||
}
|
||||
ColumnLayout{
|
||||
spacing: 5
|
||||
RibbonSwitchButton{
|
||||
text: "Button"
|
||||
show_grabber_text: false
|
||||
grabber_checked_color: "green"
|
||||
}
|
||||
RibbonSwitchButton{
|
||||
text: "Button"
|
||||
show_grabber_text: false
|
||||
text_on_left: true
|
||||
grabber_checked_color: "indigo"
|
||||
checked: true
|
||||
}
|
||||
RibbonSwitchButton{
|
||||
show_grabber_text: false
|
||||
grabber_checked_color: "yellow"
|
||||
checked: true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
RibbonTabGroup{
|
||||
width: checkbox_layout.width + 30
|
||||
text: qsTr("CheckBox")
|
||||
RowLayout{
|
||||
id: checkbox_layout
|
||||
anchors.centerIn: parent
|
||||
height: parent.height
|
||||
spacing: 0
|
||||
ColumnLayout{
|
||||
spacing: 10
|
||||
RibbonCheckBox{
|
||||
text: "CheckBox"
|
||||
icon_filled_bg_color: "blue"
|
||||
checked: true
|
||||
}
|
||||
RibbonCheckBox{
|
||||
text: "CheckBox"
|
||||
text_on_left: true
|
||||
icon_filled_bg_color: "red"
|
||||
}
|
||||
RowLayout{
|
||||
spacing: 30
|
||||
RibbonCheckBox{
|
||||
icon_filled_bg_color:"orange"
|
||||
tip_text: "CheckBox"
|
||||
show_tooltip: true
|
||||
checked: true
|
||||
}
|
||||
RibbonCheckBox{
|
||||
icon_filled_bg_color:"purple"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
RibbonTabGroup{
|
||||
width: button_layout.width + 30
|
||||
text: qsTr("Button")
|
||||
RowLayout{
|
||||
id: button_layout
|
||||
anchors.centerIn: parent
|
||||
height: parent.height
|
||||
spacing: 1
|
||||
ColumnLayout{
|
||||
spacing: 10
|
||||
RibbonButton{
|
||||
text:"Button"
|
||||
icon_source: RibbonIcons.Accessibility
|
||||
checkable: true
|
||||
}
|
||||
RibbonButton{
|
||||
text:"Button"
|
||||
}
|
||||
RibbonButton{
|
||||
text:"Button"
|
||||
show_tooltip: false
|
||||
}
|
||||
}
|
||||
ColumnLayout{
|
||||
spacing: 10
|
||||
RibbonButton{
|
||||
text:"Button"
|
||||
show_bg:false
|
||||
icon_source: RibbonIcons.Beaker
|
||||
checkable: true
|
||||
}
|
||||
RibbonButton{
|
||||
text:"Button"
|
||||
show_bg:false
|
||||
}
|
||||
RibbonButton{
|
||||
text:"Button"
|
||||
show_bg:false
|
||||
show_tooltip: false
|
||||
}
|
||||
}
|
||||
ColumnLayout{
|
||||
spacing: 10
|
||||
RibbonButton{
|
||||
show_bg:false
|
||||
icon_source: RibbonIcons.Badge
|
||||
icon_source_filled: RibbonIcons_Filled.Badge
|
||||
checkable: true
|
||||
tip_text: "Button"
|
||||
}
|
||||
RibbonButton{
|
||||
show_bg:false
|
||||
icon_source: RibbonIcons.Clock
|
||||
icon_source_filled: RibbonIcons_Filled.Clock
|
||||
tip_text: "Button"
|
||||
}
|
||||
RibbonButton{
|
||||
show_bg:false
|
||||
icon_source: RibbonIcons.Board
|
||||
icon_source_filled: RibbonIcons_Filled.Board
|
||||
checkable: true
|
||||
tip_text: "Button"
|
||||
show_tooltip: false
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
RibbonTabGroup{
|
||||
width: pushbutton_layout.width + 30
|
||||
text: qsTr("Push Button")
|
||||
RowLayout{
|
||||
id: pushbutton_layout
|
||||
anchors.centerIn: parent
|
||||
height: parent.height
|
||||
spacing: 10
|
||||
RibbonPushButton{
|
||||
text: qsTr("No Menu")
|
||||
icon_source: RibbonIcons.AttachText
|
||||
}
|
||||
RibbonPushButton{
|
||||
text: qsTr("Menu")
|
||||
icon_source: RibbonIcons.MeetNow
|
||||
Action{
|
||||
text: "Test Item 1"
|
||||
}
|
||||
RibbonMenuSeparator{}
|
||||
Action{
|
||||
text: "Test Item 2"
|
||||
enabled: false
|
||||
}
|
||||
}
|
||||
RibbonPushButton{
|
||||
text: qsTr("No Menu")
|
||||
icon_source: "qrc:/qt/qml/RibbonUIAPP/resources/imgs/heart.png"
|
||||
icon_size: height-5
|
||||
}
|
||||
RibbonPushButton{
|
||||
text: qsTr("Menu")
|
||||
icon_source: "qrc:/qt/qml/RibbonUIAPP/resources/imgs/search.png"
|
||||
Action{
|
||||
text: "Test Item 3"
|
||||
}
|
||||
RibbonMenuSeparator{}
|
||||
Action{
|
||||
text: "Test Item 4"
|
||||
enabled: false
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
RibbonTabPage{
|
||||
title: qsTr("Input")
|
||||
RibbonTabGroup{
|
||||
width: lineedit_layout.width + 30
|
||||
text: qsTr("Line Edit")
|
||||
RowLayout{
|
||||
id: lineedit_layout
|
||||
anchors.centerIn: parent
|
||||
height: parent.height
|
||||
spacing: 10
|
||||
ColumnLayout{
|
||||
spacing: 10
|
||||
Layout.fillHeight: true
|
||||
RibbonLineEdit{
|
||||
}
|
||||
RibbonLineEdit{
|
||||
show_clear_btn:false
|
||||
}
|
||||
}
|
||||
ColumnLayout{
|
||||
spacing: 10
|
||||
Layout.fillHeight: true
|
||||
RibbonLineEdit{
|
||||
icon_source:RibbonIcons.Search
|
||||
}
|
||||
RibbonLineEdit{
|
||||
icon_source:RibbonIcons.Keyboard
|
||||
show_clear_btn:false
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
RibbonTabGroup{
|
||||
width: lineedit_layout.width + 30
|
||||
text: qsTr("Text Edit")
|
||||
RowLayout{
|
||||
id: textedit_layout
|
||||
anchors.centerIn: parent
|
||||
height: parent.height
|
||||
spacing: 10
|
||||
ColumnLayout{
|
||||
spacing: 30
|
||||
Layout.fillHeight: true
|
||||
RibbonTextEdit{
|
||||
max_height: 50
|
||||
}
|
||||
RibbonTextEdit{
|
||||
max_height: 30
|
||||
show_clear_btn:false
|
||||
}
|
||||
}
|
||||
ColumnLayout{
|
||||
spacing: 30
|
||||
Layout.fillHeight: true
|
||||
RibbonTextEdit{
|
||||
max_height: 50
|
||||
icon_source:RibbonIcons.Search
|
||||
}
|
||||
RibbonTextEdit{
|
||||
max_height: 30
|
||||
icon_source:RibbonIcons.Keyboard
|
||||
show_clear_btn:false
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
RibbonTabGroup{
|
||||
width: combobox_layout.width + 30
|
||||
text: qsTr("Combo Box")
|
||||
RowLayout{
|
||||
id: combobox_layout
|
||||
anchors.centerIn: parent
|
||||
height: parent.height
|
||||
spacing: 10
|
||||
ColumnLayout{
|
||||
spacing: 10
|
||||
Layout.fillHeight: true
|
||||
RibbonComboBox{
|
||||
model: ListModel {
|
||||
ListElement { text: "Test Item 1" }
|
||||
ListElement { text: "Test Item 2" }
|
||||
ListElement { text: "Test Item 3" }
|
||||
}
|
||||
}
|
||||
RibbonComboBox{
|
||||
editable: true
|
||||
model: ListModel {
|
||||
id: model
|
||||
ListElement { text: "Test Item 1" }
|
||||
ListElement { text: "Test Item 2" }
|
||||
ListElement { text: "Test Item 3" }
|
||||
}
|
||||
onAccepted: {
|
||||
if (find(editText) === -1 && editText)
|
||||
model.append({text: editText})
|
||||
}
|
||||
}
|
||||
}
|
||||
ColumnLayout{
|
||||
spacing: 10
|
||||
Layout.fillHeight: true
|
||||
RibbonComboBox{
|
||||
model: ListModel {
|
||||
ListElement { text: "Test Item 1" }
|
||||
ListElement { text: "Test Item 2" }
|
||||
ListElement { text: "Test Item 3" }
|
||||
}
|
||||
icon_source: RibbonIcons.Beaker
|
||||
}
|
||||
RibbonComboBox{
|
||||
editable: true
|
||||
model: ListModel {
|
||||
id: model_1
|
||||
ListElement { text: "Test Item 1" }
|
||||
ListElement { text: "Test Item 2" }
|
||||
ListElement { text: "Test Item 3" }
|
||||
}
|
||||
icon_source: RibbonIcons.Calendar
|
||||
onAccepted: {
|
||||
if (find(editText) === -1 && editText)
|
||||
model_1.append({text: editText})
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
RibbonTabGroup{
|
||||
width: spinbox_layout.width + 30
|
||||
text: qsTr("Spin Box")
|
||||
show_border: false
|
||||
RowLayout{
|
||||
id: spinbox_layout
|
||||
anchors.centerIn: parent
|
||||
height: parent.height
|
||||
spacing: 10
|
||||
ColumnLayout{
|
||||
spacing: 10
|
||||
Layout.fillHeight: true
|
||||
RibbonSpinBox{
|
||||
width: 100
|
||||
}
|
||||
RibbonSpinBox{
|
||||
id: spinbox
|
||||
width: 80
|
||||
icon_source: RibbonIcons.DataPie
|
||||
validator: DoubleValidator {
|
||||
bottom: Math.min(spinbox.from, spinbox.to)
|
||||
top: Math.max(spinbox.from, spinbox.to)
|
||||
decimals: 2
|
||||
notation: DoubleValidator.StandardNotation
|
||||
}
|
||||
textFromValue: function(value, locale) {
|
||||
return Number(value / 100).toLocaleString(locale, 'f', 2)
|
||||
}
|
||||
valueFromText: function(text, locale) {
|
||||
return Math.round(Number.fromLocaleString(locale, text) * 100)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
RibbonTabPage{
|
||||
title: qsTr("Views")
|
||||
RibbonTabGroup{
|
||||
width: message_list_view_layout.width + 30
|
||||
text: qsTr("MessageListView")
|
||||
RowLayout{
|
||||
id: message_list_view_layout
|
||||
anchors.centerIn: parent
|
||||
height: parent.height
|
||||
spacing: 10
|
||||
RibbonButton{
|
||||
text: qsTr('Open Message List View')
|
||||
icon_source: RibbonIcons.Open
|
||||
onClicked: {
|
||||
Window.window.popup.show_content("qrc:/qt/qml/RibbonUIAPP/components/RibbonMessageListViewExample.qml")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
RibbonTabPage{
|
||||
title: qsTr("Others")
|
||||
RibbonTabGroup{
|
||||
width: text_layout.width + 30
|
||||
text: qsTr("Text")
|
||||
RowLayout{
|
||||
id: text_layout
|
||||
anchors.centerIn: parent
|
||||
height: parent.height
|
||||
spacing: 10
|
||||
ColumnLayout{
|
||||
spacing: 10
|
||||
Layout.fillHeight: true
|
||||
RibbonText{
|
||||
font.pixelSize: 13
|
||||
text: "Test Text"
|
||||
}
|
||||
RibbonText{
|
||||
font.pixelSize: 13
|
||||
text: "Test Text (Read Only)"
|
||||
view_only: true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
RibbonTabGroup{
|
||||
width: menu_layout.width + 30
|
||||
text: qsTr("Menu")
|
||||
RowLayout{
|
||||
id: menu_layout
|
||||
anchors.centerIn: parent
|
||||
height: parent.height
|
||||
spacing: 10
|
||||
RibbonButton{
|
||||
text: qsTr("Open Menu")
|
||||
icon_source: RibbonIcons.Open
|
||||
onClicked: menu.popup()
|
||||
}
|
||||
}
|
||||
}
|
||||
RibbonTabGroup{
|
||||
width: popup_layout.width + 30
|
||||
text: qsTr("Popup")
|
||||
RowLayout{
|
||||
id: popup_layout
|
||||
anchors.centerIn: parent
|
||||
height: parent.height
|
||||
spacing: 10
|
||||
ColumnLayout{
|
||||
spacing: 10
|
||||
Layout.fillHeight: true
|
||||
RibbonButton{
|
||||
text: qsTr("Open Popup")
|
||||
icon_source: RibbonIcons.Open
|
||||
onClicked: popup.open()
|
||||
}
|
||||
RibbonButton{
|
||||
text: qsTr("Open Popup Dialog (Double Choices)")
|
||||
icon_source: RibbonIcons.Open
|
||||
onClicked: {
|
||||
dialog.buttonFlags = RibbonPopupDialogType.NegativeButton | RibbonPopupDialogType.PositiveButton
|
||||
dialog.open()
|
||||
}
|
||||
}
|
||||
RibbonButton{
|
||||
text: qsTr("Open Popup Dialog (Triple Choices)")
|
||||
icon_source: RibbonIcons.Open
|
||||
onClicked: {
|
||||
dialog.buttonFlags = RibbonPopupDialogType.NegativeButton | RibbonPopupDialogType.PositiveButton | RibbonPopupDialogType.NeutralButton
|
||||
dialog.open()
|
||||
}
|
||||
}
|
||||
}
|
||||
RibbonPopup{
|
||||
id: popup
|
||||
height: 200
|
||||
width: height
|
||||
target: window_items
|
||||
blur_enabled: true
|
||||
target_rect: Qt.rect(window_items.x + x, window_items.y + y, width, height)
|
||||
}
|
||||
RibbonPopupDialog{
|
||||
id: dialog
|
||||
target: window_items
|
||||
blur_enabled: true
|
||||
target_rect: Qt.rect(window_items.x + x, window_items.y + y, width, height)
|
||||
}
|
||||
}
|
||||
}
|
||||
RibbonTabGroup{
|
||||
width: theme_layout.width + 30
|
||||
text: qsTr("Theme")
|
||||
RowLayout{
|
||||
id: theme_layout
|
||||
anchors.centerIn: parent
|
||||
height: parent.height
|
||||
spacing: 10
|
||||
RibbonComboBox{
|
||||
id: theme_combo
|
||||
model: ListModel {
|
||||
id: model_theme
|
||||
ListElement { text: "Light" }
|
||||
ListElement { text: "Dark" }
|
||||
ListElement { text: "System" }
|
||||
}
|
||||
icon_source: RibbonIcons.DarkTheme
|
||||
Component.onCompleted: update_state()
|
||||
onActivated: {
|
||||
if (currentText === "System")
|
||||
RibbonTheme.theme_mode = RibbonThemeType.System
|
||||
else if (currentText === "Light")
|
||||
RibbonTheme.theme_mode = RibbonThemeType.Light
|
||||
else
|
||||
RibbonTheme.theme_mode = RibbonThemeType.Dark
|
||||
}
|
||||
Connections{
|
||||
target: RibbonTheme
|
||||
function onTheme_modeChanged(){
|
||||
theme_combo.update_state()
|
||||
}
|
||||
}
|
||||
function update_state(){
|
||||
let str = (RibbonTheme.theme_mode === RibbonThemeType.System ? "System" : RibbonTheme.theme_mode === RibbonThemeType.Light ? "Light" : "Dark")
|
||||
currentIndex = find(str)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
RibbonPaperView{
|
||||
id: view
|
||||
anchors.fill: parent
|
||||
top_padding: tab_bar.height
|
||||
bottom_padding: bottom_bar.height
|
||||
page_width: (page_slider.value / 100.0) * width
|
||||
spacing: 0
|
||||
ColumnLayout{
|
||||
Layout.alignment: Qt.AlignCenter
|
||||
Layout.topMargin: 30
|
||||
spacing: 20
|
||||
RibbonText{
|
||||
Layout.alignment: Qt.AlignHCenter
|
||||
Layout.topMargin: 50
|
||||
text: "RibbonUI"
|
||||
font{
|
||||
pixelSize: 50
|
||||
bold: true
|
||||
italic: true
|
||||
}
|
||||
}
|
||||
Image {
|
||||
source: "qrc:/qt/qml/RibbonUI/resources/imgs/icon.png"
|
||||
fillMode:Image.PreserveAspectFit
|
||||
Layout.preferredHeight: 300
|
||||
Layout.preferredWidth: height
|
||||
Layout.alignment: Qt.AlignHCenter
|
||||
layer.enabled: true
|
||||
layer.effect: RibbonShadow{}
|
||||
}
|
||||
RibbonText{
|
||||
Layout.alignment: Qt.AlignHCenter
|
||||
text: "A Lightweight, minimalist and \nelegant Qt component library."
|
||||
font{
|
||||
pixelSize: 30
|
||||
bold: true
|
||||
italic: true
|
||||
}
|
||||
}
|
||||
RibbonText{
|
||||
Layout.alignment: Qt.AlignHCenter
|
||||
text: "Author: mentalfl0w"
|
||||
font{
|
||||
pixelSize: 25
|
||||
bold: true
|
||||
italic: true
|
||||
}
|
||||
}
|
||||
RibbonText{
|
||||
Layout.alignment: Qt.AlignHCenter
|
||||
text: "Email: mentalflow@ourdocs.cn"
|
||||
font{
|
||||
pixelSize: 25
|
||||
bold: true
|
||||
italic: true
|
||||
}
|
||||
}
|
||||
RibbonText{
|
||||
Layout.alignment: Qt.AlignHCenter
|
||||
text: `Current Version: V${RibbonUI.version}`
|
||||
font{
|
||||
pixelSize: 20
|
||||
bold: true
|
||||
italic: true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
RibbonBottomBar{
|
||||
id: bottom_bar
|
||||
anchors{
|
||||
left: parent.left
|
||||
right: parent.right
|
||||
bottom: parent.bottom
|
||||
}
|
||||
right_content: RowLayout{
|
||||
clip: true
|
||||
spacing:1
|
||||
Layout.preferredHeight: parent.height
|
||||
layoutDirection: Qt.RightToLeft
|
||||
RibbonSlider{
|
||||
id: page_slider
|
||||
slide_width: 80
|
||||
show_filled_color: false
|
||||
value: 70
|
||||
}
|
||||
RibbonButton{
|
||||
text:"Test Button 3"
|
||||
show_bg:false
|
||||
adapt_height:true
|
||||
icon_source: RibbonIcons.Airplane
|
||||
}
|
||||
RibbonButton{
|
||||
text:"Test Button 4"
|
||||
show_bg:false
|
||||
adapt_height:true
|
||||
}
|
||||
}
|
||||
RibbonButton{
|
||||
text:"Test Button 5"
|
||||
show_bg:false
|
||||
adapt_height:true
|
||||
icon_source: RibbonIcons.AccessTime
|
||||
checkable: true
|
||||
}
|
||||
RibbonButton{
|
||||
text:"Test Button 6"
|
||||
show_bg:false
|
||||
adapt_height:true
|
||||
}
|
||||
RibbonButton{
|
||||
show_bg:false
|
||||
adapt_height:true
|
||||
icon_source: RibbonIcons.AppStore
|
||||
checkable: true
|
||||
tip_text: "Test Button 7"
|
||||
}
|
||||
}
|
||||
|
||||
title_bar.right_content:RowLayout{
|
||||
spacing: 1
|
||||
layoutDirection: Qt.RightToLeft
|
||||
RibbonButton{
|
||||
show_bg:false
|
||||
icon_source: RibbonIcons.Info
|
||||
icon_source_filled: RibbonIcons_Filled.Info
|
||||
tip_text: qsTr("About")
|
||||
hover_color: Qt.rgba(0,0,0, 0.3)
|
||||
pressed_color: Qt.rgba(0,0,0, 0.4)
|
||||
text_color: title_bar.title_text_color
|
||||
text_color_reverse: false
|
||||
onClicked: root.show_window(Qt.resolvedUrl("about.qml"))
|
||||
}
|
||||
RibbonButton{
|
||||
show_bg:false
|
||||
icon_source: RibbonIcons.CalendarStar
|
||||
icon_source_filled: RibbonIcons_Filled.CalendarStar
|
||||
checkable: true
|
||||
tip_text: "Test Button 11"
|
||||
hover_color: Qt.rgba(0,0,0, 0.3)
|
||||
pressed_color: Qt.rgba(0,0,0, 0.4)
|
||||
text_color: title_bar.title_text_color
|
||||
text_color_reverse: false
|
||||
}
|
||||
|
||||
}
|
||||
title_bar.left_content:RowLayout{
|
||||
spacing: 1
|
||||
RibbonButton{
|
||||
show_bg:false
|
||||
icon_source: RibbonIcons.ChevronDown
|
||||
tip_text: "Test Button 8"
|
||||
hover_color: Qt.rgba(0,0,0, 0.3)
|
||||
pressed_color: Qt.rgba(0,0,0, 0.4)
|
||||
text_color: title_bar.title_text_color
|
||||
text_color_reverse: false
|
||||
RibbonMenu{
|
||||
id:menu
|
||||
width: 200
|
||||
Action{
|
||||
text: "Test Long Text Test Long Text Test Long Text"
|
||||
checkable: true
|
||||
}
|
||||
RibbonMenuSeparator{}
|
||||
Action{
|
||||
text: "Test Item 1"
|
||||
enabled: false
|
||||
}
|
||||
RibbonMenu{
|
||||
width: parent.width
|
||||
title: "Sub Menu"
|
||||
Action { text: qsTr("Test Item 2") }
|
||||
Action { text: qsTr("Test Item 3") }
|
||||
}
|
||||
}
|
||||
onClicked:menu.popup()
|
||||
}
|
||||
RibbonButton{
|
||||
show_bg:false
|
||||
icon_source: RibbonIcons.Apps
|
||||
icon_source_filled: RibbonIcons_Filled.Apps
|
||||
checkable: true
|
||||
tip_text: "Test Button 9"
|
||||
hover_color: Qt.rgba(0,0,0, 0.3)
|
||||
pressed_color: Qt.rgba(0,0,0, 0.4)
|
||||
text_color: title_bar.title_text_color
|
||||
text_color_reverse: false
|
||||
enabled: false
|
||||
}
|
||||
}
|
||||
}
|
After Width: | Height: | Size: 32 KiB |
After Width: | Height: | Size: 13 KiB |
After Width: | Height: | Size: 74 KiB |
After Width: | Height: | Size: 126 KiB |
|
@ -0,0 +1,130 @@
|
|||
# References:
|
||||
# https://clang.llvm.org/docs/ClangFormatStyleOptions.html
|
||||
# https://code.qt.io/cgit/qt/qt5.git/tree/_clang-format
|
||||
|
||||
BasedOnStyle: LLVM
|
||||
|
||||
Standard: c++17
|
||||
|
||||
# 指针和引用的对齐方式。
|
||||
# 可能的值有:
|
||||
# PAS_Left (在配置中: Left) 指针左对齐。
|
||||
# PAS_Right (在配置中: Right) 指针右对齐。
|
||||
# PAS_Middle (在配置中: Middle) 指针中间对齐。
|
||||
PointerAlignment: Right
|
||||
|
||||
# public/protected/private 等访问修饰符偏移量
|
||||
AccessModifierOffset: -4
|
||||
|
||||
# 缩进长度
|
||||
IndentWidth: 4
|
||||
|
||||
# 连续空行的最大数
|
||||
MaxEmptyLinesToKeep: 999
|
||||
|
||||
# 在OC中的@property后面添加一个空格。例如:使用“@property (readonly)”而不是“@property(readonly)”
|
||||
ObjCSpaceAfterProperty: true
|
||||
|
||||
# OC块中所拍的字符数
|
||||
ObjCBlockIndentWidth: 4
|
||||
|
||||
# 取决于值, 语句“int f() { return 0; }”可以被放到一个单行。
|
||||
# 可能的值有:
|
||||
# SFS_None (在配置中: None) 从不合并方法或函数到单独的一行。
|
||||
# SFS_Empty (在配置中: Empty) 仅合并空的函数。
|
||||
# SFS_Inline (在配置中: Inline) 仅合并类中定义的方法或函数. 意味着 “empty”.
|
||||
# SFS_All (在配置中: All) 合并所有的方法适应单行.
|
||||
AllowShortFunctionsOnASingleLine: None
|
||||
|
||||
# 如果为真(true), 语句“if (a) return;” 能被放到单行。
|
||||
AllowShortIfStatementsOnASingleLine: false
|
||||
|
||||
# 如果为真(true), 对齐注释。
|
||||
AlignTrailingComments: true
|
||||
|
||||
# 如果为真,对齐连续的宏定义
|
||||
AlignConsecutiveMacros: true
|
||||
|
||||
# 如果为真(true),将会在“[”之后和“]”之前插入空格。
|
||||
SpacesInSquareBrackets: false
|
||||
|
||||
# 如果为真(true), 将会在“(”之后和“)”之前插入空格。
|
||||
SpacesInParentheses : false
|
||||
|
||||
# 如果为真(true), 校准连续的声明。
|
||||
# 这将会校准连续多行的声明的名字。这将会导致像下面这样的格式:
|
||||
# int aaaa = 12;
|
||||
# float b = 23;
|
||||
# std::string ccc = 23;
|
||||
AlignConsecutiveDeclarations: false
|
||||
|
||||
# 如果为真(true),连续调整多行
|
||||
# 这将会调整连续行中的分配操作符。这将会导致像下面这样的格式:
|
||||
# int aaaa = 12;
|
||||
# int b = 23;
|
||||
# int ccc = 23;
|
||||
AlignConsecutiveAssignments: false
|
||||
|
||||
# 如果为假(false),移除分配操作符(=)前空格。
|
||||
SpaceBeforeAssignmentOperators: true
|
||||
|
||||
# 如果为真(true), 将会在字面量容器中插入空格(例如 OC和Javascript的数组和字典字面量)。
|
||||
SpacesInContainerLiterals: false
|
||||
|
||||
# 缩进case标签
|
||||
IndentCaseLabels: true
|
||||
|
||||
# 如果表达式中包含函数调用,并且函数调用因为表达式太长被放到了下一行,是否缩进
|
||||
IndentWrappedFunctionNames: true
|
||||
|
||||
# 如果为真(true), 保持块的起始空行。
|
||||
# true: false:
|
||||
# if (foo) { vs. if (foo) {
|
||||
# bar();
|
||||
# bar(); }
|
||||
# }
|
||||
KeepEmptyLinesAtTheStartOfBlocks: true
|
||||
|
||||
# 允许所有参数都被放在下一行
|
||||
AllowAllParametersOfDeclarationOnNextLine: false
|
||||
|
||||
# 使用C风格强制类型转换后,是否在中间添加一个空格
|
||||
SpaceAfterCStyleCast: true
|
||||
|
||||
# 在模板定义后换行
|
||||
AlwaysBreakTemplateDeclarations: Yes
|
||||
|
||||
# Tab长度
|
||||
TabWidth: 4
|
||||
|
||||
# 是否使用Tab
|
||||
UseTab: Never
|
||||
|
||||
# 在括号后对齐参数
|
||||
# someLongFunction(argument1,
|
||||
# argument2);
|
||||
AlignAfterOpenBracket: Align
|
||||
|
||||
# 名字空间内部缩进
|
||||
NamespaceIndentation: All
|
||||
|
||||
# 一行最长列数
|
||||
ColumnLimit: 100
|
||||
|
||||
# 按层次缩进宏定义
|
||||
IndentPPDirectives: AfterHash
|
||||
|
||||
# 预处理语句缩进为 2
|
||||
PPIndentWidth: 2
|
||||
|
||||
# 数组元素对齐
|
||||
AlignArrayOfStructures: Left
|
||||
|
||||
# 不对头文件排序
|
||||
SortIncludes: Never
|
||||
|
||||
FixNamespaceComments: false
|
||||
|
||||
StatementMacros: ['__qas_attr__', '__qas_exclude__', '__qas_include__']
|
||||
|
||||
ForEachMacros: [ foreach, Q_FOREACH, BOOST_FOREACH, forever, Q_FOREVER, QBENCHMARK, QBENCHMARK_ONCE ]
|
|
@ -0,0 +1,98 @@
|
|||
# This file is used to ignore files which are generated
|
||||
# ----------------------------------------------------------------------------
|
||||
|
||||
*~
|
||||
*.log
|
||||
*.autosave
|
||||
*.a
|
||||
*.core
|
||||
*.moc
|
||||
*.o
|
||||
*.obj
|
||||
*.orig
|
||||
*.rej
|
||||
*.so
|
||||
*.so.*
|
||||
*_pch.h.cpp
|
||||
*_resource.rc
|
||||
*.qm
|
||||
.#*
|
||||
*.*#
|
||||
core
|
||||
!core/
|
||||
tags
|
||||
.DS_Store
|
||||
.directory
|
||||
*.debug
|
||||
Makefile*
|
||||
*.prl
|
||||
*.app
|
||||
moc_*.cpp
|
||||
ui_*.h
|
||||
qrc_*.cpp
|
||||
Thumbs.db
|
||||
# *.res
|
||||
# *.rc
|
||||
/.qmake.cache
|
||||
/.qmake.stash
|
||||
|
||||
# qtcreator generated files
|
||||
*.pro.user*
|
||||
|
||||
# xemacs temporary files
|
||||
*.flc
|
||||
|
||||
# Vim temporary files
|
||||
.*.swp
|
||||
|
||||
# Visual Studio generated files
|
||||
*.ib_pdb_index
|
||||
*.idb
|
||||
*.ilk
|
||||
*.pdb
|
||||
*.sln
|
||||
*.suo
|
||||
*.vcproj
|
||||
*vcproj.*.*.user
|
||||
*.ncb
|
||||
*.sdf
|
||||
*.opensdf
|
||||
*.vcxproj
|
||||
*vcxproj.*
|
||||
|
||||
# MinGW generated files
|
||||
*.Debug
|
||||
*.Release
|
||||
|
||||
# Python byte code
|
||||
__pycache__
|
||||
*.pyc
|
||||
|
||||
# Binaries
|
||||
# --------
|
||||
*.dll
|
||||
*.exe
|
||||
|
||||
.DS_Store
|
||||
*/.DS_Store
|
||||
|
||||
build-*
|
||||
build/
|
||||
cmake-build*
|
||||
*.user
|
||||
*.lnk
|
||||
_workingDir*
|
||||
.vscode
|
||||
.idea
|
||||
.cache
|
||||
cache
|
||||
.vs
|
||||
out/
|
||||
CMakeSettings.json
|
||||
# /vcpkg
|
||||
/data
|
||||
/*.natvis
|
||||
|
||||
*.sublime-*
|
||||
setup-vcpkg.json
|
||||
setup-vcpkg-temp*
|
|
@ -0,0 +1,4 @@
|
|||
[submodule "qmsetup"]
|
||||
path = qmsetup
|
||||
url = ../../stdware/qmsetup.git
|
||||
branch = main
|
|
@ -0,0 +1,84 @@
|
|||
cmake_minimum_required(VERSION 3.19)
|
||||
|
||||
project(QWindowKit VERSION 1.1.1.0 LANGUAGES CXX)
|
||||
|
||||
# ----------------------------------
|
||||
# Build Options
|
||||
# ----------------------------------
|
||||
option(QWINDOWKIT_BUILD_STATIC "Build static libraries" OFF)
|
||||
option(QWINDOWKIT_BUILD_WIDGETS "Build widgets module" ON)
|
||||
option(QWINDOWKIT_BUILD_QUICK "Build quick module" OFF)
|
||||
option(QWINDOWKIT_BUILD_EXAMPLES "Build examples" OFF)
|
||||
option(QWINDOWKIT_BUILD_DOCUMENTATIONS "Build documentations" OFF)
|
||||
option(QWINDOWKIT_INSTALL "Install library" ON)
|
||||
|
||||
option(QWINDOWKIT_ENABLE_QT_WINDOW_CONTEXT "Enable Qt Window Context anyway" OFF)
|
||||
option(QWINDOWKIT_ENABLE_WINDOWS_SYSTEM_BORDERS "Enable system borders on Windows" ON)
|
||||
option(QWINDOWKIT_ENABLE_STYLE_AGENT "Enable building style agent" ON)
|
||||
|
||||
# ----------------------------------
|
||||
# CMake Settings
|
||||
# ----------------------------------
|
||||
if(MSVC)
|
||||
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} /manifest:no")
|
||||
set(CMAKE_MODULE_LINKER_FLAGS "${CMAKE_MODULE_LINKER_FLAGS} /manifest:no")
|
||||
set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} /manifest:no")
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /utf-8")
|
||||
|
||||
if(NOT DEFINED CMAKE_DEBUG_POSTFIX)
|
||||
set(CMAKE_DEBUG_POSTFIX "d")
|
||||
endif()
|
||||
elseif(MINGW)
|
||||
set(CMAKE_STATIC_LIBRARY_PREFIX "")
|
||||
set(CMAKE_SHARED_LIBRARY_PREFIX "")
|
||||
endif()
|
||||
|
||||
if(QWINDOWKIT_INSTALL)
|
||||
include(GNUInstallDirs)
|
||||
include(CMakePackageConfigHelpers)
|
||||
endif()
|
||||
|
||||
# ----------------------------------
|
||||
# Project Variables
|
||||
# ----------------------------------
|
||||
set(QWINDOWKIT_VERSION ${PROJECT_VERSION})
|
||||
set(QWINDOWKIT_INSTALL_NAME ${PROJECT_NAME})
|
||||
|
||||
# ----------------------------------
|
||||
# Find basic dependencies
|
||||
# ----------------------------------
|
||||
find_package(qmsetup QUIET)
|
||||
|
||||
if(NOT TARGET qmsetup::library)
|
||||
# Modify this variable according to your project structure
|
||||
set(_source_dir ${CMAKE_CURRENT_SOURCE_DIR}/qmsetup)
|
||||
|
||||
# Import install function
|
||||
include("${_source_dir}/cmake/modules/InstallPackage.cmake")
|
||||
|
||||
# Install package in place
|
||||
set(_package_path)
|
||||
qm_install_package(qmsetup
|
||||
SOURCE_DIR ${_source_dir}
|
||||
BUILD_TYPE Release
|
||||
RESULT_PATH _package_path
|
||||
)
|
||||
|
||||
# Find package again
|
||||
find_package(qmsetup REQUIRED PATHS ${_package_path})
|
||||
|
||||
# Update import path
|
||||
set(qmsetup_DIR ${_package_path} CACHE PATH "" FORCE)
|
||||
endif()
|
||||
|
||||
qm_import(Filesystem)
|
||||
qm_init_directories()
|
||||
|
||||
# ----------------------------------
|
||||
# Add source modules
|
||||
# ----------------------------------
|
||||
add_subdirectory(src)
|
||||
|
||||
if(QWINDOWKIT_BUILD_EXAMPLES)
|
||||
add_subdirectory(examples)
|
||||
endif()
|
|
@ -0,0 +1,202 @@
|
|||
Apache License
|
||||
Version 2.0, January 2004
|
||||
http://www.apache.org/licenses/
|
||||
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
|
||||
1. Definitions.
|
||||
|
||||
"License" shall mean the terms and conditions for use, reproduction,
|
||||
and distribution as defined by Sections 1 through 9 of this document.
|
||||
|
||||
"Licensor" shall mean the copyright owner or entity authorized by
|
||||
the copyright owner that is granting the License.
|
||||
|
||||
"Legal Entity" shall mean the union of the acting entity and all
|
||||
other entities that control, are controlled by, or are under common
|
||||
control with that entity. For the purposes of this definition,
|
||||
"control" means (i) the power, direct or indirect, to cause the
|
||||
direction or management of such entity, whether by contract or
|
||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||
|
||||
"You" (or "Your") shall mean an individual or Legal Entity
|
||||
exercising permissions granted by this License.
|
||||
|
||||
"Source" form shall mean the preferred form for making modifications,
|
||||
including but not limited to software source code, documentation
|
||||
source, and configuration files.
|
||||
|
||||
"Object" form shall mean any form resulting from mechanical
|
||||
transformation or translation of a Source form, including but
|
||||
not limited to compiled object code, generated documentation,
|
||||
and conversions to other media types.
|
||||
|
||||
"Work" shall mean the work of authorship, whether in Source or
|
||||
Object form, made available under the License, as indicated by a
|
||||
copyright notice that is included in or attached to the work
|
||||
(an example is provided in the Appendix below).
|
||||
|
||||
"Derivative Works" shall mean any work, whether in Source or Object
|
||||
form, that is based on (or derived from) the Work and for which the
|
||||
editorial revisions, annotations, elaborations, or other modifications
|
||||
represent, as a whole, an original work of authorship. For the purposes
|
||||
of this License, Derivative Works shall not include works that remain
|
||||
separable from, or merely link (or bind by name) to the interfaces of,
|
||||
the Work and Derivative Works thereof.
|
||||
|
||||
"Contribution" shall mean any work of authorship, including
|
||||
the original version of the Work and any modifications or additions
|
||||
to that Work or Derivative Works thereof, that is intentionally
|
||||
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||
or by an individual or Legal Entity authorized to submit on behalf of
|
||||
the copyright owner. For the purposes of this definition, "submitted"
|
||||
means any form of electronic, verbal, or written communication sent
|
||||
to the Licensor or its representatives, including but not limited to
|
||||
communication on electronic mailing lists, source code control systems,
|
||||
and issue tracking systems that are managed by, or on behalf of, the
|
||||
Licensor for the purpose of discussing and improving the Work, but
|
||||
excluding communication that is conspicuously marked or otherwise
|
||||
designated in writing by the copyright owner as "Not a Contribution."
|
||||
|
||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||
on behalf of whom a Contribution has been received by Licensor and
|
||||
subsequently incorporated within the Work.
|
||||
|
||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
copyright license to reproduce, prepare Derivative Works of,
|
||||
publicly display, publicly perform, sublicense, and distribute the
|
||||
Work and such Derivative Works in Source or Object form.
|
||||
|
||||
3. Grant of Patent License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
(except as stated in this section) patent license to make, have made,
|
||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||
where such license applies only to those patent claims licensable
|
||||
by such Contributor that are necessarily infringed by their
|
||||
Contribution(s) alone or by combination of their Contribution(s)
|
||||
with the Work to which such Contribution(s) was submitted. If You
|
||||
institute patent litigation against any entity (including a
|
||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||
or a Contribution incorporated within the Work constitutes direct
|
||||
or contributory patent infringement, then any patent licenses
|
||||
granted to You under this License for that Work shall terminate
|
||||
as of the date such litigation is filed.
|
||||
|
||||
4. Redistribution. You may reproduce and distribute copies of the
|
||||
Work or Derivative Works thereof in any medium, with or without
|
||||
modifications, and in Source or Object form, provided that You
|
||||
meet the following conditions:
|
||||
|
||||
(a) You must give any other recipients of the Work or
|
||||
Derivative Works a copy of this License; and
|
||||
|
||||
(b) You must cause any modified files to carry prominent notices
|
||||
stating that You changed the files; and
|
||||
|
||||
(c) You must retain, in the Source form of any Derivative Works
|
||||
that You distribute, all copyright, patent, trademark, and
|
||||
attribution notices from the Source form of the Work,
|
||||
excluding those notices that do not pertain to any part of
|
||||
the Derivative Works; and
|
||||
|
||||
(d) If the Work includes a "NOTICE" text file as part of its
|
||||
distribution, then any Derivative Works that You distribute must
|
||||
include a readable copy of the attribution notices contained
|
||||
within such NOTICE file, excluding those notices that do not
|
||||
pertain to any part of the Derivative Works, in at least one
|
||||
of the following places: within a NOTICE text file distributed
|
||||
as part of the Derivative Works; within the Source form or
|
||||
documentation, if provided along with the Derivative Works; or,
|
||||
within a display generated by the Derivative Works, if and
|
||||
wherever such third-party notices normally appear. The contents
|
||||
of the NOTICE file are for informational purposes only and
|
||||
do not modify the License. You may add Your own attribution
|
||||
notices within Derivative Works that You distribute, alongside
|
||||
or as an addendum to the NOTICE text from the Work, provided
|
||||
that such additional attribution notices cannot be construed
|
||||
as modifying the License.
|
||||
|
||||
You may add Your own copyright statement to Your modifications and
|
||||
may provide additional or different license terms and conditions
|
||||
for use, reproduction, or distribution of Your modifications, or
|
||||
for any such Derivative Works as a whole, provided Your use,
|
||||
reproduction, and distribution of the Work otherwise complies with
|
||||
the conditions stated in this License.
|
||||
|
||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||
any Contribution intentionally submitted for inclusion in the Work
|
||||
by You to the Licensor shall be under the terms and conditions of
|
||||
this License, without any additional terms or conditions.
|
||||
Notwithstanding the above, nothing herein shall supersede or modify
|
||||
the terms of any separate license agreement you may have executed
|
||||
with Licensor regarding such Contributions.
|
||||
|
||||
6. Trademarks. This License does not grant permission to use the trade
|
||||
names, trademarks, service marks, or product names of the Licensor,
|
||||
except as required for reasonable and customary use in describing the
|
||||
origin of the Work and reproducing the content of the NOTICE file.
|
||||
|
||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||
agreed to in writing, Licensor provides the Work (and each
|
||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
implied, including, without limitation, any warranties or conditions
|
||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||
appropriateness of using or redistributing the Work and assume any
|
||||
risks associated with Your exercise of permissions under this License.
|
||||
|
||||
8. Limitation of Liability. In no event and under no legal theory,
|
||||
whether in tort (including negligence), contract, or otherwise,
|
||||
unless required by applicable law (such as deliberate and grossly
|
||||
negligent acts) or agreed to in writing, shall any Contributor be
|
||||
liable to You for damages, including any direct, indirect, special,
|
||||
incidental, or consequential damages of any character arising as a
|
||||
result of this License or out of the use or inability to use the
|
||||
Work (including but not limited to damages for loss of goodwill,
|
||||
work stoppage, computer failure or malfunction, or any and all
|
||||
other commercial damages or losses), even if such Contributor
|
||||
has been advised of the possibility of such damages.
|
||||
|
||||
9. Accepting Warranty or Additional Liability. While redistributing
|
||||
the Work or Derivative Works thereof, You may choose to offer,
|
||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||
or other liability obligations and/or rights consistent with this
|
||||
License. However, in accepting such obligations, You may act only
|
||||
on Your own behalf and on Your sole responsibility, not on behalf
|
||||
of any other Contributor, and only if You agree to indemnify,
|
||||
defend, and hold each Contributor harmless for any liability
|
||||
incurred by, or claims asserted against, such Contributor by reason
|
||||
of your accepting any such warranty or additional liability.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
APPENDIX: How to apply the Apache License to your work.
|
||||
|
||||
To apply the Apache License to your work, attach the following
|
||||
boilerplate notice, with the fields enclosed by brackets "[]"
|
||||
replaced with your own identifying information. (Don't include
|
||||
the brackets!) The text should be enclosed in the appropriate
|
||||
comment syntax for the file format. We also recommend that a
|
||||
file or class name and description of purpose be included on the
|
||||
same "printed page" as the copyright notice for easier
|
||||
identification within third-party archives.
|
||||
|
||||
Copyright (C) 2023-2024 Stdware Collections (https://www.github.com/stdware)
|
||||
Copyright (C) 2021-2023 wangwenx190 (Yuhang Zhao)
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
|
@ -0,0 +1,301 @@
|
|||
# QWindowKit
|
||||
|
||||
Cross-platform window customization framework for Qt Widgets and Qt Quick.
|
||||
|
||||
This project inherited most of [wangwenx190 FramelessHelper](https://github.com/wangwenx190/framelesshelper)
|
||||
implementation, with a complete refactoring and upgrading of the architecture.
|
||||
|
||||
Feature requests are welcome.
|
||||
|
||||
## Join with Us :triangular_flag_on_post:
|
||||
|
||||
You can join our [Discord channel](https://discord.gg/grrM4Tmesy). You can share your findings, thoughts and ideas on improving / implementing FramelessHelper functionalities on more platforms and apps!
|
||||
|
||||
## Supported Platforms
|
||||
|
||||
+ Microsoft Windows
|
||||
+ Apple macOS (11+)
|
||||
+ GNU/Linux
|
||||
|
||||
## Features
|
||||
|
||||
+ Full support of Windows 11 Snap Layout
|
||||
+ Better workaround to handle Windows 10 top border issue
|
||||
+ Support Mac system buttons geometry customization
|
||||
+ Simpler APIs, more detailed documentations and comments
|
||||
|
||||
## Gallery
|
||||
|
||||
### Windows 11 (With Snap Layout)
|
||||
|
||||

|
||||
|
||||
### Windows 10 (And 7, Vista)
|
||||
|
||||

|
||||
|
||||
### macOS & Linux
|
||||
|
||||
| macOS | Linux (Ubuntu 20.04) |
|
||||
|:-------------------------------:|:---------------------------------:|
|
||||
|  |  |
|
||||
|
||||
## Requirements
|
||||
|
||||
| Component | Requirement | Details |
|
||||
|:---------:|:-----------:|:-------------------------:|
|
||||
| Qt | \>=5.12 | Core, Gui, Widgets, Quick |
|
||||
| Compiler | \>=C++17 | MSVC 2019, GCC, Clang |
|
||||
| CMake | \>=3.19 | >=3.20 is recommended |
|
||||
|
||||
### Tested Compilers
|
||||
|
||||
+ Windows
|
||||
+ MSVC: 2019, 2022
|
||||
+ MinGW (GCC): 13.2.0
|
||||
+ macOS
|
||||
+ Clang 14.0.3
|
||||
+ Ubuntu
|
||||
+ GCC: 9.4.0
|
||||
|
||||
## Dependencies
|
||||
|
||||
+ Qt 5.12 or higher
|
||||
+ [qmsetup](https://github.com/stdware/qmsetup)
|
||||
|
||||
## Integrate
|
||||
|
||||
### Configure Options
|
||||
|
||||
+ `QWINDOWKIT_BUILD_DOCUMENTATIONS`
|
||||
+ If you have installed `Doxygen`, you can **enable** this option so that the documentations will also be built and installed.
|
||||
+ If not, you can read the comments in *qdoc* style in `cpp` files to get detailed usages of the public APIs.
|
||||
|
||||
+ `QWINDOWKIT_ENABLE_WINDOWS_SYSTEM_BORDERS`
|
||||
+ If you don't want the system borders on Windows 10/11, you can **disable** this option.
|
||||
+ If so, the Windows 10 top border issue will disappear. However, part of the client edge area will be occupied as the resizing margins.
|
||||
|
||||
+ `QWINDOWKIT_ENABLE_QT_WINDOW_CONTEXT`
|
||||
+ If you want to use pure Qt emulated frameless implementation, you can **enable** this option.
|
||||
+ If so, all system native features will be lost.
|
||||
|
||||
+ `QWINDOWKIT_ENABLE_STYLE_AGENT`
|
||||
+ Select whether to exclude the style component by **disabling** this option according to your requirements and your Qt version.
|
||||
|
||||
### Build & Install
|
||||
|
||||
```sh
|
||||
git clone --recursive https://github.com/stdware/qwindowkit
|
||||
cd qwindowkit
|
||||
|
||||
cmake -B build -S . \
|
||||
-Dqmsetup_DIR=<dir> \ # Optional
|
||||
-DCMAKE_INSTALL_PREFIX=/path/install \
|
||||
-G "Ninja Multi-Config"
|
||||
|
||||
cmake --build build --target install --config Debug
|
||||
cmake --build build --target install --config Release
|
||||
```
|
||||
|
||||
You can also include this directory as a subproject if you choose CMake as your build system.
|
||||
|
||||
For other build systems, you need to install with CMake first and include the corresponding configuration files in your
|
||||
project.
|
||||
|
||||
### Import
|
||||
|
||||
#### CMake Project
|
||||
|
||||
```sh
|
||||
cmake -B build -DQWindowKit_DIR=/path/install/lib/cmake/QWindowKit
|
||||
```
|
||||
|
||||
```cmake
|
||||
find_package(QWindowKit REQUIRED)
|
||||
target_link_libraries(widgets_app PUBLIC QWindowKit::Widgets)
|
||||
target_link_libraries(quick_app PUBLIC QWindowKit::Quick)
|
||||
```
|
||||
|
||||
#### QMake Project
|
||||
|
||||
```cmake
|
||||
# WidgetsApp.pro
|
||||
include("/path/install/share/QWindowKit/qmake/QWKWidgets.pri")
|
||||
|
||||
# QuickApp.pro
|
||||
include("/path/install/share/QWindowKit/qmake/QWKQuick.pri")
|
||||
```
|
||||
|
||||
#### Visual Studio Project
|
||||
|
||||
TODO
|
||||
|
||||
## Quick Start
|
||||
|
||||
### Qt Widgets Application
|
||||
|
||||
#### Initialization
|
||||
|
||||
The following initialization should be done before any widget constructs.
|
||||
|
||||
```cpp
|
||||
#include <QtWidgets/QApplication>
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
QGuiApplication::setAttribute(Qt::AA_DontCreateNativeWidgetSiblings)
|
||||
|
||||
// ...
|
||||
}
|
||||
```
|
||||
|
||||
#### Setup Window Agent
|
||||
|
||||
First, setup `WidgetWindowAgent` for your top `QWidget` instance. (Each window needs its own agent.)
|
||||
|
||||
```c++
|
||||
#include <QWKWidgets/widgetwindowagent.h>
|
||||
|
||||
MyWidget::MyWidget(QWidget *parent) {
|
||||
// ...
|
||||
auto agent = new QWK::WidgetWindowAgent(this);
|
||||
agent->setup(this);
|
||||
// ...
|
||||
}
|
||||
```
|
||||
|
||||
If you don't want to derive a new widget class or change the constructor, you can initialize the agent after the window
|
||||
constructs.
|
||||
|
||||
```c++
|
||||
auto w = new MyWidget();
|
||||
auto agent = new QWK::WidgetWindowAgent(w);
|
||||
agent->setup(w);
|
||||
```
|
||||
|
||||
#### Construct Title bar
|
||||
|
||||
Then, construct your title bar widget, without which the window lacks the basic interaction feature, and it's better to
|
||||
put it into the window's layout.
|
||||
|
||||
You can use the [`WindowBar`](examples/shared/widgetframe/windowbar.h) provided by `WidgetFrame` in the examples as the
|
||||
container of your title bar components.
|
||||
|
||||
Let `WidgetWindowAgent` know which widget the title bar is.
|
||||
|
||||
```c++
|
||||
agent->setTitleBar(myTitleBar);
|
||||
```
|
||||
|
||||
Next, set system button hints to let `WidgetWindowAgent` know the role of the child widgets, which is important for the
|
||||
Snap Layout to work.
|
||||
|
||||
```c++
|
||||
agent->setSystemButton(QWK::WindowAgentBase::WindowIcon, myTitleBar->iconButton());
|
||||
agent->setSystemButton(QWK::WindowAgentBase::Minimize, myTitleBar->minButton());
|
||||
agent->setSystemButton(QWK::WindowAgentBase::Maximize, myTitleBar->maxButton());
|
||||
agent->setSystemButton(QWK::WindowAgentBase::Close, myTitleBar->closeButton());
|
||||
```
|
||||
|
||||
Doing this does not mean that these buttons' click events are automatically associated with window actions, you still need to manually connect the signals and slots to emulate the native window behaviors.
|
||||
|
||||
On macOS, this step can be skipped because it is better to use the buttons provided by the system.
|
||||
|
||||
Last but not least, set hit-test visible hint to let `WidgetWindowAgent` know other widgets that desire to receive mouse events.
|
||||
|
||||
```c++
|
||||
agent->setHitTestVisible(myTitleBar->menuBar(), true);
|
||||
```
|
||||
|
||||
The rest region within the title bar will be regarded as the draggable area for the user to move the window.
|
||||
|
||||
<!-- #### Window Attributes (Experimental)
|
||||
|
||||
On Windows 11, you can use this API to enable system effects.
|
||||
|
||||
```c++
|
||||
agent->setWindowAttribute("mica", true);
|
||||
```
|
||||
|
||||
Available keys: `mica`, `mica-alt`, `acrylic`, `dark-mode`. -->
|
||||
|
||||
### Qt Quick Application
|
||||
|
||||
#### Initialization
|
||||
|
||||
Make sure you have registered `QWindowKit` into QtQuick:
|
||||
|
||||
```cpp
|
||||
#include <QWKQuick/qwkquickglobal.h>
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
// ...
|
||||
QQmlApplicationEngine engine;
|
||||
// ...
|
||||
QWK::registerTypes(&engine);
|
||||
// ...
|
||||
}
|
||||
```
|
||||
|
||||
#### Setup Window Components
|
||||
|
||||
Then you can use `QWindowKit` data types and classes by importing it's URI:
|
||||
|
||||
```qml
|
||||
import QtQuick 2.15
|
||||
import QtQuick.Window 2.15
|
||||
import QWindowKit 1.0
|
||||
|
||||
Window {
|
||||
id: window
|
||||
visible: false // We hide it first, so we can move the window to our desired position silently.
|
||||
Component.onCompleted: {
|
||||
windowAgent.setup(window)
|
||||
window.visible = true
|
||||
}
|
||||
WindowAgent {
|
||||
id: windowAgent
|
||||
// ...
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
You can omit the version number or use "auto" instead of "1.0" for the module URI if you are using Qt6.
|
||||
|
||||
### Learn More
|
||||
|
||||
See [examples](examples) for more demo use cases. The examples have no High DPI support.
|
||||
|
||||
+ QWindowKit Internals [TODO]
|
||||
+ [FramelessHelper Related](docs/framelesshelper-related.md)
|
||||
|
||||
|
||||
### Vulnerabilities
|
||||
|
||||
+ Once you have made the window frameless, it will not be able to switch back to the system border.
|
||||
+ There must not be any internal child widget with `Qt::WA_NativeWindow` property enabled, otherwise the native features and display may be abnormal. Therefore, do not set any widget that has called `QWidget::winId()` or `QWidget::setAttribute(Qt::WA_NativeWindow)` as a descendant of a frameless window.
|
||||
+ If you really need to move widgets between different windows, make sure that the widget is not a top-level window and wrap it with a frameless container.
|
||||
|
||||
## TODO
|
||||
|
||||
+ Fix 5.15 window abnormal behavior
|
||||
+ More documentations
|
||||
+ When do we support Linux native features?
|
||||
|
||||
## Special Thanks
|
||||
|
||||
+ [Maplespe](https://github.com/Maplespe)
|
||||
+ [zhiyiYo](https://github.com/zhiyiYo)
|
||||
|
||||
## License
|
||||
|
||||
QWindowKit is licensed under the [Apache 2.0 License](./LICENSE).
|
||||
|
||||
<!--
|
||||
|
||||
**You MUST keep a copyright notice of QWindowKit in a prominent place on your project, such as the README document and the About Dialog.**
|
||||
|
||||
**You MUST NOT remove the license text from the header files and source files of QWindowKit.**
|
||||
|
||||
-->
|
89
KGCAPP/3rdparty/RibbonUI/lib_source/3rdparty/qwindowkit/docs/framelesshelper-related.md
vendored
Normal file
|
@ -0,0 +1,89 @@
|
|||
# FramelessHelper 2.x
|
||||
|
||||
Cross-platform window customization framework for Qt Widgets and Qt Quick. Supports Windows, Linux and macOS.
|
||||
|
||||
## Join with Us :triangular_flag_on_post:
|
||||
|
||||
You can join our [Discord channel](https://discord.gg/grrM4Tmesy) to communicate with us. You can share your findings, thoughts and ideas on improving / implementing FramelessHelper functionalities on more platforms and apps!
|
||||
|
||||
## More
|
||||
|
||||
### Title Bar Design Guidance
|
||||
|
||||
- Microsoft: <https://docs.microsoft.com/en-us/windows/apps/design/basics/titlebar-design>
|
||||
- KDE: <https://develop.kde.org/hig/>
|
||||
- GNOME: <https://developer.gnome.org/hig/patterns/containers/header-bars.html>
|
||||
- Apple: <https://developer.apple.com/design/human-interface-guidelines/macos/windows-and-views/window-anatomy/>
|
||||
|
||||
## Platform Notes
|
||||
|
||||
### Windows
|
||||
|
||||
- If DWM composition is disabled in some very rare cases (only possible on Windows 7), the top-left corner and top-right corner will appear in round shape. The round corners can be restored to square if you re-enable DWM composition.
|
||||
- There's an OpenGL driver bug which will cause some frameless windows have a strange black bar right on top of your homemade title bar, and it also makes the controls in your windows shifted to the bottom-right corner for some pixels. It's a bug of your graphics card driver, specifically, your OpenGL driver, not FramelessHelper. There are some solutions provided by our users but some of them may not work in all conditions, you can pick one from them:
|
||||
|
||||
Solution | Principle
|
||||
-------- | ---------
|
||||
Upgrade the graphics driver | Try to use a newer driver which may ship with the fix
|
||||
Change the system theme to "Basic" (in contrary to "Windows Aero") | Let Windows use pure software rendering
|
||||
If there are multiple graphics cards, use another one instead | Try to use a different driver which may don't have such bug at all
|
||||
Upgrade the system to at least Windows 11 | Windows 11 redesigned the windowing system so the bug can no longer be triggered
|
||||
Remove the `WS_THICKFRAME` and `WS_OVERLAPPED` styles from the window, and maybe also add the `WS_POPUP` style at the same time, and don't do anything inside the `WM_NCCALCSIZE` block (just return `false` directly or remove/comment out the whole block) | Try to mirror Qt's `FramelessWindowHint`'s behavior
|
||||
Use `Qt::FramelessWindowHint` instead of doing the `WM_NCCALCSIZE` trick | Qt's rendering code path is totally different between these two solutions
|
||||
Force Qt to use the ANGLE backend instead of the Desktop OpenGL | ANGLE will translate OpenGL directives into D3D ones
|
||||
Force Qt to use pure software rendering instead of rendering through OpenGL | Qt is not using OpenGL at all
|
||||
Force Qt to use the Mesa 3D libraries instead of normal OpenGL | Try to use a different OpenGL implementation
|
||||
Use Direct3D/Vulkan/Metal instead of OpenGL | Just don't use the buggy OpenGL
|
||||
|
||||
If you are lucky enough, one of them may fix the issue for you. If not, you may try to use multiple solutions together. **But I can't guarantee the issue can 100% be fixed.**
|
||||
- Due to there are many sub-versions of Windows 10, it's highly recommended to use the latest version of Windows 10, at least **no older than Windows 10 1809**. If you try to use this framework on some very old Windows 10 versions such as 1507 or 1607, there may be some compatibility issues. Using this framework on Windows 7 is also supported but not recommended. To get the most stable behavior and the best appearance, you should use it on the latest version of Windows 10 or Windows 11.
|
||||
- To make the snap layout work as expected, there are some additional rules for your homemade system buttons to follow:
|
||||
- **Add a manifest file to your application. In the manifest file, you need to claim your application supports Windows 11 explicitly. This step is VERY VERY IMPORTANT. Without this step, the snap layout feature can't be enabled.**
|
||||
- Call `setSystemButton()` for each button (it can be any *QWidget* or *QQuickItem*) to let FramelessHelper know which is the minimize/maximize/close button.
|
||||
|
||||
### Linux
|
||||
|
||||
- FramelessHelper will force your application to use the _XCB_ platform plugin when running on Wayland.
|
||||
- The resize area is inside of the window.
|
||||
|
||||
### macOS
|
||||
|
||||
- Some users reported that the window is not resizable on some old macOS versions.
|
||||
|
||||
## Special Thanks
|
||||
|
||||
*Ordered by first contribution time (it may not be very accurate, sorry)*
|
||||
|
||||
- [Yuhang Zhao](https://github.com/wangwenx190): Help me create this project. This project is mainly based on his code.
|
||||
- [Julien](https://github.com/JulienMaille): Help me test this library on many various environments and help me fix the bugs we found. Contributed many code to improve this library. The MainWindow example is mostly based on his code.
|
||||
- [Altair Wei](https://github.com/altairwei): Help me fix quite some small bugs and give me many important suggestions, the 2.x version is also inspired by his idea during our discussions.
|
||||
- [Kenji Mouri](https://github.com/MouriNaruto): Give me a lot of help on Win32 native developing.
|
||||
- [Dylan Liu](https://github.com/mentalfl0w): Help me improve the build process on macOS.
|
||||
- [SineStriker](https://github.com/SineStriker): Spent over a whole week helping me improve the Snap Layout implementation, fixing potential bugs and also give me a lot of professional and useful suggestions. Without his great effort, the new implementation may never come.
|
||||
- And also thanks to other contributors not listed here! Without their valuable help, this library wouldn't have such good quality and user experience!
|
||||
|
||||
## License
|
||||
|
||||
```text
|
||||
MIT License
|
||||
|
||||
Copyright (C) 2021-2023 by wangwenx190 (Yuhang Zhao)
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
```
|
BIN
KGCAPP/3rdparty/RibbonUI/lib_source/3rdparty/qwindowkit/docs/images/linux.png
vendored
Normal file
After Width: | Height: | Size: 53 KiB |
BIN
KGCAPP/3rdparty/RibbonUI/lib_source/3rdparty/qwindowkit/docs/images/mac.png
vendored
Normal file
After Width: | Height: | Size: 68 KiB |
BIN
KGCAPP/3rdparty/RibbonUI/lib_source/3rdparty/qwindowkit/docs/images/win10.png
vendored
Normal file
After Width: | Height: | Size: 37 KiB |
BIN
KGCAPP/3rdparty/RibbonUI/lib_source/3rdparty/qwindowkit/docs/images/win11.png
vendored
Normal file
After Width: | Height: | Size: 349 KiB |
23
KGCAPP/3rdparty/RibbonUI/lib_source/3rdparty/qwindowkit/examples/CMakeLists.txt
vendored
Normal file
|
@ -0,0 +1,23 @@
|
|||
set(QWK_EXAMPLES_DIR ${CMAKE_CURRENT_SOURCE_DIR})
|
||||
|
||||
macro(qwk_add_example _target)
|
||||
set(CMAKE_AUTOMOC ON)
|
||||
set(CMAKE_AUTOUIC ON)
|
||||
set(CMAKE_AUTORCC ON)
|
||||
|
||||
add_executable(${_target})
|
||||
qm_configure_target(${_target} ${ARGN})
|
||||
qm_add_win_rc(${_target} ICON ${QWK_EXAMPLES_DIR}/shared/resources/app/example.ico)
|
||||
qm_add_win_manifest(${_target})
|
||||
qm_add_mac_bundle(${_target} ICON ${QWK_EXAMPLES_DIR}/shared/resources/app/example.icns)
|
||||
endmacro()
|
||||
|
||||
add_subdirectory(shared)
|
||||
|
||||
if(QWINDOWKIT_BUILD_WIDGETS)
|
||||
add_subdirectory(mainwindow)
|
||||
endif()
|
||||
|
||||
if(QWINDOWKIT_BUILD_QUICK)
|
||||
add_subdirectory(qml)
|
||||
endif()
|
9
KGCAPP/3rdparty/RibbonUI/lib_source/3rdparty/qwindowkit/examples/mainwindow/CMakeLists.txt
vendored
Normal file
|
@ -0,0 +1,9 @@
|
|||
project(QWKExample_MainWindow)
|
||||
|
||||
file(GLOB _src *.h *.cpp)
|
||||
|
||||
qwk_add_example(${PROJECT_NAME}
|
||||
SOURCES ${_src} mainwindow.qrc ../shared/resources/shared.qrc
|
||||
QT_LINKS Core Gui Widgets # MultimediaWidgets
|
||||
LINKS QWKWidgets WidgetFrame
|
||||
)
|
158
KGCAPP/3rdparty/RibbonUI/lib_source/3rdparty/qwindowkit/examples/mainwindow/dark-style.qss
vendored
Normal file
|
@ -0,0 +1,158 @@
|
|||
/* Window bar */
|
||||
|
||||
QWK--WindowBar[bar-active=true] {
|
||||
background-color: #3C3C3C;
|
||||
}
|
||||
|
||||
QWK--WindowBar[bar-active=false] {
|
||||
background-color: #505050;
|
||||
}
|
||||
|
||||
|
||||
/* Title label */
|
||||
|
||||
QWK--WindowBar>QLabel#win-title-label {
|
||||
padding: 0;
|
||||
border: none;
|
||||
color: #ECECEC;
|
||||
background-color: transparent;
|
||||
min-height: 28px;
|
||||
}
|
||||
|
||||
|
||||
/* System buttons */
|
||||
|
||||
QWK--WindowBar>QAbstractButton[system-button=true] {
|
||||
qproperty-iconSize: 12px 12px;
|
||||
min-width: 50px;
|
||||
border: none;
|
||||
padding: 0;
|
||||
background-color: transparent;
|
||||
}
|
||||
|
||||
QWK--WindowBar>QAbstractButton#min-button {
|
||||
qproperty-iconNormal: url(":/window-bar/minimize.svg");
|
||||
qproperty-iconSize: 12px 12px;
|
||||
}
|
||||
|
||||
QWK--WindowBar>QAbstractButton#min-button:hover,
|
||||
QWK--WindowBar>QAbstractButton#min-button:pressed {
|
||||
background-color: rgba(255, 255, 255, 15%);
|
||||
}
|
||||
|
||||
QWK--WindowBar>QAbstractButton#max-button {
|
||||
qproperty-iconNormal: url(":/window-bar/maximize.svg");
|
||||
qproperty-iconChecked: url(":/window-bar/restore.svg");
|
||||
}
|
||||
|
||||
QWK--WindowBar>QAbstractButton#max-button:hover,
|
||||
QWK--WindowBar>QAbstractButton#max-button:pressed {
|
||||
background-color: rgba(255, 255, 255, 15%);
|
||||
}
|
||||
|
||||
QWK--WindowBar>QAbstractButton#close-button {
|
||||
qproperty-iconNormal: url(":/window-bar/close.svg");
|
||||
}
|
||||
|
||||
QWK--WindowBar>QAbstractButton#close-button:hover,
|
||||
QWK--WindowBar>QAbstractButton#close-button:pressed {
|
||||
background-color: #e81123;
|
||||
}
|
||||
|
||||
|
||||
/* Icon button */
|
||||
|
||||
QWK--WindowBar>QAbstractButton#icon-button {
|
||||
qproperty-iconNormal: url(":/app/example.png");
|
||||
qproperty-iconSize: 18px 18px;
|
||||
min-width: 40px;
|
||||
border: none;
|
||||
padding: 0;
|
||||
background-color: transparent;
|
||||
}
|
||||
|
||||
|
||||
/* Menu Bar */
|
||||
|
||||
QMenuBar {
|
||||
background-color: transparent;
|
||||
border: none;
|
||||
}
|
||||
|
||||
QMenuBar>QToolButton#qt_menubar_ext_button {
|
||||
qproperty-icon: url(":/window-bar/more-line.svg");
|
||||
}
|
||||
|
||||
QMenuBar>QToolButton#qt_menubar_ext_button:hover,
|
||||
QMenuBar>QToolButton#qt_menubar_ext_button:pressed {
|
||||
background-color: rgba(255, 255, 255, 10%);
|
||||
}
|
||||
|
||||
QMenuBar::item {
|
||||
color: #CCCCCC;
|
||||
border: none;
|
||||
padding: 8px 12px;
|
||||
}
|
||||
|
||||
QMenuBar::item:selected {
|
||||
background-color: rgba(255, 255, 255, 10%);
|
||||
}
|
||||
|
||||
|
||||
/* Menu */
|
||||
|
||||
QMenu {
|
||||
padding: 4px;
|
||||
background: #303030;
|
||||
border: 1px solid transparent;
|
||||
}
|
||||
|
||||
QMenu::indicator {
|
||||
left: 6px;
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
}
|
||||
|
||||
QMenu::icon {
|
||||
left: 6px;
|
||||
}
|
||||
|
||||
QMenu::item {
|
||||
background: transparent;
|
||||
color: #CCCCCC;
|
||||
padding: 6px 24px;
|
||||
}
|
||||
|
||||
QMenu::item:selected {
|
||||
color: white;
|
||||
background-color: #0060C0;
|
||||
}
|
||||
|
||||
QMenu::item:disabled {
|
||||
color: #666666;
|
||||
background-color: transparent;
|
||||
}
|
||||
|
||||
QMenu::separator {
|
||||
height: 2px;
|
||||
background-color: #5B5B5B;
|
||||
margin: 6px 0;
|
||||
}
|
||||
|
||||
|
||||
/* Window */
|
||||
|
||||
MainWindow {
|
||||
background-color: #1E1E1E;
|
||||
}
|
||||
|
||||
MainWindow[custom-style=true] {
|
||||
background-color: transparent;
|
||||
}
|
||||
|
||||
QWidget#clock-widget {
|
||||
font-size: 75px;
|
||||
color: #FEFEFE;
|
||||
font-weight: bold;
|
||||
background-color: transparent;
|
||||
}
|
156
KGCAPP/3rdparty/RibbonUI/lib_source/3rdparty/qwindowkit/examples/mainwindow/light-style.qss
vendored
Normal file
|
@ -0,0 +1,156 @@
|
|||
/* Window bar */
|
||||
|
||||
QWK--WindowBar[bar-active=true] {
|
||||
background-color: #195ABE;
|
||||
}
|
||||
|
||||
QWK--WindowBar[bar-active=false] {
|
||||
background-color: #195ABE;
|
||||
}
|
||||
|
||||
|
||||
/* Title label */
|
||||
|
||||
QWK--WindowBar>QLabel#win-title-label {
|
||||
padding: 0;
|
||||
border: none;
|
||||
color: #ECECEC;
|
||||
background-color: transparent;
|
||||
min-height: 28px;
|
||||
}
|
||||
|
||||
|
||||
/* System buttons */
|
||||
|
||||
QWK--WindowBar>QAbstractButton[system-button=true] {
|
||||
qproperty-iconSize: 12px 12px;
|
||||
min-width: 50px;
|
||||
border: none;
|
||||
padding: 0;
|
||||
background-color: transparent;
|
||||
}
|
||||
|
||||
QWK--WindowBar>QAbstractButton#min-button {
|
||||
qproperty-iconNormal: url(":/window-bar/minimize.svg");
|
||||
qproperty-iconSize: 12px 12px;
|
||||
}
|
||||
|
||||
QWK--WindowBar>QAbstractButton#min-button:hover,
|
||||
QWK--WindowBar>QAbstractButton#min-button:pressed {
|
||||
background-color: rgba(0, 0, 0, 15%);
|
||||
}
|
||||
|
||||
QWK--WindowBar>QAbstractButton#max-button {
|
||||
qproperty-iconNormal: url(":/window-bar/maximize.svg");
|
||||
qproperty-iconChecked: url(":/window-bar/restore.svg");
|
||||
}
|
||||
|
||||
QWK--WindowBar>QAbstractButton#max-button:hover,
|
||||
QWK--WindowBar>QAbstractButton#max-button:pressed {
|
||||
background-color: rgba(0, 0, 0, 15%);
|
||||
}
|
||||
|
||||
QWK--WindowBar>QAbstractButton#close-button {
|
||||
qproperty-iconNormal: url(":/window-bar/close.svg");
|
||||
}
|
||||
|
||||
QWK--WindowBar>QAbstractButton#close-button:hover,
|
||||
QWK--WindowBar>QAbstractButton#close-button:pressed {
|
||||
background-color: #e81123;
|
||||
}
|
||||
|
||||
|
||||
/* Icon button */
|
||||
|
||||
QWK--WindowBar>QAbstractButton#icon-button {
|
||||
qproperty-iconNormal: url(":/app/example.png");
|
||||
qproperty-iconSize: 18px 18px;
|
||||
min-width: 40px;
|
||||
border: none;
|
||||
padding: 0;
|
||||
background-color: transparent;
|
||||
}
|
||||
|
||||
|
||||
/* Menu Bar */
|
||||
|
||||
QMenuBar {
|
||||
background-color: transparent;
|
||||
border: none;
|
||||
}
|
||||
|
||||
QMenuBar>QToolButton#qt_menubar_ext_button {
|
||||
qproperty-icon: url(":/window-bar/more-line.svg");
|
||||
}
|
||||
|
||||
QMenuBar>QToolButton#qt_menubar_ext_button:hover,
|
||||
QMenuBar>QToolButton#qt_menubar_ext_button:pressed {
|
||||
background-color: rgba(255, 255, 255, 10%);
|
||||
}
|
||||
|
||||
QMenuBar::item {
|
||||
color: #EEEEEE;
|
||||
border: none;
|
||||
padding: 8px 12px;
|
||||
}
|
||||
|
||||
QMenuBar::item:selected {
|
||||
background-color: rgba(255, 255, 255, 10%);
|
||||
}
|
||||
|
||||
|
||||
/* Menu */
|
||||
|
||||
QMenu {
|
||||
padding: 4px;
|
||||
background: white;
|
||||
border: 1px solid #E0E0E0;
|
||||
}
|
||||
|
||||
QMenu::indicator {
|
||||
left: 6px;
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
}
|
||||
|
||||
QMenu::icon {
|
||||
left: 6px;
|
||||
}
|
||||
|
||||
QMenu::item {
|
||||
background: transparent;
|
||||
color: #333333;
|
||||
padding: 6px 24px;
|
||||
}
|
||||
|
||||
QMenu::item:selected {
|
||||
background-color: rgba(0, 0, 0, 10%);
|
||||
}
|
||||
|
||||
QMenu::item:disabled {
|
||||
color: #CCCCCC;
|
||||
}
|
||||
|
||||
QMenu::separator {
|
||||
height: 2px;
|
||||
background-color: #CCCCCC;
|
||||
margin: 6px 0;
|
||||
}
|
||||
|
||||
|
||||
/* Window */
|
||||
|
||||
MainWindow {
|
||||
background-color: #F3F3F3;
|
||||
}
|
||||
|
||||
MainWindow[custom-style=true] {
|
||||
background-color: transparent;
|
||||
}
|
||||
|
||||
QWidget#clock-widget {
|
||||
font-size: 75px;
|
||||
color: #333333;
|
||||
font-weight: bold;
|
||||
background-color: transparent;
|
||||
}
|
41
KGCAPP/3rdparty/RibbonUI/lib_source/3rdparty/qwindowkit/examples/mainwindow/main.cpp
vendored
Normal file
|
@ -0,0 +1,41 @@
|
|||
// Copyright (C) 2023-2024 Stdware Collections (https://www.github.com/stdware)
|
||||
// Copyright (C) 2021-2023 wangwenx190 (Yuhang Zhao)
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
#include <QtWidgets/QApplication>
|
||||
|
||||
#include "mainwindow.h"
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
qputenv("QT_WIN_DEBUG_CONSOLE", "attach");
|
||||
qputenv("QSG_INFO", "1");
|
||||
#if 0
|
||||
qputenv("QT_WIDGETS_RHI", "1");
|
||||
qputenv("QSG_RHI_BACKEND", "d3d12");
|
||||
qputenv("QSG_RHI_HDR", "scrgb");
|
||||
qputenv("QT_QPA_DISABLE_REDIRECTION_SURFACE", "1");
|
||||
|
||||
QGuiApplication::setHighDpiScaleFactorRoundingPolicy(
|
||||
Qt::HighDpiScaleFactorRoundingPolicy::PassThrough);
|
||||
#endif
|
||||
|
||||
QApplication a(argc, argv);
|
||||
|
||||
#if 0 && defined(Q_OS_WINDOWS) && QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
|
||||
QApplication::setFont([]() {
|
||||
QFont f("Microsoft YaHei");
|
||||
f.setStyleStrategy(QFont::PreferAntialias);
|
||||
f.setPixelSize(15);
|
||||
return f;
|
||||
}());
|
||||
#endif
|
||||
|
||||
MainWindow w;
|
||||
w.show();
|
||||
|
||||
#if 0
|
||||
QMainWindow w2;
|
||||
w2.show();
|
||||
#endif
|
||||
return a.exec();
|
||||
}
|
372
KGCAPP/3rdparty/RibbonUI/lib_source/3rdparty/qwindowkit/examples/mainwindow/mainwindow.cpp
vendored
Normal file
|
@ -0,0 +1,372 @@
|
|||
// Copyright (C) 2023-2024 Stdware Collections (https://www.github.com/stdware)
|
||||
// Copyright (C) 2021-2023 wangwenx190 (Yuhang Zhao)
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
#include "mainwindow.h"
|
||||
|
||||
#include <QtCore/QDebug>
|
||||
#include <QtCore/QFile>
|
||||
#include <QtCore/QTime>
|
||||
#include <QtCore/QTimer>
|
||||
#include <QtGui/QPainter>
|
||||
#include <QtGui/QWindow>
|
||||
#include <QtWidgets/QApplication>
|
||||
#include <QtWidgets/QStyle>
|
||||
#include <QtWidgets/QPushButton>
|
||||
#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
|
||||
# include <QtGui/QActionGroup>
|
||||
#else
|
||||
# include <QtWidgets/QActionGroup>
|
||||
#endif
|
||||
|
||||
// #include <QtWebEngineWidgets/QWebEngineView>
|
||||
|
||||
#include <QWKWidgets/widgetwindowagent.h>
|
||||
|
||||
#include <widgetframe/windowbar.h>
|
||||
#include <widgetframe/windowbutton.h>
|
||||
|
||||
class ClockWidget : public QLabel {
|
||||
public:
|
||||
explicit ClockWidget(QWidget *parent = nullptr) : QLabel(parent) {
|
||||
startTimer(100);
|
||||
setAlignment(Qt::AlignCenter);
|
||||
}
|
||||
|
||||
~ClockWidget() override = default;
|
||||
|
||||
protected:
|
||||
void timerEvent(QTimerEvent *event) override {
|
||||
setText(QTime::currentTime().toString(QStringLiteral("hh:mm:ss")));
|
||||
}
|
||||
};
|
||||
|
||||
MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent) {
|
||||
installWindowAgent();
|
||||
|
||||
#if 1
|
||||
auto clockWidget = new ClockWidget();
|
||||
clockWidget->setObjectName(QStringLiteral("clock-widget"));
|
||||
clockWidget->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
|
||||
setCentralWidget(clockWidget);
|
||||
#else
|
||||
auto webView = new QWebEngineView();
|
||||
webView->load(QUrl("https://www.baidu.com"));
|
||||
setCentralWidget(webView);
|
||||
#endif
|
||||
|
||||
loadStyleSheet(Dark);
|
||||
|
||||
setWindowTitle(tr("Example MainWindow"));
|
||||
resize(800, 600);
|
||||
|
||||
// windowAgent->centralize();
|
||||
}
|
||||
|
||||
static inline void emulateLeaveEvent(QWidget *widget) {
|
||||
Q_ASSERT(widget);
|
||||
if (!widget) {
|
||||
return;
|
||||
}
|
||||
QTimer::singleShot(0, widget, [widget]() {
|
||||
#if (QT_VERSION >= QT_VERSION_CHECK(5, 14, 0))
|
||||
const QScreen *screen = widget->screen();
|
||||
#else
|
||||
const QScreen *screen = widget->windowHandle()->screen();
|
||||
#endif
|
||||
const QPoint globalPos = QCursor::pos(screen);
|
||||
if (!QRect(widget->mapToGlobal(QPoint{0, 0}), widget->size()).contains(globalPos)) {
|
||||
QCoreApplication::postEvent(widget, new QEvent(QEvent::Leave));
|
||||
if (widget->testAttribute(Qt::WA_Hover)) {
|
||||
const QPoint localPos = widget->mapFromGlobal(globalPos);
|
||||
const QPoint scenePos = widget->window()->mapFromGlobal(globalPos);
|
||||
static constexpr const auto oldPos = QPoint{};
|
||||
const Qt::KeyboardModifiers modifiers = QGuiApplication::keyboardModifiers();
|
||||
#if (QT_VERSION >= QT_VERSION_CHECK(6, 4, 0))
|
||||
const auto event =
|
||||
new QHoverEvent(QEvent::HoverLeave, scenePos, globalPos, oldPos, modifiers);
|
||||
Q_UNUSED(localPos);
|
||||
#elif (QT_VERSION >= QT_VERSION_CHECK(6, 3, 0))
|
||||
const auto event = new QHoverEvent(QEvent::HoverLeave, localPos, globalPos, oldPos, modifiers);
|
||||
Q_UNUSED(scenePos);
|
||||
#else
|
||||
const auto event = new QHoverEvent(QEvent::HoverLeave, localPos, oldPos, modifiers);
|
||||
Q_UNUSED(scenePos);
|
||||
#endif
|
||||
QCoreApplication::postEvent(widget, event);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
MainWindow::~MainWindow() = default;
|
||||
|
||||
bool MainWindow::event(QEvent *event) {
|
||||
switch (event->type()) {
|
||||
case QEvent::WindowActivate: {
|
||||
auto menu = menuWidget();
|
||||
menu->setProperty("bar-active", true);
|
||||
style()->polish(menu);
|
||||
break;
|
||||
}
|
||||
|
||||
case QEvent::WindowDeactivate: {
|
||||
auto menu = menuWidget();
|
||||
menu->setProperty("bar-active", false);
|
||||
style()->polish(menu);
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return QMainWindow::event(event);
|
||||
}
|
||||
|
||||
|
||||
void MainWindow::closeEvent(QCloseEvent *event) {
|
||||
// if (!(qApp->keyboardModifiers() & Qt::ControlModifier)) {
|
||||
// QTimer::singleShot(1000, this, &QWidget::show);
|
||||
// }
|
||||
event->accept();
|
||||
}
|
||||
|
||||
void MainWindow::installWindowAgent() {
|
||||
// 1. Setup window agent
|
||||
windowAgent = new QWK::WidgetWindowAgent(this);
|
||||
windowAgent->setup(this);
|
||||
|
||||
// 2. Construct your title bar
|
||||
auto menuBar = [this]() {
|
||||
auto menuBar = new QMenuBar();
|
||||
|
||||
// Virtual menu
|
||||
auto file = new QMenu(tr("File(&F)"), menuBar);
|
||||
file->addAction(new QAction(tr("New(&N)"), menuBar));
|
||||
file->addAction(new QAction(tr("Open(&O)"), menuBar));
|
||||
file->addSeparator();
|
||||
|
||||
auto edit = new QMenu(tr("Edit(&E)"), menuBar);
|
||||
edit->addAction(new QAction(tr("Undo(&U)"), menuBar));
|
||||
edit->addAction(new QAction(tr("Redo(&R)"), menuBar));
|
||||
|
||||
// Theme action
|
||||
auto darkAction = new QAction(tr("Enable dark theme"), menuBar);
|
||||
darkAction->setCheckable(true);
|
||||
connect(darkAction, &QAction::triggered, this, [this](bool checked) {
|
||||
loadStyleSheet(checked ? Dark : Light); //
|
||||
});
|
||||
connect(this, &MainWindow::themeChanged, darkAction, [this, darkAction]() {
|
||||
darkAction->setChecked(currentTheme == Dark); //
|
||||
});
|
||||
|
||||
#ifdef Q_OS_WIN
|
||||
auto dwmBlurAction = new QAction(tr("Enable DWM blur"), menuBar);
|
||||
dwmBlurAction->setCheckable(true);
|
||||
connect(dwmBlurAction, &QAction::toggled, this, [this](bool checked) {
|
||||
if (!windowAgent->setWindowAttribute(QStringLiteral("dwm-blur"), checked)) {
|
||||
return;
|
||||
}
|
||||
setProperty("custom-style", checked);
|
||||
style()->polish(this);
|
||||
});
|
||||
|
||||
auto acrylicAction = new QAction(tr("Enable acrylic material"), menuBar);
|
||||
acrylicAction->setCheckable(true);
|
||||
connect(acrylicAction, &QAction::toggled, this, [this](bool checked) {
|
||||
if (!windowAgent->setWindowAttribute(QStringLiteral("acrylic-material"), true)) {
|
||||
return;
|
||||
}
|
||||
setProperty("custom-style", checked);
|
||||
style()->polish(this);
|
||||
});
|
||||
|
||||
auto micaAction = new QAction(tr("Enable mica"), menuBar);
|
||||
micaAction->setCheckable(true);
|
||||
connect(micaAction, &QAction::toggled, this, [this](bool checked) {
|
||||
if (!windowAgent->setWindowAttribute(QStringLiteral("mica"), checked)) {
|
||||
return;
|
||||
}
|
||||
setProperty("custom-style", checked);
|
||||
style()->polish(this);
|
||||
});
|
||||
|
||||
auto micaAltAction = new QAction(tr("Enable mica alt"), menuBar);
|
||||
micaAltAction->setCheckable(true);
|
||||
connect(micaAltAction, &QAction::toggled, this, [this](bool checked) {
|
||||
if (!windowAgent->setWindowAttribute(QStringLiteral("mica-alt"), checked)) {
|
||||
return;
|
||||
}
|
||||
setProperty("custom-style", checked);
|
||||
style()->polish(this);
|
||||
});
|
||||
#elif defined(Q_OS_MAC)
|
||||
auto darkBlurAction = new QAction(tr("Dark blur"), menuBar);
|
||||
darkBlurAction->setCheckable(true);
|
||||
connect(darkBlurAction, &QAction::toggled, this, [this](bool checked) {
|
||||
if (!windowAgent->setWindowAttribute(QStringLiteral("blur-effect"), "dark")) {
|
||||
return;
|
||||
}
|
||||
if (checked) {
|
||||
setProperty("custom-style", true);
|
||||
style()->polish(this);
|
||||
}
|
||||
});
|
||||
|
||||
auto lightBlurAction = new QAction(tr("Light blur"), menuBar);
|
||||
lightBlurAction->setCheckable(true);
|
||||
connect(lightBlurAction, &QAction::toggled, this, [this](bool checked) {
|
||||
if (!windowAgent->setWindowAttribute(QStringLiteral("blur-effect"), "light")) {
|
||||
return;
|
||||
}
|
||||
if (checked) {
|
||||
setProperty("custom-style", true);
|
||||
style()->polish(this);
|
||||
}
|
||||
});
|
||||
|
||||
auto noBlurAction = new QAction(tr("No blur"), menuBar);
|
||||
noBlurAction->setCheckable(true);
|
||||
connect(noBlurAction, &QAction::toggled, this, [this](bool checked) {
|
||||
if (!windowAgent->setWindowAttribute(QStringLiteral("blur-effect"), "none")) {
|
||||
return;
|
||||
}
|
||||
if (checked) {
|
||||
setProperty("custom-style", false);
|
||||
style()->polish(this);
|
||||
}
|
||||
});
|
||||
|
||||
auto macStyleGroup = new QActionGroup(menuBar);
|
||||
macStyleGroup->addAction(darkBlurAction);
|
||||
macStyleGroup->addAction(lightBlurAction);
|
||||
macStyleGroup->addAction(noBlurAction);
|
||||
#endif
|
||||
|
||||
// Real menu
|
||||
auto settings = new QMenu(tr("Settings(&S)"), menuBar);
|
||||
settings->addAction(darkAction);
|
||||
|
||||
#ifdef Q_OS_WIN
|
||||
settings->addSeparator();
|
||||
settings->addAction(dwmBlurAction);
|
||||
settings->addAction(acrylicAction);
|
||||
settings->addAction(micaAction);
|
||||
settings->addAction(micaAltAction);
|
||||
#elif defined(Q_OS_MAC)
|
||||
settings->addAction(darkBlurAction);
|
||||
settings->addAction(lightBlurAction);
|
||||
settings->addAction(noBlurAction);
|
||||
#endif
|
||||
|
||||
menuBar->addMenu(file);
|
||||
menuBar->addMenu(edit);
|
||||
menuBar->addMenu(settings);
|
||||
return menuBar;
|
||||
}();
|
||||
menuBar->setObjectName(QStringLiteral("win-menu-bar"));
|
||||
|
||||
auto titleLabel = new QLabel();
|
||||
titleLabel->setAlignment(Qt::AlignCenter);
|
||||
titleLabel->setObjectName(QStringLiteral("win-title-label"));
|
||||
|
||||
#ifndef Q_OS_MAC
|
||||
auto iconButton = new QWK::WindowButton();
|
||||
iconButton->setObjectName(QStringLiteral("icon-button"));
|
||||
iconButton->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred);
|
||||
|
||||
auto minButton = new QWK::WindowButton();
|
||||
minButton->setObjectName(QStringLiteral("min-button"));
|
||||
minButton->setProperty("system-button", true);
|
||||
minButton->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred);
|
||||
|
||||
auto maxButton = new QWK::WindowButton();
|
||||
maxButton->setCheckable(true);
|
||||
maxButton->setObjectName(QStringLiteral("max-button"));
|
||||
maxButton->setProperty("system-button", true);
|
||||
maxButton->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred);
|
||||
|
||||
auto closeButton = new QWK::WindowButton();
|
||||
closeButton->setObjectName(QStringLiteral("close-button"));
|
||||
closeButton->setProperty("system-button", true);
|
||||
closeButton->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred);
|
||||
#endif
|
||||
|
||||
auto windowBar = new QWK::WindowBar();
|
||||
#ifndef Q_OS_MAC
|
||||
windowBar->setIconButton(iconButton);
|
||||
windowBar->setMinButton(minButton);
|
||||
windowBar->setMaxButton(maxButton);
|
||||
windowBar->setCloseButton(closeButton);
|
||||
#endif
|
||||
windowBar->setMenuBar(menuBar);
|
||||
windowBar->setTitleLabel(titleLabel);
|
||||
windowBar->setHostWidget(this);
|
||||
|
||||
windowAgent->setTitleBar(windowBar);
|
||||
#ifndef Q_OS_MAC
|
||||
windowAgent->setSystemButton(QWK::WindowAgentBase::WindowIcon, iconButton);
|
||||
windowAgent->setSystemButton(QWK::WindowAgentBase::Minimize, minButton);
|
||||
windowAgent->setSystemButton(QWK::WindowAgentBase::Maximize, maxButton);
|
||||
windowAgent->setSystemButton(QWK::WindowAgentBase::Close, closeButton);
|
||||
#endif
|
||||
windowAgent->setHitTestVisible(menuBar, true);
|
||||
|
||||
#ifdef Q_OS_MAC
|
||||
windowAgent->setSystemButtonAreaCallback([](const QSize &size) {
|
||||
static constexpr const int width = 75;
|
||||
return QRect(QPoint(size.width() - width, 0), QSize(width, size.height())); //
|
||||
});
|
||||
#endif
|
||||
|
||||
setMenuWidget(windowBar);
|
||||
|
||||
// 3. Adds simulated mouse events to the title bar buttons
|
||||
#ifdef Q_OS_WINDOWS
|
||||
// Emulate Window system menu button behaviors
|
||||
connect(iconButton, &QAbstractButton::clicked, windowAgent, [this, iconButton] {
|
||||
iconButton->setProperty("double-click-close", false);
|
||||
|
||||
// Pick a suitable time threshold
|
||||
QTimer::singleShot(75, windowAgent, [this, iconButton]() {
|
||||
if (iconButton->property("double-click-close").toBool())
|
||||
return;
|
||||
windowAgent->showSystemMenu(iconButton->mapToGlobal(QPoint{0, iconButton->height()}));
|
||||
});
|
||||
});
|
||||
connect(iconButton, &QWK::WindowButton::doubleClicked, this, [iconButton, this]() {
|
||||
iconButton->setProperty("double-click-close", true);
|
||||
close();
|
||||
});
|
||||
#endif
|
||||
|
||||
#ifndef Q_OS_MAC
|
||||
connect(windowBar, &QWK::WindowBar::minimizeRequested, this, &QWidget::showMinimized);
|
||||
connect(windowBar, &QWK::WindowBar::maximizeRequested, this, [this, maxButton](bool max) {
|
||||
if (max) {
|
||||
showMaximized();
|
||||
} else {
|
||||
showNormal();
|
||||
}
|
||||
|
||||
// It's a Qt issue that if a QAbstractButton::clicked triggers a window's maximization,
|
||||
// the button remains to be hovered until the mouse move. As a result, we need to
|
||||
// manually send leave events to the button.
|
||||
emulateLeaveEvent(maxButton);
|
||||
});
|
||||
connect(windowBar, &QWK::WindowBar::closeRequested, this, &QWidget::close);
|
||||
#endif
|
||||
}
|
||||
|
||||
void MainWindow::loadStyleSheet(Theme theme) {
|
||||
if (!styleSheet().isEmpty() && theme == currentTheme)
|
||||
return;
|
||||
currentTheme = theme;
|
||||
|
||||
if (QFile qss(theme == Dark ? QStringLiteral(":/dark-style.qss")
|
||||
: QStringLiteral(":/light-style.qss"));
|
||||
qss.open(QIODevice::ReadOnly | QIODevice::Text)) {
|
||||
setStyleSheet(QString::fromUtf8(qss.readAll()));
|
||||
Q_EMIT themeChanged();
|
||||
}
|
||||
}
|
44
KGCAPP/3rdparty/RibbonUI/lib_source/3rdparty/qwindowkit/examples/mainwindow/mainwindow.h
vendored
Normal file
|
@ -0,0 +1,44 @@
|
|||
// Copyright (C) 2023-2024 Stdware Collections (https://www.github.com/stdware)
|
||||
// Copyright (C) 2021-2023 wangwenx190 (Yuhang Zhao)
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
#ifndef MAINWINDOW_H
|
||||
#define MAINWINDOW_H
|
||||
|
||||
#include <QtWidgets/QMainWindow>
|
||||
|
||||
namespace QWK {
|
||||
class WidgetWindowAgent;
|
||||
class StyleAgent;
|
||||
}
|
||||
|
||||
class MainWindow : public QMainWindow {
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit MainWindow(QWidget *parent = nullptr);
|
||||
~MainWindow() override;
|
||||
|
||||
enum Theme {
|
||||
Dark,
|
||||
Light,
|
||||
};
|
||||
Q_ENUM(Theme)
|
||||
|
||||
Q_SIGNALS:
|
||||
void themeChanged();
|
||||
|
||||
protected:
|
||||
bool event(QEvent *event) override;
|
||||
|
||||
void closeEvent(QCloseEvent *event) override;
|
||||
|
||||
private:
|
||||
void installWindowAgent();
|
||||
void loadStyleSheet(Theme theme);
|
||||
|
||||
Theme currentTheme{};
|
||||
|
||||
QWK::WidgetWindowAgent *windowAgent;
|
||||
};
|
||||
|
||||
#endif // MAINWINDOW_H
|
6
KGCAPP/3rdparty/RibbonUI/lib_source/3rdparty/qwindowkit/examples/mainwindow/mainwindow.qrc
vendored
Normal file
|
@ -0,0 +1,6 @@
|
|||
<RCC>
|
||||
<qresource prefix="/">
|
||||
<file>dark-style.qss</file>
|
||||
<file>light-style.qss</file>
|
||||
</qresource>
|
||||
</RCC>
|
14
KGCAPP/3rdparty/RibbonUI/lib_source/3rdparty/qwindowkit/examples/qml/CMakeLists.txt
vendored
Normal file
|
@ -0,0 +1,14 @@
|
|||
project(QWKExample_QML)
|
||||
|
||||
file(GLOB _src *.h *.cpp *.qrc)
|
||||
|
||||
qwk_add_example(${PROJECT_NAME}
|
||||
SOURCES ${_src} ../shared/resources/shared.qrc
|
||||
QT_LINKS Core Gui Qml Quick
|
||||
LINKS QWKQuick
|
||||
)
|
||||
|
||||
set_target_properties(${PROJECT_NAME} PROPERTIES
|
||||
CXX_STANDARD 17
|
||||
CXX_STANDARD_REQUIRED TRUE
|
||||
)
|
39
KGCAPP/3rdparty/RibbonUI/lib_source/3rdparty/qwindowkit/examples/qml/QWKButton.qml
vendored
Normal file
|
@ -0,0 +1,39 @@
|
|||
import QtQuick 2.15
|
||||
import QtQuick.Controls 2.15
|
||||
|
||||
Button {
|
||||
id: root
|
||||
width: height * 1.5
|
||||
leftPadding: 0
|
||||
topPadding: 0
|
||||
rightPadding: 0
|
||||
bottomPadding: 0
|
||||
leftInset: 0
|
||||
topInset: 0
|
||||
rightInset: 0
|
||||
bottomInset: 0
|
||||
property alias source: image.source
|
||||
contentItem: Item {
|
||||
Image {
|
||||
id: image
|
||||
anchors.centerIn: parent
|
||||
mipmap: true
|
||||
width: 12
|
||||
height: 12
|
||||
}
|
||||
}
|
||||
background: Rectangle {
|
||||
color: {
|
||||
if (!root.enabled) {
|
||||
return "gray";
|
||||
}
|
||||
if (root.pressed) {
|
||||
return Qt.rgba(0, 0, 0, 0.15);
|
||||
}
|
||||
if (root.hovered) {
|
||||
return Qt.rgba(0, 0, 0, 0.15);
|
||||
}
|
||||
return "transparent";
|
||||
}
|
||||
}
|
||||
}
|
33
KGCAPP/3rdparty/RibbonUI/lib_source/3rdparty/qwindowkit/examples/qml/main.cpp
vendored
Normal file
|
@ -0,0 +1,33 @@
|
|||
// Copyright (C) 2023-2024 Stdware Collections (https://www.github.com/stdware)
|
||||
// Copyright (C) 2021-2023 wangwenx190 (Yuhang Zhao)
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
#include <QtGui/QGuiApplication>
|
||||
#include <QtQml/QQmlApplicationEngine>
|
||||
#include <QtQuick/QQuickWindow>
|
||||
|
||||
#include <QWKQuick/qwkquickglobal.h>
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
qputenv("QT_WIN_DEBUG_CONSOLE", "attach");
|
||||
qputenv("QSG_INFO", "1");
|
||||
#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
|
||||
qputenv("QT_QUICK_CONTROLS_STYLE", "Basic");
|
||||
#else
|
||||
qputenv("QT_QUICK_CONTROLS_STYLE", "Default");
|
||||
#endif
|
||||
#if 0
|
||||
qputenv("QSG_RHI_BACKEND", "opengl");
|
||||
//qputenv("QSG_RHI_HDR", "scrgb");
|
||||
//qputenv("QT_QPA_DISABLE_REDIRECTION_SURFACE", "1");
|
||||
QGuiApplication::setHighDpiScaleFactorRoundingPolicy(
|
||||
Qt::HighDpiScaleFactorRoundingPolicy::PassThrough);
|
||||
#endif
|
||||
QGuiApplication application(argc, argv);
|
||||
// Make sure alpha channel is requested, our special effects on Windows depends on it.
|
||||
QQuickWindow::setDefaultAlphaBuffer(true);
|
||||
QQmlApplicationEngine engine;
|
||||
QWK::registerTypes(&engine);
|
||||
engine.load(QUrl(QStringLiteral("qrc:///main.qml")));
|
||||
return application.exec();
|
||||
}
|
220
KGCAPP/3rdparty/RibbonUI/lib_source/3rdparty/qwindowkit/examples/qml/main.qml
vendored
Normal file
|
@ -0,0 +1,220 @@
|
|||
import QtQuick 2.15
|
||||
import QtQuick.Window 2.15
|
||||
import QtQuick.Controls 2.15
|
||||
import Qt.labs.platform 1.1
|
||||
import QWindowKit 1.0
|
||||
|
||||
Window {
|
||||
id: window
|
||||
width: 800
|
||||
height: 600
|
||||
color: darkStyle.windowBackgroundColor
|
||||
title: qsTr("Hello, world!")
|
||||
Component.onCompleted: {
|
||||
windowAgent.setup(window)
|
||||
window.visible = true
|
||||
}
|
||||
|
||||
QtObject {
|
||||
id: lightStyle
|
||||
}
|
||||
|
||||
QtObject {
|
||||
id: darkStyle
|
||||
readonly property color windowBackgroundColor: "#1E1E1E"
|
||||
}
|
||||
|
||||
Timer {
|
||||
interval: 100
|
||||
running: true
|
||||
repeat: true
|
||||
onTriggered: timeLabel.text = Qt.formatTime(new Date(), "hh:mm:ss")
|
||||
}
|
||||
|
||||
WindowAgent {
|
||||
id: windowAgent
|
||||
}
|
||||
|
||||
MouseArea {
|
||||
anchors.fill: parent
|
||||
acceptedButtons: Qt.RightButton
|
||||
onClicked: contextMenu.open()
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
id: titleBar
|
||||
anchors {
|
||||
top: parent.top
|
||||
topMargin: 1
|
||||
left: parent.left
|
||||
right: parent.right
|
||||
}
|
||||
height: 32
|
||||
color: window.active ? "#3C3C3C" : "#505050"
|
||||
Component.onCompleted: windowAgent.setTitleBar(titleBar)
|
||||
|
||||
Image {
|
||||
id: iconButton
|
||||
anchors {
|
||||
verticalCenter: parent.verticalCenter
|
||||
left: parent.left
|
||||
leftMargin: 10
|
||||
}
|
||||
width: 18
|
||||
height: 18
|
||||
mipmap: true
|
||||
source: "qrc:///app/example.png"
|
||||
}
|
||||
|
||||
Text {
|
||||
anchors {
|
||||
verticalCenter: parent.verticalCenter
|
||||
left: iconButton.right
|
||||
leftMargin: 10
|
||||
}
|
||||
horizontalAlignment: Text.AlignHCenter
|
||||
verticalAlignment: Text.AlignVCenter
|
||||
text: window.title
|
||||
font.pixelSize: 14
|
||||
color: "#ECECEC"
|
||||
}
|
||||
|
||||
Row {
|
||||
anchors {
|
||||
top: parent.top
|
||||
right: parent.right
|
||||
}
|
||||
height: parent.height
|
||||
|
||||
QWKButton {
|
||||
id: minButton
|
||||
height: parent.height
|
||||
source: "qrc:///window-bar/minimize.svg"
|
||||
onClicked: window.showMinimized()
|
||||
Component.onCompleted: windowAgent.setSystemButton(WindowAgent.Minimize, minButton)
|
||||
}
|
||||
|
||||
QWKButton {
|
||||
id: maxButton
|
||||
height: parent.height
|
||||
source: window.visibility === Window.Maximized ? "qrc:///window-bar/restore.svg" : "qrc:///window-bar/maximize.svg"
|
||||
onClicked: {
|
||||
if (window.visibility === Window.Maximized) {
|
||||
window.showNormal()
|
||||
} else {
|
||||
window.showMaximized()
|
||||
}
|
||||
}
|
||||
Component.onCompleted: windowAgent.setSystemButton(WindowAgent.Maximize, maxButton)
|
||||
}
|
||||
|
||||
QWKButton {
|
||||
id: closeButton
|
||||
height: parent.height
|
||||
source: "qrc:///window-bar/close.svg"
|
||||
background: Rectangle {
|
||||
color: {
|
||||
if (!closeButton.enabled) {
|
||||
return "gray";
|
||||
}
|
||||
if (closeButton.pressed) {
|
||||
return "#e81123";
|
||||
}
|
||||
if (closeButton.hovered) {
|
||||
return "#e81123";
|
||||
}
|
||||
return "transparent";
|
||||
}
|
||||
}
|
||||
onClicked: window.close()
|
||||
Component.onCompleted: windowAgent.setSystemButton(WindowAgent.Close, closeButton)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Label {
|
||||
id: timeLabel
|
||||
anchors.centerIn: parent
|
||||
font {
|
||||
pointSize: 75
|
||||
bold: true
|
||||
}
|
||||
color: "#FEFEFE"
|
||||
}
|
||||
|
||||
Menu {
|
||||
id: contextMenu
|
||||
|
||||
Menu {
|
||||
id: themeMenu
|
||||
title: qsTr("Theme")
|
||||
|
||||
MenuItemGroup {
|
||||
id: themeMenuGroup
|
||||
items: themeMenu.items
|
||||
}
|
||||
|
||||
MenuItem {
|
||||
text: qsTr("Light")
|
||||
checkable: true
|
||||
onTriggered: windowAgent.setWindowAttribute("dark-mode", false)
|
||||
}
|
||||
|
||||
MenuItem {
|
||||
text: qsTr("Dark")
|
||||
checkable: true
|
||||
onTriggered: windowAgent.setWindowAttribute("dark-mode", true)
|
||||
}
|
||||
}
|
||||
|
||||
Menu {
|
||||
id: specialEffectMenu
|
||||
title: qsTr("Special effect")
|
||||
|
||||
MenuItemGroup {
|
||||
id: specialEffectMenuGroup
|
||||
items: specialEffectMenu.items
|
||||
}
|
||||
|
||||
MenuItem {
|
||||
enabled: Qt.platform.os === "windows"
|
||||
text: qsTr("DWM blur")
|
||||
checkable: true
|
||||
onTriggered: {
|
||||
window.color = checked ? "transparent" : darkStyle.windowBackgroundColor
|
||||
windowAgent.setWindowAttribute("dwm-blur", checked)
|
||||
}
|
||||
}
|
||||
|
||||
MenuItem {
|
||||
enabled: Qt.platform.os === "windows"
|
||||
text: qsTr("Acrylic material")
|
||||
checkable: true
|
||||
onTriggered: {
|
||||
window.color = checked ? "transparent" : darkStyle.windowBackgroundColor
|
||||
windowAgent.setWindowAttribute("acrylic-material", checked)
|
||||
}
|
||||
}
|
||||
|
||||
MenuItem {
|
||||
enabled: Qt.platform.os === "windows"
|
||||
text: qsTr("Mica")
|
||||
checkable: true
|
||||
onTriggered: {
|
||||
window.color = checked ? "transparent" : darkStyle.windowBackgroundColor
|
||||
windowAgent.setWindowAttribute("mica", checked)
|
||||
}
|
||||
}
|
||||
|
||||
MenuItem {
|
||||
enabled: Qt.platform.os === "windows"
|
||||
text: qsTr("Mica Alt")
|
||||
checkable: true
|
||||
onTriggered: {
|
||||
window.color = checked ? "transparent" : darkStyle.windowBackgroundColor
|
||||
windowAgent.setWindowAttribute("mica-alt", checked)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,6 @@
|
|||
<RCC>
|
||||
<qresource prefix="/">
|
||||
<file>main.qml</file>
|
||||
<file>QWKButton.qml</file>
|
||||
</qresource>
|
||||
</RCC>
|
1
KGCAPP/3rdparty/RibbonUI/lib_source/3rdparty/qwindowkit/examples/shared/CMakeLists.txt
vendored
Normal file
|
@ -0,0 +1 @@
|
|||
add_subdirectory(widgetframe)
|
BIN
KGCAPP/3rdparty/RibbonUI/lib_source/3rdparty/qwindowkit/examples/shared/resources/app/example.icns
vendored
Normal file
BIN
KGCAPP/3rdparty/RibbonUI/lib_source/3rdparty/qwindowkit/examples/shared/resources/app/example.ico
vendored
Normal file
After Width: | Height: | Size: 52 KiB |
BIN
KGCAPP/3rdparty/RibbonUI/lib_source/3rdparty/qwindowkit/examples/shared/resources/app/example.png
vendored
Normal file
After Width: | Height: | Size: 2.9 KiB |
11
KGCAPP/3rdparty/RibbonUI/lib_source/3rdparty/qwindowkit/examples/shared/resources/shared.qrc
vendored
Normal file
|
@ -0,0 +1,11 @@
|
|||
<RCC>
|
||||
<qresource prefix="/">
|
||||
<file>window-bar/close.svg</file>
|
||||
<file>window-bar/fullscreen.svg</file>
|
||||
<file>window-bar/maximize.svg</file>
|
||||
<file>window-bar/minimize.svg</file>
|
||||
<file>window-bar/restore.svg</file>
|
||||
<file>window-bar/more-line.svg</file>
|
||||
<file>app/example.png</file>
|
||||
</qresource>
|
||||
</RCC>
|
|
@ -0,0 +1,15 @@
|
|||
<svg id="图层_1" data-name="图层 1" xmlns="http://www.w3.org/2000/svg" width="10.88" height="10.88"
|
||||
viewBox="0 0 10.88 10.88">
|
||||
<defs>
|
||||
<style>
|
||||
.cls-1 {
|
||||
fill: none;
|
||||
stroke: white;
|
||||
stroke-miterlimit: 10;
|
||||
stroke-width: 1.25px;
|
||||
}
|
||||
</style>
|
||||
</defs>
|
||||
<line class="cls-1" x1="0.44" y1="0.44" x2="10.44" y2="10.44" />
|
||||
<line class="cls-1" x1="0.44" y1="10.44" x2="10.44" y2="0.44" />
|
||||
</svg>
|
After Width: | Height: | Size: 444 B |
|
@ -0,0 +1,11 @@
|
|||
<?xml version="1.0" standalone="no"?>
|
||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1594017175519"
|
||||
class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="1933"
|
||||
xmlns:xlink="http://www.w3.org/1999/xlink" width="16" height="16">
|
||||
<defs>
|
||||
<style type="text/css"></style>
|
||||
</defs>
|
||||
<path
|
||||
d="M874.666667 128h-170.666667a21.333333 21.333333 0 0 0 0 42.666667h119.168l-176.917333 176.917333a21.333333 21.333333 0 1 0 30.165333 30.165333L853.333333 200.832V320a21.333333 21.333333 0 0 0 42.666667 0V149.333333a21.333333 21.333333 0 0 0-21.333333-21.333333zM347.584 646.250667L170.666667 823.168V704a21.333333 21.333333 0 0 0-42.666667 0v170.666667a21.333333 21.333333 0 0 0 21.333333 21.333333h170.666667a21.333333 21.333333 0 0 0 0-42.666667H200.832l176.917333-176.917333a21.333333 21.333333 0 0 0-30.165333-30.165333zM874.666667 682.666667a21.333333 21.333333 0 0 0-21.333334 21.333333v119.168l-176.917333-176.917333a21.333333 21.333333 0 0 0-30.165333 30.165333L823.168 853.333333H704a21.333333 21.333333 0 0 0 0 42.666667h170.666667a21.333333 21.333333 0 0 0 21.333333-21.333333v-170.666667a21.333333 21.333333 0 0 0-21.333333-21.333333zM200.832 170.666667H320a21.333333 21.333333 0 0 0 0-42.666667H149.333333a21.333333 21.333333 0 0 0-21.333333 21.333333v170.666667a21.333333 21.333333 0 0 0 42.666667 0V200.832l176.917333 176.917333a21.333333 21.333333 0 0 0 30.165333-30.165333z"
|
||||
fill="#ffffff" p-id="1934"></path>
|
||||
</svg>
|
After Width: | Height: | Size: 1.5 KiB |
|
@ -0,0 +1,12 @@
|
|||
<svg id="图层_1" data-name="图层 1" xmlns="http://www.w3.org/2000/svg" width="10" height="10" viewBox="0 0 10 10">
|
||||
<defs>
|
||||
<style>
|
||||
.cls-1 {
|
||||
fill: none;
|
||||
stroke: white;
|
||||
stroke-miterlimit: 10;
|
||||
}
|
||||
</style>
|
||||
</defs>
|
||||
<rect class="cls-1" x="0.5" y="0.5" width="9" height="9" />
|
||||
</svg>
|
After Width: | Height: | Size: 328 B |
|
@ -0,0 +1,11 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Generator: Adobe Illustrator 24.3.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
||||
<svg version="1.1" id="图层_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px"
|
||||
y="0px" viewBox="0 0 10 10" style="enable-background:new 0 0 10 10;" xml:space="preserve">
|
||||
<style type="text/css">
|
||||
.st0 {
|
||||
fill: white;
|
||||
}
|
||||
</style>
|
||||
<rect y="4.5" class="st0" width="10" height="1" />
|
||||
</svg>
|
After Width: | Height: | Size: 467 B |
|
@ -0,0 +1,5 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="24" height="24">
|
||||
<path fill="none" d="M0 0h24v24H0z" />
|
||||
<path fill="white"
|
||||
d="M4.5 10.5c-.825 0-1.5.675-1.5 1.5s.675 1.5 1.5 1.5S6 12.825 6 12s-.675-1.5-1.5-1.5zm15 0c-.825 0-1.5.675-1.5 1.5s.675 1.5 1.5 1.5S21 12.825 21 12s-.675-1.5-1.5-1.5zm-7.5 0c-.825 0-1.5.675-1.5 1.5s.675 1.5 1.5 1.5 1.5-.675 1.5-1.5-.675-1.5-1.5-1.5z" />
|
||||
</svg>
|
After Width: | Height: | Size: 419 B |
|
@ -0,0 +1,16 @@
|
|||
<svg id="图层_1" data-name="图层 1" xmlns="http://www.w3.org/2000/svg" width="12" height="12" viewBox="0 0 12 12">
|
||||
<defs>
|
||||
<style>
|
||||
.cls-1 {
|
||||
fill: none;
|
||||
stroke: white;
|
||||
stroke-miterlimit: 10;
|
||||
}
|
||||
</style>
|
||||
</defs>
|
||||
<rect class="cls-1" x="0.5" y="2.5" width="9" height="9" />
|
||||
<line class="cls-1" x1="2.5" y1="2.5" x2="2.5" y2="0.5" />
|
||||
<line class="cls-1" x1="12" y1="0.5" x2="2" y2="0.5" />
|
||||
<line class="cls-1" x1="11.5" y1="10" x2="11.5" />
|
||||
<line class="cls-1" x1="10" y1="9.5" x2="12" y2="9.5" />
|
||||
</svg>
|
After Width: | Height: | Size: 559 B |
|
@ -0,0 +1,21 @@
|
|||
project(WidgetFrame)
|
||||
|
||||
set(CMAKE_AUTOMOC ON)
|
||||
set(CMAKE_AUTOUIC ON)
|
||||
set(CMAKE_AUTORCC ON)
|
||||
|
||||
file(GLOB _src *.h *.cpp)
|
||||
|
||||
add_library(${PROJECT_NAME} STATIC)
|
||||
|
||||
qm_configure_target(${PROJECT_NAME}
|
||||
SOURCES ${_src}
|
||||
QT_LINKS Core Gui Widgets
|
||||
)
|
||||
|
||||
set_target_properties(${PROJECT_NAME} PROPERTIES
|
||||
CXX_STANDARD 17
|
||||
CXX_STANDARD_REQUIRED TRUE
|
||||
)
|
||||
|
||||
target_include_directories(${PROJECT_NAME} PUBLIC . ..)
|
298
KGCAPP/3rdparty/RibbonUI/lib_source/3rdparty/qwindowkit/examples/shared/widgetframe/windowbar.cpp
vendored
Normal file
|
@ -0,0 +1,298 @@
|
|||
// Copyright (C) 2023-2024 Stdware Collections (https://www.github.com/stdware)
|
||||
// Copyright (C) 2021-2023 wangwenx190 (Yuhang Zhao)
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
#include "windowbar.h"
|
||||
#include "windowbar_p.h"
|
||||
|
||||
#include <QtCore/QDebug>
|
||||
#include <QtCore/QLocale>
|
||||
#include <QtGui/QtEvents>
|
||||
|
||||
namespace QWK {
|
||||
|
||||
WindowBarPrivate::WindowBarPrivate() {
|
||||
w = nullptr;
|
||||
autoTitle = true;
|
||||
autoIcon = false;
|
||||
}
|
||||
|
||||
WindowBarPrivate::~WindowBarPrivate() = default;
|
||||
|
||||
void WindowBarPrivate::init() {
|
||||
Q_Q(WindowBar);
|
||||
layout = new QHBoxLayout();
|
||||
if (QLocale::system().textDirection() == Qt::RightToLeft) {
|
||||
layout->setDirection(QBoxLayout::RightToLeft);
|
||||
}
|
||||
|
||||
layout->setContentsMargins(QMargins());
|
||||
layout->setSpacing(0);
|
||||
for (int i = IconButton; i <= CloseButton; ++i) {
|
||||
insertDefaultSpace(i);
|
||||
}
|
||||
q->setLayout(layout);
|
||||
}
|
||||
|
||||
void WindowBarPrivate::setWidgetAt(int index, QWidget *widget) {
|
||||
auto item = layout->takeAt(index);
|
||||
auto orgWidget = item->widget();
|
||||
if (orgWidget) {
|
||||
orgWidget->deleteLater();
|
||||
}
|
||||
delete item;
|
||||
if (!widget) {
|
||||
insertDefaultSpace(index);
|
||||
} else {
|
||||
layout->insertWidget(index, widget);
|
||||
}
|
||||
}
|
||||
|
||||
QWidget *WindowBarPrivate::takeWidgetAt(int index) {
|
||||
auto item = layout->itemAt(index);
|
||||
auto orgWidget = item->widget();
|
||||
if (orgWidget) {
|
||||
item = layout->takeAt(index);
|
||||
delete item;
|
||||
insertDefaultSpace(index);
|
||||
}
|
||||
return orgWidget;
|
||||
}
|
||||
|
||||
WindowBar::WindowBar(QWidget *parent) : WindowBar(*new WindowBarPrivate(), parent) {
|
||||
}
|
||||
|
||||
WindowBar::~WindowBar() = default;
|
||||
|
||||
QMenuBar *WindowBar::menuBar() const {
|
||||
Q_D(const WindowBar);
|
||||
return static_cast<QMenuBar *>(d->widgetAt(WindowBarPrivate::MenuWidget));
|
||||
}
|
||||
|
||||
QLabel *WindowBar::titleLabel() const {
|
||||
Q_D(const WindowBar);
|
||||
return static_cast<QLabel *>(d->widgetAt(WindowBarPrivate::TitleLabel));
|
||||
}
|
||||
|
||||
QAbstractButton *WindowBar::iconButton() const {
|
||||
Q_D(const WindowBar);
|
||||
return static_cast<QAbstractButton *>(d->widgetAt(WindowBarPrivate::IconButton));
|
||||
}
|
||||
|
||||
QAbstractButton *WindowBar::minButton() const {
|
||||
Q_D(const WindowBar);
|
||||
return static_cast<QAbstractButton *>(d->widgetAt(WindowBarPrivate::MinimumButton));
|
||||
}
|
||||
|
||||
QAbstractButton *WindowBar::maxButton() const {
|
||||
Q_D(const WindowBar);
|
||||
return static_cast<QAbstractButton *>(d->widgetAt(WindowBarPrivate::MaximumButton));
|
||||
}
|
||||
|
||||
QAbstractButton *WindowBar::closeButton() const {
|
||||
Q_D(const WindowBar);
|
||||
return static_cast<QAbstractButton *>(d->widgetAt(WindowBarPrivate::CloseButton));
|
||||
}
|
||||
|
||||
void WindowBar::setMenuBar(QMenuBar *menuBar) {
|
||||
Q_D(WindowBar);
|
||||
auto org = takeMenuBar();
|
||||
if (org)
|
||||
org->deleteLater();
|
||||
if (!menuBar)
|
||||
return;
|
||||
d->setWidgetAt(WindowBarPrivate::MenuWidget, menuBar);
|
||||
menuBar->setSizePolicy(QSizePolicy::Maximum, QSizePolicy::Minimum);
|
||||
}
|
||||
|
||||
void WindowBar::setTitleLabel(QLabel *label) {
|
||||
Q_D(WindowBar);
|
||||
auto org = takeTitleLabel();
|
||||
if (org)
|
||||
org->deleteLater();
|
||||
if (!label)
|
||||
return;
|
||||
d->setWidgetAt(WindowBarPrivate::TitleLabel, label);
|
||||
if (d->autoTitle && d->w)
|
||||
label->setText(d->w->windowTitle());
|
||||
label->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Minimum);
|
||||
}
|
||||
|
||||
void WindowBar::setIconButton(QAbstractButton *btn) {
|
||||
Q_D(WindowBar);
|
||||
auto org = takeIconButton();
|
||||
if (org)
|
||||
org->deleteLater();
|
||||
if (!btn)
|
||||
return;
|
||||
d->setWidgetAt(WindowBarPrivate::IconButton, btn);
|
||||
if (d->autoIcon && d->w)
|
||||
btn->setIcon(d->w->windowIcon());
|
||||
btn->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Preferred);
|
||||
}
|
||||
|
||||
void WindowBar::setMinButton(QAbstractButton *btn) {
|
||||
Q_D(WindowBar);
|
||||
auto org = takeMinButton();
|
||||
if (org)
|
||||
org->deleteLater();
|
||||
if (!btn)
|
||||
return;
|
||||
d->setWidgetAt(WindowBarPrivate::MinimumButton, btn);
|
||||
connect(btn, &QAbstractButton::clicked, this, &WindowBar::minimizeRequested);
|
||||
}
|
||||
|
||||
void WindowBar::setMaxButton(QAbstractButton *btn) {
|
||||
Q_D(WindowBar);
|
||||
auto org = takeMaxButton();
|
||||
if (org)
|
||||
org->deleteLater();
|
||||
if (!btn)
|
||||
return;
|
||||
d->setWidgetAt(WindowBarPrivate::MaximumButton, btn);
|
||||
connect(btn, &QAbstractButton::clicked, this, &WindowBar::maximizeRequested);
|
||||
}
|
||||
|
||||
void WindowBar::setCloseButton(QAbstractButton *btn) {
|
||||
Q_D(WindowBar);
|
||||
auto org = takeCloseButton();
|
||||
if (org)
|
||||
org->deleteLater();
|
||||
if (!btn)
|
||||
return;
|
||||
d->setWidgetAt(WindowBarPrivate::CloseButton, btn);
|
||||
connect(btn, &QAbstractButton::clicked, this, &WindowBar::closeRequested);
|
||||
}
|
||||
|
||||
QMenuBar *WindowBar::takeMenuBar() {
|
||||
Q_D(WindowBar);
|
||||
return static_cast<QMenuBar *>(d->takeWidgetAt(WindowBarPrivate::MenuWidget));
|
||||
}
|
||||
|
||||
QLabel *WindowBar::takeTitleLabel() {
|
||||
Q_D(WindowBar);
|
||||
return static_cast<QLabel *>(d->takeWidgetAt(WindowBarPrivate::TitleLabel));
|
||||
}
|
||||
|
||||
QAbstractButton *WindowBar::takeIconButton() {
|
||||
Q_D(WindowBar);
|
||||
return static_cast<QAbstractButton *>(d->takeWidgetAt(WindowBarPrivate::IconButton));
|
||||
}
|
||||
|
||||
QAbstractButton *WindowBar::takeMinButton() {
|
||||
Q_D(WindowBar);
|
||||
auto btn = static_cast<QAbstractButton *>(d->takeWidgetAt(WindowBarPrivate::MinimumButton));
|
||||
if (!btn) {
|
||||
return nullptr;
|
||||
}
|
||||
disconnect(btn, &QAbstractButton::clicked, this, &WindowBar::minimizeRequested);
|
||||
return btn;
|
||||
}
|
||||
|
||||
QAbstractButton *WindowBar::takeMaxButton() {
|
||||
Q_D(WindowBar);
|
||||
auto btn = static_cast<QAbstractButton *>(d->takeWidgetAt(WindowBarPrivate::MaximumButton));
|
||||
if (!btn) {
|
||||
return nullptr;
|
||||
}
|
||||
disconnect(btn, &QAbstractButton::clicked, this, &WindowBar::maximizeRequested);
|
||||
return btn;
|
||||
}
|
||||
|
||||
QAbstractButton *WindowBar::takeCloseButton() {
|
||||
Q_D(WindowBar);
|
||||
auto btn = static_cast<QAbstractButton *>(d->takeWidgetAt(WindowBarPrivate::CloseButton));
|
||||
if (!btn) {
|
||||
return nullptr;
|
||||
}
|
||||
disconnect(btn, &QAbstractButton::clicked, this, &WindowBar::closeRequested);
|
||||
return btn;
|
||||
}
|
||||
|
||||
QWidget *WindowBar::hostWidget() const {
|
||||
Q_D(const WindowBar);
|
||||
return d->w;
|
||||
}
|
||||
|
||||
void WindowBar::setHostWidget(QWidget *w) {
|
||||
Q_D(WindowBar);
|
||||
|
||||
QWidget *org = d->w;
|
||||
if (org) {
|
||||
org->removeEventFilter(this);
|
||||
}
|
||||
d_ptr->w = w;
|
||||
if (w) {
|
||||
w->installEventFilter(this);
|
||||
}
|
||||
}
|
||||
|
||||
bool WindowBar::titleFollowWindow() const {
|
||||
Q_D(const WindowBar);
|
||||
return d->autoTitle;
|
||||
}
|
||||
|
||||
void WindowBar::setTitleFollowWindow(bool value) {
|
||||
Q_D(WindowBar);
|
||||
d->autoTitle = value;
|
||||
}
|
||||
|
||||
bool WindowBar::iconFollowWindow() const {
|
||||
Q_D(const WindowBar);
|
||||
return d->autoIcon;
|
||||
}
|
||||
|
||||
void WindowBar::setIconFollowWindow(bool value) {
|
||||
Q_D(WindowBar);
|
||||
d->autoIcon = value;
|
||||
}
|
||||
|
||||
bool WindowBar::eventFilter(QObject *obj, QEvent *event) {
|
||||
Q_D(WindowBar);
|
||||
auto w = d->w;
|
||||
if (obj == w) {
|
||||
QAbstractButton *iconBtn = iconButton();
|
||||
QLabel *label = titleLabel();
|
||||
QAbstractButton *maxBtn = maxButton();
|
||||
switch (event->type()) {
|
||||
case QEvent::WindowIconChange: {
|
||||
if (d_ptr->autoIcon && iconBtn) {
|
||||
iconBtn->setIcon(w->windowIcon());
|
||||
iconChanged(w->windowIcon());
|
||||
}
|
||||
break;
|
||||
}
|
||||
case QEvent::WindowTitleChange: {
|
||||
if (d_ptr->autoTitle && label) {
|
||||
label->setText(w->windowTitle());
|
||||
titleChanged(w->windowTitle());
|
||||
}
|
||||
break;
|
||||
}
|
||||
case QEvent::WindowStateChange: {
|
||||
if (maxBtn) {
|
||||
maxBtn->setChecked(w->isMaximized());
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
return QWidget::eventFilter(obj, event);
|
||||
}
|
||||
|
||||
void WindowBar::titleChanged(const QString &text) {
|
||||
Q_UNUSED(text)
|
||||
}
|
||||
|
||||
void WindowBar::iconChanged(const QIcon &icon){Q_UNUSED(icon)}
|
||||
|
||||
WindowBar::WindowBar(WindowBarPrivate &d, QWidget *parent)
|
||||
: QFrame(parent), d_ptr(&d) {
|
||||
d.q_ptr = this;
|
||||
|
||||
d.init();
|
||||
}
|
||||
|
||||
}
|
74
KGCAPP/3rdparty/RibbonUI/lib_source/3rdparty/qwindowkit/examples/shared/widgetframe/windowbar.h
vendored
Normal file
|
@ -0,0 +1,74 @@
|
|||
// Copyright (C) 2023-2024 Stdware Collections (https://www.github.com/stdware)
|
||||
// Copyright (C) 2021-2023 wangwenx190 (Yuhang Zhao)
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
#ifndef WINDOWBAR_H
|
||||
#define WINDOWBAR_H
|
||||
|
||||
#include <QFrame>
|
||||
#include <QAbstractButton>
|
||||
#include <QMenuBar>
|
||||
#include <QLabel>
|
||||
|
||||
namespace QWK {
|
||||
|
||||
class WindowBarPrivate;
|
||||
|
||||
class WindowBar : public QFrame {
|
||||
Q_OBJECT
|
||||
Q_DECLARE_PRIVATE(WindowBar)
|
||||
public:
|
||||
explicit WindowBar(QWidget *parent = nullptr);
|
||||
~WindowBar();
|
||||
|
||||
public:
|
||||
QMenuBar *menuBar() const;
|
||||
QLabel *titleLabel() const;
|
||||
QAbstractButton *iconButton() const;
|
||||
QAbstractButton *minButton() const;
|
||||
QAbstractButton *maxButton() const;
|
||||
QAbstractButton *closeButton() const;
|
||||
|
||||
void setMenuBar(QMenuBar *menuBar);
|
||||
void setTitleLabel(QLabel *label);
|
||||
void setIconButton(QAbstractButton *btn);
|
||||
void setMinButton(QAbstractButton *btn);
|
||||
void setMaxButton(QAbstractButton *btn);
|
||||
void setCloseButton(QAbstractButton *btn);
|
||||
|
||||
QMenuBar *takeMenuBar();
|
||||
QLabel *takeTitleLabel();
|
||||
QAbstractButton *takeIconButton();
|
||||
QAbstractButton *takeMinButton();
|
||||
QAbstractButton *takeMaxButton();
|
||||
QAbstractButton *takeCloseButton();
|
||||
|
||||
QWidget *hostWidget() const;
|
||||
void setHostWidget(QWidget *w);
|
||||
|
||||
bool titleFollowWindow() const;
|
||||
void setTitleFollowWindow(bool value);
|
||||
|
||||
bool iconFollowWindow() const;
|
||||
void setIconFollowWindow(bool value);
|
||||
|
||||
Q_SIGNALS:
|
||||
void minimizeRequested();
|
||||
void maximizeRequested(bool max = false);
|
||||
void closeRequested();
|
||||
|
||||
protected:
|
||||
bool eventFilter(QObject *obj, QEvent *event) override;
|
||||
|
||||
virtual void titleChanged(const QString &text);
|
||||
virtual void iconChanged(const QIcon &icon);
|
||||
|
||||
protected:
|
||||
WindowBar(WindowBarPrivate &d, QWidget *parent = nullptr);
|
||||
|
||||
QScopedPointer<WindowBarPrivate> d_ptr;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif // WINDOWBAR_H
|