├── .cmake ├── HuskarUIHelper.cmake └── WinResource.rc.in ├── .github └── workflows │ ├── linux-qt6.7.3-gcc.yml │ ├── linux-qt6.8.3-gcc.yml │ ├── windows-qt6.7.3-msvc2019.yml │ └── windows-qt6.8.3-msvc2022.yml ├── .gitignore ├── .gitmodules ├── CMakeLists.txt ├── LICENSE ├── README-zh_CN.md ├── README.md ├── gallery ├── CMakeLists.txt ├── cpp │ ├── creator.cpp │ ├── creator.h │ ├── creator_p.h │ ├── customtheme.cpp │ ├── customtheme.h │ ├── datagenerator.cpp │ ├── datagenerator.h │ ├── main.cpp │ ├── themeswitchitem.cpp │ └── themeswitchitem.h ├── images │ ├── huskarui_icon.svg │ ├── swithc_effect1.jpg │ └── swithc_effect2.jpg ├── qml │ ├── Controls │ │ ├── CodeBox.qml │ │ ├── CodeRunner.qml │ │ ├── Description.qml │ │ ├── ThemeToken.qml │ │ └── UpdateDesc.qml │ ├── Examples │ │ ├── DataDisplay │ │ │ ├── ExpAvatar.qml │ │ │ ├── ExpBadge.qml │ │ │ ├── ExpCard.qml │ │ │ ├── ExpCarousel.qml │ │ │ ├── ExpCollapse.qml │ │ │ ├── ExpEmpty.qml │ │ │ ├── ExpImage.qml │ │ │ ├── ExpImagePreview.qml │ │ │ ├── ExpTabView.qml │ │ │ ├── ExpTableView.qml │ │ │ ├── ExpTag.qml │ │ │ ├── ExpTimeline.qml │ │ │ ├── ExpToolTip.qml │ │ │ ├── ExpTourFocus.qml │ │ │ └── ExpTourStep.qml │ │ ├── DataEntry │ │ │ ├── ExpAutoComplete.qml │ │ │ ├── ExpCheckBox.qml │ │ │ ├── ExpDateTimePicker.qml │ │ │ ├── ExpInput.qml │ │ │ ├── ExpInputNumber.qml │ │ │ ├── ExpMultiSelect.qml │ │ │ ├── ExpOTPInput.qml │ │ │ ├── ExpRadio.qml │ │ │ ├── ExpRadioBlock.qml │ │ │ ├── ExpRate.qml │ │ │ ├── ExpSelect.qml │ │ │ ├── ExpSlider.qml │ │ │ ├── ExpSwitch.qml │ │ │ └── ExpTextArea.qml │ │ ├── Effect │ │ │ ├── ExpAcrylic.qml │ │ │ ├── ExpShadow.qml │ │ │ └── ExpSwitchEffect.qml │ │ ├── Feedback │ │ │ ├── ExpDrawer.qml │ │ │ ├── ExpMessage.qml │ │ │ ├── ExpModal.qml │ │ │ ├── ExpNotification.qml │ │ │ ├── ExpPopconfirm.qml │ │ │ ├── ExpPopover.qml │ │ │ ├── ExpProgress.qml │ │ │ └── ExpWatermark.qml │ │ ├── General │ │ │ ├── ExpButton.qml │ │ │ ├── ExpButtonBlock.qml │ │ │ ├── ExpCaptionBar.qml │ │ │ ├── ExpCaptionButton.qml │ │ │ ├── ExpCopyableText.qml │ │ │ ├── ExpIconButton.qml │ │ │ ├── ExpIconText.qml │ │ │ ├── ExpMoveMouseArea.qml │ │ │ ├── ExpPopup.qml │ │ │ ├── ExpRadius.qml │ │ │ ├── ExpRectangle.qml │ │ │ ├── ExpResizeMouseArea.qml │ │ │ ├── ExpText.qml │ │ │ └── ExpWindow.qml │ │ ├── Layout │ │ │ └── ExpDivider.qml │ │ ├── Navigation │ │ │ ├── ExpBreadcrumb.qml │ │ │ ├── ExpContextMenu.qml │ │ │ ├── ExpMenu.qml │ │ │ ├── ExpPagination.qml │ │ │ └── ExpScrollBar.qml │ │ ├── Theme │ │ │ └── ExpTheme.qml │ │ └── Utils │ │ │ └── ExpAsyncHasher.qml │ ├── Gallery.qml │ ├── Global.qml │ └── Home │ │ ├── AboutPage.qml │ │ ├── CreatorPage.qml │ │ ├── HomePage.qml │ │ └── SettingsPage.qml └── shaders │ ├── effect1.frag │ ├── effect1.vert │ ├── effect2.frag │ └── effect2.vert ├── preview ├── dark.png ├── doc.png └── light.png ├── resources ├── huskarui_icon.ico ├── huskarui_icon.png └── huskarui_icon.svg └── src ├── CMakeLists.txt ├── cpp ├── controls │ ├── husiconfont.cpp │ ├── husiconfont.h │ ├── husrectangle.cpp │ ├── husrectangle.h │ ├── huswatermark.cpp │ ├── huswatermark.h │ ├── huswindowagent.cpp │ └── huswindowagent.h ├── husapp.cpp ├── husapp.h ├── husdefinitions.h ├── husglobal.h ├── huskaruiplugin.cpp ├── theme │ ├── huscolorgenerator.cpp │ ├── huscolorgenerator.h │ ├── husradiusgenerator.cpp │ ├── husradiusgenerator.h │ ├── hussizegenerator.cpp │ ├── hussizegenerator.h │ ├── hussystemthemehelper.cpp │ ├── hussystemthemehelper.h │ ├── hustheme.cpp │ ├── hustheme.h │ ├── hustheme_p.h │ ├── husthemefunctions.cpp │ └── husthemefunctions.h └── utils │ ├── husapi.cpp │ ├── husapi.h │ ├── husasynchasher.cpp │ └── husasynchasher.h ├── imports ├── HusAcrylic.qml ├── HusAutoComplete.qml ├── HusAvatar.qml ├── HusBadge.qml ├── HusBreadcrumb.qml ├── HusButton.qml ├── HusButtonBlock.qml ├── HusCaptionBar.qml ├── HusCaptionButton.qml ├── HusCard.qml ├── HusCarousel.qml ├── HusCheckBox.qml ├── HusCollapse.qml ├── HusContextMenu.qml ├── HusCopyableText.qml ├── HusDateTimePicker.qml ├── HusDivider.qml ├── HusDrawer.qml ├── HusEmpty.qml ├── HusIconButton.qml ├── HusIconText.qml ├── HusImage.qml ├── HusImagePreview.qml ├── HusInput.qml ├── HusInputNumber.qml ├── HusMenu.qml ├── HusMessage.qml ├── HusModal.qml ├── HusMoveMouseArea.qml ├── HusMultiSelect.qml ├── HusNotification.qml ├── HusOTPInput.qml ├── HusPagination.qml ├── HusPopconfirm.qml ├── HusPopover.qml ├── HusPopup.qml ├── HusProgress.qml ├── HusRadio.qml ├── HusRadioBlock.qml ├── HusRate.qml ├── HusResizeMouseArea.qml ├── HusScrollBar.qml ├── HusSelect.qml ├── HusShadow.qml ├── HusSlider.qml ├── HusSwitch.qml ├── HusSwitchEffect.qml ├── HusTabView.qml ├── HusTableView.qml ├── HusTag.qml ├── HusText.qml ├── HusTextArea.qml ├── HusTimeline.qml ├── HusToolTip.qml ├── HusTourFocus.qml ├── HusTourStep.qml └── HusWindow.qml ├── resources ├── font │ └── HuskarUI-Icons.ttf └── images │ ├── empty-default.svg │ ├── empty-simple.svg │ ├── hblinds.png │ ├── heart.png │ ├── smoke.png │ ├── star.png │ └── stripes.png ├── shaders └── husrate.frag └── theme ├── HusAutoComplete.json ├── HusBreadcrumb.json ├── HusButton.json ├── HusCaptionButton.json ├── HusCard.json ├── HusCarousel.json ├── HusCheckBox.json ├── HusCollapse.json ├── HusCopyableText.json ├── HusDateTimePicker.json ├── HusDivider.json ├── HusDrawer.json ├── HusEmpty.json ├── HusIconText.json ├── HusImage.json ├── HusInput.json ├── HusMenu.json ├── HusMessage.json ├── HusModal.json ├── HusMultiSelect.json ├── HusNotification.json ├── HusPagination.json ├── HusPopconfirm.json ├── HusPopover.json ├── HusPopup.json ├── HusProgress.json ├── HusRadio.json ├── HusRate.json ├── HusScrollBar.json ├── HusSelect.json ├── HusSlider.json ├── HusSwitch.json ├── HusTabView.json ├── HusTableView.json ├── HusTag.json ├── HusTextArea.json ├── HusTimeline.json ├── HusToolTip.json ├── HusTour.json └── Index.json /.cmake/HuskarUIHelper.cmake: -------------------------------------------------------------------------------- 1 | #[[ 2 | Get all files in the directory that match the filter. 3 | 4 | hus_get_dir_sources( 5 | [FILTER filter] 6 | [OUTPUT outputvar] 7 | ) 8 | ]] # 9 | 10 | function(hus_get_dir_sources) 11 | set(oneValueArgs OUTPUT) 12 | set(multiValueArgs FILTER) 13 | cmake_parse_arguments(PARAM "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN}) 14 | file(GLOB_RECURSE PATHS ${PARAM_FILTER}) 15 | set(TEMP_OUTPUT "") 16 | foreach (filepath ${PATHS}) 17 | string(REPLACE "${CMAKE_CURRENT_SOURCE_DIR}/" "" filename ${filepath}) 18 | list(APPEND TEMP_OUTPUT ${filename}) 19 | endforeach (filepath) 20 | set(${PARAM_OUTPUT} ${TEMP_OUTPUT} PARENT_SCOPE) 21 | endfunction() 22 | 23 | #[[ 24 | Attach windows RC file to a target. 25 | 26 | hus_add_win_rc( 27 | [COMMENTS comments] 28 | [NAME name] 29 | [VERSION version] 30 | [COMPANY company] 31 | [DESCRIPTION desc] 32 | [COPYRIGHT copyright] 33 | [TRADEMARK trademark] 34 | [ICONS icons] 35 | [OUTPUT_FILE file] 36 | ) 37 | ]] # 38 | 39 | function(hus_add_win_rc _target) 40 | if(NOT WIN32) 41 | return() 42 | endif() 43 | 44 | set(options) 45 | set(oneValueArgs COMMENTS NAME VERSION COMPANY DESCRIPTION COPYRIGHT TRADEMARK OUTPUT_FILE) 46 | set(multiValueArgs ICONS) 47 | cmake_parse_arguments(PARAM "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN}) 48 | 49 | set(_comments ${PARAM_COMMENTS}) 50 | set(_name ${PARAM_NAME}) 51 | set(_version ${PARAM_VERSION}) 52 | set(_company ${PARAM_COMPANY}) 53 | set(_desc ${PARAM_DESCRIPTION}) 54 | set(_copyright ${PARAM_COPYRIGHT}) 55 | set(_trademark ${PARAM_TRADEMARK}) 56 | set(_out_file ${PARAM_OUTPUT_FILE}) 57 | 58 | #Parse version string 59 | string(REPLACE "." ";" _version_list ${_version}) 60 | list(LENGTH _version_list _version_count) 61 | list(PREPEND _version_list 0) # Add placeholder 62 | foreach(_i RANGE 1 4) 63 | if(_i LESS_EQUAL _version_count) 64 | list(GET _version_list ${_i} _item) 65 | else() 66 | set(_item 0) 67 | endif() 68 | 69 | set(_ver_${_i} ${_item}) 70 | endforeach() 71 | set(RC_VERSION ${_ver_1},${_ver_2},${_ver_3},${_ver_4}) 72 | set(RC_VERSION_STRING ${_ver_1}.${_ver_2}.${_ver_3}.${_ver_4}) 73 | 74 | #Parse file type 75 | GET_FILENAME_COMPONENT(_file_ext ${_name} EXT) 76 | if (_file_ext STREQUAL ".exe") 77 | set(RC_FILE_TYPE VFT_APP) 78 | elseif (_file_ext STREQUAL ".dll") 79 | set(RC_FILE_TYPE VFT_DLL) 80 | elseif (_file_ext STREQUAL ".lib") 81 | set(RC_FILE_TYPE VFT_STATIC_LIB) 82 | else() 83 | set(RC_FILE_TYPE VFT_UNKNOWN) 84 | endif() 85 | 86 | set(RC_COMMENTS ${_comments}) 87 | set(RC_COMPANY ${_company}) 88 | set(RC_DESCRIPTION ${_desc}) 89 | set(RC_COPYRIGHT ${_copyright}) 90 | set(RC_TRADEMARK ${_trademark}) 91 | set(RC_FILENAME ${_name}) 92 | set(RC_PROJECT_NAME ${_target}) 93 | 94 | set(_icons) 95 | 96 | if(PARAM_ICONS) 97 | set(_index 1) 98 | 99 | foreach(_icon IN LISTS PARAM_ICONS) 100 | get_filename_component(_icon_path ${_icon} ABSOLUTE) 101 | string(APPEND _icons "IDI_ICON${_index} ICON \"${_icon_path}\"\n") 102 | math(EXPR _index "${_index} +1") 103 | endforeach() 104 | endif() 105 | 106 | set(RC_ICONS ${_icons}) 107 | 108 | configure_file("${CMAKE_CURRENT_FUNCTION_LIST_DIR}/WinResource.rc.in" ${_out_file}) 109 | 110 | foreach(_icon IN LISTS PARAM_ICONS) 111 | if(${_icon} IS_NEWER_THAN ${_out_file}) 112 | file(TOUCH_NOCREATE ${_out_file}) 113 | break() 114 | endif() 115 | endforeach() 116 | endfunction() 117 | -------------------------------------------------------------------------------- /.cmake/WinResource.rc.in: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | @RC_ICONS@ 4 | 5 | VS_VERSION_INFO VERSIONINFO 6 | FILEVERSION @RC_VERSION@ 7 | PRODUCTVERSION @RC_VERSION@ 8 | FILEFLAGSMASK 0x3fL 9 | #ifdef _DEBUG 10 | FILEFLAGS VS_FF_DEBUG 11 | #else 12 | FILEFLAGS 0x0L 13 | #endif 14 | FILEOS VOS_NT_WINDOWS32 15 | FILETYPE @RC_FILE_TYPE@ 16 | FILESUBTYPE VFT2_UNKNOWN 17 | BEGIN 18 | BLOCK "StringFileInfo" 19 | BEGIN 20 | BLOCK "080404b0" 21 | BEGIN 22 | VALUE "Comments", "@RC_COMMENTS@" 23 | VALUE "CompanyName", "@RC_COMPANY@" 24 | VALUE "FileDescription", "@RC_DESCRIPTION@" 25 | VALUE "FileVersion", "@RC_VERSION_STRING@" 26 | VALUE "InternalName", "@RC_PROJECT_NAME@" 27 | VALUE "LegalCopyright", "@RC_COPYRIGHT@" 28 | VALUE "LegalTrademarks", "@RC_TRADEMARK@" 29 | VALUE "OriginalFilename", "@RC_FILENAME@" 30 | VALUE "ProductName", "@RC_PROJECT_NAME@" 31 | VALUE "ProductVersion", "@RC_VERSION_STRING@" 32 | END 33 | END 34 | BLOCK "VarFileInfo" 35 | BEGIN 36 | VALUE "Translation", 0x804, 1200 37 | END 38 | END 39 | -------------------------------------------------------------------------------- /.github/workflows/linux-qt6.7.3-gcc.yml: -------------------------------------------------------------------------------- 1 | # This starter workflow is for a CMake project running on multiple platforms. There is a different starter workflow if you just want a single platform. 2 | # See: https://github.com/actions/starter-workflows/blob/main/ci/cmake-single-platform.yml 3 | name: CMake on Linux - Qt6.7.3 4 | 5 | on: 6 | push: 7 | pull_request: 8 | 9 | jobs: 10 | build: 11 | permissions: write-all 12 | runs-on: ${{ matrix.os }} 13 | strategy: 14 | matrix: 15 | os: [ubuntu-latest] 16 | build_types: [Release] 17 | c_compiler: [gcc] 18 | cxx_compiler: [g++] 19 | include: 20 | - qt_ver: 6.7.3 21 | qt_arch: linux_gcc_64 22 | 23 | env: 24 | targetName: Gallery 25 | buildlibName: HuskarUI_${{ matrix.qt_arch }}_Qt${{ matrix.qt_ver }} 26 | 27 | steps: 28 | - name: Checkout repository 29 | uses: actions/checkout@v3 30 | with: 31 | submodules: recursive 32 | 33 | - name: Install Qt 34 | uses: jurplel/install-qt-action@v3 35 | with: 36 | version: ${{ matrix.qt_ver }} 37 | arch: ${{ matrix.qt_arch }} 38 | modules: 'qt5compat qtshadertools' 39 | 40 | - name: Setup Ninja 41 | uses: seanmiddleditch/gha-setup-ninja@v3 42 | with: 43 | version: 1.10.2 44 | 45 | - name: Ubuntu install GL library 46 | 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 47 | 48 | - name: Ubuntu install libfuse2 49 | run: sudo apt install libfuse2 50 | 51 | - name: Set reusable strings 52 | # Turn repeated input strings (such as the build output directory) into step outputs. These step outputs can be used throughout the workflow file. 53 | id: strings 54 | shell: bash 55 | run: | 56 | echo "build-output-dir=${{ github.workspace }}/build" >> "$GITHUB_OUTPUT" 57 | 58 | - name: Build 59 | id: build 60 | run: | 61 | ninja --version 62 | cmake --version 63 | cmake -B ${{ steps.strings.outputs.build-output-dir }} -S ${{ github.workspace }} \ 64 | -DCMAKE_MESSAGE_LOG_LEVEL=STATUS \ 65 | -DCMAKE_C_COMPILER=${{ matrix.c_compiler }} \ 66 | -DCMAKE_CXX_COMPILER=${{ matrix.cxx_compiler }} \ 67 | -DCMAKE_BUILD_TYPE=${{ matrix.build_types }} \ 68 | -DCMAKE_PREFIX_PATH=${{ env.Qt6_DIR }} \ 69 | -GNinja 70 | cd ${{ steps.strings.outputs.build-output-dir }} 71 | cmake --build . --config ${{ matrix.build_types }} --parallel --target all -- 72 | cmake --install . 73 | 74 | - name: Install Linux QtDeploy 75 | uses: miurahr/install-linuxdeploy-action@v1 76 | with: 77 | plugins: qt appimage 78 | 79 | - name: Check if svg file exists 80 | run: if [ ! -f "${targetName}.svg" ]; then echo "File not found, creating..."; touch ${targetName}.svg; fi 81 | 82 | - name: Package 83 | run: | 84 | # 确保Qt插件找到Qml源代码, 以便部署导入的文件 85 | export QML_SOURCES_PATHS=./ 86 | # 拷贝依赖 87 | linuxdeploy-x86_64.AppImage --plugin=qt --output=appimage --create-desktop-file --icon-file=${targetName}.svg --executable=bin/Release/${targetName} --appdir bin/release/ 88 | mv ${{ env.targetName }}-*.AppImage ${{ env.targetName }}.AppImage 89 | 90 | - name: Upload Artifact 91 | uses: actions/upload-artifact@v4 92 | with: 93 | name: ${{ env.targetName }}_${{ matrix.qt_arch }}_Qt${{ matrix.qt_ver }}.zip 94 | path: ${{ env.targetName }}.AppImage 95 | 96 | - name: Upload Release 97 | if: startsWith(github.event.ref, 'refs/tags/') 98 | uses: svenstaro/upload-release-action@v2 99 | with: 100 | repo_token: ${{ secrets.GITHUB_TOKEN }} 101 | file: ${{ env.targetName }}.AppImage 102 | asset_name: ${{ env.targetName }}_${{ github.ref_name }}_${{ matrix.qt_arch }}_Qt${{ matrix.qt_ver }}.AppImage 103 | tag: ${{ github.ref }} 104 | overwrite: true 105 | 106 | - name: Zip Library 107 | run: | 108 | zip -r ${{ env.buildlibName }}.zip HuskarUI 109 | 110 | - name: Upload Library 111 | if: startsWith(github.event.ref, 'refs/tags/') 112 | uses: svenstaro/upload-release-action@v2 113 | with: 114 | repo_token: ${{ secrets.GITHUB_TOKEN }} 115 | file: ${{ env.buildlibName }}.zip 116 | asset_name: $HuskarUI_${{ github.ref_name }}_${{ matrix.qt_arch }}_Qt${{ matrix.qt_ver }}.zip 117 | tag: ${{ github.ref }} 118 | overwrite: true 119 | -------------------------------------------------------------------------------- /.github/workflows/linux-qt6.8.3-gcc.yml: -------------------------------------------------------------------------------- 1 | # This starter workflow is for a CMake project running on multiple platforms. There is a different starter workflow if you just want a single platform. 2 | # See: https://github.com/actions/starter-workflows/blob/main/ci/cmake-single-platform.yml 3 | name: CMake on Linux - Qt6.8.3 4 | 5 | on: 6 | push: 7 | pull_request: 8 | 9 | jobs: 10 | build: 11 | permissions: write-all 12 | runs-on: ${{ matrix.os }} 13 | strategy: 14 | matrix: 15 | os: [ubuntu-latest] 16 | build_types: [Release] 17 | c_compiler: [gcc] 18 | cxx_compiler: [g++] 19 | include: 20 | - qt_ver: 6.8.3 21 | qt_arch: linux_gcc_64 22 | 23 | env: 24 | targetName: Gallery 25 | buildlibName: HuskarUI_${{ matrix.qt_arch }}_Qt${{ matrix.qt_ver }} 26 | 27 | steps: 28 | - name: Checkout repository 29 | uses: actions/checkout@v3 30 | with: 31 | submodules: recursive 32 | 33 | - name: Install Qt 34 | uses: jurplel/install-qt-action@v3 35 | with: 36 | version: ${{ matrix.qt_ver }} 37 | arch: ${{ matrix.qt_arch }} 38 | modules: 'qt5compat qtshadertools' 39 | 40 | - name: Setup Ninja 41 | uses: seanmiddleditch/gha-setup-ninja@v3 42 | with: 43 | version: 1.10.2 44 | 45 | - name: Ubuntu install GL library 46 | 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 47 | 48 | - name: Ubuntu install libfuse2 49 | run: sudo apt install libfuse2 50 | 51 | - name: Set reusable strings 52 | # Turn repeated input strings (such as the build output directory) into step outputs. These step outputs can be used throughout the workflow file. 53 | id: strings 54 | shell: bash 55 | run: | 56 | echo "build-output-dir=${{ github.workspace }}/build" >> "$GITHUB_OUTPUT" 57 | 58 | - name: Build 59 | id: build 60 | run: | 61 | ninja --version 62 | cmake --version 63 | cmake -B ${{ steps.strings.outputs.build-output-dir }} -S ${{ github.workspace }} \ 64 | -DCMAKE_MESSAGE_LOG_LEVEL=STATUS \ 65 | -DCMAKE_C_COMPILER=${{ matrix.c_compiler }} \ 66 | -DCMAKE_CXX_COMPILER=${{ matrix.cxx_compiler }} \ 67 | -DCMAKE_BUILD_TYPE=${{ matrix.build_types }} \ 68 | -DCMAKE_PREFIX_PATH=${{ env.Qt6_DIR }} \ 69 | -GNinja 70 | cd ${{ steps.strings.outputs.build-output-dir }} 71 | cmake --build . --config ${{ matrix.build_types }} --parallel --target all -- 72 | cmake --install . 73 | 74 | - name: Install Linux QtDeploy 75 | uses: miurahr/install-linuxdeploy-action@v1 76 | with: 77 | plugins: qt appimage 78 | 79 | - name: Check if svg file exists 80 | run: if [ ! -f "${targetName}.svg" ]; then echo "File not found, creating..."; touch ${targetName}.svg; fi 81 | 82 | - name: Package 83 | run: | 84 | # 确保Qt插件找到Qml源代码, 以便部署导入的文件 85 | export QML_SOURCES_PATHS=./ 86 | # 拷贝依赖 87 | linuxdeploy-x86_64.AppImage --plugin=qt --output=appimage --create-desktop-file --icon-file=${targetName}.svg --executable=bin/Release/${targetName} --appdir bin/release/ 88 | mv ${{ env.targetName }}-*.AppImage ${{ env.targetName }}.AppImage 89 | 90 | - name: Upload Artifact 91 | uses: actions/upload-artifact@v4 92 | with: 93 | name: ${{ env.targetName }}_${{ matrix.qt_arch }}_Qt${{ matrix.qt_ver }}.zip 94 | path: ${{ env.targetName }}.AppImage 95 | 96 | - name: Upload Release 97 | if: startsWith(github.event.ref, 'refs/tags/') 98 | uses: svenstaro/upload-release-action@v2 99 | with: 100 | repo_token: ${{ secrets.GITHUB_TOKEN }} 101 | file: ${{ env.targetName }}.AppImage 102 | asset_name: ${{ env.targetName }}_${{ github.ref_name }}_${{ matrix.qt_arch }}_Qt${{ matrix.qt_ver }}.AppImage 103 | tag: ${{ github.ref }} 104 | overwrite: true 105 | 106 | - name: Zip Library 107 | run: | 108 | zip -r ${{ env.buildlibName }}.zip HuskarUI 109 | 110 | - name: Upload Library 111 | if: startsWith(github.event.ref, 'refs/tags/') 112 | uses: svenstaro/upload-release-action@v2 113 | with: 114 | repo_token: ${{ secrets.GITHUB_TOKEN }} 115 | file: ${{ env.buildlibName }}.zip 116 | asset_name: $HuskarUI_${{ github.ref_name }}_${{ matrix.qt_arch }}_Qt${{ matrix.qt_ver }}.zip 117 | tag: ${{ github.ref }} 118 | overwrite: true 119 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # This file is used to ignore files which are generated 2 | # ---------------------------------------------------------------------------- 3 | 4 | *~ 5 | *.autosave 6 | *.a 7 | *.core 8 | *.moc 9 | *.o 10 | *.obj 11 | *.orig 12 | *.rej 13 | *.so 14 | *.so.* 15 | *_pch.h.cpp 16 | *_resource.rc 17 | *.qm 18 | .#* 19 | *.*# 20 | core 21 | !core/ 22 | tags 23 | .DS_Store 24 | .directory 25 | *.debug 26 | Makefile* 27 | *.prl 28 | *.app 29 | moc_*.cpp 30 | ui_*.h 31 | qrc_*.cpp 32 | Thumbs.db 33 | *.res 34 | *.rc 35 | /.qmake.cache 36 | /.qmake.stash 37 | 38 | # qtcreator generated files 39 | *.pro.user* 40 | CMakeLists.txt.user* 41 | 42 | # xemacs temporary files 43 | *.flc 44 | 45 | # Vim temporary files 46 | .*.swp 47 | 48 | # Visual Studio generated files 49 | *.ib_pdb_index 50 | *.idb 51 | *.ilk 52 | *.pdb 53 | *.sln 54 | *.suo 55 | *.vcproj 56 | *vcproj.*.*.user 57 | *.ncb 58 | *.sdf 59 | *.opensdf 60 | *.vcxproj 61 | *vcxproj.* 62 | 63 | # MinGW generated files 64 | *.Debug 65 | *.Release 66 | 67 | # Python byte code 68 | *.pyc 69 | 70 | # Binaries 71 | # -------- 72 | *.dll 73 | *.exe 74 | 75 | # CMake generated files 76 | /HuskarUI/ 77 | /build/ 78 | /bin/ 79 | /gallery/bin/ 80 | /package/ 81 | CMakeCache.txt 82 | CMakeFiles 83 | cmake_install.cmake 84 | install_manifest.txt 85 | Makefile 86 | 87 | # VS Code 88 | /.vscode/ 89 | .qmlls.ini 90 | 91 | # clang 92 | /.cache/ 93 | 94 | # clion 95 | **/.idea 96 | -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "3rdparty/qwindowkit"] 2 | path = 3rdparty/qwindowkit 3 | url = https://github.com/stdware/qwindowkit.git 4 | -------------------------------------------------------------------------------- /CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.16) 2 | 3 | project(HuskarUI_Solution) 4 | 5 | option(BUILD_HUSKARUI_GALLERY "Build HuskarUI Gallery." ON) 6 | option(BUILD_HUSKARUI_STATIC_LIBRARY "Build HuskarUI as a static library." OFF) 7 | option(BUILD_HUSKARUI_ON_DESKTOP_PLATFORM "Build HuskarUI on desktop platform (mobile platform set OFF)." ON) 8 | option(BUILD_HUSKARUI_IN_DEFAULT_LOCATION "Build HuskarUI in default location[QtSDK Dir]." ON) 9 | 10 | #Set HuskarUI output dir 11 | set(HUSKARUI_HEADER_OUTPUT_DIRECTORY "" CACHE PATH "HuskarUI header output dir.") 12 | set(HUSKARUI_LIBRARY_OUTPUT_DIRECTORY "" CACHE PATH "HuskarUI library output dir.") 13 | set(HUSKARUI_PLUGIN_OUTPUT_DIRECTORY "" CACHE PATH "HuskarUI plugin output dir (Must end with [HuskarUI/Basic]).") 14 | 15 | set(MACOS FALSE) 16 | if(APPLE) 17 | if(CMAKE_SYSTEM_NAME STREQUAL "Darwin") 18 | set(MACOS TRUE) 19 | else() 20 | set(MACOS FALSE) 21 | endif() 22 | endif() 23 | 24 | if(WIN32 OR MACOS OR LINUX) 25 | set(BUILD_HUSKARUI_ON_DESKTOP_PLATFORM ON) 26 | else() 27 | set(BUILD_HUSKARUI_ON_DESKTOP_PLATFORM OFF) 28 | endif() 29 | 30 | if(BUILD_HUSKARUI_ON_DESKTOP_PLATFORM) 31 | #Build QWindowKit 32 | set(QWINDOWKIT_BUILD_STATIC ON) 33 | set(QWINDOWKIT_BUILD_WIDGETS OFF) 34 | set(QWINDOWKIT_BUILD_QUICK ON) 35 | set(QWINDOWKIT_INSTALL OFF) 36 | add_subdirectory(3rdparty/qwindowkit) 37 | endif() 38 | 39 | set(CMAKE_INSTALL_PREFIX ${CMAKE_CURRENT_SOURCE_DIR}) 40 | add_subdirectory(src) 41 | 42 | if(BUILD_HUSKARUI_GALLERY) 43 | add_subdirectory(gallery) 44 | endif() 45 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2024 mengps 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README-zh_CN.md: -------------------------------------------------------------------------------- 1 |
2 | 3 | 4 | # 「 HuskarUI 」 基于 Qml 的现代 UI 5 | 6 | Qt Qml 的 Ant 设计组件库 7 | 8 | 如果你需要 Qt5 实现 [HuskarUI for Qt5](https://github.com/mengps/HuskarUI_Qt5) 9 | 10 |
11 | 12 |
13 | 14 | ![win-badge] ![linux-badge] ![macos-badge] ![android-badge] 15 | 16 | [![Issues][issues-open-image]][issues-open-url] [![Issues][issues-close-image]][issues-close-url] [![Release][release-image]][release-url] 17 | 18 | [![QQGroup][qqgroup-image]][qqgroup-url] 19 | 20 | [English](./README.md) | 中文 21 | 22 |
23 | 24 | [win-badge]: https://img.shields.io/badge/Windows-passing-brightgreen?style=flat-square 25 | [linux-badge]: https://img.shields.io/badge/Linux-passing-brightgreen?style=flat-square 26 | [macos-badge]: https://img.shields.io/badge/MacOS-passing-brightgreen?style=flat-square 27 | [android-badge]: https://img.shields.io/badge/Android-passing-brightgreen?style=flat-square 28 | 29 | [issues-open-image]: https://img.shields.io/github/issues/mengps/HuskarUI?label=Issue&style=flat-square 30 | [issues-open-url]: https://github.com/mengps/HuskarUI/issues 31 | [issues-close-image]: https://img.shields.io/github/issues-closed/mengps/HuskarUI?color=brightgreen&label=Issue&style=flat-square 32 | [issues-close-url]: https://github.com/mengps/HuskarUI/issues?q=is%3Aissue%20state%3Aclosed 33 | 34 | [release-image]: https://img.shields.io/github/v/release/mengps/HuskarUI?label=Release&style=flat-square 35 | [release-url]: https://github.com/mengps/HuskarUI/releases 36 | 37 | [qqgroup-image]: https://img.shields.io/badge/QQGroup-490328047-f74658?style=flat-square 38 | [qqgroup-url]: https://qm.qq.com/q/cMNHn2tWeY 39 | 40 |
41 | 42 | ## 🌈 陈列室预览 43 | 44 | 45 | 46 | 47 | 48 |
49 | 50 | ## ✨ 特性 51 | 52 | - 📦 一套开箱即用的优质 Qml 组件. 53 | - 🎨 强大的主题定制系统. 54 | - 💻 基于Qml,完全跨平台. 55 | - 🔧 高度灵活的基于委托的组件定制. 56 | 57 | ## 🗺️ 路线图 58 | 59 | 开发计划可以在这里看到: [组件路线图](https://github.com/mengps/HuskarUI/discussions/5). 60 | 61 | 任何人都可以通过 issue/qq群/wx群 进行讨论, 最终有意义的组件/功能将添加到开发计划. 62 | 63 | ## 🌐 在线 wiki 64 | - [HuskarUI 在线 wiki (AI)](https://deepwiki.com/mengps/HuskarUI) 65 | 66 | ## 📺 在线演示 67 | 68 | - [哔哩哔哩](https://www.bilibili.com/video/BV1jodhYhE8a/?spm_id_from=333.1387.homepage.video_card.click) 69 | 70 | ## 🗂️ 预编译包 71 | 72 | 预编译了两个平台的 `Windows / Linux` 程序包和二进制库包. 73 | 74 | 前往 [Release](https://github.com/mengps/HuskarUI/releases) 中下载. 75 | 76 | ## 🔨 如何构建 77 | 78 | - 克隆 79 | ```auto 80 | git clone --recursive https://github.com/mengps/HuskarUI.git 81 | ``` 82 | - 构建 83 | ```cmake 84 | cd HuskarUI 85 | cmake -S . -B build 86 | cmake --build build --config Release --target all --parallel 87 | ``` 88 | 89 | - 使用 MinGW 构建 90 | ```cmake 91 | cmake -S . -B build -G "Ninja" 92 | or 93 | cmake -S . -B build -G "MinGW Makefiles" 94 | ``` 95 | > [!IMPORTANT] 96 | > 默认情况下,`BUILD_HUSKARUI_IN_DEFAULT_LOCATION=ON`: 97 | > - `headers` 将构建在 `[QtDir]/[QtVersion]/[Kit]/include/HuskarUI` 目录中。 98 | > - `*.dll/*.so` 将构建在 `[QtDir]/[QtVersion]/[Kit]/bin` 目录中。 99 | > - `*.lib` 将构建在 `[QtDir]/[QtVersion]/[Kit]/lib` 目录中。 100 | > - `plugin` 将构建在 `[QtDir]/[QtVersion]/[Kit]/qml/HuskarUI` 目录中。 101 | 102 | - 安装 103 | ```cmake 104 | cmake --install --prefix 105 | ``` 106 | 安装目录结构 107 | ```auto 108 | ── 109 | ├─include 110 | │ *.h 111 | ├─bin 112 | │ *.dll 113 | ├─lib 114 | │ *.lib/so 115 | └─imports 116 | └─HuskarUI/Basic 117 | ``` 118 | - 使用 119 | - 链接 `/lib`. 120 | - 包含 `/include`. 121 | - 复制 `/bin/HuskarUIBasic.[dll/so]` 到 `[QtDir]/[QtVersion]/[Kit]/bin`. 122 | - 复制 `/imports/HuskarUI` 到 `[QtDir]/[QtVersion]/[Kit]/qml`. 123 | 124 | ## 📦 上手 125 | 126 | - 创建 QtQuick 应用 `QtVersion >= 6.7` 127 | - 添加下面的 cmake 命令到您的项目 `CMakeLists.txt` 中 128 | ```cmake 129 | target_include_directories( PRIVATE HuskarUI/include) 130 | target_link_directories( PRIVATE HuskarUI/lib) 131 | target_link_libraries( PRIVATE HuskarUIBasic) 132 | ``` 133 | - 添加下面的代码到您的 `main.cpp` 中 134 | ```cpp 135 | #include "husapp.h" 136 | 137 | int main(int argc, char *argv[]) 138 | { 139 | ... 140 | /*! 设置 OpenGL, 可选 */ 141 | QQuickWindow::setGraphicsApi(QSGRendererInterface::OpenGL); 142 | QQuickWindow::setDefaultAlphaBuffer(true); 143 | ... 144 | QGuiApplication app(argc, argv); 145 | QQmlApplicationEngine engine; 146 | HusApp::initialize(&engine); 147 | ... 148 | } 149 | ``` 150 | - 添加下面的代码到您的 `.qml` 中 151 | ```qml 152 | import HuskarUI.Basic 153 | HusWindow { 154 | ... 155 | } 156 | ``` 157 | 好了,你现在可以愉快的开始使用 HuskarUI 了。 158 | 159 | ## 🚩 参考 160 | 161 | - Ant-d 组件: https://ant-design.antgroup.com/components/overview-cn 162 | - Ant 设计: https://ant-design.antgroup.com/docs/spec/introduce-cn 163 | 164 | ## 💓 许可证 165 | 166 | 使用 `MIT LICENSE` 167 | 168 | ## 🌇 环境 169 | 170 | Windows 11 / Ubuntu 24.04.2, Qt Version >= 6.7 171 | 172 | ## 🎉 Star 历史 173 | 174 | [![Star History Chart](https://api.star-history.com/svg?repos=mengps/HuskarUI&type=Date)](https://star-history.com/#mengps/HuskarUI&Date) -------------------------------------------------------------------------------- /gallery/cpp/creator.h: -------------------------------------------------------------------------------- 1 | #ifndef CREATOR_H 2 | #define CREATOR_H 3 | 4 | #include 5 | 6 | class Creator : public QObject 7 | { 8 | Q_OBJECT 9 | QML_SINGLETON 10 | QML_NAMED_ELEMENT(Creator) 11 | 12 | public: 13 | enum ContainMethod 14 | { 15 | NoContain = 0, 16 | SourceContain, 17 | LibraryContain 18 | }; 19 | Q_ENUM(ContainMethod); 20 | 21 | static Creator *instance(); 22 | static Creator *create(QQmlEngine *, QJSEngine *); 23 | 24 | Q_INVOKABLE QUrl localFileToUrl(const QString &file); 25 | Q_INVOKABLE QString urlToLocalFile(const QUrl &url); 26 | 27 | Q_INVOKABLE void createProject(const QVariant &projectParams); 28 | 29 | private: 30 | Creator(QObject *parent = nullptr) : QObject{parent} { } 31 | }; 32 | 33 | #endif // CREATOR_H 34 | -------------------------------------------------------------------------------- /gallery/cpp/customtheme.cpp: -------------------------------------------------------------------------------- 1 | #include "customtheme.h" 2 | #include "hustheme.h" 3 | 4 | CustomTheme *CustomTheme::instance() 5 | { 6 | static CustomTheme *ins = new CustomTheme; 7 | return ins; 8 | } 9 | 10 | CustomTheme *CustomTheme::create(QQmlEngine *, QJSEngine *) 11 | { 12 | return instance(); 13 | } 14 | 15 | void CustomTheme::registerAll() 16 | { 17 | /*HusTheme::instance()->registerCustomComponentTheme(this, "MyControl", &m_MyControl, ":/Gallery/theme/MyControl.json"); 18 | HusTheme::instance()->reloadTheme();*/ 19 | } 20 | 21 | CustomTheme::CustomTheme(QObject *parent) 22 | : QObject{parent} 23 | { 24 | 25 | } 26 | -------------------------------------------------------------------------------- /gallery/cpp/customtheme.h: -------------------------------------------------------------------------------- 1 | #ifndef CUSTOMTHEME_H 2 | #define CUSTOMTHEME_H 3 | 4 | #include 5 | 6 | #include "husdefinitions.h" 7 | 8 | class CustomTheme : public QObject 9 | { 10 | Q_OBJECT 11 | QML_SINGLETON 12 | QML_NAMED_ELEMENT(CustomTheme) 13 | 14 | HUS_PROPERTY_READONLY(QVariantMap, MyControl); 15 | 16 | public: 17 | static CustomTheme *instance(); 18 | static CustomTheme *create(QQmlEngine *, QJSEngine *); 19 | 20 | void registerAll(); 21 | 22 | private: 23 | CustomTheme(QObject *parent = nullptr); 24 | }; 25 | 26 | #endif // CUSTOMTHEME_H 27 | -------------------------------------------------------------------------------- /gallery/cpp/datagenerator.cpp: -------------------------------------------------------------------------------- 1 | #include "datagenerator.h" 2 | 3 | #include 4 | #include 5 | #include 6 | 7 | DataGenerator *DataGenerator::instance() 8 | { 9 | static DataGenerator *ins = new DataGenerator; 10 | return ins; 11 | } 12 | 13 | DataGenerator *DataGenerator::create(QQmlEngine *, QJSEngine *) 14 | { 15 | return instance(); 16 | } 17 | 18 | QVariantList DataGenerator::genTableData(int rows) 19 | { 20 | static const QString tagList[5] = { "nice", "cool", "loser", "teacher", "developer" }; 21 | static const auto genString = [](int len) -> QString { 22 | QString str; 23 | for (int i = 0; i < len; i++) { 24 | str += QChar::fromLatin1(97 + QRandomGenerator::global()->generate() % 26); 25 | } 26 | return str; 27 | }; 28 | 29 | /*! 数据源通常从后台获取 */ 30 | QJsonArray data; 31 | for (int i = 0; i < rows; i++) { 32 | /*! 随机成[0-5]个tags */ 33 | QJsonArray tags; 34 | auto tagCount = QRandomGenerator::global()->generate() % 5; 35 | for (int j = 1; j < tagCount; j++) { 36 | tags.append(tagList[j]); 37 | } 38 | 39 | QJsonObject object; 40 | object["key"] = i; 41 | object["name"] = genString(12); 42 | object["age"] = qint64(QRandomGenerator::global()->generate() % 20 + 30); 43 | object["address"] = genString(22); 44 | object["tags"] = tags; 45 | data.append(object); 46 | } 47 | 48 | /*! qml 可直接访问 QVariantList */ 49 | /*! QVariant -> var QList -> List */ 50 | 51 | return data.toVariantList(); 52 | } 53 | -------------------------------------------------------------------------------- /gallery/cpp/datagenerator.h: -------------------------------------------------------------------------------- 1 | #ifndef DATAGENERATOR_H 2 | #define DATAGENERATOR_H 3 | 4 | #include 5 | 6 | class DataGenerator : public QObject 7 | { 8 | Q_OBJECT 9 | QML_SINGLETON 10 | QML_NAMED_ELEMENT(DataGenerator) 11 | 12 | public: 13 | static DataGenerator *instance(); 14 | static DataGenerator *create(QQmlEngine *, QJSEngine *); 15 | 16 | Q_INVOKABLE QVariantList genTableData(int rows); 17 | 18 | private: 19 | DataGenerator(QObject *parent = nullptr) : QObject{parent} { } 20 | }; 21 | 22 | #endif // DATAGENERATOR_H 23 | -------------------------------------------------------------------------------- /gallery/cpp/main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | #ifdef BUILD_HUSKARUI_STATIC_LIBRARY 6 | #include 7 | Q_IMPORT_QML_PLUGIN(HuskarUI_BasicPlugin) 8 | #endif 9 | 10 | #include "customtheme.h" 11 | #include "husapp.h" 12 | 13 | int main(int argc, char *argv[]) 14 | { 15 | QQuickWindow::setGraphicsApi(QSGRendererInterface::OpenGL); 16 | QQuickWindow::setDefaultAlphaBuffer(true); 17 | 18 | const QGuiApplication app(argc, argv); 19 | QGuiApplication::setOrganizationName("MenPenS"); 20 | QGuiApplication::setApplicationName("HuskarUI"); 21 | QGuiApplication::setApplicationDisplayName("HuskarUI Gallery"); 22 | QGuiApplication::setApplicationVersion(HusApp::libVersion()); 23 | 24 | QQmlApplicationEngine engine; 25 | 26 | HusApp::initialize(&engine); 27 | CustomTheme::instance()->registerAll(); 28 | 29 | const QUrl url = QUrl(QStringLiteral("qrc:/Gallery/qml/Gallery.qml")); 30 | QObject::connect(&engine, &QQmlApplicationEngine::objectCreated, 31 | &app, [url](QObject *obj, const QUrl &objUrl) { 32 | if (!obj && url == objUrl) 33 | QCoreApplication::exit(-1); 34 | }, Qt::QueuedConnection); 35 | engine.load(url); 36 | 37 | return QGuiApplication::exec(); 38 | } 39 | -------------------------------------------------------------------------------- /gallery/cpp/themeswitchitem.cpp: -------------------------------------------------------------------------------- 1 | #include "themeswitchitem.h" 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | ThemeSwitchItem::ThemeSwitchItem(QQuickItem *parent) 10 | : QQuickPaintedItem{parent} 11 | , m_isDark{false} 12 | , m_target{nullptr} 13 | , m_radius{0} 14 | , m_duration{300} 15 | { 16 | m_animation = new QPropertyAnimation(this, "radius", this); 17 | m_animation->setDuration(m_duration); 18 | m_animation->setEasingCurve(QEasingCurve::OutCubic); 19 | 20 | setVisible(false); 21 | 22 | connect(m_animation, &QPropertyAnimation::finished, this, [this] { 23 | update(); 24 | setVisible(false); 25 | emit animationFinished(); 26 | }); 27 | connect(this, &ThemeSwitchItem::radiusChanged, this, &QQuickItem::update); 28 | connect(this, &ThemeSwitchItem::durationChanged, this, [this] { m_animation->setDuration(m_duration); }); 29 | } 30 | 31 | void ThemeSwitchItem::paint(QPainter *painter) 32 | { 33 | painter->save(); 34 | painter->setRenderHint(QPainter::Antialiasing); 35 | 36 | painter->drawImage(QRect(0, 0, width(), height()), m_source); 37 | 38 | QPainterPath path; 39 | path.moveTo(m_center.x(), m_center.y()); 40 | path.addEllipse(QPointF(m_center.x(), m_center.y()), m_radius, m_radius); 41 | 42 | painter->setCompositionMode(QPainter::CompositionMode_Xor); 43 | if (m_isDark) { 44 | painter->fillPath(path, m_colorBg); 45 | } else { 46 | QPainterPath outerRect; 47 | outerRect.addRect(0, 0, width(), height()); 48 | outerRect = outerRect.subtracted(path); 49 | painter->fillPath(outerRect, m_colorBg); 50 | } 51 | 52 | painter->restore(); 53 | } 54 | 55 | void ThemeSwitchItem::start(int width, int height, const QPoint ¢er, int radius) 56 | { 57 | if (!m_target) return; 58 | 59 | if (m_animation->state() == QAbstractAnimation::Running) { 60 | m_animation->stop(); 61 | int currentRadius = m_radius; 62 | m_animation->setStartValue(currentRadius); 63 | m_animation->setEndValue(m_isDark ? 0 : radius); 64 | } else { 65 | if (m_isDark) { 66 | m_animation->setStartValue(radius); 67 | m_animation->setEndValue(0); 68 | } else { 69 | m_animation->setStartValue(0); 70 | m_animation->setEndValue(radius); 71 | } 72 | } 73 | 74 | m_center = center; 75 | m_grabResult = m_target->grabToImage(QSize(width, height)); 76 | connect(m_grabResult.data(), &QQuickItemGrabResult::ready, this, [this] { 77 | m_source = m_grabResult.data()->image(); 78 | update(); 79 | setVisible(true); 80 | emit switchStarted(); 81 | m_animation->start(); 82 | }); 83 | } 84 | -------------------------------------------------------------------------------- /gallery/cpp/themeswitchitem.h: -------------------------------------------------------------------------------- 1 | #ifndef THEMESWITCHITEM_H 2 | #define THEMESWITCHITEM_H 3 | 4 | #include 5 | #include 6 | 7 | #include "husdefinitions.h" 8 | 9 | QT_FORWARD_DECLARE_CLASS(QPropertyAnimation) 10 | 11 | class ThemeSwitchItem : public QQuickPaintedItem 12 | { 13 | Q_OBJECT 14 | QML_NAMED_ELEMENT(ThemeSwitchItem) 15 | 16 | HUS_PROPERTY(int, radius, setRadius) 17 | HUS_PROPERTY(int, duration, setDuration) 18 | HUS_PROPERTY(QColor, colorBg, setColorBg) 19 | HUS_PROPERTY(bool, isDark, setIsDark) 20 | HUS_PROPERTY_P(QQuickItem*, target, setTarget) 21 | 22 | public: 23 | explicit ThemeSwitchItem(QQuickItem *parent = nullptr); 24 | 25 | Q_INVOKABLE void start(int width, int height, const QPoint ¢er, int radius); 26 | 27 | signals: 28 | void switchStarted(); 29 | void animationFinished(); 30 | 31 | protected: 32 | void paint(QPainter *painter) override; 33 | 34 | private: 35 | QImage m_source; 36 | QPoint m_center; 37 | QSharedPointer m_grabResult; 38 | QPropertyAnimation *m_animation { nullptr }; 39 | }; 40 | 41 | #endif // THEMESWITCHITEM_H 42 | -------------------------------------------------------------------------------- /gallery/images/huskarui_icon.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | -------------------------------------------------------------------------------- /gallery/images/swithc_effect1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mengps/HuskarUI/bf203f39db0e502499c53c66b763d163e453d0a8/gallery/images/swithc_effect1.jpg -------------------------------------------------------------------------------- /gallery/images/swithc_effect2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mengps/HuskarUI/bf203f39db0e502499c53c66b763d163e453d0a8/gallery/images/swithc_effect2.jpg -------------------------------------------------------------------------------- /gallery/qml/Controls/CodeRunner.qml: -------------------------------------------------------------------------------- 1 | import QtQuick 2 | import QtQuick.Controls.Basic 3 | import HuskarUI.Basic 4 | 5 | HusWindow { 6 | id: root 7 | 8 | width: 900 9 | height: 600 10 | title: qsTr('代码运行器') 11 | captionBar.closeCallback: 12 | () => { 13 | root.destroy(); 14 | } 15 | captionBar.winIconDelegate: Item { 16 | Image { 17 | width: 16 18 | height: 16 19 | anchors.centerIn: parent 20 | source: 'qrc:/Gallery/images/huskarui_icon.svg' 21 | } 22 | } 23 | Component.onCompleted: { 24 | if (Qt.platform.os === 'windows') { 25 | if (setSpecialEffect(HusWindow.Win_DwmBlur)) return; 26 | } else if (Qt.platform.os === 'osx') { 27 | if (setSpecialEffect(HusWindow.Mac_BlurEffect)) return; 28 | } 29 | HusApi.setWindowStaysOnTopHint(root, true); 30 | } 31 | 32 | property var created: undefined 33 | 34 | function createQmlObject(code) { 35 | codeEdit.text = code; 36 | updateCode(); 37 | } 38 | 39 | function updateCode() { 40 | try { 41 | errorEdit.clear(); 42 | if (created) 43 | created.destroy(); 44 | created = Qt.createQmlObject(codeEdit.text, runnerBlock); 45 | created.parent = runnerBlock; 46 | } catch (error) { 47 | errorEdit.text = error.message; 48 | } 49 | } 50 | 51 | HusDivider { 52 | id: divider 53 | width: parent.width 54 | height: 1 55 | anchors.top: captionBar.bottom 56 | } 57 | 58 | Item { 59 | id: content 60 | width: parent.width 61 | anchors.top: divider.bottom 62 | anchors.bottom: parent.bottom 63 | 64 | Item { 65 | id: codeBlock 66 | width: parent.width * 0.4 67 | height: parent.height 68 | 69 | ScrollView { 70 | width: parent.width 71 | anchors.top: parent.top 72 | anchors.bottom: divider1.top 73 | ScrollBar.vertical: HusScrollBar { } 74 | ScrollBar.horizontal: HusScrollBar { } 75 | 76 | HusCopyableText { 77 | id: codeEdit 78 | readOnly: false 79 | wrapMode: Text.WrapAnywhere 80 | } 81 | } 82 | 83 | HusDivider { 84 | id: divider1 85 | width: parent.width 86 | height: 10 87 | anchors.bottom: errorView.top 88 | title: qsTr('错误') 89 | } 90 | 91 | ScrollView { 92 | id: errorView 93 | width: parent.width 94 | height: 100 95 | anchors.bottom: parent.bottom 96 | 97 | TextArea { 98 | id: errorEdit 99 | readOnly: true 100 | selectByKeyboard: true 101 | selectByMouse: true 102 | font { 103 | family: HusTheme.Primary.fontPrimaryFamily 104 | pixelSize: HusTheme.Primary.fontPrimarySize 105 | } 106 | color: HusTheme.Primary.colorError 107 | wrapMode: Text.WordWrap 108 | } 109 | } 110 | } 111 | 112 | HusDivider { 113 | id: divider2 114 | width: 10 115 | height: parent.height 116 | anchors.left: codeBlock.right 117 | orientation: Qt.Vertical 118 | titleAlign: HusDivider.Align_Center 119 | titleDelegate: HusIconButton { 120 | padding: 5 121 | iconSize: HusTheme.Primary.fontPrimarySizeHeading4 122 | iconSource: HusIcon.PlayCircleOutlined 123 | onClicked: { 124 | root.updateCode(); 125 | } 126 | HusToolTip { 127 | visible: parent.hovered 128 | text: qsTr('运行') 129 | } 130 | } 131 | } 132 | 133 | Item { 134 | id: runnerBlock 135 | anchors.left: divider2.right 136 | anchors.right: parent.right 137 | anchors.top: parent.top 138 | anchors.bottom: parent.bottom 139 | anchors.margins: 5 140 | } 141 | } 142 | } 143 | -------------------------------------------------------------------------------- /gallery/qml/Controls/Description.qml: -------------------------------------------------------------------------------- 1 | import QtQuick 2 | import HuskarUI.Basic 3 | 4 | Item { 5 | id: root 6 | 7 | width: parent.width 8 | height: column.height 9 | 10 | property alias title: titleText.text 11 | property alias desc: descText.text 12 | 13 | Column { 14 | id: column 15 | width: parent.width - 20 16 | anchors.horizontalCenter: parent.horizontalCenter 17 | spacing: 15 18 | 19 | HusText { 20 | id: titleText 21 | width: parent.width 22 | visible: text.length !== 0 23 | font { 24 | pixelSize: HusTheme.Primary.fontPrimarySizeHeading3 25 | weight: Font.DemiBold 26 | } 27 | } 28 | 29 | HusText { 30 | id: descText 31 | width: parent.width 32 | lineHeight: 1.2 33 | visible: text.length !== 0 34 | textFormat: Text.MarkdownText 35 | onLinkActivated: 36 | (link) => { 37 | if (link.startsWith('internal://')) { 38 | galleryMenu.gotoMenu(link.slice(11)); 39 | } else { 40 | Qt.openUrlExternally(link); 41 | } 42 | } 43 | onLinkHovered: 44 | (link) => { 45 | shapeMouse.cursorShape = link !== '' ? Qt.PointingHandCursor : Qt.ArrowCursor; 46 | } 47 | 48 | MouseArea { 49 | id: shapeMouse 50 | anchors.fill: parent 51 | z: parent.z - 2 52 | propagateComposedEvents: true 53 | onClicked: 54 | (mouse) => { 55 | mouse.accepted = false; 56 | } 57 | } 58 | } 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /gallery/qml/Controls/UpdateDesc.qml: -------------------------------------------------------------------------------- 1 | import QtQuick 2 | import HuskarUI.Basic 3 | 4 | Item { 5 | id: root 6 | 7 | width: parent.width 8 | height: visible ? column.height + 20 : 0 9 | visible: containerLoader.tagState !== '' 10 | 11 | Column { 12 | id: column 13 | spacing: 10 14 | 15 | HusText { 16 | text: qsTr('更新信息') 17 | font { 18 | pixelSize: HusTheme.Primary.fontPrimarySizeHeading3 19 | weight: Font.DemiBold 20 | } 21 | } 22 | 23 | HusTag { 24 | text: `${containerLoader.tagState}: version ${containerLoader.version}` 25 | presetColor: { 26 | if (containerLoader.tagState === 'New') 27 | return 'red'; 28 | else if (containerLoader.tagState === 'Update') 29 | return 'green'; 30 | else return ''; 31 | } 32 | } 33 | 34 | HusTag { 35 | text: `${containerLoader.desc}` 36 | presetColor: 'purple' 37 | } 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /gallery/qml/Examples/DataDisplay/ExpEmpty.qml: -------------------------------------------------------------------------------- 1 | import QtQuick 2 | import HuskarUI.Basic 3 | 4 | import '../../Controls' 5 | 6 | Flickable { 7 | contentHeight: column.height 8 | HusScrollBar.vertical: HusScrollBar { } 9 | 10 | Column { 11 | id: column 12 | width: parent.width - 15 13 | spacing: 30 14 | 15 | Description { 16 | desc: qsTr(` 17 | # HusEmpty 空状态 \n 18 | 显示一个表示空状态的图像和描述文本。\n 19 | * **继承自 { Item }**\n 20 | \n
21 | \n### 支持的代理:\n 22 | - **imageDelegate: Component** 图片代理\n 23 | - **descriptionDelegate: Component** 描述文本代理\n 24 | \n
25 | \n### 支持的属性:\n 26 | 属性名 | 类型 | 默认值 | 描述 27 | ------ | --- | :---: | --- 28 | imageSource | string | '' | 自定义的图片地址(优先显示此地址) 29 | imageStyle | int | HusEmpty.Style_Default | 预设的图片样式(来自 HusEmpty) 30 | imageWidth | int | - | 图片宽度 31 | imageHeight | int | - | 图片高度 32 | showDescription | bool | true | 是否显示描述文本 33 | description | string | '' | 描述文本 34 | descriptionFont | font | - | 描述文本字体 35 | descriptionSpacing | int | 12 | 描述文本与图像的间距 36 | colorDescription | color | - | 描述文本颜色 37 | \n
38 | `) 39 | } 40 | 41 | Description { 42 | title: qsTr('何时使用') 43 | desc: qsTr(` 44 | 目标元素为空,如查无数据时,在目标元素占位。\n 45 | `) 46 | } 47 | 48 | ThemeToken { 49 | source: 'HusEmpty' 50 | } 51 | 52 | Description { 53 | title: qsTr('代码演示') 54 | } 55 | 56 | CodeBox { 57 | width: parent.width 58 | descTitle: qsTr('基本') 59 | desc: qsTr(` 60 | 最简单的用法,支持图像和描述。\n 61 | 通过 \`imageSource\` 属性设置图片地址。\n 62 | 通过 \`imageStyle\` 属性设置预设的图片样式。\n 63 | 通过 \`description\` 属性设置描述文本。\n 64 | `) 65 | code: ` 66 | import QtQuick 67 | import HuskarUI.Basic 68 | 69 | Column { 70 | spacing: 10 71 | 72 | HusRadioBlock { 73 | id: imageStyleRadio 74 | initCheckedIndex: 1 75 | model: [ 76 | { label: 'None', value: HusEmpty.Style_None }, 77 | { label: 'Default', value: HusEmpty.Style_Default }, 78 | { label: 'Simple', value: HusEmpty.Style_Simple } 79 | ] 80 | } 81 | 82 | Rectangle { 83 | width: 230 84 | height: 230 85 | color: HusTheme.Primary.colorBgBase 86 | 87 | HusEmpty { 88 | anchors.fill: parent 89 | imageStyle: imageStyleRadio.currentCheckedValue 90 | description: qsTr('暂无数据') 91 | } 92 | } 93 | } 94 | ` 95 | exampleDelegate: Column { 96 | spacing: 10 97 | 98 | HusRadioBlock { 99 | id: imageStyleRadio 100 | initCheckedIndex: 1 101 | model: [ 102 | { label: 'None', value: HusEmpty.Style_None }, 103 | { label: 'Default', value: HusEmpty.Style_Default }, 104 | { label: 'Simple', value: HusEmpty.Style_Simple } 105 | ] 106 | } 107 | 108 | Rectangle { 109 | width: 230 110 | height: 230 111 | color: HusTheme.Primary.colorBgBase 112 | 113 | HusEmpty { 114 | anchors.fill: parent 115 | imageStyle: imageStyleRadio.currentCheckedValue 116 | description: qsTr('暂无数据') 117 | } 118 | } 119 | } 120 | } 121 | } 122 | } 123 | -------------------------------------------------------------------------------- /gallery/qml/Examples/Feedback/ExpPopover.qml: -------------------------------------------------------------------------------- 1 | import QtQuick 2 | import QtQuick.Controls.Basic 3 | import HuskarUI.Basic 4 | 5 | import '../../Controls' 6 | 7 | Flickable { 8 | contentHeight: column.height 9 | ScrollBar.vertical: HusScrollBar { } 10 | 11 | HusMessage { 12 | id: message 13 | z: 999 14 | parent: galleryWindow.captionBar 15 | width: parent.width 16 | anchors.horizontalCenter: parent.horizontalCenter 17 | anchors.top: parent.bottom 18 | } 19 | 20 | Column { 21 | id: column 22 | width: parent.width - 15 23 | spacing: 30 24 | 25 | Description { 26 | desc: qsTr(` 27 | # HusPopover 气泡显示框 \n 28 | 点击元素,弹出气泡式的显示框。\n 29 | * **继承自 { [HusPopup](internal://HusPopup) }**\n 30 | \n
31 | \n### 支持的代理:\n 32 | - **arrowDelegate: Component** 箭头代理\n 33 | - **iconDelegate: Component** 图标代理\n 34 | - **titleDelegate: Component** 标题代理\n 35 | - **descriptionDelegate: Component** 描述代理\n 36 | - **contentDelegate: Component** 内容代理\n 37 | - **bgDelegate: Component** 背景代理\n 38 | - **footerDelegate: Component** 页脚代理\n 39 | \n
40 | \n### 支持的属性:\n 41 | 属性名 | 类型 | 默认值 | 描述 42 | ------ | --- | :---: | --- 43 | animationEnabled | bool | HusTheme.animationEnabled | 是否开启动画 44 | iconSource | int丨string | HusIcon.ExclamationCircleFilled丨'' | 图标源(来自 HusIcon)或图标链接 45 | iconSize | int | 16 | 图标大小 46 | title | string | '' | 标题文本 47 | description | string | '' | 描述文本 48 | showArrow | bool | true | 是否显示箭头 49 | arrowWidth | int | 16 | 箭头宽度 50 | arrowHeight | int | 8 | 箭头高度 51 | colorIcon | color | - | 图标颜色 52 | colorTitle | color | - | 标题文本颜色 53 | colorDescription | color | - | 描述文本颜色 54 | titleFont | font | - | 标题文本字体 55 | descriptionFont | font | - | 描述文本字体 56 | \n
57 | `) 58 | } 59 | 60 | Description { 61 | title: qsTr('何时使用') 62 | desc: qsTr(` 63 | 目标元素的操作需要展示更多详细信息时,在目标元素附近弹出浮层提示。\n 64 | `) 65 | } 66 | 67 | ThemeToken { 68 | source: 'HusPopover' 69 | } 70 | 71 | Description { 72 | title: qsTr('代码演示') 73 | } 74 | 75 | CodeBox { 76 | width: parent.width 77 | descTitle: qsTr('基本') 78 | desc: qsTr(` 79 | 最简单的用法,支持标题和描述。\n 80 | 通过 \`title\` 属性设置标题文本。\n 81 | 通过 \`description\` 属性设置描述文本。\n 82 | `) 83 | code: ` 84 | import QtQuick 85 | import HuskarUI.Basic 86 | 87 | Row { 88 | spacing: 10 89 | 90 | HusButton { 91 | text: 'Hover' 92 | type: HusButton.Type_Outlined 93 | 94 | HusPopover { 95 | x: (parent.width - width) * 0.5 96 | y: parent.height + 6 97 | width: 300 98 | visible: parent.hovered || parent.down 99 | closePolicy: HusPopover.NoAutoClose 100 | title: 'Hover details' 101 | description: 'What are you doing here?' 102 | } 103 | } 104 | 105 | HusButton { 106 | text: 'Click' 107 | type: HusButton.Type_Outlined 108 | onClicked: popover.open(); 109 | 110 | HusPopover { 111 | id: popover 112 | x: (parent.width - width) * 0.5 113 | y: parent.height + 6 114 | width: 300 115 | title: 'Click details' 116 | description: 'What are you doing here?' 117 | } 118 | } 119 | } 120 | ` 121 | exampleDelegate: Row { 122 | spacing: 10 123 | 124 | HusButton { 125 | text: 'Hover' 126 | type: HusButton.Type_Outlined 127 | 128 | HusPopover { 129 | x: (parent.width - width) * 0.5 130 | y: parent.height + 6 131 | width: 300 132 | visible: parent.hovered || parent.down 133 | closePolicy: HusPopover.NoAutoClose 134 | title: 'Hover details' 135 | description: 'What are you doing here?' 136 | } 137 | } 138 | 139 | HusButton { 140 | text: 'Click' 141 | type: HusButton.Type_Outlined 142 | onClicked: popover.open(); 143 | 144 | HusPopover { 145 | id: popover 146 | x: (parent.width - width) * 0.5 147 | y: parent.height + 6 148 | width: 300 149 | title: 'Click details' 150 | description: 'What are you doing here?' 151 | } 152 | } 153 | } 154 | } 155 | } 156 | } 157 | -------------------------------------------------------------------------------- /gallery/qml/Examples/General/ExpCaptionBar.qml: -------------------------------------------------------------------------------- 1 | import QtQuick 2 | import QtQuick.Controls.Basic 3 | import HuskarUI.Basic 4 | 5 | import '../../Controls' 6 | 7 | Flickable { 8 | contentHeight: column.height 9 | ScrollBar.vertical: HusScrollBar { } 10 | 11 | Column { 12 | id: column 13 | width: parent.width - 15 14 | spacing: 30 15 | 16 | Description { 17 | desc: qsTr(` 18 | # HusCaptionBar 标题栏\n 19 | 为无边框窗口提供一个通用的标题栏。\n 20 | * **继承自 { Rectangle }**\n 21 | \n
22 | \n### 支持的代理:\n 23 | - **winIconDelegate: Component** 窗口图标代理\n 24 | - **winTitleDelegate: Component** 窗口标题代理\n 25 | - **winPresetButtonsDelegate: Component** 窗口预设按钮代理(默认为主题切换&置顶按钮)\n 26 | - **winExtraButtonsDelegate: Component** 窗口额外按钮代理(默认为空)\n 27 | - **winButtonsDelegate: Component** 窗口按钮代理(默认最小化&最大化&关闭按钮)\n 28 | \n
29 | \n### 支持的属性:\n 30 | 属性名 | 类型 | 默认值 | 描述 31 | ------ | --- | :---: | --- 32 | targetWindow | var | null | 目标窗口 33 | windowAgent | HusWindowAgent | null | 无边框窗口代理(通常不使用) 34 | layoutDirection | enum | Qt.LeftToRight | 布局方向 35 | winIcon | url | '' | 窗口图标 36 | winIconWidth | real | - | 窗口图标宽度 37 | winIconHeight | real | - | 窗口图标高度 38 | winIconVisible | bool | true | 窗口图标是否可见 39 | winTitle | string | '' | 窗口标题 40 | winTitleFont | font | - | 窗口标题字体 41 | winTitleColor | color | - | 窗口标题颜色 42 | winTitleVisible | bool | true | 窗口标题是否可见 43 | returnButtonVisible | bool | false | 返回按钮是否可见 44 | themeButtonVisible | bool | false | 主题按钮是否可见 45 | topButtonChecked | bool | false | 置顶按钮是否默认选中 46 | topButtonVisible | bool | false | 置顶按钮是否可见 47 | minimizeButtonVisible | bool | true | 最小化按钮是否可见 48 | maximizeButtonVisible | bool | true | 最大化按钮是否可见 49 | closeButtonVisible | bool | true | 关闭按钮是否可见 50 | returnCallback | function | function() | 按下返回按钮时回调 51 | themeCallback | function | function() | 按下主题按钮时回调 52 | topCallback | function | function(checked) | 按下置顶按钮时回调 53 | minimizeCallback | function | function() | 按下最小化按钮时回调 54 | maximizeCallback | function | function() | 按下最大化按钮时回调 55 | closeCallback | function | function() | 按下关闭按钮时回调 56 | contentDescription | string | - | 内容描述(提高可用性) 57 | \n
58 | \n### 支持的函数:\n 59 | - \`addInteractionItem(item: var)\` 添加交互项 \`item\` (当交互项覆盖标题栏时需要使用)\n 60 | - \`removeInteractionItem(item: var)\` 删除交互项 \`item\`\n 61 | `) 62 | } 63 | 64 | Description { 65 | title: qsTr('何时使用') 66 | desc: qsTr(` 67 | 当无边框窗口需要一个通用的标题栏时使用。 68 | `) 69 | } 70 | 71 | Description { 72 | title: qsTr('代码演示') 73 | } 74 | 75 | CodeBox { 76 | width: parent.width 77 | desc: qsTr(` 78 | \`HusWindow\` 自带一个 \`HusCaptionBar\`,通常不需要单独使用。 79 | `) 80 | } 81 | } 82 | } 83 | -------------------------------------------------------------------------------- /gallery/qml/Examples/General/ExpCaptionButton.qml: -------------------------------------------------------------------------------- 1 | import QtQuick 2 | import QtQuick.Controls.Basic 3 | import HuskarUI.Basic 4 | 5 | import '../../Controls' 6 | 7 | Flickable { 8 | contentHeight: column.height 9 | ScrollBar.vertical: HusScrollBar { } 10 | 11 | Column { 12 | id: column 13 | width: parent.width - 15 14 | spacing: 30 15 | 16 | Description { 17 | desc: qsTr(` 18 | # HusCaptionButton 标题按钮\n 19 | 一般用于窗口标题栏的按钮。\n 20 | * **继承自 { [HusIconButton](internal://HusIconButton) }**\n 21 | \n
22 | \n### 支持的代理:\n 23 | - 无\n 24 | \n
25 | \n### 支持的属性:\n 26 | 属性名 | 类型 | 默认值 | 描述 27 | ------ | --- | :---: | --- 28 | isError | bool | false | 是否为警示按钮 29 | noDisabledState | bool | false | 无禁用状态(即被禁用时不会更改颜色) 30 | `) 31 | } 32 | 33 | ThemeToken { 34 | source: 'HusCaptionButton' 35 | } 36 | 37 | Description { 38 | title: qsTr('何时使用') 39 | desc: qsTr(` 40 | 一般配合无边框窗口使用,用于窗口标题栏的自定义按钮。 41 | `) 42 | } 43 | 44 | Description { 45 | title: qsTr('代码演示') 46 | } 47 | 48 | CodeBox { 49 | width: parent.width 50 | desc: qsTr(` 51 | 通过 \`isError\` 属性设置为警示按钮,例如关闭按钮。 52 | `) 53 | code: ` 54 | import QtQuick 55 | import HuskarUI.Basic 56 | 57 | Row { 58 | spacing: 15 59 | 60 | HusCaptionButton { 61 | iconSource: HusIcon.CloseOutlined 62 | } 63 | 64 | HusCaptionButton { 65 | isError: true 66 | iconSource: HusIcon.CloseOutlined 67 | } 68 | 69 | HusCaptionButton { 70 | text: qsTr('关闭') 71 | colorText: colorIcon 72 | iconSource: HusIcon.CloseOutlined 73 | } 74 | } 75 | ` 76 | exampleDelegate: Row { 77 | spacing: 15 78 | 79 | HusCaptionButton { 80 | iconSource: HusIcon.CloseOutlined 81 | } 82 | 83 | HusCaptionButton { 84 | isError: true 85 | iconSource: HusIcon.CloseOutlined 86 | } 87 | 88 | HusCaptionButton { 89 | text: qsTr('关闭') 90 | colorText: colorIcon 91 | iconSource: HusIcon.CloseOutlined 92 | } 93 | } 94 | } 95 | } 96 | } 97 | -------------------------------------------------------------------------------- /gallery/qml/Examples/General/ExpCopyableText.qml: -------------------------------------------------------------------------------- 1 | import QtQuick 2 | import QtQuick.Controls.Basic 3 | import HuskarUI.Basic 4 | 5 | import '../../Controls' 6 | 7 | Flickable { 8 | contentHeight: column.height 9 | ScrollBar.vertical: HusScrollBar { } 10 | 11 | Column { 12 | id: column 13 | width: parent.width - 15 14 | spacing: 30 15 | 16 | Description { 17 | desc: qsTr(` 18 | # HusCopyableText 可复制文本\n 19 | 在需要可复制的文本时使用(替代Text)。\n 20 | * **继承自 { TextEdit }**\n 21 | \n
22 | \n### 支持的代理:\n 23 | - 无\n 24 | `) 25 | } 26 | 27 | Description { 28 | title: qsTr('何时使用') 29 | desc: qsTr(` 30 | Qml中普通文本(Text)无法复制,因此在需要可复制的文本时建议使用。 31 | `) 32 | } 33 | 34 | Description { 35 | title: qsTr('代码演示') 36 | } 37 | 38 | CodeBox { 39 | width: parent.width 40 | desc: qsTr(` 41 | 使用方法等同于 \`TextEdit\` 42 | `) 43 | code: ` 44 | import QtQuick 45 | import HuskarUI.Basic 46 | 47 | Row { 48 | spacing: 15 49 | 50 | HusCopyableText { 51 | text: qsTr('可以复制我') 52 | } 53 | } 54 | ` 55 | exampleDelegate: Row { 56 | spacing: 15 57 | 58 | HusCopyableText { 59 | text: qsTr('可以复制我') 60 | } 61 | } 62 | } 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /gallery/qml/Examples/General/ExpIconButton.qml: -------------------------------------------------------------------------------- 1 | import QtQuick 2 | import QtQuick.Controls.Basic 3 | import HuskarUI.Basic 4 | 5 | import '../../Controls' 6 | 7 | Flickable { 8 | contentHeight: column.height 9 | ScrollBar.vertical: HusScrollBar { } 10 | 11 | Column { 12 | id: column 13 | width: parent.width - 15 14 | spacing: 30 15 | 16 | Description { 17 | desc: qsTr(` 18 | # HusIconButton 图标按钮\n 19 | 带图标的按钮。\n 20 | * **继承自 { [HusButton](internal://HusButton) }**\n 21 | \n
22 | \n### 支持的代理:\n 23 | - 无\n 24 | \n
25 | \n### 支持的属性:\n 26 | 属性名 | 类型 | 默认值 | 描述 27 | ------ | --- | :---: | --- 28 | iconSource | int丨string | 0丨'' | 图标源(来自 HusIcon)或图标链接 29 | iconSize | int | - | 图标大小 30 | iconSpacing | int | 5 | 图标间隔 31 | iconPosition | enum | HusIconButton.Position_Start | 图标位置(来自 HusIconButton) 32 | colorIcon | color | - | 图标颜色 33 | `) 34 | } 35 | 36 | Description { 37 | title: qsTr('何时使用') 38 | desc: qsTr(` 39 | 等同于 [HusButton](internal://HusButton),但提供一个前/后的可选图标。 40 | `) 41 | } 42 | 43 | ThemeToken { 44 | source: 'HusButton' 45 | } 46 | 47 | Description { 48 | title: qsTr('代码演示') 49 | } 50 | 51 | CodeBox { 52 | width: parent.width 53 | desc: qsTr(` 54 | 通过 \`iconSource\` 属性设置图标源{ HusIcon中定义 }\n 55 | 通过 \`iconSize\` 属性设置图标大小\n 56 | 通过 \`iconPosition\` 属性设置图标位置,支持的位置有:\n 57 | - 图标处于开始位置(默认){ HusIconButton.Position_Start }\n 58 | - 图标处于结束位置{ HusIconButton.Position_End } 59 | `) 60 | code: ` 61 | import QtQuick 62 | import HuskarUI.Basic 63 | 64 | Row { 65 | spacing: 15 66 | 67 | HusIconButton { 68 | text: qsTr('搜索') 69 | iconSource: HusIcon.SearchOutlined 70 | } 71 | 72 | HusIconButton { 73 | text: qsTr('搜索') 74 | type: HusButton.Type_Outlined 75 | iconSource: HusIcon.SearchOutlined 76 | } 77 | 78 | HusIconButton { 79 | type: HusButton.Type_Primary 80 | iconSource: HusIcon.SearchOutlined 81 | } 82 | 83 | HusIconButton { 84 | text: qsTr('搜索') 85 | type: HusButton.Type_Primary 86 | iconSource: HusIcon.SearchOutlined 87 | } 88 | 89 | HusIconButton { 90 | text: qsTr('搜索') 91 | type: HusButton.Type_Primary 92 | iconSource: HusIcon.SearchOutlined 93 | iconPosition: HusIconButton.Position_End 94 | } 95 | 96 | HusIconButton { 97 | text: qsTr('搜索') 98 | type: HusButton.Type_Filled 99 | iconSource: HusIcon.SearchOutlined 100 | } 101 | 102 | HusIconButton { 103 | text: qsTr('搜索') 104 | type: HusButton.Type_Text 105 | iconSource: HusIcon.SearchOutlined 106 | } 107 | } 108 | ` 109 | exampleDelegate: Row { 110 | spacing: 15 111 | 112 | HusIconButton { 113 | text: qsTr('搜索') 114 | iconSource: HusIcon.SearchOutlined 115 | } 116 | 117 | HusIconButton { 118 | text: qsTr('搜索') 119 | type: HusButton.Type_Outlined 120 | iconSource: HusIcon.SearchOutlined 121 | } 122 | 123 | HusIconButton { 124 | type: HusButton.Type_Primary 125 | iconSource: HusIcon.SearchOutlined 126 | } 127 | 128 | HusIconButton { 129 | text: qsTr('搜索') 130 | type: HusButton.Type_Primary 131 | iconSource: HusIcon.SearchOutlined 132 | } 133 | 134 | HusIconButton { 135 | text: qsTr('搜索') 136 | type: HusButton.Type_Primary 137 | iconSource: HusIcon.SearchOutlined 138 | iconPosition: HusIconButton.Position_End 139 | } 140 | 141 | HusIconButton { 142 | text: qsTr('搜索') 143 | type: HusButton.Type_Filled 144 | iconSource: HusIcon.SearchOutlined 145 | } 146 | 147 | HusIconButton { 148 | text: qsTr('搜索') 149 | type: HusButton.Type_Text 150 | iconSource: HusIcon.SearchOutlined 151 | } 152 | 153 | } 154 | } 155 | } 156 | } 157 | -------------------------------------------------------------------------------- /gallery/qml/Examples/General/ExpMoveMouseArea.qml: -------------------------------------------------------------------------------- 1 | import QtQuick 2 | import QtQuick.Controls.Basic 3 | import HuskarUI.Basic 4 | 5 | import '../../Controls' 6 | 7 | Flickable { 8 | contentHeight: column.height 9 | ScrollBar.vertical: HusScrollBar { } 10 | 11 | Column { 12 | id: column 13 | width: parent.width - 15 14 | spacing: 30 15 | 16 | Description { 17 | desc: qsTr(` 18 | # HusMoveMouseArea 移动鼠标区域\n 19 | 提供对任意 Item 进行鼠标移动操作的区域。\n 20 | * **继承自 { MouseArea }**\n 21 | \n
22 | \n### 支持的代理:\n 23 | - 无\n 24 | \n
25 | \n### 支持的属性:\n 26 | 属性名 | 类型 | 默认值 | 描述 27 | ------ | --- | :---: | --- 28 | target | var | undefined | 要移动的目标 29 | minimumX | real | -Number.MAX_VALUE | 可移动的最小x坐标 30 | maximumX | real | Number.MAX_VALUE | 可移动的最大x坐标 31 | minimumY | real | -Number.MAX_VALUE | 可移动的最小y坐标 32 | maximumY | real | Number.MAX_VALUE | 可移动的最大y坐标 33 | `) 34 | } 35 | 36 | Description { 37 | title: qsTr('何时使用') 38 | desc: qsTr(` 39 | 需要实时移动某一项时使用。 40 | `) 41 | } 42 | 43 | Description { 44 | title: qsTr('代码演示') 45 | } 46 | 47 | CodeBox { 48 | width: parent.width 49 | desc: qsTr(` 50 | 通过 \`target\` 设置要移动的目标。 51 | `) 52 | code: ` 53 | import QtQuick 54 | import HuskarUI.Basic 55 | 56 | Rectangle { 57 | color: 'transparent' 58 | border.color: HusTheme.Primary.colorTextQuaternary 59 | width: 400 60 | height: 400 61 | clip: true 62 | 63 | Rectangle { 64 | width: 100 65 | height: 100 66 | color: 'red' 67 | 68 | HusMoveMouseArea { 69 | anchors.fill: parent 70 | target: parent 71 | preventStealing: true 72 | } 73 | } 74 | } 75 | ` 76 | exampleDelegate: Rectangle { 77 | color: 'transparent' 78 | border.color: HusTheme.Primary.colorTextQuaternary 79 | width: 400 80 | height: 400 81 | clip: true 82 | 83 | Rectangle { 84 | width: 100 85 | height: 100 86 | color: 'red' 87 | 88 | HusMoveMouseArea { 89 | anchors.fill: parent 90 | target: parent 91 | preventStealing: true 92 | } 93 | } 94 | } 95 | } 96 | } 97 | } 98 | -------------------------------------------------------------------------------- /gallery/qml/Examples/General/ExpPopup.qml: -------------------------------------------------------------------------------- 1 | import QtQuick 2 | import QtQuick.Controls.Basic 3 | import HuskarUI.Basic 4 | 5 | import '../../Controls' 6 | 7 | Flickable { 8 | contentHeight: column.height 9 | ScrollBar.vertical: HusScrollBar { } 10 | 11 | Column { 12 | id: column 13 | width: parent.width - 15 14 | spacing: 30 15 | 16 | Description { 17 | id: description 18 | desc: qsTr(` 19 | # HusPopup 弹窗\n 20 | 自带跟随主题切换的背景和阴影, 用来替代内置 Popup。\n 21 | * **继承自 { Popup }**\n 22 | \n
23 | \n### 支持的代理:\n 24 | - 无\n 25 | \n
26 | \n### 支持的属性:\n 27 | 属性名 | 类型 | 默认值 | 描述 28 | ------ | --- | :---: | --- 29 | animationEnabled | bool | HusTheme.animationEnabled | 是否开启动画 30 | movable | bool | false | 是否可移动 31 | resizable | bool | false | 是否可改变大小 32 | minimumX | int | Number.NaN | 可移动的最小X坐标(movable为true生效) 33 | maximumX | int | Number.NaN | 可移动的最大X坐标(movable为true生效) 34 | minimumY | int | Number.NaN | 可移动的最小Y坐标(movable为true生效) 35 | maximumY | int | Number.NaN | 可移动的最大Y坐标(movable为true生效) 36 | minimumWidth | int | 0 | 可改变的最小宽度(resizable为true生效) 37 | maximumWidth | int | Number.NaN | 可改变的最小宽度(resizable为true生效) 38 | minimumHeight | int | 0 | 可改变的最小高度(resizable为true生效) 39 | maximumHeight | int | Number.NaN | 可改变的最小高度(resizable为true生效) 40 | colorShadow | color | - | 阴影颜色 41 | colorBg | color | - | 背景颜色 42 | radiusBg | [HusRadius](internal://HusRadius) | - | 背景圆角半径 43 | `) 44 | } 45 | 46 | Description { 47 | title: qsTr('何时使用') 48 | desc: qsTr(` 49 | 需要一个弹出式窗口时使用。 50 | `) 51 | } 52 | 53 | ThemeToken { 54 | source: 'HusPopup' 55 | } 56 | 57 | Description { 58 | title: qsTr('代码演示') 59 | } 60 | 61 | CodeBox { 62 | width: parent.width 63 | desc: qsTr(` 64 | 使用方法等同于 \`Popup\` \n 65 | 通过 \`movable\` 设置为可移动 \n 66 | 通过 \`resizable\` 设置为可改变大小 \n 67 | `) 68 | code: ` 69 | import QtQuick 70 | import QtQuick.Controls.Basic 71 | import HuskarUI.Basic 72 | 73 | Item { 74 | height: 50 75 | 76 | HusButton { 77 | text: (popup.opened ? qsTr('隐藏') : qsTr('显示')) 78 | type: HusButton.Type_Primary 79 | onClicked: { 80 | if (popup.opened) 81 | popup.close(); 82 | else 83 | popup.open(); 84 | } 85 | } 86 | 87 | HusPopup { 88 | id: popup 89 | x: (parent.width - width) * 0.5 90 | y: (parent.height - height) * 0.5 91 | width: 400 92 | height: 300 93 | parent: Overlay.overlay 94 | closePolicy: HusPopup.NoAutoClose 95 | movable: true 96 | resizable: true 97 | minimumX: 0 98 | maximumX: parent.width - width 99 | minimumY: 0 100 | maximumY: parent.height - height 101 | minimumWidth: 400 102 | minimumHeight: 300 103 | radiusBg.topLeft: 100 104 | radiusBg.bottomRight: 100 105 | contentItem: Item { 106 | HusCaptionButton { 107 | anchors.right: parent.right 108 | radiusBg.topRight: popup.radiusBg.topRight 109 | colorText: colorIcon 110 | iconSource: HusIcon.CloseOutlined 111 | onClicked: popup.close(); 112 | } 113 | } 114 | } 115 | } 116 | ` 117 | exampleDelegate: Item { 118 | height: 50 119 | 120 | HusButton { 121 | text: (popup.opened ? qsTr('隐藏') : qsTr('显示')) 122 | type: HusButton.Type_Primary 123 | onClicked: { 124 | if (popup.opened) 125 | popup.close(); 126 | else 127 | popup.open(); 128 | } 129 | } 130 | 131 | HusPopup { 132 | id: popup 133 | x: (parent.width - width) * 0.5 134 | y: (parent.height - height) * 0.5 135 | width: 400 136 | height: 300 137 | parent: Overlay.overlay 138 | closePolicy: HusPopup.NoAutoClose 139 | movable: true 140 | resizable: true 141 | minimumX: 0 142 | maximumX: parent.width - width 143 | minimumY: 0 144 | maximumY: parent.height - height 145 | minimumWidth: 400 146 | minimumHeight: 300 147 | radiusBg.topLeft: 100 148 | radiusBg.bottomRight: 100 149 | contentItem: Item { 150 | HusCaptionButton { 151 | anchors.right: parent.right 152 | radiusBg.topRight: popup.radiusBg.topRight 153 | colorText: colorIcon 154 | iconSource: HusIcon.CloseOutlined 155 | onClicked: popup.close(); 156 | } 157 | } 158 | } 159 | } 160 | } 161 | } 162 | } 163 | -------------------------------------------------------------------------------- /gallery/qml/Examples/General/ExpRadius.qml: -------------------------------------------------------------------------------- 1 | import QtQuick 2 | import QtQuick.Controls.Basic 3 | import HuskarUI.Basic 4 | 5 | import '../../Controls' 6 | 7 | Flickable { 8 | contentHeight: column.height 9 | ScrollBar.vertical: HusScrollBar { } 10 | 11 | Column { 12 | id: column 13 | width: parent.width - 15 14 | spacing: 30 15 | 16 | Description { 17 | desc: qsTr(` 18 | # HusRadius 圆角半径\n 19 | 提供四方向的圆角半径类型。\n 20 | * **继承自 { QObject }**\n 21 | \n
22 | \n### 支持的代理:\n 23 | - 无\n 24 | \n
25 | \n### 支持的属性:\n 26 | 属性名 | 类型 | 默认值 | 描述 27 | ------ | --- | :---: | --- 28 | all | real | 0 | 统一设置四个圆角半径 29 | topLeft | real | -1 | 左上圆角半径 30 | topRight | real | -1 | 右上圆角半径 31 | bottomLeft | real | -1 | 左下圆角半径 32 | bottomRight | real | -1 | 右下圆角半径 33 | `) 34 | } 35 | 36 | Description { 37 | title: qsTr('何时使用') 38 | desc: qsTr(` 39 | 在用户需要任意方向圆角半径类型时使用。\n 40 | `) 41 | } 42 | 43 | ThemeToken { } 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /gallery/qml/Examples/General/ExpResizeMouseArea.qml: -------------------------------------------------------------------------------- 1 | import QtQuick 2 | import QtQuick.Controls.Basic 3 | import HuskarUI.Basic 4 | 5 | import '../../Controls' 6 | 7 | Flickable { 8 | contentHeight: column.height 9 | ScrollBar.vertical: HusScrollBar { } 10 | 11 | Column { 12 | id: column 13 | width: parent.width - 15 14 | spacing: 30 15 | 16 | Description { 17 | desc: qsTr(` 18 | # HusResizeMouseArea 改变大小鼠标区域\n 19 | 提供对任意 Item 进行鼠标改变大小操作的区域。\n 20 | * **继承自 { Item }**\n 21 | \n
22 | \n### 支持的代理:\n 23 | - 无\n 24 | \n
25 | \n### 支持的属性:\n 26 | 属性名 | 类型 | 默认值 | 描述 27 | ------ | --- | :---: | --- 28 | target | var | undefined | 要移动的目标 29 | preventStealing | bool | false | 鼠标事件不可被盗取 30 | areaMarginSize | int | 8 | 改变大小区域的边缘大小 31 | resizable | bool | true | 是否可改变大小 32 | minimumWidth | real | 0 | 可改变的最小宽度 33 | maximumWidth | real | Number.MAX_VALUE | 可改变的最大宽度 34 | minimumHeight | real | 0 | 可改变的最小高度 35 | maximumHeight | real | Number.MAX_VALUE |可改变的最小高度 36 | movable | bool | false | 可移动的最小x坐标 37 | minimumX | real | -Number.MAX_VALUE | 可移动的最小x坐标 38 | maximumX | real | Number.MAX_VALUE | 可移动的最大x坐标 39 | minimumY | real | -Number.MAX_VALUE | 可移动的最小y坐标 40 | maximumY | real | Number.MAX_VALUE | 可移动的最大y坐标 41 | `) 42 | } 43 | 44 | Description { 45 | title: qsTr('何时使用') 46 | desc: qsTr(` 47 | 需要实时对某一项调整大小时使用。 48 | `) 49 | } 50 | 51 | Description { 52 | title: qsTr('代码演示') 53 | } 54 | 55 | CodeBox { 56 | width: parent.width 57 | desc: qsTr(` 58 | 通过 \`target\` 设置要改变大小的目标。 59 | `) 60 | code: ` 61 | import QtQuick 62 | import HuskarUI.Basic 63 | 64 | Rectangle { 65 | color: 'transparent' 66 | border.color: HusTheme.Primary.colorTextQuaternary 67 | width: 400 68 | height: 400 69 | clip: true 70 | 71 | Rectangle { 72 | width: 100 73 | height: 100 74 | color: 'red' 75 | 76 | HusResizeMouseArea { 77 | anchors.fill: parent 78 | target: parent 79 | movable: true 80 | preventStealing: true 81 | minimumWidth: 50 82 | minimumHeight: 50 83 | } 84 | } 85 | } 86 | ` 87 | exampleDelegate: Rectangle { 88 | color: 'transparent' 89 | border.color: HusTheme.Primary.colorTextQuaternary 90 | width: 400 91 | height: 400 92 | clip: true 93 | 94 | Rectangle { 95 | width: 100 96 | height: 100 97 | color: 'red' 98 | 99 | HusResizeMouseArea { 100 | anchors.fill: parent 101 | target: parent 102 | movable: true 103 | preventStealing: true 104 | minimumWidth: 50 105 | minimumHeight: 50 106 | } 107 | } 108 | } 109 | } 110 | } 111 | } 112 | -------------------------------------------------------------------------------- /gallery/qml/Examples/General/ExpText.qml: -------------------------------------------------------------------------------- 1 | import QtQuick 2 | import QtQuick.Controls.Basic 3 | import HuskarUI.Basic 4 | 5 | import '../../Controls' 6 | 7 | Flickable { 8 | contentHeight: column.height 9 | ScrollBar.vertical: HusScrollBar { } 10 | 11 | Column { 12 | id: column 13 | width: parent.width - 15 14 | spacing: 30 15 | 16 | Description { 17 | desc: qsTr(` 18 | # HusText 文本\n 19 | 提供统一字体和颜色的文本(替代Text)。\n 20 | * **继承自 { Text }**\n 21 | \n
22 | \n### 支持的代理:\n 23 | - 无\n 24 | `) 25 | } 26 | 27 | Description { 28 | title: qsTr('何时使用') 29 | desc: qsTr(` 30 | 需要统一字体和颜色的文本时建议使用。 31 | `) 32 | } 33 | 34 | Description { 35 | title: qsTr('代码演示') 36 | } 37 | 38 | CodeBox { 39 | width: parent.width 40 | desc: qsTr(` 41 | 使用方法等同于 \`Text\` 42 | `) 43 | code: ` 44 | import QtQuick 45 | import HuskarUI.Basic 46 | 47 | Row { 48 | spacing: 15 49 | 50 | HusText { 51 | text: qsTr('HusText文本') 52 | } 53 | } 54 | ` 55 | exampleDelegate: Row { 56 | spacing: 15 57 | 58 | HusText { 59 | text: qsTr('HusText文本') 60 | } 61 | } 62 | } 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /gallery/qml/Examples/General/ExpWindow.qml: -------------------------------------------------------------------------------- 1 | import QtQuick 2 | import QtQuick.Controls.Basic 3 | import HuskarUI.Basic 4 | 5 | import '../../Controls' 6 | 7 | Flickable { 8 | contentHeight: column.height 9 | ScrollBar.vertical: HusScrollBar { } 10 | 11 | Column { 12 | id: column 13 | width: parent.width - 15 14 | spacing: 30 15 | 16 | Description { 17 | id: description 18 | desc: qsTr(` 19 | # HusWindow 无边框窗口\n 20 | 跨平台无边框窗口的最佳实现,基于 [QWindowKit](https://github.com/stdware/qwindowkit)。\n 21 | * **继承自 { Window }**\n 22 | \n
23 | \n### 支持的代理:\n 24 | - 无\n 25 | \n
26 | \n### 支持的属性:\n 27 | 属性名 | 类型 | 默认值 | 描述 28 | ------ | --- | :---: | --- 29 | contentHeight | int | - | 窗口内容高度(即减去标题栏高度) 30 | captionBar | [HusCaptionBar](internal://HusCaptionBar) | - | 窗口标题栏 31 | windowAgent | HusWindowAgent | - | 窗口代理 32 | followThemeSwitch | bool | true | 是否跟随系统明/暗模式自动切换 33 | initialized | bool | false | 指示窗口是否已经初始化完毕 34 | specialEffect | enum | HusWindow.None | 特殊效果(来自 HusWindow) 35 | \n
36 | \n### 支持的函数:\n 37 | - \`setMacSystemButtonsVisible(visible: bool): bool\` 设置是否显示系统按钮(MacOSX有效) \n 38 | - \`setWindowMode(isDark: bool): bool\` 设置窗口明/暗模式 \n 39 | - \`setSpecialEffect(specialEffect: int): bool\` 设置窗口的特殊效果 \n 40 | `) 41 | } 42 | 43 | Description { 44 | title: qsTr('何时使用') 45 | desc: qsTr(` 46 | 当用户需要自定义窗口形态时作为基础无边框窗口使用,默认提供一个 [HusCaptionBar](internal://HusCaptionBar)。 47 | `) 48 | } 49 | 50 | Description { 51 | title: qsTr('代码演示') 52 | } 53 | 54 | CodeBox { 55 | width: parent.width 56 | desc: qsTr(` 57 | 使用方法等同于 \`Window\` \n 58 | **注意** 不要嵌套使用 HusWindow (源于Qt的某些BUG):\n 59 | \`\`\`qml 60 | HusWindow { 61 | HusWindow { } 62 | } 63 | \`\`\` 64 | 更应该使用动态创建:\n 65 | \`\`\`qml 66 | HusWindow { 67 | Loader { 68 | id: loader 69 | visible: false 70 | sourceComponent: HusWindow { 71 | visible: loader.visible 72 | } 73 | } 74 | } 75 | \`\`\` 76 | `) 77 | code: ` 78 | import QtQuick 79 | import HuskarUI.Basic 80 | 81 | Item { 82 | height: 50 83 | 84 | HusButton { 85 | text: (windowLoader.visible ? qsTr('隐藏') : qsTr('显示')) + qsTr('窗口') 86 | type: HusButton.Type_Primary 87 | onClicked: windowLoader.visible = !windowLoader.visible; 88 | } 89 | 90 | Loader { 91 | id: windowLoader 92 | visible: false 93 | sourceComponent: HusWindow { 94 | width: 600 95 | height: 400 96 | visible: windowLoader.visible 97 | title: qsTr('无边框窗口') 98 | captionBar.winIconWidth: 0 99 | captionBar.winIconHeight: 0 100 | captionBar.winIconDelegate: Item { } 101 | captionBar.closeCallback: () => windowLoader.visible = false; 102 | } 103 | } 104 | } 105 | ` 106 | exampleDelegate: Item { 107 | height: 50 108 | 109 | HusButton { 110 | text: (windowLoader.visible ? qsTr('隐藏') : qsTr('显示')) + qsTr('窗口') 111 | type: HusButton.Type_Primary 112 | onClicked: windowLoader.visible = !windowLoader.visible; 113 | } 114 | 115 | Loader { 116 | id: windowLoader 117 | visible: false 118 | sourceComponent: HusWindow { 119 | width: 600 120 | height: 400 121 | visible: windowLoader.visible 122 | title: qsTr('无边框窗口') 123 | captionBar.winIconWidth: 0 124 | captionBar.winIconHeight: 0 125 | captionBar.winIconDelegate: Item { } 126 | captionBar.closeCallback: () => windowLoader.visible = false; 127 | } 128 | } 129 | } 130 | } 131 | } 132 | } 133 | -------------------------------------------------------------------------------- /gallery/qml/Examples/Navigation/ExpScrollBar.qml: -------------------------------------------------------------------------------- 1 | import QtQuick 2 | import QtQuick.Controls.Basic 3 | import HuskarUI.Basic 4 | 5 | import '../../Controls' 6 | 7 | Flickable { 8 | contentHeight: column.height 9 | ScrollBar.vertical: HusScrollBar { } 10 | 11 | Column { 12 | id: column 13 | width: parent.width - 15 14 | spacing: 30 15 | 16 | Description { 17 | desc: qsTr(` 18 | # HusScrollBar 滚动条\n 19 | 滚动条是一个交互式栏,用于滚动某个区域或视图到特定位置。\n 20 | * **继承自 { ScrollBar }**\n 21 | \n
22 | \n### 支持的代理:\n 23 | - 无\n 24 | \n
25 | \n### 支持的属性:\n 26 | 属性名 | 类型 | 默认值 | 描述 | 27 | ------ | --- | :---: | --- 28 | animationEnabled | bool | true | 是否开启动画 29 | minimumHandleSize | int | 24 | 滑块的最小大小 30 | colorBar | color | - | 把手颜色 31 | colorBg | color | - | 背景颜色 32 | colorIcon | color | - | 图标颜色(即箭头颜色) 33 | `) 34 | } 35 | 36 | Description { 37 | title: qsTr('何时使用') 38 | desc: qsTr(` 39 | 当一个项超出其容器大小时使用,提供比原生[ScrollBar]更好的外观和操作体验。 40 | `) 41 | } 42 | 43 | ThemeToken { 44 | source: 'HusScrollBar' 45 | } 46 | 47 | Description { 48 | title: qsTr('代码演示') 49 | } 50 | 51 | CodeBox { 52 | width: parent.width 53 | desc: qsTr(` 54 | 使用方法和 \`ScrollBar\` 一致。 55 | `) 56 | code: ` 57 | import QtQuick 58 | import QtQuick.Controls.Basic 59 | import HuskarUI.Basic 60 | 61 | Item { 62 | Flickable { 63 | width: 200 64 | height: 200 65 | contentWidth: 400 66 | contentHeight: 400 67 | ScrollBar.vertical: HusScrollBar { } 68 | ScrollBar.horizontal: HusScrollBar { } 69 | clip: true 70 | 71 | HusIconText { 72 | iconSize: 400 73 | iconSource: HusIcon.BugOutlined 74 | } 75 | } 76 | } 77 | ` 78 | exampleDelegate: Item { 79 | height: 200 80 | 81 | Flickable { 82 | width: 200 83 | height: 200 84 | contentWidth: 400 85 | contentHeight: 400 86 | ScrollBar.vertical: HusScrollBar { } 87 | ScrollBar.horizontal: HusScrollBar { } 88 | clip: true 89 | 90 | HusIconText { 91 | iconSize: 400 92 | iconSource: HusIcon.BugOutlined 93 | } 94 | } 95 | } 96 | } 97 | } 98 | } 99 | -------------------------------------------------------------------------------- /gallery/qml/Examples/Utils/ExpAsyncHasher.qml: -------------------------------------------------------------------------------- 1 | import QtQuick 2 | import QtQuick.Controls.Basic 3 | import HuskarUI.Basic 4 | 5 | import '../../Controls' 6 | 7 | Flickable { 8 | contentHeight: column.height 9 | ScrollBar.vertical: HusScrollBar { } 10 | 11 | Column { 12 | id: column 13 | width: parent.width - 15 14 | spacing: 30 15 | 16 | Description { 17 | desc: qsTr(` 18 | # HusAsyncHasher 异步散列器 \n 19 | 可对任意数据(url/text/object)生成加密哈希的异步散列器。\n 20 | * **继承自 { QObject }**\n 21 | \n
22 | \n### 支持的代理:\n 23 | - 无\n 24 | \n
25 | \n### 支持的属性:\n 26 | 属性名 | 类型 | 默认值 | 描述 27 | ------ | --- | :---: | --- 28 | algorithm | enum | HusAsyncHasher.Md5 | 哈希算法(来自 HusAsyncHasher) 29 | asynchronous | bool | true | 是否异步 30 | hashValue | string | '' | 目标的哈希值 31 | hashLength | int | - | 目标的哈希长度 32 | source | url | '' | 目标的源地址 33 | sourceText | color | '' | 目标的源文本 34 | sourceData | arraybuffer | '' | 目标的源数据 35 | sourceObject | QObject* | null | 目标的源指针 36 | \n
37 | \n### 支持的信号:\n 38 | - \`hashProgress(processed: int, total: int)\` 散列值计算进度\n 39 | - \`processed\` 已处理的字节数\n 40 | - \`total\` 总字节数\n 41 | - \`started(processed: int, total: int)\` 散列值计算开始时发出\n 42 | - \`finished(processed: int, total: int)\` 散列值计算结束时发出\n 43 | `) 44 | } 45 | 46 | Description { 47 | title: qsTr('何时使用') 48 | desc: qsTr(` 49 | 当需要对(url/text/object)生成加密哈希时使用。\n 50 | `) 51 | } 52 | 53 | Description { 54 | title: qsTr('代码演示') 55 | } 56 | 57 | CodeBox { 58 | width: parent.width 59 | desc: qsTr(` 60 | 通过 \`algorithm\` 属性改变使用的哈希算法,支持的算法:\n 61 | - Md4{ HusAsyncHasher.Md4 }\n 62 | - Md5(默认){ HusAsyncHasher.Md5 }\n 63 | - Sha1{ HusAsyncHasher.Sha1 }\n 64 | - Sha224{ HusAsyncHasher.Sha224 }\n 65 | - Sha256{ HusAsyncHasher.Sha256 }\n 66 | - Sha384{ HusAsyncHasher.Sha384 }\n 67 | - Sha512{ HusAsyncHasher.Sha512 }\n 68 | - Keccak_224{ HusAsyncHasher.Keccak_224 }\n 69 | - Keccak_256{ HusAsyncHasher.Keccak_256 }\n 70 | - Keccak_384{ HusAsyncHasher.Keccak_384 }\n 71 | - Keccak_512{ HusAsyncHasher.Keccak_512 }\n 72 | - RealSha3_224{ HusAsyncHasher.RealSha3_224 }\n 73 | - RealSha3_256{ HusAsyncHasher.RealSha3_256 }\n 74 | - RealSha3_384{ HusAsyncHasher.RealSha3_384 }\n 75 | - RealSha3_512{ HusAsyncHasher.RealSha3_512 }\n 76 | - Sha3_224{ HusAsyncHasher.Sha3_224 }\n 77 | - Sha3_256{ HusAsyncHasher.Sha3_256 }\n 78 | - Sha3_384{ HusAsyncHasher.Sha3_384 }\n 79 | - Sha3_512{ HusAsyncHasher.Sha3_512 }\n 80 | - Blake2b_160{ HusAsyncHasher.Blake2b_160 }\n 81 | - Blake2b_256{ HusAsyncHasher.Blake2b_256 }\n 82 | - Blake2b_384{ HusAsyncHasher.Blake2b_384 }\n 83 | - Blake2b_512{ HusAsyncHasher.Blake2b_512 }\n 84 | - Blake2s_128{ HusAsyncHasher.Blake2s_128 }\n 85 | - Blake2s_160{ HusAsyncHasher.Blake2s_160 }\n 86 | - Blake2s_224{ HusAsyncHasher.Blake2s_224 }\n 87 | - Blake2s_256{ HusAsyncHasher.Blake2s_256 }\n 88 | 通过 \`sourceText\` 属性设置需要进行哈希计算的目标源文本。\n 89 | `) 90 | code: ` 91 | import QtQuick 92 | import HuskarUI.Basic 93 | 94 | Column { 95 | HusCopyableText { 96 | text: '[Source] ' + hasher.sourceText 97 | } 98 | 99 | HusCopyableText { 100 | text: '[Result] ' + hasher.hashValue 101 | } 102 | 103 | HusAsyncHasher { 104 | id: hasher 105 | algorithm: HusAsyncHasher.Md5 106 | sourceText: 'HuskarUI' 107 | } 108 | } 109 | ` 110 | exampleDelegate: Column { 111 | HusCopyableText { 112 | text: '[Source] ' + hasher.sourceText 113 | } 114 | 115 | HusCopyableText { 116 | text: '[Result] ' + hasher.hashValue 117 | } 118 | 119 | HusAsyncHasher { 120 | id: hasher 121 | algorithm: HusAsyncHasher.Md5 122 | sourceText: 'HuskarUI' 123 | } 124 | } 125 | } 126 | } 127 | } 128 | -------------------------------------------------------------------------------- /gallery/qml/Home/AboutPage.qml: -------------------------------------------------------------------------------- 1 | import QtQuick 2 | import QtQuick.Layouts 3 | import QtQuick.Effects 4 | import QtQuick.Controls.Basic 5 | import HuskarUI.Basic 6 | 7 | HusWindow { 8 | id: root 9 | width: 400 10 | height: 500 11 | minimumWidth: 400 12 | minimumHeight: 500 13 | captionBar.minimizeButtonVisible: false 14 | captionBar.maximizeButtonVisible: false 15 | captionBar.winTitle: qsTr('关于') 16 | captionBar.winIconDelegate: Item { 17 | Image { 18 | width: 16 19 | height: 16 20 | anchors.centerIn: parent 21 | source: 'qrc:/Gallery/images/huskarui_icon.svg' 22 | } 23 | } 24 | captionBar.closeCallback: () => aboutLoader.visible = false; 25 | 26 | Item { 27 | anchors.fill: parent 28 | 29 | MultiEffect { 30 | anchors.fill: backRect 31 | source: backRect 32 | shadowColor: HusTheme.Primary.colorTextBase 33 | shadowEnabled: true 34 | } 35 | 36 | Rectangle { 37 | id: backRect 38 | anchors.fill: parent 39 | radius: 6 40 | color: HusTheme.Primary.colorBgBase 41 | border.color: HusThemeFunctions.alpha(HusTheme.Primary.colorTextBase, 0.2) 42 | } 43 | 44 | Item { 45 | anchors.fill: parent 46 | 47 | ShaderEffect { 48 | anchors.fill: parent 49 | vertexShader: 'qrc:/Gallery/shaders/effect2.vert.qsb' 50 | fragmentShader: 'qrc:/Gallery/shaders/effect2.frag.qsb' 51 | opacity: 0.5 52 | 53 | property vector3d iResolution: Qt.vector3d(width, height, 0) 54 | property real iTime: 0 55 | 56 | Timer { 57 | running: true 58 | repeat: true 59 | interval: 10 60 | onTriggered: parent.iTime += 0.03; 61 | } 62 | } 63 | } 64 | 65 | Column { 66 | width: parent.width 67 | anchors.top: parent.top 68 | anchors.topMargin: captionBar.height 69 | spacing: 10 70 | 71 | Item { 72 | width: 80 73 | height: width 74 | anchors.horizontalCenter: parent.horizontalCenter 75 | 76 | Image { 77 | width: parent.width 78 | height: width 79 | anchors.centerIn: parent 80 | source: 'qrc:/Gallery/images/huskarui_icon.svg' 81 | } 82 | } 83 | 84 | HusText { 85 | anchors.horizontalCenter: parent.horizontalCenter 86 | font { 87 | family: HusTheme.Primary.fontPrimaryFamily 88 | pixelSize: HusTheme.Primary.fontPrimarySizeHeading3 89 | bold: true 90 | } 91 | text: 'HuskarUI Gallery' 92 | } 93 | 94 | HusCopyableText { 95 | anchors.horizontalCenter: parent.horizontalCenter 96 | text: qsTr('库版本: ') + HusApp.libVersion() 97 | } 98 | 99 | HusCopyableText { 100 | anchors.horizontalCenter: parent.horizontalCenter 101 | text: qsTr('作者: MenPenS') 102 | } 103 | 104 | HusCopyableText { 105 | anchors.horizontalCenter: parent.horizontalCenter 106 | text: qsTr('微信号: MenPenS0612') 107 | } 108 | 109 | HusCopyableText { 110 | width: parent.width - 30 111 | anchors.horizontalCenter: parent.horizontalCenter 112 | wrapMode: HusCopyableText.WordWrap 113 | horizontalAlignment: HusCopyableText.AlignHCenter 114 | text: qsTr('QQ交流群号: 490328047') 115 | textFormat: HusCopyableText.RichText 116 | onLinkActivated: (link) => Qt.openUrlExternally(link); 117 | } 118 | 119 | HusCopyableText { 120 | width: parent.width - 30 121 | anchors.horizontalCenter: parent.horizontalCenter 122 | wrapMode: HusCopyableText.WordWrap 123 | horizontalAlignment: HusCopyableText.AlignHCenter 124 | text: 'Github: https://github.com/mengps/HuskarUI' 125 | textFormat: HusCopyableText.RichText 126 | onLinkActivated: (link) => Qt.openUrlExternally(link); 127 | } 128 | 129 | HusCopyableText { 130 | width: parent.width - 30 131 | anchors.horizontalCenter: parent.horizontalCenter 132 | wrapMode: HusCopyableText.WordWrap 133 | horizontalAlignment: HusCopyableText.AlignHCenter 134 | text: qsTr('如果该项目/源码对你有用,就请点击上方链接给一个免费的Star,谢谢!') 135 | } 136 | 137 | HusCopyableText { 138 | width: parent.width - 30 139 | anchors.horizontalCenter: parent.horizontalCenter 140 | wrapMode: HusCopyableText.WordWrap 141 | horizontalAlignment: HusCopyableText.AlignHCenter 142 | text: qsTr('有任何问题可以提Issues或进群!') 143 | } 144 | } 145 | } 146 | } 147 | -------------------------------------------------------------------------------- /gallery/shaders/effect1.frag: -------------------------------------------------------------------------------- 1 | #version 450 2 | 3 | layout(location = 0) in vec2 fragCoord; 4 | layout(location = 0) out vec4 fragColor; 5 | layout(std140, binding = 0) uniform buf { 6 | mat4 qt_Matrix; 7 | float qt_Opacity; 8 | vec3 iResolution; // viewport resolution (in pixels) 9 | float iTime; // shader playback time (in seconds) 10 | }; 11 | 12 | float gTime = 0.; 13 | const float REPEAT = 5.0; 14 | 15 | //来自 https://www.shadertoy.com/view/tlVGDt 16 | 17 | // 回転行列 18 | mat2 rot(float a) { 19 | float c = cos(a), s = sin(a); 20 | 21 | return mat2(c,s,-s,c); 22 | } 23 | 24 | float sdBox( vec3 p, vec3 b ) { 25 | vec3 q = abs(p) - b; 26 | 27 | return length(max(q,0.0)) + min(max(q.x,max(q.y,q.z)),0.0); 28 | } 29 | 30 | float box(vec3 pos, float scale) { 31 | pos *= scale; 32 | float base = sdBox(pos, vec3(.4,.4,.1)) /1.5; 33 | pos.xy *= 5.; 34 | pos.y -= 3.5; 35 | pos.xy *= rot(.75); 36 | float result = -base; 37 | 38 | return result; 39 | } 40 | 41 | float box_set(vec3 pos, float iTime) { 42 | vec3 pos_origin = pos; 43 | pos = pos_origin; 44 | pos .y += sin(gTime * 0.4) * 2.5; 45 | pos.xy *= rot(.8); 46 | float box1 = box(pos,2. - abs(sin(gTime * 0.4)) * 1.5); 47 | pos = pos_origin; 48 | pos .y -=sin(gTime * 0.4) * 2.5; 49 | pos.xy *= rot(.8); 50 | float box2 = box(pos,2. - abs(sin(gTime * 0.4)) * 1.5); 51 | pos = pos_origin; 52 | pos .x +=sin(gTime * 0.4) * 2.5; 53 | pos.xy *= rot(.8); 54 | float box3 = box(pos,2. - abs(sin(gTime * 0.4)) * 1.5); 55 | pos = pos_origin; 56 | pos .x -=sin(gTime * 0.4) * 2.5; 57 | pos.xy *= rot(.8); 58 | float box4 = box(pos,2. - abs(sin(gTime * 0.4)) * 1.5); 59 | pos = pos_origin; 60 | pos.xy *= rot(.8); 61 | float box5 = box(pos,.5) * 6.; 62 | pos = pos_origin; 63 | float box6 = box(pos,.5) * 6.; 64 | float result = max(max(max(max(max(box1,box2),box3),box4),box5),box6); 65 | 66 | return result; 67 | } 68 | 69 | float map(vec3 pos, float iTime) { 70 | vec3 pos_origin = pos; 71 | float box_set1 = box_set(pos, iTime); 72 | 73 | return box_set1; 74 | } 75 | 76 | void mainImage(out vec4 fragColor, in vec2 fragCoord) { 77 | vec2 p = (fragCoord.xy * 2. - iResolution.xy) / min(iResolution.x, iResolution.y); 78 | vec3 ro = vec3(0., -0.2 ,iTime * 4.); 79 | vec3 ray = normalize(vec3(p, 1.5)); 80 | ray.xy = ray.xy * rot(sin(iTime * .03) * 5.); 81 | ray.yz = ray.yz * rot(sin(iTime * .05) * .2); 82 | float t = 0.1; 83 | vec3 col = vec3(0.); 84 | float ac = 0.0; 85 | 86 | for (int i = 0; i < 99; i++){ 87 | vec3 pos = ro + ray * t; 88 | pos = mod(pos-2., 4.) -2.; 89 | gTime = iTime -float(i) * 0.01; 90 | 91 | float d = map(pos, iTime); 92 | 93 | d = max(abs(d), 0.01); 94 | ac += exp(-d*23.); 95 | 96 | t += d* 0.55; 97 | } 98 | 99 | col = vec3(ac * 0.02); 100 | 101 | col +=vec3(0.,0.2 * abs(sin(iTime)),0.5 + sin(iTime) * 0.2); 102 | 103 | fragColor = vec4(col, 1.0 - t * (0.02 + 0.02 * sin (iTime))) * qt_Opacity; 104 | } 105 | 106 | void main() { 107 | mainImage(fragColor, fragCoord); 108 | } 109 | -------------------------------------------------------------------------------- /gallery/shaders/effect1.vert: -------------------------------------------------------------------------------- 1 | #version 450 2 | 3 | layout(location = 0) in vec4 qt_Vertex; 4 | layout(location = 1) in vec2 qt_MultiTexCoord0; 5 | layout(location = 0) out vec2 fragCoord; 6 | layout(std140, binding = 0) uniform buf { 7 | mat4 qt_Matrix; 8 | float qt_Opacity; 9 | }; 10 | 11 | void main() 12 | { 13 | fragCoord = vec2(qt_Vertex); 14 | gl_Position = qt_Matrix * qt_Vertex; 15 | } 16 | -------------------------------------------------------------------------------- /gallery/shaders/effect2.frag: -------------------------------------------------------------------------------- 1 | #version 450 2 | 3 | layout(location = 0) in vec2 fragCoord; 4 | layout(location = 0) out vec4 fragColor; 5 | layout(std140, binding = 0) uniform buf { 6 | mat4 qt_Matrix; 7 | float qt_Opacity; 8 | vec3 iResolution; // viewport resolution (in pixels) 9 | float iTime; // shader playback time (in seconds) 10 | }; 11 | 12 | //来自 https://www.shadertoy.com/view/wdyczG 13 | 14 | #define S(a,b,t) smoothstep(a,b,t) 15 | 16 | mat2 Rot(float a) 17 | { 18 | float s = sin(a); 19 | float c = cos(a); 20 | return mat2(c, -s, s, c); 21 | } 22 | 23 | 24 | // Created by inigo quilez - iq/2014 25 | // License Creative Commons Attribution-NonCommercial-ShareAlike 3.0 Unported License. 26 | vec2 hash( vec2 p ) 27 | { 28 | p = vec2( dot(p,vec2(2127.1,81.17)), dot(p,vec2(1269.5,283.37)) ); 29 | return fract(sin(p)*43758.5453); 30 | } 31 | 32 | float noise( in vec2 p ) 33 | { 34 | vec2 i = floor( p ); 35 | vec2 f = fract( p ); 36 | 37 | vec2 u = f*f*(3.0-2.0*f); 38 | 39 | float n = mix( mix( dot( -1.0+2.0*hash( i + vec2(0.0,0.0) ), f - vec2(0.0,0.0) ), 40 | dot( -1.0+2.0*hash( i + vec2(1.0,0.0) ), f - vec2(1.0,0.0) ), u.x), 41 | mix( dot( -1.0+2.0*hash( i + vec2(0.0,1.0) ), f - vec2(0.0,1.0) ), 42 | dot( -1.0+2.0*hash( i + vec2(1.0,1.0) ), f - vec2(1.0,1.0) ), u.x), u.y); 43 | return 0.5 + 0.5*n; 44 | } 45 | 46 | 47 | void mainImage( out vec4 fragColor, in vec2 fragCoord ) 48 | { 49 | vec2 uv = fragCoord/iResolution.xy; 50 | float ratio = iResolution.x / iResolution.y; 51 | 52 | vec2 tuv = uv; 53 | tuv -= .5; 54 | 55 | // rotate with Noise 56 | float degree = noise(vec2(iTime*.1, tuv.x*tuv.y)); 57 | 58 | tuv.y *= 1./ratio; 59 | tuv *= Rot(radians((degree-.5)*720.+180.)); 60 | tuv.y *= ratio; 61 | 62 | 63 | // Wave warp with sin 64 | float frequency = 5.; 65 | float amplitude = 30.; 66 | float speed = iTime * 2.; 67 | tuv.x += sin(tuv.y*frequency+speed)/amplitude; 68 | tuv.y += sin(tuv.x*frequency*1.5+speed)/(amplitude*.5); 69 | 70 | 71 | // draw the image 72 | vec3 colorYellow = vec3(.957, .804, .623); 73 | vec3 colorDeepBlue = vec3(.192, .384, .933); 74 | vec3 layer1 = mix(colorYellow, colorDeepBlue, S(-.3, .2, (tuv*Rot(radians(-5.))).x)); 75 | 76 | vec3 colorRed = vec3(.910, .510, .8); 77 | vec3 colorBlue = vec3(0.350, .71, .953); 78 | vec3 layer2 = mix(colorRed, colorBlue, S(-.3, .2, (tuv*Rot(radians(-5.))).x)); 79 | 80 | vec3 finalComp = mix(layer1, layer2, S(.5, -.3, tuv.y)); 81 | 82 | vec3 col = finalComp; 83 | 84 | fragColor = vec4(col,1.0) * qt_Opacity; 85 | } 86 | 87 | void main() { 88 | mainImage(fragColor, fragCoord); 89 | } 90 | -------------------------------------------------------------------------------- /gallery/shaders/effect2.vert: -------------------------------------------------------------------------------- 1 | #version 450 2 | 3 | layout(location = 0) in vec4 qt_Vertex; 4 | layout(location = 1) in vec2 qt_MultiTexCoord0; 5 | layout(location = 0) out vec2 fragCoord; 6 | layout(std140, binding = 0) uniform buf { 7 | mat4 qt_Matrix; 8 | float qt_Opacity; 9 | }; 10 | 11 | void main() 12 | { 13 | fragCoord = vec2(qt_Vertex); 14 | gl_Position = qt_Matrix * qt_Vertex; 15 | } 16 | -------------------------------------------------------------------------------- /preview/dark.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mengps/HuskarUI/bf203f39db0e502499c53c66b763d163e453d0a8/preview/dark.png -------------------------------------------------------------------------------- /preview/doc.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mengps/HuskarUI/bf203f39db0e502499c53c66b763d163e453d0a8/preview/doc.png -------------------------------------------------------------------------------- /preview/light.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mengps/HuskarUI/bf203f39db0e502499c53c66b763d163e453d0a8/preview/light.png -------------------------------------------------------------------------------- /resources/huskarui_icon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mengps/HuskarUI/bf203f39db0e502499c53c66b763d163e453d0a8/resources/huskarui_icon.ico -------------------------------------------------------------------------------- /resources/huskarui_icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mengps/HuskarUI/bf203f39db0e502499c53c66b763d163e453d0a8/resources/huskarui_icon.png -------------------------------------------------------------------------------- /resources/huskarui_icon.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | -------------------------------------------------------------------------------- /src/cpp/controls/husiconfont.cpp: -------------------------------------------------------------------------------- 1 | #include "husiconfont.h" 2 | 3 | HusIcon::HusIcon(QObject *parent) 4 | : QObject{parent} 5 | { 6 | 7 | } 8 | 9 | HusIcon::~HusIcon() 10 | { 11 | 12 | } 13 | 14 | HusIcon *HusIcon::instance() 15 | { 16 | static HusIcon *ins = new HusIcon; 17 | 18 | return ins; 19 | } 20 | 21 | HusIcon *HusIcon::create(QQmlEngine *, QJSEngine *) 22 | { 23 | return instance(); 24 | } 25 | 26 | QVariantMap HusIcon::allIconNames() 27 | { 28 | QVariantMap iconMap; 29 | QMetaEnum me = QMetaEnum::fromType(); 30 | for (int i = 0; i < me.keyCount(); i++) { 31 | iconMap[QString::fromLatin1(me.key(i))] = me.value(i); 32 | } 33 | 34 | return iconMap; 35 | } 36 | -------------------------------------------------------------------------------- /src/cpp/controls/husrectangle.h: -------------------------------------------------------------------------------- 1 | #ifndef HUSRECTANGLE_H 2 | #define HUSRECTANGLE_H 3 | 4 | #include 5 | 6 | #include "husglobal.h" 7 | #include "husdefinitions.h" 8 | 9 | QT_FORWARD_DECLARE_CLASS(HusRectanglePrivate) 10 | 11 | class HUSKARUI_EXPORT HusRadius: public QObject 12 | { 13 | Q_OBJECT 14 | 15 | Q_PROPERTY(qreal all READ all WRITE setAll NOTIFY allChanged FINAL) 16 | Q_PROPERTY(qreal topLeft READ topLeft WRITE setTopLeft NOTIFY topLeftChanged FINAL) 17 | Q_PROPERTY(qreal topRight READ topRight WRITE setTopRight NOTIFY topRightChanged FINAL) 18 | Q_PROPERTY(qreal bottomLeft READ bottomLeft WRITE setBottomLeft NOTIFY bottomLeftChanged FINAL) 19 | Q_PROPERTY(qreal bottomRight READ bottomRight WRITE setBottomRight NOTIFY bottomRightChanged FINAL) 20 | 21 | QML_NAMED_ELEMENT(HusRadius) 22 | 23 | public: 24 | HusRadius(QObject *parent = nullptr) : QObject{parent} { } 25 | ~HusRadius() { } 26 | 27 | qreal all() const; 28 | void setAll(qreal all); 29 | 30 | qreal topLeft() const; 31 | void setTopLeft(qreal topLeft); 32 | 33 | qreal topRight() const; 34 | void setTopRight(qreal topRight); 35 | 36 | qreal bottomLeft() const; 37 | void setBottomLeft(qreal bottomLeft); 38 | 39 | qreal bottomRight() const; 40 | void setBottomRight(qreal bottomRight); 41 | 42 | signals: 43 | void allChanged(); 44 | void topLeftChanged(); 45 | void topRightChanged(); 46 | void bottomLeftChanged(); 47 | void bottomRightChanged(); 48 | 49 | private: 50 | qreal m_all = 0.; 51 | qreal m_topLeft = -1.; 52 | qreal m_topRight = -1.; 53 | qreal m_bottomLeft = -1.; 54 | qreal m_bottomRight = -1.; 55 | }; 56 | 57 | class HUSKARUI_EXPORT HusPen: public QObject 58 | { 59 | Q_OBJECT 60 | 61 | HUS_PROPERTY_INIT(qreal, width, setWidth, 1) 62 | HUS_PROPERTY_INIT(QColor, color, setColor, Qt::transparent) 63 | HUS_PROPERTY_INIT(int, style, setStyle, Qt::SolidLine) 64 | 65 | QML_NAMED_ELEMENT(HusPen) 66 | 67 | public: 68 | HusPen(QObject *parent = nullptr) : QObject{parent} { } 69 | 70 | bool isValid() const { 71 | return m_width > 0 && m_color.isValid() && m_color.alpha() > 0; 72 | } 73 | }; 74 | 75 | class HUSKARUI_EXPORT HusRectangle: public QQuickPaintedItem 76 | { 77 | Q_OBJECT 78 | 79 | Q_PROPERTY(QColor color READ color WRITE setColor NOTIFY colorChanged FINAL) 80 | Q_PROPERTY(QJSValue gradient READ gradient WRITE setGradient RESET resetGradient) 81 | Q_PROPERTY(HusPen* border READ border CONSTANT) 82 | 83 | Q_PROPERTY(qreal radius READ radius WRITE setRadius NOTIFY radiusChanged FINAL) 84 | Q_PROPERTY(qreal topLeftRadius READ topLeftRadius WRITE setTopLeftRadius NOTIFY topLeftRadiusChanged FINAL) 85 | Q_PROPERTY(qreal topRightRadius READ topRightRadius WRITE setTopRightRadius NOTIFY topRightRadiusChanged FINAL) 86 | Q_PROPERTY(qreal bottomLeftRadius READ bottomLeftRadius WRITE setBottomLeftRadius NOTIFY bottomLeftRadiusChanged FINAL) 87 | Q_PROPERTY(qreal bottomRightRadius READ bottomRightRadius WRITE setBottomRightRadius NOTIFY bottomRightRadiusChanged FINAL) 88 | 89 | QML_NAMED_ELEMENT(HusRectangle) 90 | 91 | public: 92 | explicit HusRectangle(QQuickItem *parent = nullptr); 93 | ~HusRectangle(); 94 | 95 | QColor color() const; 96 | void setColor(QColor color); 97 | 98 | HusPen *border(); 99 | 100 | QJSValue gradient() const; 101 | void setGradient(const QJSValue &gradient); 102 | void resetGradient(); 103 | 104 | qreal radius() const; 105 | void setRadius(qreal radius); 106 | 107 | qreal topLeftRadius() const; 108 | void setTopLeftRadius(qreal radius); 109 | 110 | qreal topRightRadius() const; 111 | void setTopRightRadius(qreal radius); 112 | 113 | qreal bottomLeftRadius() const; 114 | void setBottomLeftRadius(qreal radius); 115 | 116 | qreal bottomRightRadius() const; 117 | void setBottomRightRadius(qreal radius); 118 | 119 | signals: 120 | void colorChanged(); 121 | void radiusChanged(); 122 | void topLeftRadiusChanged(); 123 | void topRightRadiusChanged(); 124 | void bottomLeftRadiusChanged(); 125 | void bottomRightRadiusChanged(); 126 | 127 | protected: 128 | void paint(QPainter *painter) override; 129 | 130 | private Q_SLOTS: 131 | void doUpdate(); 132 | 133 | private: 134 | Q_DECLARE_PRIVATE(HusRectangle); 135 | QSharedPointer d_ptr; 136 | }; 137 | 138 | #if QT_VERSION >= QT_VERSION_CHECK(6, 7, 0) 139 | # include 140 | 141 | /*! 内部矩形, 作为高版本基础控件时在内部使用, 但无法使用 border.style */ 142 | class HusRectangleInternal: public QQuickRectangle 143 | { 144 | Q_OBJECT 145 | 146 | QML_NAMED_ELEMENT(HusRectangleInternal) 147 | 148 | public: 149 | explicit HusRectangleInternal(QQuickItem *parent = nullptr) : QQuickRectangle{parent} { } 150 | ~HusRectangleInternal() { } 151 | }; 152 | 153 | #else 154 | 155 | class HusRectangleInternal: public HusRectangle 156 | { 157 | Q_OBJECT 158 | 159 | QML_NAMED_ELEMENT(HusRectangleInternal) 160 | 161 | public: 162 | explicit HusRectangleInternal(QQuickItem *parent = nullptr) : HusRectangle{parent} { } 163 | ~HusRectangleInternal() { } 164 | }; 165 | 166 | #endif 167 | 168 | #endif // HUSRECTANGLE_H 169 | -------------------------------------------------------------------------------- /src/cpp/controls/huswatermark.h: -------------------------------------------------------------------------------- 1 | #ifndef HUSWATERMARK_H 2 | #define HUSWATERMARK_H 3 | 4 | #include 5 | 6 | #include "husglobal.h" 7 | 8 | QT_FORWARD_DECLARE_CLASS(HusWatermarkPrivate); 9 | 10 | class HUSKARUI_EXPORT HusWatermark : public QQuickPaintedItem 11 | { 12 | Q_OBJECT 13 | 14 | Q_PROPERTY(QString text READ text WRITE setText NOTIFY textChanged FINAL) 15 | Q_PROPERTY(QUrl image READ image WRITE setImage NOTIFY imageChanged FINAL) 16 | Q_PROPERTY(QSize markSize READ markSize WRITE setMarkSize NOTIFY markSizeChanged FINAL) 17 | Q_PROPERTY(QPointF gap READ gap WRITE setGap NOTIFY gapChanged FINAL) 18 | Q_PROPERTY(QPointF offset READ offset WRITE setOffset NOTIFY offsetChanged FINAL) 19 | Q_PROPERTY(qreal rotate READ rotate WRITE setRotate NOTIFY rotateChanged FINAL) 20 | Q_PROPERTY(QFont font READ font WRITE setFont NOTIFY fontChanged FINAL) 21 | Q_PROPERTY(QColor colorText READ colorText WRITE setColorText NOTIFY colorTextChanged FINAL) 22 | 23 | QML_NAMED_ELEMENT(HusWatermark) 24 | 25 | public: 26 | HusWatermark(QQuickItem *parent = nullptr); 27 | ~HusWatermark(); 28 | 29 | QString text() const; 30 | void setText(const QString &text); 31 | 32 | QUrl image() const; 33 | void setImage(const QUrl &image); 34 | 35 | QSize markSize() const; 36 | void setMarkSize(const QSize &markSize); 37 | 38 | QPointF gap() const; 39 | void setGap(const QPointF &gap); 40 | 41 | QPointF offset() const; 42 | void setOffset(const QPointF &offset); 43 | 44 | qreal rotate() const; 45 | void setRotate(qreal rotate); 46 | 47 | QFont font() const; 48 | void setFont(const QFont &font); 49 | 50 | QColor colorText() const; 51 | void setColorText(const QColor &colorText); 52 | 53 | protected: 54 | void paint(QPainter *painter) override; 55 | 56 | signals: 57 | void textChanged(); 58 | void imageChanged(); 59 | void markSizeChanged(); 60 | void gapChanged(); 61 | void offsetChanged(); 62 | void rotateChanged(); 63 | void fontChanged(); 64 | void colorTextChanged(); 65 | 66 | private: 67 | Q_DECLARE_PRIVATE(HusWatermark); 68 | QScopedPointer d_ptr; 69 | }; 70 | 71 | #endif // HUSWATERMARK_H 72 | -------------------------------------------------------------------------------- /src/cpp/controls/huswindowagent.cpp: -------------------------------------------------------------------------------- 1 | #include "huswindowagent.h" 2 | 3 | HusWindowAgent::HusWindowAgent(QObject *parent) 4 | #ifdef BUILD_HUSKARUI_ON_DESKTOP_PLATFORM 5 | : QWK::QuickWindowAgent{parent} 6 | #else 7 | : QObject{parent} 8 | #endif 9 | { 10 | 11 | } 12 | 13 | HusWindowAgent::~HusWindowAgent() 14 | { 15 | 16 | } 17 | 18 | void HusWindowAgent::classBegin() 19 | { 20 | auto p = parent(); 21 | Q_ASSERT_X(p, "HusWindowAgent", "parent() return nullptr!"); 22 | if (p) { 23 | #ifdef BUILD_HUSKARUI_ON_DESKTOP_PLATFORM 24 | # if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0) 25 | if (p->objectName() == QLatin1StringView("__HusWindow__")) { 26 | setup(qobject_cast(p)); 27 | } 28 | # else 29 | if (p->objectName() == QLatin1String("__HusWindow__")) { 30 | setup(qobject_cast(p)); 31 | } 32 | # endif 33 | #endif 34 | } 35 | } 36 | 37 | void HusWindowAgent::componentComplete() 38 | { 39 | 40 | } 41 | -------------------------------------------------------------------------------- /src/cpp/controls/huswindowagent.h: -------------------------------------------------------------------------------- 1 | #ifndef HUSWINDOWAGENT_H 2 | #define HUSWINDOWAGENT_H 3 | 4 | #include 5 | #include 6 | 7 | #include "husglobal.h" 8 | 9 | #ifdef BUILD_HUSKARUI_ON_DESKTOP_PLATFORM 10 | #include 11 | #endif 12 | 13 | #ifdef BUILD_HUSKARUI_ON_DESKTOP_PLATFORM 14 | class HUSKARUI_EXPORT HusWindowAgent : public QWK::QuickWindowAgent, public QQmlParserStatus 15 | #else 16 | class HUSKARUI_EXPORT HusWindowAgent : public QObject, public QQmlParserStatus 17 | #endif 18 | { 19 | Q_OBJECT 20 | Q_INTERFACES(QQmlParserStatus) 21 | QML_NAMED_ELEMENT(HusWindowAgent) 22 | 23 | public: 24 | explicit HusWindowAgent(QObject *parent = nullptr); 25 | ~HusWindowAgent(); 26 | 27 | void classBegin() override; 28 | void componentComplete() override; 29 | }; 30 | 31 | #endif // HUSWINDOWAGENT_H 32 | -------------------------------------------------------------------------------- /src/cpp/husapp.cpp: -------------------------------------------------------------------------------- 1 | #include "husapp.h" 2 | 3 | #ifdef BUILD_HUSKARUI_ON_DESKTOP_PLATFORM 4 | #include 5 | #endif 6 | 7 | #include 8 | 9 | /* 10 | #if QT_VERSION >= QT_VERSION_CHECK(6, 5, 0) && defined(Q_OS_WIN) 11 | # include 12 | # include 13 | #endif 14 | */ 15 | 16 | HusApp::~HusApp() 17 | { 18 | 19 | } 20 | 21 | void HusApp::initialize(QQmlEngine *engine) 22 | { 23 | #ifdef BUILD_HUSKARUI_ON_DESKTOP_PLATFORM 24 | QWK::registerTypes(engine); 25 | #endif 26 | 27 | QFontDatabase::addApplicationFont(":/HuskarUI/resources/font/HuskarUI-Icons.ttf"); 28 | } 29 | 30 | QString HusApp::libVersion() 31 | { 32 | return HUSKARUI_LIBRARY_VERSION; 33 | } 34 | 35 | HusApp *HusApp::instance() 36 | { 37 | static HusApp *ins = new HusApp; 38 | return ins; 39 | } 40 | 41 | HusApp *HusApp::create(QQmlEngine *, QJSEngine *) 42 | { 43 | /*! 移除Qt窗口的暗黑模式, 但会造成`QGuiApplication::styleHints()->colorScheme()`失效, 暂时不使用 */ 44 | /* 45 | #if QT_VERSION >= QT_VERSION_CHECK(6, 5, 0) && defined(Q_OS_WIN) 46 | using QWindowsApplication = QNativeInterface::Private::QWindowsApplication; 47 | auto nativeWindowsApp = dynamic_cast(QGuiApplicationPrivate::platformIntegration()); 48 | if (nativeWindowsApp) 49 | nativeWindowsApp->setDarkModeHandling(QWindowsApplication::DarkModeStyle); 50 | #endif 51 | */ 52 | 53 | return instance(); 54 | } 55 | 56 | HusApp::HusApp(QObject *parent) 57 | : QObject{parent} 58 | { 59 | 60 | } 61 | -------------------------------------------------------------------------------- /src/cpp/husapp.h: -------------------------------------------------------------------------------- 1 | #ifndef HUSAPP_H 2 | #define HUSAPP_H 3 | 4 | #include 5 | 6 | #include "husglobal.h" 7 | 8 | class HUSKARUI_EXPORT HusApp : public QObject 9 | { 10 | Q_OBJECT 11 | QML_SINGLETON 12 | QML_NAMED_ELEMENT(HusApp) 13 | 14 | public: 15 | ~HusApp(); 16 | 17 | static void initialize(QQmlEngine *engine); 18 | 19 | Q_INVOKABLE static QString libVersion(); 20 | 21 | static HusApp *instance(); 22 | static HusApp *create(QQmlEngine *, QJSEngine *); 23 | 24 | private: 25 | explicit HusApp(QObject *parent = nullptr); 26 | }; 27 | 28 | #endif // HUSAPP_H 29 | -------------------------------------------------------------------------------- /src/cpp/husdefinitions.h: -------------------------------------------------------------------------------- 1 | #ifndef HUSDEFINITIONS_H 2 | #define HUSDEFINITIONS_H 3 | 4 | /*! 声明一般属性 */ 5 | #define HUS_PROPERTY(type, get, set) \ 6 | private:\ 7 | Q_PROPERTY(type get READ get WRITE set NOTIFY get##Changed) \ 8 | public: \ 9 | type get() const { return m_##get; } \ 10 | void set(const type &t) { if (t != m_##get) { m_##get = t; emit get##Changed(); } } \ 11 | Q_SIGNAL void get##Changed(); \ 12 | private: \ 13 | type m_##get; 14 | 15 | 16 | /*! 声明指针属性 */ 17 | #define HUS_PROPERTY_P(type, get, set) \ 18 | private:\ 19 | Q_PROPERTY(type get READ get WRITE set NOTIFY get##Changed) \ 20 | public: \ 21 | type get() const { return m_##get; } \ 22 | void set(type t) { if (t != m_##get) { m_##get = t; emit get##Changed(); } } \ 23 | Q_SIGNAL void get##Changed(); \ 24 | private: \ 25 | type m_##get; 26 | 27 | 28 | /*! 声明一般属性并初始化 */ 29 | #define HUS_PROPERTY_INIT(type, get, set, init_value) \ 30 | private:\ 31 | Q_PROPERTY(type get READ get WRITE set NOTIFY get##Changed) \ 32 | public: \ 33 | type get() const { return m_##get; } \ 34 | void set(const type &t) { if (t != m_##get) { m_##get = t; emit get##Changed(); } } \ 35 | Q_SIGNAL void get##Changed(); \ 36 | private: \ 37 | type m_##get{init_value}; 38 | 39 | 40 | /*! 声明指针属性并初始化 */ 41 | #define HUS_PROPERTY_P_INIT(type, get, set, init_value) \ 42 | private:\ 43 | Q_PROPERTY(type get READ get WRITE set NOTIFY get##Changed) \ 44 | public: \ 45 | type get() const { return m_##get; } \ 46 | void set(const type &t) { if (t != m_##get) { m_##get = t; emit get##Changed(); } } \ 47 | Q_SIGNAL void get##Changed(); \ 48 | private: \ 49 | type m_##get{init_value}; 50 | 51 | 52 | /*! 声明只读属性 */ 53 | #define HUS_PROPERTY_READONLY(type, get) \ 54 | private:\ 55 | Q_PROPERTY(type get READ get NOTIFY get##Changed) \ 56 | public: \ 57 | type get() const { return m_##get; } \ 58 | Q_SIGNAL void get##Changed(); \ 59 | private: \ 60 | type m_##get; 61 | 62 | #endif // HUSDEFINITIONS_H 63 | -------------------------------------------------------------------------------- /src/cpp/husglobal.h: -------------------------------------------------------------------------------- 1 | #ifndef HUSGLOBAL_H 2 | #define HUSGLOBAL_H 3 | 4 | #if !defined(BUILD_HUSKARUI_STATIC_LIBRARY) 5 | # if defined(BUILD_HUSKARUI_LIB) 6 | # define HUSKARUI_EXPORT Q_DECL_EXPORT 7 | # else 8 | # define HUSKARUI_EXPORT Q_DECL_IMPORT 9 | # endif 10 | #else 11 | # define HUSKARUI_EXPORT 12 | #endif 13 | 14 | #endif // HUSGLOBAL_H 15 | -------------------------------------------------------------------------------- /src/cpp/huskaruiplugin.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | extern void qml_register_types_HuskarUI(); 4 | Q_GHS_KEEP_REFERENCE(qml_register_types_HuskarUI); 5 | 6 | class HuskarUIPlugin : public QQmlEngineExtensionPlugin 7 | { 8 | Q_OBJECT 9 | Q_PLUGIN_METADATA(IID QQmlExtensionInterface_iid) 10 | public: 11 | HuskarUIPlugin(QObject *parent = nullptr) : QQmlEngineExtensionPlugin(parent) 12 | { 13 | volatile auto registration = &qml_register_types_HuskarUI; 14 | Q_UNUSED(registration); 15 | } 16 | }; 17 | 18 | #include "huskaruiplugin.moc" 19 | -------------------------------------------------------------------------------- /src/cpp/theme/huscolorgenerator.h: -------------------------------------------------------------------------------- 1 | #ifndef HUSCOLORGENERATOR_H 2 | #define HUSCOLORGENERATOR_H 3 | 4 | #include 5 | #include 6 | #include 7 | 8 | #include "husglobal.h" 9 | 10 | class HUSKARUI_EXPORT HusColorGenerator : public QObject 11 | { 12 | Q_OBJECT 13 | QML_NAMED_ELEMENT(HusColorGenerator) 14 | 15 | public: 16 | enum class Preset 17 | { 18 | Preset_Red = 1, 19 | Preset_Volcano, 20 | Preset_Orange, 21 | Preset_Gold, 22 | Preset_Yellow, 23 | Preset_Lime, 24 | Preset_Green, 25 | Preset_Cyan, 26 | Preset_Blue, 27 | Preset_Geekblue, 28 | Preset_Purple, 29 | Preset_Magenta, 30 | Preset_Grey 31 | }; 32 | Q_ENUM(Preset); 33 | 34 | HusColorGenerator(QObject *parent = nullptr); 35 | ~HusColorGenerator(); 36 | 37 | Q_INVOKABLE static QColor reverseColor(const QColor &color); 38 | Q_INVOKABLE static QColor presetToColor(const QString& color); 39 | Q_INVOKABLE static QColor presetToColor(HusColorGenerator::Preset color); 40 | Q_INVOKABLE static QList generate(HusColorGenerator::Preset color, bool light = true, const QColor &background = QColor(QColor::Invalid)); 41 | Q_INVOKABLE static QList generate(const QColor &color, bool light = true, const QColor &background = QColor(QColor::Invalid)); 42 | }; 43 | 44 | 45 | #endif // HUSCOLORGENERATOR_H 46 | -------------------------------------------------------------------------------- /src/cpp/theme/husradiusgenerator.cpp: -------------------------------------------------------------------------------- 1 | #include "husradiusgenerator.h" 2 | 3 | HusRadiusGenerator::HusRadiusGenerator(QObject *parent) 4 | : QObject{parent} 5 | { 6 | 7 | } 8 | 9 | HusRadiusGenerator::~HusRadiusGenerator() 10 | { 11 | 12 | } 13 | 14 | QList HusRadiusGenerator::generateRadius(int radiusBase) 15 | { 16 | auto radiusLG = radiusBase; 17 | auto radiusSM = radiusBase; 18 | auto radiusXS = radiusBase; 19 | auto radiusOuter = radiusBase; 20 | 21 | // radiusLG 22 | if (radiusBase < 6 && radiusBase >= 5) { 23 | radiusLG = radiusBase + 1; 24 | } else if (radiusBase < 16 && radiusBase >= 6) { 25 | radiusLG = radiusBase + 2; 26 | } else if (radiusBase >= 16) { 27 | radiusLG = 16; 28 | } 29 | 30 | // radiusSM 31 | if (radiusBase < 7 && radiusBase >= 5) { 32 | radiusSM = 4; 33 | } else if (radiusBase < 8 && radiusBase >= 7) { 34 | radiusSM = 5; 35 | } else if (radiusBase < 14 && radiusBase >= 8) { 36 | radiusSM = 6; 37 | } else if (radiusBase < 16 && radiusBase >= 14) { 38 | radiusSM = 7; 39 | } else if (radiusBase >= 16) { 40 | radiusSM = 8; 41 | } 42 | 43 | // radiusXS 44 | if (radiusBase < 6 && radiusBase >= 2) { 45 | radiusXS = 1; 46 | } else if (radiusBase >= 6) { 47 | radiusXS = 2; 48 | } 49 | 50 | // radiusOuter 51 | if (radiusBase > 4 && radiusBase < 8) { 52 | radiusOuter = 4; 53 | } else if (radiusBase >= 8) { 54 | radiusOuter = 6; 55 | } 56 | 57 | return { 58 | radiusBase, 59 | radiusLG, 60 | radiusSM, 61 | radiusXS, 62 | radiusOuter 63 | }; 64 | } 65 | -------------------------------------------------------------------------------- /src/cpp/theme/husradiusgenerator.h: -------------------------------------------------------------------------------- 1 | #ifndef HUSRADIUSGENERATOR_H 2 | #define HUSRADIUSGENERATOR_H 3 | 4 | #include 5 | #include 6 | 7 | #include "husglobal.h" 8 | 9 | class HUSKARUI_EXPORT HusRadiusGenerator : public QObject 10 | { 11 | Q_OBJECT 12 | QML_NAMED_ELEMENT(HusRadiusGenerator) 13 | 14 | public: 15 | HusRadiusGenerator(QObject *parent = nullptr); 16 | ~HusRadiusGenerator(); 17 | 18 | Q_INVOKABLE static QList generateRadius(int radiusBase); 19 | }; 20 | 21 | #endif // HUSRADIUSGENERATOR_H 22 | -------------------------------------------------------------------------------- /src/cpp/theme/hussizegenerator.cpp: -------------------------------------------------------------------------------- 1 | #include "hussizegenerator.h" 2 | 3 | #include 4 | 5 | HusSizeGenerator::HusSizeGenerator(QObject *parent) 6 | : QObject{parent} 7 | { 8 | 9 | } 10 | 11 | HusSizeGenerator::~HusSizeGenerator() 12 | { 13 | 14 | } 15 | 16 | QList HusSizeGenerator::generateFontSize(qreal fontSizeBase) 17 | { 18 | #if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0) 19 | QList fontSizes(10); 20 | for (int index = 0; index < 10; index++) { 21 | const auto i = index - 1; 22 | const auto baseSize = fontSizeBase * std::pow(M_E, i / 5.0); 23 | const auto intSize = (i + 1) > 1 ? std::floor(baseSize) : std::ceil(baseSize); 24 | // Convert to even 25 | fontSizes[index] = std::floor(intSize / 2) * 2; 26 | } 27 | fontSizes[1] = fontSizeBase; 28 | 29 | return fontSizes; 30 | #else 31 | QVector fontSizes(10); 32 | 33 | for (int index = 0; index < 10; index++) { 34 | const auto i = index - 1; 35 | const auto baseSize = fontSizeBase * std::pow(M_E, i / 5.0); 36 | const auto intSize = (i + 1) > 1 ? std::floor(baseSize) : std::ceil(baseSize); 37 | // Convert to even 38 | fontSizes[index] = std::floor(intSize / 2) * 2; 39 | } 40 | fontSizes[1] = fontSizeBase; 41 | 42 | return fontSizes.toList(); 43 | #endif 44 | } 45 | 46 | QList HusSizeGenerator::generateFontLineHeight(qreal fontSizeBase) 47 | { 48 | QList fontLineHeights = generateFontSize(fontSizeBase); 49 | for (int index = 0; index < 10; index++) { 50 | auto fontSize = fontLineHeights[index]; 51 | fontLineHeights[index] = (fontSize + 8) / fontSize; 52 | } 53 | 54 | return fontLineHeights; 55 | } 56 | -------------------------------------------------------------------------------- /src/cpp/theme/hussizegenerator.h: -------------------------------------------------------------------------------- 1 | #ifndef HUSSIZEGENERATOR_H 2 | #define HUSSIZEGENERATOR_H 3 | 4 | #include 5 | #include 6 | 7 | #include "husglobal.h" 8 | 9 | class HUSKARUI_EXPORT HusSizeGenerator : public QObject 10 | { 11 | Q_OBJECT 12 | QML_NAMED_ELEMENT(HusSizeGenerator) 13 | 14 | public: 15 | HusSizeGenerator(QObject *parent = nullptr); 16 | ~HusSizeGenerator(); 17 | 18 | Q_INVOKABLE static QList generateFontSize(qreal fontSizeBase); 19 | Q_INVOKABLE static QList generateFontLineHeight(qreal fontSizeBase); 20 | }; 21 | 22 | #endif // HUSSIZEGENERATOR_H 23 | -------------------------------------------------------------------------------- /src/cpp/theme/hussystemthemehelper.h: -------------------------------------------------------------------------------- 1 | #ifndef HUSSYSTEMTHEMEHELPER_H 2 | #define HUSSYSTEMTHEMEHELPER_H 3 | 4 | #include 5 | #include 6 | #include 7 | 8 | #include "husglobal.h" 9 | 10 | QT_FORWARD_DECLARE_CLASS(QWindow); 11 | QT_FORWARD_DECLARE_CLASS(QWidget); 12 | 13 | QT_FORWARD_DECLARE_CLASS(HusSystemThemeHelperPrivate); 14 | 15 | #ifndef BUILD_HUSKARUI_ON_DESKTOP_PLATFORM 16 | Q_DECLARE_OPAQUE_POINTER(QWindow*); 17 | Q_DECLARE_OPAQUE_POINTER(QWidget*); 18 | #endif 19 | 20 | class HUSKARUI_EXPORT HusSystemThemeHelper : public QObject 21 | { 22 | Q_OBJECT 23 | 24 | Q_PROPERTY(QColor themeColor READ themeColor NOTIFY themeColorChanged) 25 | Q_PROPERTY(HusSystemThemeHelper::ColorScheme colorScheme READ colorScheme NOTIFY colorSchemeChanged) 26 | 27 | QML_NAMED_ELEMENT(HusSystemThemeHelper) 28 | 29 | public: 30 | enum class ColorScheme { 31 | None = 0, 32 | Dark = 1, 33 | Light = 2 34 | }; 35 | Q_ENUM(ColorScheme); 36 | 37 | HusSystemThemeHelper(QObject *parent = nullptr); 38 | ~HusSystemThemeHelper(); 39 | 40 | /** 41 | * @brief getThemeColor 立即获取当前主题颜色{不可用于绑定} 42 | * @warning 此接口更快,但不会自动更新 43 | * @return QColor 44 | */ 45 | Q_INVOKABLE QColor getThemeColor() const; 46 | /** 47 | * @brief getColorScheme 立即获取当前颜色方案{不可用于绑定} 48 | * @warning 此接口更快,但不会自动更新 49 | * @return {@link HusSystemThemeHelper::ColorScheme} 50 | */ 51 | Q_INVOKABLE HusSystemThemeHelper::ColorScheme getColorScheme() const; 52 | /** 53 | * @brief colorScheme 获取当前主题颜色{可用于绑定} 54 | * @return QColor 55 | */ 56 | QColor themeColor(); 57 | /** 58 | * @brief colorScheme 获取当前颜色方案{可用于绑定} 59 | * @return {@link HusSystemThemeHelper::ColorScheme} 60 | */ 61 | HusSystemThemeHelper::ColorScheme colorScheme(); 62 | 63 | Q_INVOKABLE static bool setWindowTitleBarMode(QWindow *window, bool isDark); 64 | 65 | #ifdef QT_WIDGETS_LIB 66 | Q_INVOKABLE static bool setWindowTitleBarMode(QWidget *window, bool isDark); 67 | #endif 68 | 69 | signals: 70 | void themeColorChanged(const QColor &color); 71 | void colorSchemeChanged(HusSystemThemeHelper::ColorScheme scheme); 72 | 73 | protected: 74 | virtual void timerEvent(QTimerEvent *); 75 | 76 | private: 77 | Q_DECLARE_PRIVATE(HusSystemThemeHelper); 78 | QScopedPointer d_ptr; 79 | }; 80 | 81 | 82 | #endif // HUSSYSTEMTHEMEHELPER_H 83 | -------------------------------------------------------------------------------- /src/cpp/theme/husthemefunctions.cpp: -------------------------------------------------------------------------------- 1 | #include "husthemefunctions.h" 2 | #include "huscolorgenerator.h" 3 | #include "hussizegenerator.h" 4 | #include "husradiusgenerator.h" 5 | 6 | #include 7 | 8 | HusThemeFunctions::HusThemeFunctions(QObject *parent) 9 | : QObject{parent} 10 | { 11 | 12 | } 13 | 14 | HusThemeFunctions *HusThemeFunctions::instance() 15 | { 16 | static HusThemeFunctions *ins = new HusThemeFunctions; 17 | return ins; 18 | } 19 | 20 | HusThemeFunctions *HusThemeFunctions::create(QQmlEngine *, QJSEngine *) 21 | { 22 | return instance(); 23 | } 24 | 25 | QList HusThemeFunctions::genColor(int preset, bool light, const QColor &background) 26 | { 27 | return HusColorGenerator::generate(HusColorGenerator::Preset(preset), light, background); 28 | } 29 | 30 | QList HusThemeFunctions::genColor(const QColor &color, bool light, const QColor &background) 31 | { 32 | return HusColorGenerator::generate(color, light, background); 33 | } 34 | 35 | QList HusThemeFunctions::genColorString(const QColor &color, bool light, const QColor &background) 36 | { 37 | QList result; 38 | const auto listColor = HusColorGenerator::generate(color, light, background); 39 | for (const auto &color: listColor) 40 | result.append(color.name()); 41 | 42 | return result; 43 | } 44 | 45 | QList HusThemeFunctions::genFontSize(qreal fontSizeBase) 46 | { 47 | return HusSizeGenerator::generateFontSize(fontSizeBase); 48 | } 49 | 50 | QList HusThemeFunctions::genFontLineHeight(qreal fontSizeBase) 51 | { 52 | return HusSizeGenerator::generateFontLineHeight(fontSizeBase); 53 | } 54 | 55 | QList HusThemeFunctions::genRadius(int radiusBase) 56 | { 57 | return HusRadiusGenerator::generateRadius(radiusBase); 58 | } 59 | 60 | QString HusThemeFunctions::genFontFamily(const QString &familyBase) 61 | { 62 | const auto families = familyBase.split(','); 63 | #if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0) 64 | const auto database = QFontDatabase::families(); 65 | #else 66 | const auto database = QFontDatabase().families(); 67 | #endif 68 | for(auto family: families) { 69 | auto normalize = family.remove('\'').remove('\"').trimmed(); 70 | if (database.contains(normalize)) { 71 | return normalize.trimmed(); 72 | } 73 | } 74 | return database.first(); 75 | } 76 | 77 | QColor HusThemeFunctions::darker(const QColor &color, int factor) 78 | { 79 | return color.darker(factor); 80 | } 81 | 82 | QColor HusThemeFunctions::lighter(const QColor &color, int factor) 83 | { 84 | return color.lighter(factor); 85 | } 86 | 87 | QColor HusThemeFunctions::alpha(const QColor &color, qreal alpha) 88 | { 89 | return QColor(color.red(), color.green(), color.blue(), alpha * 255); 90 | } 91 | 92 | QColor HusThemeFunctions::onBackground(const QColor &color, const QColor &background) 93 | { 94 | const auto fg = color.toRgb(); 95 | const auto bg = background.toRgb(); 96 | const auto alpha = fg.alphaF() + bg.alphaF() * (1 - fg.alphaF()); 97 | 98 | return QColor::fromRgbF( 99 | fg.redF() * fg.alphaF() + bg.redF() * bg.alphaF() * (1 - fg.alphaF()) / alpha, 100 | fg.greenF() * fg.alphaF() + bg.greenF() * bg.alphaF() * (1 - fg.alphaF()) / alpha, 101 | fg.blueF() * fg.alphaF() + bg.blueF() * bg.alphaF() * (1 - fg.alphaF()) / alpha, 102 | alpha 103 | ); 104 | } 105 | 106 | qreal HusThemeFunctions::multiply(qreal num1, qreal num2) 107 | { 108 | return num1 * num2; 109 | } 110 | -------------------------------------------------------------------------------- /src/cpp/theme/husthemefunctions.h: -------------------------------------------------------------------------------- 1 | #ifndef HUSTHEMEFUNCTIONS_H 2 | #define HUSTHEMEFUNCTIONS_H 3 | 4 | #include 5 | #include 6 | #include 7 | 8 | #include "husglobal.h" 9 | 10 | class HUSKARUI_EXPORT HusThemeFunctions : public QObject 11 | { 12 | Q_OBJECT 13 | QML_SINGLETON 14 | QML_NAMED_ELEMENT(HusThemeFunctions) 15 | 16 | public: 17 | HusThemeFunctions(QObject *parent = nullptr); 18 | 19 | static HusThemeFunctions *instance(); 20 | static HusThemeFunctions *create(QQmlEngine *, QJSEngine *); 21 | 22 | Q_INVOKABLE static QList genColor(int preset, bool light = true, const QColor &background = QColor(QColor::Invalid)); 23 | Q_INVOKABLE static QList genColor(const QColor &color, bool light = true, const QColor &background = QColor(QColor::Invalid)); 24 | Q_INVOKABLE static QList genColorString(const QColor &color, bool light = true, const QColor &background = QColor(QColor::Invalid)); 25 | Q_INVOKABLE static QList genFontSize(qreal fontSizeBase); 26 | Q_INVOKABLE static QList genFontLineHeight(qreal fontSizeBase); 27 | Q_INVOKABLE static QList genRadius(int radiusBase); 28 | Q_INVOKABLE static QString genFontFamily(const QString &fontFamilyBase); 29 | Q_INVOKABLE static QColor darker(const QColor &color, int factor = 140); 30 | Q_INVOKABLE static QColor lighter(const QColor &color, int factor = 140); 31 | Q_INVOKABLE static QColor alpha(const QColor &color, qreal alpha = 0.5); 32 | Q_INVOKABLE static QColor onBackground(const QColor &color, const QColor &background); 33 | Q_INVOKABLE static qreal multiply(qreal num1, qreal num2); 34 | }; 35 | 36 | #endif // HUSTHEMEFUNCTIONS_H 37 | -------------------------------------------------------------------------------- /src/cpp/utils/husapi.cpp: -------------------------------------------------------------------------------- 1 | #include "husapi.h" 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | #if QT_VERSION < QT_VERSION_CHECK(6, 0, 0) 10 | # include 11 | #endif 12 | 13 | #include 14 | 15 | #ifdef Q_OS_WIN 16 | # include 17 | #endif 18 | 19 | Q_LOGGING_CATEGORY(lcHusApi, "huskarui.basic.api"); 20 | 21 | HusApi::~HusApi() 22 | { 23 | 24 | } 25 | 26 | HusApi *HusApi::instance() 27 | { 28 | static HusApi *ins = new HusApi; 29 | return ins; 30 | } 31 | 32 | HusApi *HusApi::create(QQmlEngine *, QJSEngine *) 33 | { 34 | return instance(); 35 | } 36 | 37 | void HusApi::setWindowStaysOnTopHint(QWindow *window, bool hint) 38 | { 39 | if (window) { 40 | #ifdef Q_OS_WIN 41 | HWND hwnd = reinterpret_cast(window->winId()); 42 | if (hint) { 43 | ::SetWindowPos(hwnd, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE); 44 | } else { 45 | ::SetWindowPos(hwnd, HWND_NOTOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE); 46 | } 47 | #else 48 | window->setFlag(Qt::WindowStaysOnTopHint, hint); 49 | #endif 50 | } 51 | } 52 | 53 | void HusApi::setWindowState(QWindow *window, int state) 54 | { 55 | if (window) { 56 | #ifdef Q_OS_WIN 57 | HWND hwnd = reinterpret_cast(window->winId()); 58 | switch (state) { 59 | case Qt::WindowMinimized: 60 | ::ShowWindow(hwnd, SW_MINIMIZE); 61 | break; 62 | case Qt::WindowMaximized: 63 | ::ShowWindow(hwnd, SW_MAXIMIZE); 64 | break; 65 | default: 66 | window->setWindowState(Qt::WindowState(state)); 67 | break; 68 | } 69 | #else 70 | window->setWindowState(Qt::WindowState(state)); 71 | #endif 72 | } 73 | } 74 | 75 | void HusApi::setPopupAllowAutoFlip(QObject *popup, bool allowVerticalFlip, bool allowHorizontalFlip) 76 | { 77 | if (auto p = qobject_cast(popup)) { 78 | QQuickPopupPrivate::get(p)->allowVerticalFlip = allowVerticalFlip; 79 | QQuickPopupPrivate::get(p)->allowHorizontalFlip = allowHorizontalFlip; 80 | } else { 81 | qmlWarning(popup) << "Conversion to Popup failed!"; 82 | } 83 | } 84 | 85 | QString HusApi::getClipbordText() const 86 | { 87 | if (auto clipboard = QGuiApplication::clipboard()) { 88 | return clipboard->text(); 89 | } 90 | 91 | return QString(); 92 | } 93 | 94 | bool HusApi::setClipbordText(const QString &text) 95 | { 96 | if (auto clipboard = QGuiApplication::clipboard()) { 97 | clipboard->setText(text); 98 | return true; 99 | } 100 | 101 | return false; 102 | } 103 | 104 | QString HusApi::readFileToString(const QString &fileName) 105 | { 106 | QString result; 107 | QFile file(fileName); 108 | if (file.open(QIODevice::ReadOnly)) { 109 | result = file.readAll(); 110 | } else { 111 | qCDebug(lcHusApi) << "Open file error:" << file.errorString(); 112 | } 113 | 114 | return result; 115 | } 116 | 117 | int HusApi::getWeekNumber(const QDateTime &dateTime) const 118 | { 119 | return dateTime.date().weekNumber(); 120 | } 121 | 122 | QDateTime HusApi::dateFromString(const QString &dateTime, const QString &format) const 123 | { 124 | return QDateTime::fromString(dateTime, format); 125 | } 126 | 127 | void HusApi::openLocalUrl(const QString &local) 128 | { 129 | QDesktopServices::openUrl(QUrl::fromLocalFile(local)); 130 | } 131 | 132 | HusApi::HusApi(QObject *parent) 133 | : QObject{parent} 134 | { 135 | 136 | } 137 | -------------------------------------------------------------------------------- /src/cpp/utils/husapi.h: -------------------------------------------------------------------------------- 1 | #ifndef HUSAPI_H 2 | #define HUSAPI_H 3 | 4 | #include 5 | #include 6 | #include 7 | 8 | #include "husglobal.h" 9 | 10 | class HUSKARUI_EXPORT HusApi : public QObject 11 | { 12 | Q_OBJECT 13 | QML_SINGLETON 14 | QML_NAMED_ELEMENT(HusApi) 15 | 16 | public: 17 | ~HusApi(); 18 | 19 | static HusApi *instance(); 20 | static HusApi *create(QQmlEngine *, QJSEngine *); 21 | 22 | Q_INVOKABLE void setWindowStaysOnTopHint(QWindow *window, bool hint); 23 | Q_INVOKABLE void setWindowState(QWindow *window, int state); 24 | 25 | Q_INVOKABLE void setPopupAllowAutoFlip(QObject *popup, bool allowVerticalFlip = true, bool allowHorizontalFlip = true); 26 | 27 | Q_INVOKABLE QString getClipbordText() const; 28 | Q_INVOKABLE bool setClipbordText(const QString &text); 29 | 30 | Q_INVOKABLE QString readFileToString(const QString &fileName); 31 | 32 | Q_INVOKABLE int getWeekNumber(const QDateTime &dateTime) const; 33 | Q_INVOKABLE QDateTime dateFromString(const QString &dateTime, const QString &format) const; 34 | 35 | Q_INVOKABLE void openLocalUrl(const QString &local); 36 | 37 | private: 38 | explicit HusApi(QObject *parent = nullptr); 39 | }; 40 | 41 | #endif // HUSAPI_H 42 | -------------------------------------------------------------------------------- /src/cpp/utils/husasynchasher.h: -------------------------------------------------------------------------------- 1 | #ifndef HUSASYNCHASHER_H 2 | #define HUSASYNCHASHER_H 3 | 4 | #include 5 | #include 6 | #include 7 | 8 | #include "husglobal.h" 9 | 10 | QT_FORWARD_DECLARE_CLASS(QNetworkAccessManager); 11 | 12 | QT_FORWARD_DECLARE_CLASS(HusAsyncHasherPrivate); 13 | 14 | class HUSKARUI_EXPORT HusAsyncHasher : public QObject 15 | { 16 | Q_OBJECT 17 | 18 | Q_PROPERTY(QCryptographicHash::Algorithm algorithm READ algorithm WRITE setAlgorithm NOTIFY algorithmChanged) 19 | Q_PROPERTY(bool asynchronous READ asynchronous WRITE setAsynchronous NOTIFY asynchronousChanged) 20 | Q_PROPERTY(QString hashValue READ hashValue NOTIFY hashValueChanged) 21 | Q_PROPERTY(int hashLength READ hashLength NOTIFY hashLengthChanged) 22 | Q_PROPERTY(QUrl source READ source WRITE setSource NOTIFY sourceChanged) 23 | Q_PROPERTY(QString sourceText READ sourceText WRITE setSourceText NOTIFY sourceTextChanged) 24 | Q_PROPERTY(QByteArray sourceData READ sourceData WRITE setSourceData NOTIFY sourceDataChanged) 25 | Q_PROPERTY(QObject* sourceObject READ sourceObject WRITE setSourceObject NOTIFY sourceObjectChanged) 26 | 27 | QML_NAMED_ELEMENT(HusAsyncHasher) 28 | 29 | public: 30 | Q_ENUMS(QCryptographicHash::Algorithm); 31 | 32 | explicit HusAsyncHasher(QObject *parent = nullptr); 33 | ~HusAsyncHasher(); 34 | 35 | QCryptographicHash::Algorithm algorithm(); 36 | void setAlgorithm(QCryptographicHash::Algorithm algorithm); 37 | 38 | bool asynchronous() const; 39 | void setAsynchronous(bool async); 40 | 41 | QString hashValue() const; 42 | 43 | int hashLength() const; 44 | 45 | QUrl source() const; 46 | void setSource(const QUrl &source); 47 | 48 | QString sourceText() const; 49 | void setSourceText(const QString &sourceText); 50 | 51 | QByteArray sourceData() const; 52 | void setSourceData(const QByteArray &sourceData); 53 | 54 | QObject *sourceObject() const; 55 | void setSourceObject(QObject *sourceObject); 56 | 57 | bool operator==(const HusAsyncHasher &hasher); 58 | bool operator!=(const HusAsyncHasher &hasher); 59 | 60 | QFuture static hash(const QByteArray &data, QCryptographicHash::Algorithm algorithm); 61 | 62 | signals: 63 | void algorithmChanged(); 64 | void asynchronousChanged(); 65 | void hashValueChanged(); 66 | void hashLengthChanged(); 67 | void sourceChanged(); 68 | void sourceTextChanged(); 69 | void sourceDataChanged(); 70 | void sourceObjectChanged(); 71 | void hashProgress(qint64 processed, qint64 total); 72 | void started(); 73 | void finished(); 74 | 75 | private slots: 76 | void setHashValue(const QString &value); 77 | 78 | private: 79 | Q_DECLARE_PRIVATE(HusAsyncHasher); 80 | QScopedPointer d_ptr; 81 | }; 82 | 83 | #endif // HUSASYNCHASHER_H 84 | -------------------------------------------------------------------------------- /src/imports/HusCaptionButton.qml: -------------------------------------------------------------------------------- 1 | import QtQuick 2 | import HuskarUI.Basic 3 | 4 | HusIconButton { 5 | id: control 6 | 7 | property bool isError: false 8 | property bool noDisabledState: false 9 | 10 | objectName: '__HusCaptionButton__' 11 | leftPadding: 12 * sizeRatio 12 | rightPadding: 12 * sizeRatio 13 | radiusBg.all: 0 14 | hoverCursorShape: Qt.ArrowCursor 15 | type: HusButton.Type_Text 16 | iconSize: HusTheme.HusCaptionButton.fontSize 17 | effectEnabled: false 18 | colorIcon: { 19 | if (enabled || noDisabledState) { 20 | return checked ? HusTheme.HusCaptionButton.colorIconChecked : 21 | HusTheme.HusCaptionButton.colorIcon; 22 | } else { 23 | return HusTheme.HusCaptionButton.colorIconDisabled; 24 | } 25 | } 26 | colorBg: { 27 | if (enabled || noDisabledState) { 28 | if (isError) { 29 | return control.down ? HusTheme.HusCaptionButton.colorErrorBgActive: 30 | control.hovered ? HusTheme.HusCaptionButton.colorErrorBgHover : 31 | HusTheme.HusCaptionButton.colorErrorBg; 32 | } else { 33 | return control.down ? HusTheme.HusCaptionButton.colorBgActive: 34 | control.hovered ? HusTheme.HusCaptionButton.colorBgHover : 35 | HusTheme.HusCaptionButton.colorBg; 36 | } 37 | } else { 38 | return HusTheme.HusCaptionButton.colorBgDisabled; 39 | } 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /src/imports/HusCopyableText.qml: -------------------------------------------------------------------------------- 1 | import QtQuick 2 | import HuskarUI.Basic 3 | 4 | TextEdit { 5 | id: control 6 | 7 | objectName: '__HusCopyableText__' 8 | readOnly: true 9 | renderType: HusTheme.textRenderType 10 | color: HusTheme.HusCopyableText.colorText 11 | selectByMouse: true 12 | selectByKeyboard: true 13 | selectedTextColor: HusTheme.HusCopyableText.colorTextSelected 14 | selectionColor: HusTheme.HusCopyableText.colorSelection 15 | font { 16 | family: HusTheme.HusCopyableText.fontFamily 17 | pixelSize: HusTheme.HusCopyableText.fontSize 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /src/imports/HusDivider.qml: -------------------------------------------------------------------------------- 1 | import QtQuick 2 | import QtQuick.Shapes 3 | import HuskarUI.Basic 4 | 5 | Item { 6 | id: control 7 | 8 | enum Align 9 | { 10 | Align_Left = 0, 11 | Align_Center = 1, 12 | Align_Right = 2 13 | } 14 | 15 | enum Style 16 | { 17 | SolidLine = 0, 18 | DashLine = 1 19 | } 20 | 21 | property bool animationEnabled: HusTheme.animationEnabled 22 | property string title: '' 23 | property font titleFont: Qt.font({ 24 | family: HusTheme.HusDivider.fontFamily, 25 | pixelSize: HusTheme.HusDivider.fontSize 26 | }) 27 | property int titleAlign: HusDivider.Align_Left 28 | property int titlePadding: 20 29 | property color colorText: HusTheme.HusDivider.colorText 30 | property color colorSplit: HusTheme.HusDivider.colorSplit 31 | property int style: HusDivider.SolidLine 32 | property int orientation: Qt.Horizontal 33 | property Component titleDelegate: HusText { 34 | text: control.title 35 | font: control.titleFont 36 | color: control.colorText 37 | } 38 | property Component splitDelegate: Shape { 39 | id: __shape 40 | 41 | property real lineX: __titleLoader.x + __titleLoader.implicitWidth * 0.5 42 | property real lineY: __titleLoader.y + __titleLoader.implicitHeight * 0.5 43 | 44 | ShapePath { 45 | strokeStyle: control.style === HusDivider.SolidLine ? ShapePath.SolidLine : ShapePath.DashLine 46 | strokeColor: control.colorSplit 47 | strokeWidth: 1 48 | fillColor: 'transparent' 49 | startX: control.orientation === Qt.Horizontal ? 0 : __shape.lineX 50 | startY: control.orientation === Qt.Horizontal ? __shape.lineY : 0 51 | PathLine { 52 | x: { 53 | if (control.orientation === Qt.Horizontal) { 54 | return control.title === '' ? 0 : __titleLoader.x - 10; 55 | } else { 56 | return __shape.lineX; 57 | } 58 | } 59 | y: control.orientation === Qt.Horizontal ? __shape.lineY : __titleLoader.y - 10 60 | } 61 | } 62 | 63 | ShapePath { 64 | strokeStyle: control.style === HusDivider.SolidLine ? ShapePath.SolidLine : ShapePath.DashLine 65 | strokeColor: control.colorSplit 66 | strokeWidth: 1 67 | fillColor: 'transparent' 68 | startX: { 69 | if (control.orientation === Qt.Horizontal) { 70 | return control.title === '' ? 0 : (__titleLoader.x + __titleLoader.implicitWidth + 10); 71 | } else { 72 | return __shape.lineX; 73 | } 74 | } 75 | startY: { 76 | if (control.orientation === Qt.Horizontal) { 77 | return __shape.lineY; 78 | } else { 79 | return control.title === '' ? 0 : (__titleLoader.y + __titleLoader.implicitHeight + 10); 80 | } 81 | } 82 | 83 | PathLine { 84 | x: control.orientation === Qt.Horizontal ? control.width : __shape.lineX 85 | y: control.orientation === Qt.Horizontal ? __shape.lineY : control.height 86 | } 87 | } 88 | } 89 | property string contentDescription: title 90 | 91 | objectName: '__HusDivider__' 92 | 93 | Behavior on colorSplit { enabled: control.animationEnabled; ColorAnimation { duration: HusTheme.Primary.durationFast } } 94 | Behavior on colorText { enabled: control.animationEnabled; ColorAnimation { duration: HusTheme.Primary.durationFast } } 95 | 96 | Loader { 97 | id: __splitLoader 98 | sourceComponent: splitDelegate 99 | } 100 | 101 | Loader { 102 | id: __titleLoader 103 | z: 1 104 | anchors.top: (control.orientation !== Qt.Horizontal && control.titleAlign === HusDivider.Align_Left) ? parent.top : undefined 105 | anchors.topMargin: (control.orientation !== Qt.Horizontal && control.titleAlign === HusDivider.Align_Left) ? control.titlePadding : 0 106 | anchors.bottom: (control.orientation !== Qt.Horizontal && control.titleAlign === HusDivider.Align_Right) ? parent.right : undefined 107 | anchors.bottomMargin: (control.orientation !== Qt.Horizontal && control.titleAlign === HusDivider.Align_Right) ? control.titlePadding : 0 108 | anchors.left: (control.orientation === Qt.Horizontal && control.titleAlign === HusDivider.Align_Left) ? parent.left : undefined 109 | anchors.leftMargin: (control.orientation === Qt.Horizontal && control.titleAlign === HusDivider.Align_Left) ? control.titlePadding : 0 110 | anchors.right: (control.orientation === Qt.Horizontal && control.titleAlign === HusDivider.Align_Right) ? parent.right : undefined 111 | anchors.rightMargin: (control.orientation === Qt.Horizontal && control.titleAlign === HusDivider.Align_Right) ? control.titlePadding : 0 112 | anchors.horizontalCenter: (control.orientation !== Qt.Horizontal || control.titleAlign === HusDivider.Align_Center) ? parent.horizontalCenter : undefined 113 | anchors.verticalCenter: (control.orientation === Qt.Horizontal || control.titleAlign === HusDivider.Align_Center) ? parent.verticalCenter : undefined 114 | sourceComponent: titleDelegate 115 | } 116 | 117 | Accessible.role: Accessible.Separator 118 | Accessible.name: control.title 119 | Accessible.description: control.contentDescription 120 | } 121 | -------------------------------------------------------------------------------- /src/imports/HusDrawer.qml: -------------------------------------------------------------------------------- 1 | import QtQuick 2 | import QtQuick.Layouts 3 | import QtQuick.Templates as T 4 | import HuskarUI.Basic 5 | 6 | T.Drawer { 7 | id: control 8 | 9 | enum ClosePosition { 10 | Position_Start = 0, 11 | Position_End = 1 12 | } 13 | 14 | property bool animationEnabled: HusTheme.animationEnabled 15 | property bool maskClosable: true 16 | property int closePosition: HusDrawer.Position_Start 17 | property int drawerSize: 378 18 | property string title: '' 19 | property font titleFont: Qt.font({ 20 | family: HusTheme.HusDrawer.fontFamily, 21 | pixelSize: HusTheme.HusDrawer.fontSizeTitle 22 | }) 23 | property color colorTitle: HusTheme.HusDrawer.colorTitle 24 | property color colorBg: HusTheme.HusDrawer.colorBg 25 | property color colorOverlay: HusTheme.HusDrawer.colorOverlay 26 | 27 | property Component closeDelegate: Component { 28 | HusCaptionButton { 29 | topPadding: 2 30 | bottomPadding: 2 31 | leftPadding: 4 32 | rightPadding: 4 33 | anchors.verticalCenter: parent.verticalCenter 34 | animationEnabled: control.animationEnabled 35 | radiusBg.all: HusTheme.HusDrawer.radiusButtonBg 36 | iconSource: HusIcon.CloseOutlined 37 | hoverCursorShape: Qt.PointingHandCursor 38 | onClicked: { 39 | control.close(); 40 | } 41 | } 42 | } 43 | 44 | property Component titleDelegate: Item { 45 | height: 56 46 | 47 | RowLayout { 48 | anchors.fill: parent 49 | anchors.leftMargin: 15 50 | anchors.rightMargin: 15 51 | spacing: 5 52 | 53 | Loader { 54 | id: __closeStartLoader 55 | sourceComponent: closeDelegate 56 | Layout.alignment: Qt.AlignVCenter 57 | active: control.closePosition === HusDrawer.Position_Start 58 | visible: control.closePosition === HusDrawer.Position_Start 59 | } 60 | 61 | HusText { 62 | Layout.alignment: Qt.AlignVCenter 63 | Layout.fillWidth: true 64 | horizontalAlignment: Text.AlignLeft 65 | text: control.title 66 | font: control.titleFont 67 | color: control.colorTitle 68 | } 69 | 70 | Loader { 71 | id: __closeEndLoader 72 | sourceComponent: closeDelegate 73 | Layout.alignment: Qt.AlignVCenter 74 | active: control.closePosition === HusDrawer.Position_End 75 | visible: control.closePosition === HusDrawer.Position_End 76 | } 77 | } 78 | 79 | HusDivider { 80 | width: parent.width 81 | height: 1 82 | anchors.bottom: parent.bottom 83 | animationEnabled: control.animationEnabled 84 | } 85 | } 86 | 87 | property Component contentDelegate: Item { } 88 | 89 | objectName: '__HusDrawer__' 90 | width: edge == Qt.LeftEdge || edge == Qt.RightEdge ? drawerSize : parent.width 91 | height: edge == Qt.LeftEdge || edge == Qt.RightEdge ? parent.height : drawerSize 92 | edge: Qt.RightEdge 93 | parent: T.Overlay.overlay 94 | modal: true 95 | closePolicy: maskClosable ? T.Popup.CloseOnEscape | T.Popup.CloseOnPressOutside : T.Popup.NoAutoClose 96 | enter: Transition { NumberAnimation { duration: control.animationEnabled ? HusTheme.Primary.durationMid : 0 } } 97 | exit: Transition { NumberAnimation { duration: control.animationEnabled ? HusTheme.Primary.durationMid : 0 } } 98 | background: Item { 99 | HusShadow { 100 | anchors.fill: __rect 101 | source: __rect 102 | shadowColor: HusTheme.HusDrawer.colorShadow 103 | } 104 | 105 | Rectangle { 106 | id: __rect 107 | anchors.fill: parent 108 | color: control.colorBg 109 | } 110 | } 111 | contentItem: ColumnLayout { 112 | spacing: 0 113 | Loader { 114 | Layout.fillWidth: true 115 | sourceComponent: control.titleDelegate 116 | onLoaded: { 117 | /*! 无边框窗口的标题栏会阻止事件传递, 需要调这个 */ 118 | if (captionBar) 119 | captionBar.addInteractionItem(item); 120 | } 121 | } 122 | Loader { 123 | Layout.fillWidth: true 124 | Layout.fillHeight: true 125 | sourceComponent: control.contentDelegate 126 | } 127 | } 128 | onAboutToShow: { 129 | if (captionBar && modal) 130 | captionBar.enabled = false; 131 | } 132 | onAboutToHide: { 133 | if (captionBar && modal) 134 | captionBar.enabled = true; 135 | } 136 | 137 | T.Overlay.modal: Rectangle { 138 | color: control.colorOverlay 139 | } 140 | } 141 | -------------------------------------------------------------------------------- /src/imports/HusEmpty.qml: -------------------------------------------------------------------------------- 1 | import QtQuick 2 | import QtQuick.Layouts 3 | import HuskarUI.Basic 4 | 5 | Item { 6 | id: control 7 | 8 | enum ImageStyle 9 | { 10 | Style_None = 0, 11 | Style_Default = 1, 12 | Style_Simple = 2 13 | } 14 | 15 | property int imageStyle: HusEmpty.Image_Default 16 | property string imageSource: { 17 | switch (imageStyle) { 18 | case HusEmpty.Style_None: return ''; 19 | case HusEmpty.Style_Default: return 'qrc:/HuskarUI/resources/images/empty-default.svg'; 20 | case HusEmpty.Style_Simple: return 'qrc:/HuskarUI/resources/images/empty-simple.svg'; 21 | } 22 | } 23 | property int imageWidth: { 24 | switch (imageStyle) { 25 | case HusEmpty.Style_None: return width / 3; 26 | case HusEmpty.Style_Default: return 92; 27 | case HusEmpty.Style_Simple: return 64; 28 | } 29 | } 30 | property int imageHeight: { 31 | switch (imageStyle) { 32 | case HusEmpty.Style_None: return height / 3; 33 | case HusEmpty.Style_Default: return 76; 34 | case HusEmpty.Style_Simple: return 41; 35 | } 36 | } 37 | property bool showDescription: true 38 | property string description: '' 39 | property int descriptionSpacing: 12 40 | property font descriptionFont: Qt.font({ 41 | family: HusTheme.HusEmpty.fontFamily, 42 | pixelSize: HusTheme.HusEmpty.fontSize - 1 43 | }) 44 | property color colorDescription: HusTheme.HusEmpty.colorDescription 45 | 46 | property Component imageDelegate: Image { 47 | width: control.imageWidth 48 | height: control.imageHeight 49 | source: control.imageSource 50 | sourceSize: Qt.size(width, height) 51 | } 52 | property Component descriptionDelegate: HusText { 53 | text: control.description 54 | font: control.descriptionFont 55 | color: control.colorDescription 56 | horizontalAlignment: Text.AlignHCenter 57 | } 58 | 59 | objectName: '__HusEmpty__' 60 | width: 200 61 | height: 200 62 | 63 | ColumnLayout { 64 | anchors.centerIn: parent 65 | spacing: control.descriptionSpacing 66 | 67 | Loader { 68 | Layout.alignment: Qt.AlignHCenter 69 | Layout.fillWidth: true 70 | visible: active 71 | active: control.imageSource !== '' || control.imageType !== HusEmpty.Image_None 72 | sourceComponent: control.imageDelegate 73 | } 74 | 75 | Loader { 76 | Layout.alignment: Qt.AlignHCenter 77 | Layout.fillWidth: true 78 | visible: active 79 | active: control.showDescription 80 | sourceComponent: control.descriptionDelegate 81 | } 82 | } 83 | } 84 | -------------------------------------------------------------------------------- /src/imports/HusIconButton.qml: -------------------------------------------------------------------------------- 1 | import QtQuick 2 | import HuskarUI.Basic 3 | 4 | HusButton { 5 | id: control 6 | 7 | enum IconPosition { 8 | Position_Start = 0, 9 | Position_End = 1 10 | } 11 | 12 | property bool loading: false 13 | property var iconSource: 0 ?? '' 14 | property int iconSize: HusTheme.HusButton.fontSize 15 | property int iconSpacing: 5 * sizeRatio 16 | property int iconPosition: HusIconButton.Position_Start 17 | property color colorIcon: colorText 18 | 19 | objectName: '__HusIconButton__' 20 | contentItem: Item { 21 | implicitWidth: __row.implicitWidth 22 | implicitHeight: Math.max(__icon.implicitHeight, __text.implicitHeight) 23 | 24 | Behavior on implicitWidth { enabled: control.animationEnabled; NumberAnimation { duration: HusTheme.Primary.durationMid } } 25 | 26 | Row { 27 | id: __row 28 | anchors.horizontalCenter: parent.horizontalCenter 29 | anchors.verticalCenter: parent.verticalCenter 30 | spacing: control.iconSpacing 31 | layoutDirection: control.iconPosition === HusIconButton.Position_Start ? Qt.LeftToRight : Qt.RightToLeft 32 | 33 | HusIconText { 34 | id: __icon 35 | anchors.verticalCenter: parent.verticalCenter 36 | color: control.colorIcon 37 | iconSize: control.iconSize 38 | iconSource: control.loading ? HusIcon.LoadingOutlined : control.iconSource 39 | verticalAlignment: Text.AlignVCenter 40 | 41 | Behavior on color { enabled: control.animationEnabled; ColorAnimation { duration: HusTheme.Primary.durationFast } } 42 | 43 | NumberAnimation on rotation { 44 | running: control.loading 45 | from: 0 46 | to: 360 47 | loops: Animation.Infinite 48 | duration: 1000 49 | } 50 | } 51 | 52 | HusText { 53 | id: __text 54 | anchors.verticalCenter: parent.verticalCenter 55 | text: control.text 56 | font: control.font 57 | lineHeight: HusTheme.HusButton.fontLineHeight 58 | color: control.colorText 59 | elide: Text.ElideRight 60 | 61 | Behavior on color { enabled: control.animationEnabled; ColorAnimation { duration: HusTheme.Primary.durationFast } } 62 | } 63 | } 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /src/imports/HusIconText.qml: -------------------------------------------------------------------------------- 1 | import QtQuick 2 | import HuskarUI.Basic 3 | 4 | HusText { 5 | id: control 6 | 7 | readonly property bool empty: iconSource === 0 || iconSource === '' 8 | property var iconSource: 0 ?? '' 9 | property alias iconSize: control.font.pixelSize 10 | property alias colorIcon: control.color 11 | property string contentDescription: text 12 | 13 | objectName: '__HusIconText__' 14 | width: __iconLoader.active ? (__iconLoader.implicitWidth + leftPadding + rightPadding): implicitWidth 15 | height: __iconLoader.active ? (__iconLoader.implicitHeight + topPadding + bottomPadding) : implicitHeight 16 | text: __iconLoader.active ? '' : String.fromCharCode(iconSource) 17 | font.family: 'HuskarUI-Icons' 18 | font.pixelSize: HusTheme.HusIconText.fontSize 19 | color: HusTheme.HusIconText.colorText 20 | 21 | Loader { 22 | id: __iconLoader 23 | anchors.centerIn: parent 24 | active: typeof iconSource == 'string' && iconSource !== '' 25 | sourceComponent: Image { 26 | source: control.iconSource 27 | width: control.iconSize 28 | height: control.iconSize 29 | sourceSize: Qt.size(width, height) 30 | } 31 | } 32 | 33 | Accessible.role: Accessible.StaticText 34 | Accessible.name: control.text 35 | Accessible.description: control.contentDescription 36 | } 37 | -------------------------------------------------------------------------------- /src/imports/HusImage.qml: -------------------------------------------------------------------------------- 1 | import QtQuick 2 | import HuskarUI.Basic 3 | 4 | Image { 5 | id: control 6 | 7 | property bool animationEnabled: HusTheme.animationEnabled 8 | property bool previewEnabled: true 9 | readonly property alias hovered: __hoverHandler.hovered 10 | property int hoverCursorShape: Qt.PointingHandCursor 11 | property string fallback: '' 12 | property string placeholder: '' 13 | property var items: [] 14 | 15 | objectName: '__HusImage__' 16 | onSourceChanged: { 17 | if (items.length == 0) { 18 | __private.previewItems = [{ url: source }]; 19 | } 20 | } 21 | onItemsChanged: { 22 | if (items.length > 0) { 23 | __private.previewItems = [...items]; 24 | } 25 | } 26 | 27 | QtObject { 28 | id: __private 29 | property var previewItems: [] 30 | } 31 | 32 | Loader { 33 | anchors.centerIn: parent 34 | active: control.status === Image.Error && control.fallback !== '' 35 | sourceComponent: Image { 36 | source: control.fallback 37 | Component.onCompleted: { 38 | __private.previewItems = [{ url: control.fallback }] 39 | } 40 | } 41 | } 42 | 43 | Loader { 44 | anchors.centerIn: parent 45 | active: control.status === Image.Loading && control.placeholder !== '' 46 | sourceComponent: Image { 47 | source: control.placeholder 48 | } 49 | } 50 | 51 | Loader { 52 | anchors.fill: parent 53 | active: control.previewEnabled 54 | sourceComponent: Rectangle { 55 | color: HusTheme.Primary.colorTextTertiary 56 | opacity: control.hovered ? 1.0 : 0.0 57 | 58 | Behavior on color { enabled: control.animationEnabled; ColorAnimation { duration: HusTheme.Primary.durationMid } } 59 | Behavior on opacity { enabled: control.animationEnabled; NumberAnimation { duration: HusTheme.Primary.durationMid } } 60 | 61 | Row { 62 | anchors.centerIn: parent 63 | spacing: 5 64 | 65 | HusIconText { 66 | anchors.verticalCenter: parent.verticalCenter 67 | colorIcon: HusTheme.HusImage.colorText 68 | iconSource: HusIcon.EyeOutlined 69 | iconSize: HusTheme.HusImage.fontSize + 2 70 | } 71 | 72 | HusText { 73 | anchors.verticalCenter: parent.verticalCenter 74 | text: qsTr('预览') 75 | color: HusTheme.HusImage.colorText 76 | } 77 | } 78 | 79 | HusImagePreview { 80 | id: __preview 81 | animationEnabled: control.animationEnabled 82 | items: __private.previewItems 83 | } 84 | 85 | TapHandler { 86 | onTapped: { 87 | if (!__preview.opened) { 88 | __preview.open(); 89 | } 90 | } 91 | } 92 | } 93 | } 94 | 95 | HoverHandler { 96 | id: __hoverHandler 97 | cursorShape: control.hoverCursorShape 98 | } 99 | } 100 | -------------------------------------------------------------------------------- /src/imports/HusMoveMouseArea.qml: -------------------------------------------------------------------------------- 1 | import QtQuick 2 | 3 | MouseArea { 4 | id: root 5 | 6 | property var target: undefined 7 | property real minimumX: -Number.MAX_VALUE 8 | property real maximumX: Number.MAX_VALUE 9 | property real minimumY: -Number.MAX_VALUE 10 | property real maximumY: Number.MAX_VALUE 11 | 12 | objectName: '__HusMoveMouseArea__' 13 | onClicked: (mouse) => mouse.accepted = false; 14 | onPressed: 15 | (mouse) => { 16 | __private.startPos = Qt.point(mouse.x, mouse.y); 17 | cursorShape = Qt.SizeAllCursor; 18 | } 19 | onReleased: 20 | (mouse) => { 21 | __private.startPos = Qt.point(mouse.x, mouse.y); 22 | cursorShape = Qt.ArrowCursor; 23 | } 24 | onPositionChanged: 25 | (mouse) => { 26 | if (pressed) { 27 | __private.offsetPos = Qt.point(mouse.x - __private.startPos.x, mouse.y - __private.startPos.y); 28 | if (target) { 29 | // x 30 | if (minimumX != Number.NaN && minimumX > (target.x + __private.offsetPos.x)) { 31 | target.x = minimumX; 32 | } else if (maximumX != Number.NaN && maximumX < (target.x + __private.offsetPos.x)) { 33 | target.x = maximumX; 34 | } else { 35 | target.x = target.x + __private.offsetPos.x; 36 | } 37 | // y 38 | if (minimumY != Number.NaN && minimumY > (target.y + __private.offsetPos.y)) { 39 | target.y = minimumY; 40 | } else if (maximumY != Number.NaN && maximumY < (target.y + __private.offsetPos.y)) { 41 | target.y = maximumY; 42 | } else { 43 | target.y = target.y + __private.offsetPos.y; 44 | } 45 | } 46 | } 47 | } 48 | 49 | QtObject { 50 | id: __private 51 | property point startPos: Qt.point(0, 0) 52 | property point offsetPos: Qt.point(0, 0) 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /src/imports/HusPopconfirm.qml: -------------------------------------------------------------------------------- 1 | import QtQuick 2 | import QtQuick.Layouts 3 | import QtQuick.Templates as T 4 | import HuskarUI.Basic 5 | 6 | HusPopover { 7 | id: control 8 | 9 | signal confirm() 10 | signal cancel() 11 | 12 | property string confirmText: '' 13 | property string cancelText: '' 14 | property Component confirmButtonDelegate: HusButton { 15 | animationEnabled: control.animationEnabled 16 | padding: 10 17 | topPadding: 4 18 | bottomPadding: 4 19 | text: control.confirmText 20 | type: HusButton.Type_Primary 21 | onClicked: control.confirm(); 22 | } 23 | property Component cancelButtonDelegate: HusButton { 24 | animationEnabled: control.animationEnabled 25 | padding: 10 26 | topPadding: 4 27 | bottomPadding: 4 28 | text: control.cancelText 29 | type: HusButton.Type_Default 30 | onClicked: control.cancel(); 31 | } 32 | 33 | footerDelegate: Item { 34 | implicitHeight: __rowLayout.implicitHeight 35 | 36 | RowLayout { 37 | id: __rowLayout 38 | anchors.right: parent.right 39 | spacing: 10 40 | visible: __confirmLoader.active || __cancelLoader.active 41 | 42 | Loader { 43 | id: __confirmLoader 44 | active: control.confirmText !== '' 45 | sourceComponent: control.confirmButtonDelegate 46 | } 47 | 48 | Loader { 49 | id: __cancelLoader 50 | active: control.cancelText !== '' 51 | sourceComponent: control.cancelButtonDelegate 52 | } 53 | } 54 | } 55 | 56 | objectName: '__HusPopconfirm__' 57 | themeSource: HusTheme.HusPopconfirm 58 | } 59 | -------------------------------------------------------------------------------- /src/imports/HusPopup.qml: -------------------------------------------------------------------------------- 1 | import QtQuick 2 | import QtQuick.Templates as T 3 | import HuskarUI.Basic 4 | 5 | T.Popup { 6 | id: control 7 | 8 | property bool animationEnabled: HusTheme.animationEnabled 9 | property bool movable: false 10 | property bool resizable: false 11 | property real minimumX: Number.NaN 12 | property real maximumX: Number.NaN 13 | property real minimumY: Number.NaN 14 | property real maximumY: Number.NaN 15 | property real minimumWidth: 0 16 | property real maximumWidth: Number.NaN 17 | property real minimumHeight: 0 18 | property real maximumHeight: Number.NaN 19 | property color colorShadow: themeSource.colorShadow 20 | property color colorBg: HusTheme.isDark ? themeSource.colorBgDark : themeSource.colorBg 21 | property HusRadius radiusBg: HusRadius { all: themeSource.radiusBg } 22 | property var themeSource: HusTheme.HusPopup 23 | 24 | objectName: '__HusPopup__' 25 | implicitWidth: implicitContentWidth + leftPadding + rightPadding 26 | implicitHeight: implicitContentHeight + topPadding + bottomPadding 27 | enter: Transition { 28 | NumberAnimation { 29 | property: 'opacity' 30 | from: 0.0 31 | to: 1.0 32 | easing.type: Easing.OutQuad 33 | duration: control.animationEnabled ? HusTheme.Primary.durationMid : 0 34 | } 35 | } 36 | exit: Transition { 37 | NumberAnimation { 38 | property: 'opacity' 39 | from: 1.0 40 | to: 0 41 | easing.type: Easing.InQuad 42 | duration: control.animationEnabled ? HusTheme.Primary.durationMid : 0 43 | } 44 | } 45 | background: Item { 46 | HusShadow { 47 | anchors.fill: __popupRect 48 | source: __popupRect 49 | shadowColor: control.colorShadow 50 | } 51 | HusRectangleInternal { 52 | id: __popupRect 53 | anchors.fill: parent 54 | color: control.colorBg 55 | radius: control.radiusBg.all 56 | topLeftRadius: control.radiusBg.topLeft 57 | topRightRadius: control.radiusBg.topRight 58 | bottomLeftRadius: control.radiusBg.bottomLeft 59 | bottomRightRadius: control.radiusBg.bottomRight 60 | } 61 | Loader { 62 | active: control.movable || control.resizable 63 | sourceComponent: HusResizeMouseArea { 64 | anchors.fill: parent 65 | target: control 66 | movable: control.movable 67 | resizable: control.resizable 68 | minimumX: control.minimumX 69 | maximumX: control.maximumX 70 | minimumY: control.minimumY 71 | maximumY: control.maximumY 72 | minimumWidth: control.minimumWidth 73 | maximumWidth: control.maximumWidth 74 | minimumHeight: control.minimumHeight 75 | maximumHeight: control.maximumHeight 76 | } 77 | } 78 | } 79 | 80 | Behavior on colorBg { enabled: control.animationEnabled; ColorAnimation { duration: HusTheme.Primary.durationMid } } 81 | } 82 | -------------------------------------------------------------------------------- /src/imports/HusRadio.qml: -------------------------------------------------------------------------------- 1 | import QtQuick 2 | import QtQuick.Templates as T 3 | import HuskarUI.Basic 4 | 5 | T.RadioButton { 6 | id: control 7 | 8 | property bool animationEnabled: HusTheme.animationEnabled 9 | property bool effectEnabled: true 10 | property int hoverCursorShape: Qt.PointingHandCursor 11 | property color colorText: enabled ? HusTheme.HusRadio.colorText : HusTheme.HusRadio.colorTextDisabled 12 | property color colorIndicator: enabled ? 13 | checked ? HusTheme.HusRadio.colorIndicatorChecked : 14 | HusTheme.HusRadio.colorIndicator : HusTheme.HusRadio.colorIndicatorDisabled 15 | property color colorIndicatorBorder: (enabled && (hovered || checked)) ? HusTheme.HusRadio.colorIndicatorBorderChecked : 16 | HusTheme.HusRadio.colorIndicatorBorder 17 | property HusRadius radiusIndicator: HusRadius { all: HusTheme.HusRadio.radiusIndicator } 18 | property string contentDescription: '' 19 | 20 | objectName: '__HusRadio__' 21 | implicitWidth: implicitContentWidth + leftPadding + rightPadding 22 | implicitHeight: Math.max(implicitContentHeight, implicitIndicatorHeight) + topPadding + bottomPadding 23 | font { 24 | family: HusTheme.HusRadio.fontFamily 25 | pixelSize: HusTheme.HusRadio.fontSize 26 | } 27 | spacing: 8 28 | indicator: Item { 29 | x: control.leftPadding 30 | implicitWidth: __bg.width 31 | implicitHeight: __bg.height 32 | anchors.verticalCenter: parent.verticalCenter 33 | 34 | Rectangle { 35 | id: __effect 36 | width: __bg.width 37 | height: __bg.height 38 | radius: width * 0.5 39 | anchors.centerIn: parent 40 | visible: control.effectEnabled 41 | color: 'transparent' 42 | border.width: 0 43 | border.color: control.enabled ? HusTheme.HusRadio.colorEffectBg : 'transparent' 44 | opacity: 0.2 45 | 46 | ParallelAnimation { 47 | id: __animation 48 | onFinished: __effect.border.width = 0; 49 | NumberAnimation { 50 | target: __effect; property: 'width'; from: __bg.width + 3; to: __bg.width + 8; 51 | duration: HusTheme.Primary.durationFast 52 | easing.type: Easing.OutQuart 53 | } 54 | NumberAnimation { 55 | target: __effect; property: 'height'; from: __bg.height + 3; to: __bg.height + 8; 56 | duration: HusTheme.Primary.durationFast 57 | easing.type: Easing.OutQuart 58 | } 59 | NumberAnimation { 60 | target: __effect; property: 'opacity'; from: 0.2; to: 0; 61 | duration: HusTheme.Primary.durationSlow 62 | } 63 | } 64 | 65 | Connections { 66 | target: control 67 | function onReleased() { 68 | if (control.animationEnabled && control.effectEnabled) { 69 | __effect.border.width = 8; 70 | __animation.restart(); 71 | } 72 | } 73 | } 74 | } 75 | 76 | Rectangle { 77 | id: __bg 78 | width: control.radiusIndicator.all * 2 79 | height: width 80 | anchors.centerIn: parent 81 | radius: height * 0.5 82 | color: control.colorIndicator 83 | border.color: control.colorIndicatorBorder 84 | border.width: control.checked ? 0 : 1 85 | 86 | Behavior on color { enabled: control.animationEnabled; ColorAnimation { duration: HusTheme.Primary.durationFast } } 87 | Behavior on border.color { enabled: control.animationEnabled; ColorAnimation { duration: HusTheme.Primary.durationFast } } 88 | 89 | Rectangle { 90 | width: control.checked ? control.radiusIndicator.all - 2 : 0 91 | height: width 92 | anchors.centerIn: parent 93 | radius: width * 0.5 94 | 95 | Behavior on width { enabled: control.animationEnabled; NumberAnimation { duration: HusTheme.Primary.durationMid } } 96 | } 97 | } 98 | } 99 | contentItem: HusText { 100 | text: control.text 101 | font: control.font 102 | opacity: enabled ? 1.0 : 0.3 103 | color: control.colorText 104 | verticalAlignment: Text.AlignVCenter 105 | leftPadding: control.indicator.width + control.spacing 106 | } 107 | background: Item { } 108 | 109 | HoverHandler { 110 | cursorShape: control.hoverCursorShape 111 | } 112 | 113 | Accessible.role: Accessible.RadioButton 114 | Accessible.name: control.text 115 | Accessible.description: control.contentDescription 116 | Accessible.onPressAction: control.clicked(); 117 | } 118 | -------------------------------------------------------------------------------- /src/imports/HusShadow.qml: -------------------------------------------------------------------------------- 1 | import QtQuick 2 | import QtQuick.Effects 3 | import HuskarUI.Basic 4 | 5 | MultiEffect { 6 | shadowEnabled: true 7 | shadowColor: HusTheme.Primary.colorTextBase 8 | shadowOpacity: HusTheme.isDark ? 0.4 : 0.2 9 | shadowScale: HusTheme.isDark ? 1.03 : 1.02 10 | } 11 | -------------------------------------------------------------------------------- /src/imports/HusText.qml: -------------------------------------------------------------------------------- 1 | import QtQuick 2 | import HuskarUI.Basic 3 | 4 | Text { 5 | id: control 6 | 7 | objectName: '__HusText__' 8 | renderType: HusTheme.textRenderType 9 | color: HusTheme.Primary.colorTextBase 10 | font { 11 | family: HusTheme.Primary.fontPrimaryFamily 12 | pixelSize: HusTheme.Primary.fontPrimarySize 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /src/resources/font/HuskarUI-Icons.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mengps/HuskarUI/bf203f39db0e502499c53c66b763d163e453d0a8/src/resources/font/HuskarUI-Icons.ttf -------------------------------------------------------------------------------- /src/resources/images/empty-default.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /src/resources/images/empty-simple.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /src/resources/images/hblinds.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mengps/HuskarUI/bf203f39db0e502499c53c66b763d163e453d0a8/src/resources/images/hblinds.png -------------------------------------------------------------------------------- /src/resources/images/heart.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mengps/HuskarUI/bf203f39db0e502499c53c66b763d163e453d0a8/src/resources/images/heart.png -------------------------------------------------------------------------------- /src/resources/images/smoke.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mengps/HuskarUI/bf203f39db0e502499c53c66b763d163e453d0a8/src/resources/images/smoke.png -------------------------------------------------------------------------------- /src/resources/images/star.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mengps/HuskarUI/bf203f39db0e502499c53c66b763d163e453d0a8/src/resources/images/star.png -------------------------------------------------------------------------------- /src/resources/images/stripes.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mengps/HuskarUI/bf203f39db0e502499c53c66b763d163e453d0a8/src/resources/images/stripes.png -------------------------------------------------------------------------------- /src/shaders/husrate.frag: -------------------------------------------------------------------------------- 1 | #version 450 2 | 3 | layout(location = 0) in vec2 qt_TexCoord0; 4 | layout(location = 0) out vec4 fragColor; 5 | 6 | layout(std140, binding = 0) uniform buf { 7 | mat4 qt_Matrix; 8 | float qt_Opacity; 9 | }; 10 | layout(binding = 1) uniform sampler2D source; 11 | 12 | void main() { 13 | vec4 tex = texture(source, qt_TexCoord0); 14 | if (qt_TexCoord0.x > 0.5) 15 | fragColor = vec4(0); 16 | else 17 | fragColor = tex * qt_Opacity; 18 | } 19 | -------------------------------------------------------------------------------- /src/theme/HusAutoComplete.json: -------------------------------------------------------------------------------- 1 | { 2 | "__init__": { 3 | "__import__": ["HusInput"] 4 | }, 5 | "__style__": { 6 | "fontFamily": "@fontPrimaryFamily", 7 | "fontSize": "@fontPrimarySize", 8 | "colorItemText": "@colorTextBase", 9 | "colorItemTextDisabled": "@colorPrimaryTextDisabled", 10 | "colorItemBg": "@colorBgBase", 11 | "colorItemBgHover": "$onBackground(@colorFillSecondary, @colorBgBase)", 12 | "colorItemBgActive": "@colorPrimaryBase-1", 13 | "colorItemBgDisabled": "@colorBgBase", 14 | "radiusLabelBg": "@radiusPrimarySM" 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /src/theme/HusBreadcrumb.json: -------------------------------------------------------------------------------- 1 | { 2 | "__style__": { 3 | "fontFamily": "@fontPrimaryFamily", 4 | "fontSize": "@fontPrimarySize", 5 | "colorIcon": "$onBackground(@colorTextTertiary, @colorBgBase)", 6 | "colorIconLast": "@colorTextBase", 7 | "colorBg": "@colorFillSecondary", 8 | "colorBgLast": "$alpha(@colorTextBase, 0)", 9 | "radiusItemBg": "@radiusPrimarySM" 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /src/theme/HusButton.json: -------------------------------------------------------------------------------- 1 | { 2 | "__style__": { 3 | "fontFamily": "@fontPrimaryFamily", 4 | "fontSize": "@fontPrimarySize", 5 | "fontHeight": "@fontPrimaryHeight", 6 | "fontLineHeight": "1.0", 7 | "colorTextDisabled": "@colorPrimaryTextDisabled", 8 | "colorTextDefault": "@colorTextBase", 9 | "colorText": "@colorPrimaryText", 10 | "colorTextHover": "@colorPrimaryTextHover", 11 | "colorTextActive": "@colorPrimaryTextActive", 12 | "colorBgDisabled": "@colorPrimaryContainerBgDisabled", 13 | "colorBg": "$alpha(@colorBgBase, 0)", 14 | "colorBgHover": "@colorBgBase", 15 | "colorBgActive": "@colorBgBase", 16 | "colorPrimaryBg": "@colorPrimaryContainerBg", 17 | "colorPrimaryBgHover": "@colorPrimaryContainerBgHover", 18 | "colorPrimaryBgActive": "@colorPrimaryContainerBgActive", 19 | "colorFillBgDark": "@colorPrimaryBase-10", 20 | "colorFillBgDarkHover": "@colorPrimaryBase-9", 21 | "colorFillBgDarkActive": "@colorPrimaryBase-8", 22 | "colorFillBg": "@colorPrimaryBg", 23 | "colorFillBgHover": "@colorPrimaryBgHover", 24 | "colorFillBgActive": "@colorPrimaryBgActive", 25 | "colorTextBg": "$alpha(@colorBgBase, 0)", 26 | "colorTextBgHover": "@colorPrimaryBg", 27 | "colorTextBgActive": "@colorPrimaryBgActive", 28 | "colorBorder": "@colorPrimaryBorder", 29 | "colorBorderHover": "@colorPrimaryBorderHover", 30 | "colorBorderActive": "@colorPrimaryBorderActive", 31 | "colorBorderDisabled": "$alpha(@colorTextBase, 0.15)", 32 | "colorDefaultBorder": "#80808080", 33 | "radiusBg": "@radiusPrimary" 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /src/theme/HusCaptionButton.json: -------------------------------------------------------------------------------- 1 | { 2 | "__style__": { 3 | "fontSize": "14", 4 | "colorIconDisabled": "@colorPrimaryTextDisabled", 5 | "colorIcon": "@colorTextBase", 6 | "colorIconHover": "@colorTextBase", 7 | "colorIconActive": "@colorTextBase", 8 | "colorIconChecked": "@colorPrimaryTextHover", 9 | "colorBgDisabled": "@colorPrimaryContainerBgDisabled", 10 | "colorBg": "$alpha(@colorTextBase, 0)", 11 | "colorBgHover": "@colorFillSecondary", 12 | "colorBgActive": "@colorFill", 13 | "colorErrorBg": "$alpha(@colorError, 0)", 14 | "colorErrorBgHover": "@colorErrorHover", 15 | "colorErrorBgActive": "@colorErrorActive", 16 | "radiusBg": "@radiusPrimary" 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /src/theme/HusCard.json: -------------------------------------------------------------------------------- 1 | { 2 | "__style__": { 3 | "fontFamily": "@fontPrimaryFamily", 4 | "fontSizeTitle": "@fontPrimarySize", 5 | "fontSizeBodyTitle": "@fontPrimarySize", 6 | "fontSizeBodyDescription": "@fontPrimarySize", 7 | "colorBg": "@colorBgBase", 8 | "colorBorder": "@colorBorder", 9 | "colorBorderDark": "#424242", 10 | "colorTitle": "@colorTextBase", 11 | "colorBodyAvatar": "@colorTextBase", 12 | "colorBodyTitle": "@colorTextBase", 13 | "colorBodyDescription": "@colorTextTertiary", 14 | "radiusBg": "@radiusPrimary" 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /src/theme/HusCarousel.json: -------------------------------------------------------------------------------- 1 | { 2 | "__style__": { 3 | "colorIndicator": "$alpha(@colorBgBase, 0.2)", 4 | "colorIndicatorActive": "@colorBgBase", 5 | "colorIndicatorHover": "$alpha(@colorBgBase, 0.8)", 6 | "colorArrow": "$alpha(#fff, 0.4)", 7 | "colorArrowHover": "#fff", 8 | "radiusIndicator": "@radiusPrimaryXS" 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /src/theme/HusCheckBox.json: -------------------------------------------------------------------------------- 1 | { 2 | "__style__": { 3 | "fontFamily": "@fontPrimaryFamily", 4 | "fontSize": "@fontPrimarySize", 5 | "colorText": "@colorTextBase", 6 | "colorTextDisabled": "@colorPrimaryTextDisabled", 7 | "colorIndicator": "@colorBgBase", 8 | "colorIndicatorChecked": "@colorPrimary", 9 | "colorIndicatorCheckedHover": "@colorPrimaryHover", 10 | "colorIndicatorDisabled": "$alpha(@colorTextBase, 0.1)", 11 | "colorIndicatorBorder": "$onBackground(@colorTextQuaternary, @colorBgBase)", 12 | "colorIndicatorBorderChecked": "@colorPrimaryBorderActive", 13 | "colorEffectBg": "@colorTextTertiary", 14 | "radiusIndicator": "@radiusPrimarySM" 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /src/theme/HusCollapse.json: -------------------------------------------------------------------------------- 1 | { 2 | "__style__": { 3 | "fontFamily": "@fontPrimaryFamily", 4 | "fontSizeTitle": "@fontPrimarySize", 5 | "fontSizeContent": "@fontPrimarySize", 6 | "colorBorder": "@colorBorder", 7 | "colorBorderDark": "#424242", 8 | "colorIcon": "@colorTextPrimary", 9 | "colorTitle": "@colorTextPrimary", 10 | "colorTitleBg": "@colorFillTertiary", 11 | "colorContent": "@colorTextPrimary", 12 | "colorContentBg": "@colorBgBase", 13 | "colorBg": "@colorBgBase", 14 | "radiusBg": "@radiusPrimary" 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /src/theme/HusCopyableText.json: -------------------------------------------------------------------------------- 1 | { 2 | "__style__": { 3 | "fontFamily": "@fontPrimaryFamily", 4 | "fontSize": "@fontPrimarySize", 5 | "colorText": "@colorTextBase", 6 | "colorTextSelected": "@colorTextBase", 7 | "colorSelection": "$alpha(@colorPrimary, 0.6)" 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /src/theme/HusDateTimePicker.json: -------------------------------------------------------------------------------- 1 | { 2 | "__init__": { 3 | "__import__": ["HusInput"] 4 | }, 5 | "__style__": { 6 | "fontFamily": "@fontPrimaryFamily", 7 | "fontSize": "@fontPrimarySize", 8 | "colorWeekText": "@colorTextBase", 9 | "colorIcon": "@colorTextTertiary", 10 | "colorIconHover": "@colorTextSecondary", 11 | "colorIconDisabled": "@colorTextQuaternary", 12 | "colorDayText": "@colorTextBase", 13 | "colorDayTextNone": "@colorTextQuaternary", 14 | "colorDayItemBgCurrent": "@colorPrimary", 15 | "colorDayItemBgHover": "$alpha(@colorPrimary, 0.6)", 16 | "colorDayItemBg": "transparent", 17 | "colorDayBgCurrent": "@colorPrimary", 18 | "colorDayBgHover": "$onBackground(@colorFill, @colorBgBase)", 19 | "colorDayBg": "$alpha(@colorBgBase, 0)", 20 | "colorDayBorderToday": "@colorPrimaryBorderActive", 21 | "colorPageIconHover": "@colorTextPrimary", 22 | "colorPageIcon": "@colorTextTertiary", 23 | "colorPageTextHover": "@colorPrimary", 24 | "colorPageText": "@colorTextBase", 25 | "colorSplitLine": "$alpha(@colorTextBase, 0.1)", 26 | "colorTimeText": "@colorTextBase", 27 | "colorTimeHeaderText": "@colorTextBase", 28 | "colorPopupBg": "@colorBgBase", 29 | "colorPopupBgDark": "@colorMain-11", 30 | "colorButtonBgHover": "$alpha(@colorTextBase, 0.05)", 31 | "colorButtonBgActive": "@colorPrimaryBase-1", 32 | "radiusBg": "@radiusPrimary", 33 | "radiusItemBg": "@radiusPrimarySM", 34 | "radiusPopupBg": "@radiusPrimary" 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /src/theme/HusDivider.json: -------------------------------------------------------------------------------- 1 | { 2 | "__style__": { 3 | "fontFamily": "@fontPrimaryFamily", 4 | "fontSize": "@fontPrimarySize", 5 | "colorText": "@colorTextBase", 6 | "colorSplit": "@colorFillPrimary" 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /src/theme/HusDrawer.json: -------------------------------------------------------------------------------- 1 | { 2 | "__style__": { 3 | "fontFamily": "@fontPrimaryFamily", 4 | "fontSizeTitle": "@fontPrimarySizeHeading5", 5 | "colorTitle": "@colorTextBase", 6 | "colorShadow": "@colorTextBase", 7 | "colorBg": "$lighter(@colorBgBase)", 8 | "colorOverlay": "@colorBgMask", 9 | "radiusButtonBg": "@radiusPrimarySM" 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /src/theme/HusEmpty.json: -------------------------------------------------------------------------------- 1 | { 2 | "__style__": { 3 | "fontFamily": "@fontPrimaryFamily", 4 | "fontSize": "@fontPrimarySize", 5 | "colorDescription": "@colorTextSecondary" 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /src/theme/HusIconText.json: -------------------------------------------------------------------------------- 1 | { 2 | "__style__": { 3 | "fontSize": "@fontPrimarySize", 4 | "colorText": "@colorTextBase" 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /src/theme/HusImage.json: -------------------------------------------------------------------------------- 1 | { 2 | "__style__": { 3 | "fontFamily": "@fontPrimaryFamily", 4 | "fontSize": "@fontPrimarySize", 5 | "colorText": "#fff", 6 | "colorIndicatorText": "#ccc", 7 | "colorButtonTextDisabled": "#888", 8 | "colorButtonText": "#ccc", 9 | "colorButtonTextHover": "#fff", 10 | "colorButtonBg": "@colorFillPrimary", 11 | "colorButtonBgHover": "@colorTextQuaternary", 12 | "colorOperationBg": "@colorFillPrimary" 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /src/theme/HusInput.json: -------------------------------------------------------------------------------- 1 | { 2 | "__style__": { 3 | "fontFamily": "@fontPrimaryFamily", 4 | "fontSize": "@fontPrimarySize", 5 | "fontIconSize": "@fontPrimarySizeHeading5", 6 | "fontClearIconSize": "@fontPrimarySize", 7 | "colorIcon": "@colorTextBase", 8 | "colorIconDisabled": "$onBackground(@colorTextQuaternary, @colorBgBase)", 9 | "colorClearIcon": "$onBackground(@colorTextQuaternary, @colorBgBase)", 10 | "colorClearIconHover": "$onBackground(@colorTextTertiary, @colorBgBase)", 11 | "colorClearIconActive": "$onBackground(@colorTextPrimary, @colorBgBase)", 12 | "colorClearIconDisabled": "$onBackground(@colorTextQuaternary, @colorBgBase)", 13 | "colorText": "@colorTextBase", 14 | "colorTextDisabled": "@colorPrimaryTextDisabled", 15 | "colorPlaceholderText": "@colorTextQuaternary", 16 | "colorPlaceholderTextDisabled": "@colorPrimaryTextDisabled", 17 | "colorTextSelected": "@colorTextBase", 18 | "colorSelection": "$alpha(@colorPrimary, 0.6)", 19 | "colorBorder": "$onBackground(@colorTextQuaternary, @colorBgBase)", 20 | "colorBorderHover": "@colorPrimary", 21 | "colorBorderDisabled": "$onBackground(@colorFill, @colorBgBase)", 22 | "colorBg": "@colorBgBase", 23 | "colorBgDisabled": "$onBackground(@colorFillPrimary, @colorBgBase)", 24 | 25 | "colorLabelBg": "$onBackground(@colorFillQuaternary, @colorBgBase)", 26 | "colorLabelBgDisabled": "$onBackground(@colorFillPrimary, @colorBgBase)", 27 | "radiusBg": "@radiusPrimary" 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /src/theme/HusMenu.json: -------------------------------------------------------------------------------- 1 | { 2 | "__style__": { 3 | "fontFamily": "@fontPrimaryFamily", 4 | "fontSize": "@fontPrimarySizeHeading5", 5 | "colorTextDisabled": "@colorPrimaryTextDisabled", 6 | "colorText": "@colorTextBase", 7 | "colorTextActive": "@colorPrimaryTextHover", 8 | "colorBgDisabled": "transparent", 9 | "colorBg": "$alpha(@colorPrimaryBgActive, 0)", 10 | "colorBgHover": "$alpha(@colorPrimaryBgActive, 0.15)", 11 | "colorBgActive": "$alpha(@colorPrimaryBgActive, 0.25)", 12 | "colorChildBg": "@colorFillQuaternary", 13 | "colorEdge": "$alpha(@colorTextBase, 0.1)", 14 | "radiusMenuBg": "@radiusPrimary", 15 | "radiusPopupBg": "@radiusPrimary" 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /src/theme/HusMessage.json: -------------------------------------------------------------------------------- 1 | { 2 | "__style__": { 3 | "fontFamily": "@fontPrimaryFamily", 4 | "fontSize": "@fontPrimarySize", 5 | "colorMessage": "@colorTextPrimary", 6 | "colorBg": "@colorBgBase", 7 | "colorBgDark": "@colorMain-11", 8 | "colorBgShadow": "@colorTextBase", 9 | "colorClose": "@colorTextTertiary", 10 | "colorCloseHover": "@colorTextBase", 11 | "radiusBg": "@radiusPrimaryLG" 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /src/theme/HusModal.json: -------------------------------------------------------------------------------- 1 | { 2 | "__init__": { 3 | "__import__": ["HusPopup"] 4 | }, 5 | "__style__": { 6 | "fontTitleSize": "@fontPrimarySizeHeading5", 7 | "fontDescriptionLineHeight": "@fontPrimaryLineHeightHeading1", 8 | "fontDescriptionSize": "@fontPrimarySize", 9 | "colorOverlay": "@colorBgMask", 10 | "colorIcon": "@colorInfo", 11 | "colorTitle": "@colorTextBase", 12 | "colorDescription": "@colorTextPrimary", 13 | "radiusCloseBg": "@radiusPrimarySM" 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /src/theme/HusMultiSelect.json: -------------------------------------------------------------------------------- 1 | { 2 | "__init__": { 3 | "__import__": ["HusSelect"] 4 | }, 5 | "__style__": { 6 | "colorIconSelect": "@colorPrimary", 7 | "colorTagText": "@colorTextBase", 8 | "colorTagBg": "@colorFillPrimary", 9 | "colorTagCloseHover": "@colorTextPrimary", 10 | "colorTagClose": "@colorTextTertiary", 11 | "radiusTagBg": "@radiusPrimarySM" 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /src/theme/HusNotification.json: -------------------------------------------------------------------------------- 1 | { 2 | "__style__": { 3 | "fontFamily": "@fontPrimaryFamily", 4 | "fontMessageSize": "@fontPrimarySizeHeading5", 5 | "fontDescriptionSize": "@fontPrimarySize", 6 | "colorMessage": "@colorTextPrimary", 7 | "colorDescription": "@colorTextSecondary", 8 | "colorBg": "@colorBgBase", 9 | "colorBgDark": "@colorMain-11", 10 | "colorBgShadow": "@colorTextBase", 11 | "colorClose": "@colorTextTertiary", 12 | "colorCloseHover": "@colorTextBase", 13 | "radiusBg": "@radiusPrimaryLG" 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /src/theme/HusPagination.json: -------------------------------------------------------------------------------- 1 | { 2 | "__style__": { 3 | "colorButtonText": "@colorTextBase", 4 | "colorButtonTextActive": "@colorPrimaryTextActive", 5 | "colorButtonTextDisabled": "@colorPrimaryTextDisabled", 6 | "colorButtonBg": "@colorBgBase", 7 | "colorButtonBgHover": "$onBackground(@colorFillSecondary, @colorBgBase)", 8 | "colorButtonBgActive": "$onBackground(@colorFill, @colorBgBase)", 9 | "colorButtonBgDisabled": "$onBackground(@colorPrimaryContainerBgDisabled, @colorBgBase)", 10 | "colorActionBg": "transparent", 11 | "colorActionBgHover": "@colorFillSecondary", 12 | "colorActionBgActive": "@colorFill", 13 | "colorBorderActive": "@colorPrimaryBorderActive" 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /src/theme/HusPopconfirm.json: -------------------------------------------------------------------------------- 1 | { 2 | "__init__": { 3 | "__import__": ["HusPopover"] 4 | } 5 | } 6 | -------------------------------------------------------------------------------- /src/theme/HusPopover.json: -------------------------------------------------------------------------------- 1 | { 2 | "__init__": { 3 | "__import__": ["HusPopup"] 4 | }, 5 | "__style__": { 6 | "fontTitleSize": "@fontPrimarySizeHeading5", 7 | "fontDescriptionSize": "@fontPrimarySize", 8 | "colorIcon": "@colorWarning", 9 | "colorTitle": "@colorTextBase", 10 | "colorDescription": "@colorTextPrimary" 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /src/theme/HusPopup.json: -------------------------------------------------------------------------------- 1 | { 2 | "__style__": { 3 | "fontFamily": "@fontPrimaryFamily", 4 | "fontSize": "@fontPrimarySize", 5 | "colorShadow": "@colorTextBase", 6 | "colorBg": "@colorBgBase", 7 | "colorBgDark": "@colorMain-11", 8 | "radiusBg": "@radiusPrimary" 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /src/theme/HusProgress.json: -------------------------------------------------------------------------------- 1 | { 2 | "__style__": { 3 | "fontFamily": "@fontPrimaryFamily", 4 | "fontSize": "@fontPrimarySize", 5 | "colorTrack": "@colorFillSecondary", 6 | "colorBarSuccess": "@colorSuccess", 7 | "colorBarException": "@colorError", 8 | "colorBarNormal": "@colorPrimary", 9 | "colorBarActive": "@colorPrimary", 10 | "colorInfoSuccess": "@colorSuccess", 11 | "colorInfoException": "@colorError", 12 | "colorInfoNormal": "@colorTextBase" 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /src/theme/HusRadio.json: -------------------------------------------------------------------------------- 1 | { 2 | "__style__": { 3 | "fontFamily": "@fontPrimaryFamily", 4 | "fontSize": "@fontPrimarySize", 5 | "colorText": "@colorTextBase", 6 | "colorTextDisabled": "@colorPrimaryTextDisabled", 7 | "colorIndicator": "@colorBgBase", 8 | "colorIndicatorChecked": "@colorPrimary", 9 | "colorIndicatorDisabled": "$alpha(@colorTextBase, 0.05)", 10 | "colorIndicatorBorder": "@colorTextQuaternary", 11 | "colorIndicatorBorderChecked": "@colorPrimaryBorderActive", 12 | "colorEffectBg": "@colorTextTertiary", 13 | "radiusIndicator": "8", 14 | 15 | "colorBlockText": "@colorTextBase", 16 | "colorBlockTextFilledChecked": "#fff", 17 | "colorBlockTextChecked": "@colorPrimary", 18 | "colorBlockTextDisabled": "@colorPrimaryTextDisabled", 19 | "colorBlockBg": "@colorBgBase", 20 | "colorBlockBgChecked": "@colorPrimary", 21 | "colorBlockBgHover": "@colorPrimaryContainerBgHover", 22 | "colorBlockBgActive": "@colorPrimaryContainerBgActive", 23 | "colorBlockBgCheckedDisabled": "$alpha(@colorTextBase, 0.2)", 24 | "colorBlockBgDisabled": "$alpha(@colorTextBase, 0.05)", 25 | "colorBlockBorder": "@colorTextQuaternary", 26 | "colorBlockBorderChecked": "@colorPrimaryBorderActive", 27 | "colorBlockEffectBg": "@colorPrimaryBorderHover", 28 | "radiusBlockBg": "@radiusPrimary" 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /src/theme/HusRate.json: -------------------------------------------------------------------------------- 1 | { 2 | "__style__": { 3 | "fontFamily": "@fontPrimaryFamily", 4 | "fontSize": "@fontPrimarySize", 5 | "colorFill": "$alpha(#Preset_Yellow, 0.9)", 6 | "colorEmpty": "$alpha(@colorTextBase, 0.1)", 7 | "colorHalf": "$alpha(#Preset_Yellow, 0.9)", 8 | "colorToolTipShadow": "@colorTextBase", 9 | "colorToolTipText": "@colorTextBase", 10 | "colorToolTipBg": "@colorBgBase", 11 | "colorToolTipBgDark": "#424242", 12 | "radiusToolTipBg": "@radiusPrimary" 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /src/theme/HusScrollBar.json: -------------------------------------------------------------------------------- 1 | { 2 | "__style__": { 3 | "colorBar": "@colorTextTertiary", 4 | "colorBarHover": "@colorTextTertiary", 5 | "colorBarActive": "@colorTextSecondary", 6 | "colorBg": "$alpha(@colorBgBase, 0.6)", 7 | "colorBgHover": "$alpha(@colorBgBase, 0.4)", 8 | "colorBgActive": "$alpha(@colorBgBase, 0.4)", 9 | "colorIcon": "@colorTextTertiary", 10 | "colorIconHover": "@colorTextPrimary" 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /src/theme/HusSelect.json: -------------------------------------------------------------------------------- 1 | { 2 | "__style__": { 3 | "fontFamily": "@fontPrimaryFamily", 4 | "fontSize": "@fontPrimarySize", 5 | "colorText": "@colorTextBase", 6 | "colorTextActive": "$onBackground(@colorTextTertiary, @colorBgBase)", 7 | "colorTextDisabled": "$onBackground(@colorPrimaryTextDisabled, @colorBgBase)", 8 | "colorIndicator": "$onBackground(@colorTextQuaternary, @colorBgBase)", 9 | "colorIndicatorHover": "$onBackground(@colorTextTertiary, @colorBgBase)", 10 | "colorIndicatorActive": "$onBackground(@colorTextPrimary, @colorBgBase)", 11 | "colorIndicatorDisabled": "$onBackground(@colorTextQuaternary, @colorBgBase)", 12 | "colorBorder": "@colorTextQuaternary", 13 | "colorBorderHover": "@colorPrimary", 14 | "colorBorderDisabled": "transparent", 15 | "colorBg": "@colorBgBase", 16 | "colorBgDisabled": "$onBackground(@colorFillPrimary, @colorBgBase)", 17 | "colorPopupBg": "@colorBgBase", 18 | "colorPopupBgDark": "@colorMain-11", 19 | "colorItemText": "@colorTextBase", 20 | "colorItemTextDisabled": "@colorPrimaryTextDisabled", 21 | "colorItemBg": "@colorBgBase", 22 | "colorItemBgHover": "$onBackground(@colorFillPrimary, @colorBgBase)", 23 | "colorItemBgActive": "@colorPrimaryBase-1", 24 | "colorItemBgDisabled": "@colorBgBase", 25 | "radiusBg": "@radiusPrimary", 26 | "radiusItemBg": "@radiusPrimarySM", 27 | "radiusPopupBg": "@radiusPrimary" 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /src/theme/HusSlider.json: -------------------------------------------------------------------------------- 1 | { 2 | "__style__": { 3 | "colorHandle": "@colorBgBase", 4 | "colorHandleBorder": "@colorPrimaryBgActive", 5 | "colorHandleBorderDisabled": "@colorTextQuaternary", 6 | "colorHandleBorderHover": "@colorPrimaryBorderActive", 7 | "colorHandleBorderDark": "@colorPrimaryBase-7", 8 | "colorHandleBorderHoverDark": "@colorPrimaryBorderActive", 9 | "colorTrackDisabled": "$alpha(@colorPrimaryBgActive, 0)", 10 | "colorBg": "$alpha(@colorTextBase, 0.15)", 11 | "colorBgHover": "$alpha(@colorTextBase, 0.25)", 12 | "colorTrack": "@colorPrimaryBgActive", 13 | "colorTrackHover": "@colorPrimaryBorderHover", 14 | "colorTrackDark": "@colorPrimaryBase-7", 15 | "colorTrackHoverDark": "@colorPrimaryBase-6", 16 | "radiusBg": "@radiusPrimary" 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /src/theme/HusSwitch.json: -------------------------------------------------------------------------------- 1 | { 2 | "__style__": { 3 | "fontFamily": "@fontPrimaryFamily", 4 | "fontSize": "@fontPrimarySize", 5 | "colorText": "@colorTextBase", 6 | "colorHandle": "#ffffff", 7 | "colorBgDisabled": "$alpha(@colorTextQuaternary, 0.15)", 8 | "colorBgCheckedDisabled": "$alpha(@colorPrimary, 0.65)", 9 | "colorBg": "@colorTextQuaternary", 10 | "colorBgHover": "@colorTextTertiary", 11 | "colorBgActive": "@colorTextQuaternary", 12 | "colorBgChecked": "@colorPrimary", 13 | "colorBgCheckedHover": "@colorPrimaryHover", 14 | "colorBgCheckedActive": "@colorPrimary" 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /src/theme/HusTabView.json: -------------------------------------------------------------------------------- 1 | { 2 | "__style__": { 3 | "fontFamily": "@fontPrimaryFamily", 4 | "fontSize": "@fontPrimarySize", 5 | "colorTabClose": "@colorTextTertiary", 6 | "colorTabCloseHover": "@colorTextBase", 7 | "colorTab": "@colorTextBase", 8 | "colorTabHover": "@colorPrimaryHover", 9 | "colorTabActive": "@colorPrimaryActive", 10 | "colorTabCardBorder": "$alpha(@colorTextBase, 0.2)", 11 | "colorTabCardBg": "$darker(@colorBgBase, 105)", 12 | "colorTabCardBgChecked": "@colorBgBase", 13 | "colorTabCardBgDark": "$lighter(@colorBgBase, 200)", 14 | "colorTabCardBgCheckedDark": "@colorBgBase", 15 | "colorHightlight": "@colorPrimaryBase-6", 16 | "colorHightlightDark": "@colorPrimaryBase-5", 17 | "radiusButton": "@radiusPrimary", 18 | "radiusTabBg": "@radiusPrimary" 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /src/theme/HusTableView.json: -------------------------------------------------------------------------------- 1 | { 2 | "__style__": { 3 | "fontFamily": "@fontPrimaryFamily", 4 | "fontSize": "@fontPrimarySize", 5 | "colorBg": "@colorBgBase", 6 | "colorGridLine": "$onBackground(@colorFillTertiary, @colorBgBase)", 7 | "colorColumnTitle": "@colorTextBase", 8 | "colorColumnHeaderBg": "$onBackground(@colorFillSecondary, @colorBgBase)", 9 | "colorIcon": "@colorTextTertiary", 10 | "colorIconHover": "@colorPrimary", 11 | "colorRowTitle": "@colorTextBase", 12 | "colorRowHeaderBg": "$onBackground(@colorFillSecondary, @colorBgBase)", 13 | "colorResizeBlockBg": "$onBackground(@colorFillTertiary, @colorBgBase)", 14 | "colorCellBg": "@colorBgBase", 15 | "colorCellBgHover": "$onBackground(@colorFillSecondary, @colorBgBase)", 16 | "colorCellBgHoverChecked": "@colorPrimaryBgHover", 17 | "colorCellBgChecked": "@colorPrimaryBg", 18 | "colorCellBgDarkHoverChecked": "@colorPrimaryBase-9", 19 | "colorCellBgDarkChecked": "@colorPrimaryBase-10", 20 | "radiusBg": "@radiusPrimary" 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /src/theme/HusTag.json: -------------------------------------------------------------------------------- 1 | { 2 | "__style__": { 3 | "fontFamily": "@fontPrimaryFamily", 4 | "fontSize": "@fontPrimarySize", 5 | "colorDefaultText": "@colorTextBase", 6 | "colorDefaultBg": "@colorFillTertiary", 7 | "colorDefaultBorder": "$alpha(@colorTextBase, 0.2)", 8 | "colorCloseIconHover": "@colorTextPrimary", 9 | "colorCloseIcon": "@colorTextTertiary", 10 | "radiusBg": "@radiusPrimarySM" 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /src/theme/HusTextArea.json: -------------------------------------------------------------------------------- 1 | { 2 | "__style__": { 3 | "fontFamily": "@fontPrimaryFamily", 4 | "fontSize": "@fontPrimarySize", 5 | "colorText": "@colorTextBase", 6 | "colorTextDisabled": "@colorPrimaryTextDisabled", 7 | "colorPlaceholderText": "@colorTextQuaternary", 8 | "colorPlaceholderTextDisabled": "@colorPrimaryTextDisabled", 9 | "colorTextSelected": "@colorTextBase", 10 | "colorSelection": "$alpha(@colorPrimary, 0.6)", 11 | "colorBorder": "$onBackground(@colorTextQuaternary, @colorBgBase)", 12 | "colorBorderHover": "@colorPrimary", 13 | "colorBorderDisabled": "$onBackground(@colorFill, @colorBgBase)", 14 | "colorBg": "@colorBgBase", 15 | "colorBgDisabled": "$onBackground(@colorFillPrimary, @colorBgBase)", 16 | "radiusBg": "@radiusPrimary" 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /src/theme/HusTimeline.json: -------------------------------------------------------------------------------- 1 | { 2 | "__style__": { 3 | "fontFamily": "@fontPrimaryFamily", 4 | "fontSize": "@fontPrimarySize", 5 | "colorNode": "@colorPrimary", 6 | "colorNodeBg": "@colorBgBase", 7 | "colorLine": "$alpha(@colorTextBase, 0.15)", 8 | "colorTimeText": "@colorTextBase", 9 | "colorContentText": "@colorTextBase", 10 | "colorContentBg": "transparent", 11 | "colorContentBordor": "transparent" 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /src/theme/HusToolTip.json: -------------------------------------------------------------------------------- 1 | { 2 | "__style__": { 3 | "fontFamily": "@fontPrimaryFamily", 4 | "fontSize": "@fontPrimarySize", 5 | "colorShadow": "@colorTextBase", 6 | "colorText": "@colorTextBase", 7 | "colorBg": "@colorBgBase", 8 | "colorBgDark": "#424242", 9 | "radiusBg": "@radiusPrimary" 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /src/theme/HusTour.json: -------------------------------------------------------------------------------- 1 | { 2 | "__style__": { 3 | "fontFamily": "@fontPrimaryFamily", 4 | "fontSizeTitle": "@fontPrimarySizeHeading5", 5 | "fontSizeDescription": "@fontPrimarySize", 6 | "fontSizeIndicator": "@fontPrimarySize", 7 | "fontSizeButton": "@fontPrimarySize", 8 | "colorText": "@colorTextBase", 9 | "colorBg": "$lighter(@colorBgBase)", 10 | "colorOverlay": "@colorBgMask", 11 | "radiusCard": "@radiusPrimary", 12 | "radiusButtonBg": "@radiusPrimarySM" 13 | } 14 | } 15 | --------------------------------------------------------------------------------