From 78b5476af2a01edb23baf7076814b003cb499245 Mon Sep 17 00:00:00 2001 From: nayk Date: Mon, 21 Jul 2025 14:56:33 +0300 Subject: [PATCH] =?UTF-8?q?=D0=A0=D0=B5=D0=B0=D0=BB=D0=B8=D0=B7=D0=B0?= =?UTF-8?q?=D1=86=D0=B8=D1=8F=20=D0=B1=D0=B8=D0=B1=D0=BB=D0=B8=D0=BE=D1=82?= =?UTF-8?q?=D0=B5=D0=BA=D0=B8=20=D0=B8=20=D0=BF=D1=80=D0=B8=D0=BB=D0=BE?= =?UTF-8?q?=D0=B6=D0=B5=D0=BD=D0=B8=D1=8F=20=D0=B4=D0=BB=D1=8F=20=D0=B4?= =?UTF-8?q?=D0=B5=D0=BC=D0=BE=D0=BD=D1=81=D1=82=D1=80=D0=B0=D1=86=D0=B8?= =?UTF-8?q?=D0=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitignore | 107 ++++++ CMakeLists.txt | 10 + LICENSE | 9 + LICENSE.ru | 25 ++ README.md | 26 +- _cmake/app_settings.cmake | 28 ++ _cmake/common.cmake | 52 +++ _cmake/config.h.in | 9 + _cmake/copy_depends.cmake | 289 ++++++++++++++++ _cmake/developer.cmake | 8 + _cmake/lib_settings.cmake | 29 ++ _cmake/post_build.cmake | 40 +++ _cmake/setup_directories.cmake | 25 ++ _cmake/target_options.cmake | 55 +++ _cmake/update_translations.cmake | 70 ++++ _cmake/version.cmake | 52 +++ _cmake/versioninfo.rc.in | 35 ++ _include/application_config.cpp | 159 +++++++++ _include/application_config.h | 47 +++ _resources/icons.qrc | 12 + _resources/icons/cancel-40.png | Bin 0 -> 1039 bytes _resources/icons/change-theme-40.png | Bin 0 -> 237 bytes _resources/icons/close-40.png | Bin 0 -> 487 bytes _resources/icons/ok-40.png | Bin 0 -> 1100 bytes _resources/icons/opened-folder-40.png | Bin 0 -> 534 bytes _resources/icons/restart-40.png | Bin 0 -> 1554 bytes _resources/icons/save-as-40.png | Bin 0 -> 840 bytes _resources/icons/shutdown-40.png | Bin 0 -> 1315 bytes _resources/images/main_icon.png | Bin 0 -> 410 bytes _resources/images/main_title.png | Bin 0 -> 5469 bytes _resources/images/screenshot.png | Bin 0 -> 113818 bytes _resources/main.ico | Bin 0 -> 52014 bytes _resources/main.qrc | 6 + _resources/main_icon.rc | 1 + application/CMakeLists.txt | 82 +++++ application/main.cpp | 22 ++ application/main_window.cpp | 80 +++++ application/main_window.h | 58 ++++ application/main_window.ui | 154 +++++++++ lib_circular_menu/CMakeLists.txt | 57 +++ lib_circular_menu/circular_menu.h | 80 +++++ lib_circular_menu/private/circular_menu.cpp | 362 ++++++++++++++++++++ 42 files changed, 1988 insertions(+), 1 deletion(-) create mode 100644 .gitignore create mode 100644 CMakeLists.txt create mode 100644 LICENSE create mode 100644 LICENSE.ru create mode 100644 _cmake/app_settings.cmake create mode 100644 _cmake/common.cmake create mode 100644 _cmake/config.h.in create mode 100644 _cmake/copy_depends.cmake create mode 100644 _cmake/developer.cmake create mode 100644 _cmake/lib_settings.cmake create mode 100644 _cmake/post_build.cmake create mode 100644 _cmake/setup_directories.cmake create mode 100644 _cmake/target_options.cmake create mode 100644 _cmake/update_translations.cmake create mode 100644 _cmake/version.cmake create mode 100644 _cmake/versioninfo.rc.in create mode 100644 _include/application_config.cpp create mode 100644 _include/application_config.h create mode 100644 _resources/icons.qrc create mode 100644 _resources/icons/cancel-40.png create mode 100644 _resources/icons/change-theme-40.png create mode 100644 _resources/icons/close-40.png create mode 100644 _resources/icons/ok-40.png create mode 100644 _resources/icons/opened-folder-40.png create mode 100644 _resources/icons/restart-40.png create mode 100644 _resources/icons/save-as-40.png create mode 100644 _resources/icons/shutdown-40.png create mode 100644 _resources/images/main_icon.png create mode 100644 _resources/images/main_title.png create mode 100644 _resources/images/screenshot.png create mode 100644 _resources/main.ico create mode 100644 _resources/main.qrc create mode 100644 _resources/main_icon.rc create mode 100644 application/CMakeLists.txt create mode 100644 application/main.cpp create mode 100644 application/main_window.cpp create mode 100644 application/main_window.h create mode 100644 application/main_window.ui create mode 100644 lib_circular_menu/CMakeLists.txt create mode 100644 lib_circular_menu/circular_menu.h create mode 100644 lib_circular_menu/private/circular_menu.cpp diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..23a669a --- /dev/null +++ b/.gitignore @@ -0,0 +1,107 @@ +.build/ +_other/ +_distrib*/ + +# Tmp files +*~ +Thumbs.db* + +# C++ objects and libs +*.slo +*.lo +*.o +*.a +*.la +*.lai +*.so +*.so.* +*.dll +*.dylib +*.ko +*.obj +*.elf +*.lib + +# Qt-es +object_script.*.Release +object_script.*.Debug +*_plugin_import.cpp +/.qmake.cache +/.qmake.stash +*.pro.user +*.pro.user.* +*.qbs.user +*.qbs.user.* +*.moc +moc_*.cpp +moc_*.h +qrc_*.cpp +ui_*.h +*.qmlc +*.jsc +Makefile* +*build-* +*.qm +*.prl + +# Qt unit tests +target_wrapper.* + +# QtCreator +*.autosave + +# QtCreator Qml +*.qmlproject.user +*.qmlproject.user.* + +# QtCreator CMake +CMakeLists.txt.user* + +# QtCreator 4.8< compilation database +compile_commands.json + +# QtCreator local machine specific files for imported projects +*creator.user* + +*_qmlcache.qrc + +# ---> C +# Prerequisites +*.d + +# Linker output +*.ilk +*.map +*.exp + +# Precompiled Headers +*.gch +*.pch + +# Executables +*.exe +*.out +*.app +*.i*86 +*.x86_64 +*.hex + +# Debug files +*.dSYM/ +*.su +*.idb +*.pdb + +# Kernel Module Compile Results +*.mod* +*.cmd +.tmp_versions/ +modules.order +Module.symvers +Mkfile.old +dkms.conf + +# Fortran module files +*.mod +*.smod + diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 0000000..e984680 --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,10 @@ +cmake_minimum_required(VERSION 4.0) + +project (QtCircularMenuExample) + +# Circular menu library: +add_subdirectory(lib_circular_menu) + +# Example Application: +add_subdirectory(application) + diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..9be8c26 --- /dev/null +++ b/LICENSE @@ -0,0 +1,9 @@ +MIT License + +Copyright (c) 2025 Evgeny Teterin (nayk) + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/LICENSE.ru b/LICENSE.ru new file mode 100644 index 0000000..6aff4e4 --- /dev/null +++ b/LICENSE.ru @@ -0,0 +1,25 @@ +MIT лицензия + +Copyright (c) 2025 Evgeny Teterin (nayk) + +Данная лицензия разрешает лицам, получившим копию +данного программного обеспечения и сопутствующей документации +(в дальнейшем именуемыми «Программное Обеспечение»), безвозмездно +использовать Программное Обеспечение без ограничений, +включая неограниченное право на использование, копирование, изменение, +слияние, публикацию, распространение, сублицензирование и/или продажу +копий Программного Обеспечения, а также лицам, которым предоставляется +данное Программное Обеспечение, при соблюдении следующих условий: + +Указанное выше уведомление об авторском праве и данные условия +должны быть включены во все копии или значимые части данного Программного Обеспечения. + +ДАННОЕ ПРОГРАММНОЕ ОБЕСПЕЧЕНИЕ ПРЕДОСТАВЛЯЕТСЯ «КАК ЕСТЬ», +БЕЗ КАКИХ-ЛИБО ГАРАНТИЙ, ЯВНО ВЫРАЖЕННЫХ ИЛИ ПОДРАЗУМЕВАЕМЫХ, +ВКЛЮЧАЯ ГАРАНТИИ ТОВАРНОЙ ПРИГОДНОСТИ, СООТВЕТСТВИЯ ПО ЕГО КОНКРЕТНОМУ +НАЗНАЧЕНИЮ И ОТСУТСТВИЯ НАРУШЕНИЙ, НО НЕ ОГРАНИЧИВАЯСЬ ИМИ. +НИ В КАКОМ СЛУЧАЕ АВТОРЫ ИЛИ ПРАВООБЛАДАТЕЛИ НЕ НЕСУТ ОТВЕТСТВЕННОСТИ +ПО КАКИМ-ЛИБО ИСКАМ, ЗА УЩЕРБ ИЛИ ПО ИНЫМ ТРЕБОВАНИЯМ, В ТОМ ЧИСЛЕ, +ПРИ ДЕЙСТВИИ КОНТРАКТА, ДЕЛИКТЕ ИЛИ ИНОЙ СИТУАЦИИ, +ВОЗНИКШИМ ИЗ-ЗА ИСПОЛЬЗОВАНИЯ ПРОГРАММНОГО ОБЕСПЕЧЕНИЯ +ИЛИ ИНЫХ ДЕЙСТВИЙ С ПРОГРАММНЫМ ОБЕСПЕЧЕНИЕМ. diff --git a/README.md b/README.md index ba44bcd..966f310 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,27 @@ # Qt_Circular_Menu_Example -Пример реализации кругового меню на Qt Widgets \ No newline at end of file +Пример реализации кругового меню на Qt Widgets + +## Реализация + +Меню реализовано в виде отдельного виджета в библиотеке `lib_circular_menu`. + +Для применения в программе необходимо создать экземпляр класса `CircularMenu` и назначить список пунктов меню: + +``` +#include "circular_menu.h" +... + +QList menuActions; // заполнить список +... +CircularMenu *circularMenu = new CircularMenu(this); // родитель обязательно виджет +circularMenu->addActions(menuActions); +circularMenu->setHotKey(Qt::Key_Alt); + +``` + +## Внешний вид (Qt6, ОС Windows 11) + +![picture](/_resources/images/screenshot.png) + + diff --git a/_cmake/app_settings.cmake b/_cmake/app_settings.cmake new file mode 100644 index 0000000..3dd65b2 --- /dev/null +++ b/_cmake/app_settings.cmake @@ -0,0 +1,28 @@ + +# Файл для подключения в основной проект через include +# Настройки для приложений + +include(${CMAKE_CURRENT_LIST_DIR}/common.cmake) +include(${CMAKE_CURRENT_LIST_DIR}/developer.cmake) +include(${CMAKE_CURRENT_LIST_DIR}/version.cmake) + +# Имя выходного файла совпадает с названием проекта: +set(RUNTIME_OUTPUT_NAME ${PROJECT_NAME}) + +configure_file( + ${CMAKE_CURRENT_LIST_DIR}/config.h.in + ${CMAKE_CURRENT_BINARY_DIR}/config.h + @ONLY +) + +set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${DISTRIB_DIR}) +set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${DISTRIB_DIR}) + +if (CMAKE_SYSTEM_NAME STREQUAL "Windows") + configure_file( + ${CMAKE_CURRENT_LIST_DIR}/versioninfo.rc.in + ${CMAKE_CURRENT_BINARY_DIR}/versioninfo.rc + @ONLY + ) +endif() + diff --git a/_cmake/common.cmake b/_cmake/common.cmake new file mode 100644 index 0000000..4728977 --- /dev/null +++ b/_cmake/common.cmake @@ -0,0 +1,52 @@ + +# Общие настройки для всех типов проектов + +set(CMAKE_INCLUDE_CURRENT_DIR ON) +set(CMAKE_AUTOUIC ON) +set(CMAKE_AUTOMOC ON) +set(CMAKE_AUTORCC ON) + +if (CMAKE_COMPILER_IS_GNUCXX) + if (CMAKE_CXX_COMPILER_VERSION VERSION_LESS "9.0.0") + set(CMAKE_CXX_STANDARD 20) + else() + set(CMAKE_CXX_STANDARD 23) + endif() +else() + set(CMAKE_CXX_STANDARD 23) +endif() + +set(CMAKE_CXX_STANDARD_REQUIRED ON) + +# Поиск библиотек Qt: +find_package(QT NAMES Qt6 Qt5 REQUIRED) + +# Настройки каталогов: +include(${CMAKE_CURRENT_LIST_DIR}/setup_directories.cmake) + +# Определение разрядности: +if (${CMAKE_SIZEOF_VOID_P} STREQUAL 4) + set(DIR_PREFIX "32") +elseif (${CMAKE_SIZEOF_VOID_P} STREQUAL 8) + set(DIR_PREFIX "64") +endif () + +# Каталог для готовых приложений и библиотек после компиляции: +set(DISTRIB_DIR + ${ROOT_PROJECT_DIR}_distrib/${CMAKE_SYSTEM_NAME}_Qt${QT_VERSION}_${DIR_PREFIX}-bit +) + +if(CMAKE_BUILD_TYPE STREQUAL "Debug") + set(IS_DEBUG TRUE) + set(IS_RELEASE FALSE) +else() + set(IS_DEBUG FALSE) + set(IS_RELEASE TRUE) +endif() + +message(STATUS "Project '${PROJECT_NAME}' compiler ${CMAKE_CXX_COMPILER} version: ${CMAKE_CXX_COMPILER_VERSION}") +message(STATUS "Project '${PROJECT_NAME}' distrib dir: '${DISTRIB_DIR}'") +message(STATUS "Project '${PROJECT_NAME}' IS_RELEASE: ${IS_RELEASE}, IS_DEBUG: ${IS_DEBUG}") +message(STATUS "Project '${PROJECT_NAME}' CMAKE_PREFIX_PATH: '${CMAKE_PREFIX_PATH}'") +message(STATUS "Project '${PROJECT_NAME}' CMAKE_SYSTEM_LIBRARY_PATH: '${CMAKE_SYSTEM_LIBRARY_PATH}'") + diff --git a/_cmake/config.h.in b/_cmake/config.h.in new file mode 100644 index 0000000..41f8ac6 --- /dev/null +++ b/_cmake/config.h.in @@ -0,0 +1,9 @@ +#define PROG_NAME "@PROJECT_NAME@" +#define PROG_VERSION "@PROJECT_VERSION_MAJOR@.@PROJECT_VERSION_MINOR@.@PROJECT_VERSION_PATCH@.@BUILD_NUM@@PROJECT_VERSION_TWEAK@" +#define PROG_CAPTION "@PROJECT_NAME@ v" +#define PROG_DESCRIPTION "@PROJECT_DESCRIPTION@" +#define SOFT_DEVELOPER "@SOFT_DEVELOPER@" +#define DEVELOPER_DOMAIN "@DEVELOPER_DOMAIN@" +#define BUILD_DATE "@BUILD_DATE@" +#define BUILD_NUM "@BUILD_NUM@" +#define ORIGINAL_FILE_NAME "@ORIGINAL_FILE_NAME@" diff --git a/_cmake/copy_depends.cmake b/_cmake/copy_depends.cmake new file mode 100644 index 0000000..211a6a7 --- /dev/null +++ b/_cmake/copy_depends.cmake @@ -0,0 +1,289 @@ + +# Определение зависимостей после сборки приложения + +cmake_minimum_required(VERSION 4.0) + +set(LIBS_FIND_DIRS "${PREFIX}") +set(QT_SHARE_DIR "${PREFIX}") + +if (CMAKE_SYSTEM_NAME STREQUAL "Windows") + + if (EXISTS "${PREFIX}/bin") + set(LIBS_FIND_DIRS "${PREFIX}/bin") + endif() + +else() + + if (EXISTS "${PREFIX}/lib") + set(LIBS_FIND_DIRS "${PREFIX}/lib") + endif() + +endif() + +if (EXISTS "${PREFIX}/share/qt${QT_VERSION_MAJOR}") + set(QT_SHARE_DIR "${PREFIX}/share/qt${QT_VERSION_MAJOR}") +endif() + +if(TARGET_TYPE STREQUAL "EXECUTABLE") + + if (EXISTS "${OUTPUT_DIR}/${TARGET_NAME}") + set(TARGET_FILE "${OUTPUT_DIR}/${TARGET_NAME}") + elseif (EXISTS "${OUTPUT_DIR}/${TARGET_NAME}.exe") + set(TARGET_FILE "${OUTPUT_DIR}/${TARGET_NAME}.exe") + endif() + +else() + + if (EXISTS "${OUTPUT_DIR}/${TARGET_NAME}") + set(TARGET_FILE "${OUTPUT_DIR}/${TARGET_NAME}") + elseif (EXISTS "${OUTPUT_DIR}/${TARGET_NAME}.dll") + set(TARGET_FILE "${OUTPUT_DIR}/${TARGET_NAME}.dll") + elseif (EXISTS "${OUTPUT_DIR}/${TARGET_NAME}.so") + set(TARGET_FILE "${OUTPUT_DIR}/${TARGET_NAME}.so") + endif() + +endif() + +message(STATUS "TARGET_FILE: '${TARGET_FILE}'") +message(STATUS "LIBS_FIND_DIRS: '${LIBS_FIND_DIRS}'") +message(STATUS "OUTPUT_DIR: '${OUTPUT_DIR}'") +message(STATUS "QT_VERSION_MAJOR: '${QT_VERSION_MAJOR}'") +message(STATUS "Find and copy dependencies. Please, wait...") + +# functions -------------------------------------------------------------------- + +# Копирование файла + +function(safe_copy src dest) + + # Пытаемся скопировать через execute_process (кросс-платформенно) + execute_process( + COMMAND ${CMAKE_COMMAND} -E copy_if_different "${src}" "${dest}" + RESULT_VARIABLE copy_result + ERROR_VARIABLE copy_error + OUTPUT_QUIET # Подавляем stdout + ) + + if(NOT copy_result EQUAL 0) + message(WARNING "Не удалось скопировать ${src} -> ${dest}: ${copy_error}") + return() + endif() + +endfunction() + +# Отслеживание цепочки ссылок + +function(get_symlink_chain dep symlink_chain) + unset(chain) + set(current_dep "${dep}") + + # 1. Разрешаем основную цепочку симлинков (исходный файл → конечный файл) + while(IS_SYMLINK "${current_dep}") + execute_process( + COMMAND readlink "${current_dep}" + OUTPUT_VARIABLE link_target + OUTPUT_STRIP_TRAILING_WHITESPACE + ) + list(INSERT chain 0 "${current_dep}") # Добавляем текущий симлинк в начало + get_filename_component(parent_dir "${current_dep}" DIRECTORY) + set(current_dep "${parent_dir}/${link_target}") # Переходим по ссылке + endwhile() + + # 2. Добавляем конечный файл в начало цепочки + list(INSERT chain 0 "${current_dep}") + + # 3. Теперь ищем ВСЕ симлинки в этой директории, которые ссылаются на конечный файл + if(EXISTS "${current_dep}") + get_filename_component(final_file "${current_dep}" REALPATH) # Абсолютный путь конечного файла + get_filename_component(parent_dir "${current_dep}" DIRECTORY) # Директория конечного файла + + # Получаем список всех файлов в этой директории + file(GLOB all_files LIST_DIRECTORIES false "${parent_dir}/*") + foreach(file IN LISTS all_files) + # Если это симлинк, проверяем, ведёт ли он на конечный файл + if(IS_SYMLINK "${file}") + execute_process( + COMMAND readlink -f "${file}" # Абсолютный путь цели симлинка + OUTPUT_VARIABLE symlink_target + OUTPUT_STRIP_TRAILING_WHITESPACE + ) + # Если цель симлинка совпадает с конечным файлом, добавляем в цепочку + if(symlink_target STREQUAL final_file AND NOT file IN_LIST chain) + list(APPEND chain "${file}") + endif() + endif() + endforeach() + endif() + + set(${symlink_chain} "${chain}" PARENT_SCOPE) +endfunction() + +# ------------------------------------------------------------------------------ + +if (EXISTS "${TARGET_FILE}") + + # Получаем runtime-зависимости + file(GET_RUNTIME_DEPENDENCIES + EXECUTABLES ${TARGET_FILE} + RESOLVED_DEPENDENCIES_VAR RESOLVED_DEPS + UNRESOLVED_DEPENDENCIES_VAR UNRESOLVED_DEPS + DIRECTORIES ${LIBS_FIND_DIRS} + ) + + set(USE_SQL OFF) + set(USE_PRINT OFF) + set(USE_NETWORK OFF) + set(USE_SERIALPORT OFF) + set(USE_MULTIMEDIA OFF) + + message(STATUS "\nResolved dependencies copy:\n") + + foreach(DEP ${RESOLVED_DEPS}) + + string(FIND "${DEP}" "${LIBS_FIND_DIRS}" POS) + + if(POS EQUAL 0) + + if (CMAKE_SYSTEM_NAME STREQUAL "Windows") + + message(STATUS "${DEP}") + file(COPY "${DEP}" DESTINATION "${OUTPUT_DIR}") + + else () + + #message(STATUS "${DEP}") + #file(COPY "${DEP}" DESTINATION "${OUTPUT_DIR}/system_lib" FOLLOW_SYMLINK_CHAIN) + + get_symlink_chain("${DEP}" dep_chain) + + foreach(file IN LISTS dep_chain) + + message(STATUS "${file}") + safe_copy("${file}" "${OUTPUT_DIR}") + + endforeach() + + endif() + + endif() + + string(FIND "${DEP}" "Qt${QT_VERSION_MAJOR}Sql" POS) + + if(POS GREATER 0) + set(USE_SQL ON) + endif() + + string(FIND "${DEP}" "Qt${QT_VERSION_MAJOR}Print" POS) + + if(POS GREATER 0) + set(USE_PRINT ON) + endif() + + string(FIND "${DEP}" "Qt${QT_VERSION_MAJOR}Network" POS) + + if(POS GREATER 0) + set(USE_NETWORK ON) + endif() + + string(FIND "${DEP}" "Qt${QT_VERSION_MAJOR}Serial" POS) + + if(POS GREATER 0) + set(USE_SERIALPORT ON) + endif() + + string(FIND "${DEP}" "Qt${QT_VERSION_MAJOR}Multimedia" POS) + + if(POS GREATER 0) + set(USE_MULTIMEDIA ON) + endif() + + endforeach() + + if (EXISTS "${LIBS_FIND_DIRS}/libQt${QT_VERSION_MAJOR}XcbQpa.so") + + get_symlink_chain("${LIBS_FIND_DIRS}/libQt${QT_VERSION_MAJOR}XcbQpa.so" xcb_chain) + + foreach(file IN LISTS xcb_chain) + + message(STATUS "${file}") + safe_copy("${file}" "${OUTPUT_DIR}") + + endforeach() + + endif() + + message(STATUS "\nResolved dependencies not copy:\n") + + foreach(DEP ${RESOLVED_DEPS}) + string(FIND "${DEP}" "${LIBS_FIND_DIRS}" POS) + if(NOT POS EQUAL 0) + message(STATUS "${DEP}") + endif() + endforeach() + + message(STATUS "\nUnresolved dependencies:\n") + + foreach(DEP ${UNRESOLVED_DEPS}) + message(STATUS "${DEP}") + endforeach() + + if (EXISTS "${QT_SHARE_DIR}/plugins/platforms") + file(COPY "${QT_SHARE_DIR}/plugins/platforms" DESTINATION "${OUTPUT_DIR}") + endif() + + if (EXISTS "${QT_SHARE_DIR}/plugins/platformthemes") + file(COPY "${QT_SHARE_DIR}/plugins/platformthemes" DESTINATION "${OUTPUT_DIR}") + endif() + + if (EXISTS "${QT_SHARE_DIR}/plugins/styles") + file(COPY "${QT_SHARE_DIR}/plugins/styles" DESTINATION "${OUTPUT_DIR}") + endif() + + if (EXISTS "${QT_SHARE_DIR}/plugins/imageformats") + file(COPY "${QT_SHARE_DIR}/plugins/imageformats" DESTINATION "${OUTPUT_DIR}") + endif() + + if (USE_SQL AND (EXISTS "${QT_SHARE_DIR}/plugins/sqldrivers")) + file(COPY "${QT_SHARE_DIR}/plugins/sqldrivers" DESTINATION "${OUTPUT_DIR}") + endif() + + if (USE_PRINT AND (EXISTS "${QT_SHARE_DIR}/plugins/printsupport")) + file(COPY "${QT_SHARE_DIR}/plugins/printsupport" DESTINATION "${OUTPUT_DIR}") + endif() + + if (USE_NETWORK AND (EXISTS "${QT_SHARE_DIR}/plugins/networkinformation")) + file(COPY "${QT_SHARE_DIR}/plugins/networkinformation" DESTINATION "${OUTPUT_DIR}") + endif() + + if (USE_MULTIMEDIA AND (EXISTS "${QT_SHARE_DIR}/plugins/multimedia")) + file(COPY "${QT_SHARE_DIR}/plugins/multimedia" DESTINATION "${OUTPUT_DIR}") + endif() + + if (EXISTS "${QT_SHARE_DIR}/translations") + + file(MAKE_DIRECTORY "${OUTPUT_DIR}/translations") + + if (EXISTS "${QT_SHARE_DIR}/translations/qtbase_ru.qm") + file(COPY "${QT_SHARE_DIR}/translations/qtbase_ru.qm" DESTINATION "${OUTPUT_DIR}/translations") + endif() + + if (EXISTS "${QT_SHARE_DIR}/translations/qtdeclarative_ru.qm") + file(COPY "${QT_SHARE_DIR}/translations/qtdeclarative_ru.qm" DESTINATION "${OUTPUT_DIR}/translations") + endif() + + if (USE_SERIALPORT AND (EXISTS "${QT_SHARE_DIR}/translations/qtserialport_ru.qm")) + file(COPY "${QT_SHARE_DIR}/translations/qtserialport_ru.qm" DESTINATION "${OUTPUT_DIR}/translations") + endif() + + if (USE_MULTIMEDIA AND (EXISTS "${QT_SHARE_DIR}/translations/qtmultimedia_ru.qm")) + file(COPY "${QT_SHARE_DIR}/translations/qtmultimedia_ru.qm" DESTINATION "${OUTPUT_DIR}/translations") + endif() + + endif() + +else() + + message(STATUS "'${TARGET_FILE}' not found. Exit.") + +endif() + diff --git a/_cmake/developer.cmake b/_cmake/developer.cmake new file mode 100644 index 0000000..530fa4a --- /dev/null +++ b/_cmake/developer.cmake @@ -0,0 +1,8 @@ + +if(NOT DEFINED SOFT_DEVELOPER OR "${SOFT_DEVELOPER}" STREQUAL "") + set(SOFT_DEVELOPER "Evgeny Teterin") +endif() + +if(NOT DEFINED DEVELOPER_DOMAIN OR "${DEVELOPER_DOMAIN}" STREQUAL "") + set(DEVELOPER_DOMAIN "poseon.ru") +endif() diff --git a/_cmake/lib_settings.cmake b/_cmake/lib_settings.cmake new file mode 100644 index 0000000..324e71d --- /dev/null +++ b/_cmake/lib_settings.cmake @@ -0,0 +1,29 @@ + +# Файл для подключения в основной проект через include +# Настройки для библиотек + +include(${CMAKE_CURRENT_LIST_DIR}/common.cmake) +include(${CMAKE_CURRENT_LIST_DIR}/developer.cmake) +include(${CMAKE_CURRENT_LIST_DIR}/version.cmake) + +set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${DISTRIB_DIR}) +set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${DISTRIB_DIR}) + +if (CMAKE_SYSTEM_NAME STREQUAL "Windows") + set(RUNTIME_OUTPUT_NAME lib${PROJECT_NAME}.dll) + configure_file( + ${CMAKE_CURRENT_LIST_DIR}/versioninfo.rc.in + ${CMAKE_CURRENT_BINARY_DIR}/versioninfo.rc + @ONLY + ) +else() + set(RUNTIME_OUTPUT_NAME lib${PROJECT_NAME}.so) +endif() + +configure_file( + ${CMAKE_CURRENT_LIST_DIR}/config.h.in + ${CMAKE_CURRENT_BINARY_DIR}/config.h + @ONLY +) + + diff --git a/_cmake/post_build.cmake b/_cmake/post_build.cmake new file mode 100644 index 0000000..39c5ee3 --- /dev/null +++ b/_cmake/post_build.cmake @@ -0,0 +1,40 @@ + +# Файл для подключения в основной проект через include + +# Вспомогательные действия после сборки проекта + +if(IS_DEBUG) + message(STATUS "Project '${PROJECT_NAME}' [post-build] DEBUG building: skip post-build actions") + return() +endif() + +# Включение/выключение поиска зависимостей: +set(COPY_DEPENDS ON) + +get_target_property(TARGET_TYPE ${PROJECT_NAME} TYPE) + +if(TARGET_TYPE STREQUAL "EXECUTABLE") + message(STATUS "${PROJECT_NAME} is an executable.") +elseif(TARGET_TYPE STREQUAL "STATIC_LIBRARY" OR TARGET_TYPE STREQUAL "SHARED_LIBRARY") + message(STATUS "${PROJECT_NAME} is a library.") +else() + message(STATUS "${PROJECT_NAME} is of another type: ${TARGET_TYPE}") +endif() + +if (COPY_DEPENDS) + + add_custom_command(TARGET ${PROJECT_NAME} POST_BUILD + COMMAND ${CMAKE_COMMAND} -E echo "Copying runtime dependencies..." + COMMAND ${CMAKE_COMMAND} + -DTARGET_NAME="${RUNTIME_OUTPUT_NAME}" + -DTARGET_TYPE="${TARGET_TYPE}" + -DOUTPUT_DIR="${DISTRIB_DIR}" + -DPREFIX="${CMAKE_PREFIX_PATH}" + -DQT_VERSION_MAJOR=${QT_VERSION_MAJOR} + -DCMAKE_SYSTEM_NAME="${CMAKE_SYSTEM_NAME}" + -P "${CMAKE_INC_DIR}/copy_depends.cmake" + COMMENT "Copying runtime dependencies for ${PROJECT_NAME}" + ) + +endif() + diff --git a/_cmake/setup_directories.cmake b/_cmake/setup_directories.cmake new file mode 100644 index 0000000..99adfb9 --- /dev/null +++ b/_cmake/setup_directories.cmake @@ -0,0 +1,25 @@ + +set(ROOT_PROJECT_DIR + ${CMAKE_CURRENT_LIST_DIR}/.. +) + +cmake_path(NORMAL_PATH ROOT_PROJECT_DIR OUTPUT_VARIABLE ROOT_PROJECT_DIR) + +set(CMAKE_INC_DIR + ${ROOT_PROJECT_DIR}_cmake +) + +set(RESOURCES_DIR + ${ROOT_PROJECT_DIR}_resources +) + +set(COMMON_SOURCES_DIR + ${ROOT_PROJECT_DIR}_include +) + +if(CMAKE_SYSTEM_NAME STREQUAL "Windows") + set(SYSTEM_INCLUDE_DIR "${CMAKE_PREFIX_PATH}/include") +else () + set(SYSTEM_INCLUDE_DIR "/usr/include") +endif () + diff --git a/_cmake/target_options.cmake b/_cmake/target_options.cmake new file mode 100644 index 0000000..a8a8890 --- /dev/null +++ b/_cmake/target_options.cmake @@ -0,0 +1,55 @@ + +# Файл для подключения в основной проект через include + +# Настройки компиляции для всего + +if (DISABLE_HARD_WARNING_ERROR) + target_compile_options(${PROJECT_NAME} PRIVATE + -Wall + -Wextra + -Wpedantic + ) +else() + target_compile_options(${PROJECT_NAME} PRIVATE + -Wall # Все стандартные предупреждения + -Wextra # Дополнительные предупреждения + -Wpedantic # Соответствие стандарту C++ + -Werror # Превратить предупреждения в ошибки + -Wconversion # Предупреждения о неявных преобразованиях + -Wsign-conversion # Предупреждения о знаковых/беззнаковых преобразованиях + -Wshadow # Предупреждения о "тенях" переменных + -Wunused # Предупреждения о неиспользуемом коде + -Wold-style-cast # Запрет C-style кастов (только static_cast/dynamic_cast/...) + -Wnull-dereference # Предупреждения о возможных разыменованиях nullptr + -Wdouble-promotion # Предупреждения о неявном преобразовании float → double + -Wformat=2 # Строгая проверка printf/scanf + ) +endif() + +target_compile_definitions(${PROJECT_NAME} PRIVATE + QT_NO_FOREACH + QT_NO_URL_CAST_FROM_STRING + QT_NO_NARROWING_CONVERSIONS_IN_CONNECT + QT_STRICT_ITERATORS +) + +find_program(CLANG_TIDY_EXE NAMES "clang-tidy") + +if (CLANG_TIDY_EXE) + set(CMAKE_CXX_CLANG_TIDY "${CLANG_TIDY_EXE};-checks=*") +endif() + +if (CMAKE_BUILD_TYPE STREQUAL "Debug" OR CMAKE_BUILD_TYPE STREQUAL "RelWithDebInfo") + target_compile_options(${PROJECT_NAME} PRIVATE + -fsanitize=address # AddressSanitizer (поиск утечек, выходов за границы) + -fsanitize=undefined # UndefinedBehaviorSanitizer (UB-проверки) + -fsanitize=leak # LeakSanitizer (поиск утечек памяти) + -fno-omit-frame-pointer # Для лучшего стека вызовов в санитайзерах + ) + target_link_options(${PROJECT_NAME} PRIVATE + -fsanitize=address + -fsanitize=undefined + -fsanitize=leak + ) +endif() + diff --git a/_cmake/update_translations.cmake b/_cmake/update_translations.cmake new file mode 100644 index 0000000..f21186f --- /dev/null +++ b/_cmake/update_translations.cmake @@ -0,0 +1,70 @@ + +# Файл для подключения в основной проект через include + +# Обновление и генерация файлов переводов +# Языки переводов перечислить в переменной LNG + +if(IS_DEBUG) + message(STATUS "Project '${PROJECT_NAME}' [translations] DEBUG building: skip .qm generation") + return() +endif() + +# Если список языков не задан в основном CMakeLists.txt — применяем по умолчанию +if(NOT DEFINED LNG) + set(LNG en ru) + message(STATUS "Project '${PROJECT_NAME}' [translations] LNG not set, use default: ${LNG}") +else() + message(STATUS "Project '${PROJECT_NAME}' [translations] Use LNG: ${LNG}") +endif() + +# Подключить LinguistTools +find_package(Qt${QT_VERSION_MAJOR}LinguistTools REQUIRED) + +# Полные пути утилит +get_target_property(LUPDATE_EXECUTABLE Qt${QT_VERSION_MAJOR}::lupdate IMPORTED_LOCATION) +get_target_property(LRELEASE_EXECUTABLE Qt${QT_VERSION_MAJOR}::lrelease IMPORTED_LOCATION) + +# Каталог генерации файлов ts и qm файлов +set(TRANSLATIONS_DIR "${CMAKE_CURRENT_SOURCE_DIR}/translations") +set(QM_OUTPUT_DIR "${DISTRIB_DIR}/translations") +file(MAKE_DIRECTORY "${TRANSLATIONS_DIR}") +file(MAKE_DIRECTORY "${QM_OUTPUT_DIR}") + +# Список TS файлов в зависимости от списка языков +set(TS_FILES "") + +# Обновление каждого файла с добавлением в список +foreach(LANG ${LNG}) + + set(TS_FILE "${TRANSLATIONS_DIR}/${PROJECT_NAME}_${LANG}.ts") + list(APPEND TS_FILES "${TS_FILE}") + message(STATUS "Project '${PROJECT_NAME}' Update translation file: ${TS_FILE}") + + execute_process(COMMAND ${LUPDATE_EXECUTABLE} + ${PROJECT_SOURCES} + -ts ${TS_FILE} + WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} + ) + +endforeach() + +# Генерация файлов qm +set(QM_FILES "") + +foreach(TS ${TS_FILES}) + + get_filename_component(TS_NAME_WE ${TS} NAME_WE) + set(QM ${QM_OUTPUT_DIR}/${TS_NAME_WE}.qm) + list(APPEND QM_FILES ${QM}) + + add_custom_command( + OUTPUT ${QM} + COMMAND ${LRELEASE_EXECUTABLE} ${TS} -qm ${QM} + DEPENDS ${TS} + COMMENT "Generating ${QM}" + ) +endforeach() + +add_custom_target(translations_qm ALL DEPENDS ${QM_FILES}) + +add_dependencies(translations_qm ${PROJECT_NAME}) diff --git a/_cmake/version.cmake b/_cmake/version.cmake new file mode 100644 index 0000000..c320df2 --- /dev/null +++ b/_cmake/version.cmake @@ -0,0 +1,52 @@ + +# Variables for generating the version. +# Used in the application (config.h file and versioninfo.rc) +# + +# Получаем полный временной штамп в UTC (пример: "2025-04-16 12:33:58 UTC") +string(TIMESTAMP BUILD_DATE "%Y-%m-%d %H:%M:%S UTC" UTC) +string(TIMESTAMP VERSION_DOY "%j" UTC) # день в году (001..366) + +# Извлекаем компоненты даты и времени +string(SUBSTRING "${BUILD_DATE}" 0 4 YEAR_STR) +string(SUBSTRING "${BUILD_DATE}" 2 2 VERSION_YY) +string(SUBSTRING "${BUILD_DATE}" 5 2 VERSION_MM) +string(SUBSTRING "${BUILD_DATE}" 8 2 VERSION_DD) +string(SUBSTRING "${BUILD_DATE}" 11 2 VERSION_HH) +string(SUBSTRING "${BUILD_DATE}" 14 2 VERSION_MIN) +string(SUBSTRING "${BUILD_DATE}" 17 2 VERSION_SS) + +# Убираем ведущие нули путём преобразования в числа +math(EXPR VERSION_YY_NOZERO "${VERSION_YY}") +math(EXPR VERSION_MM_NOZERO "${VERSION_MM}") +math(EXPR VERSION_DD_NOZERO "${VERSION_DD}") +math(EXPR VERSION_HH_NOZERO "${VERSION_HH}") +math(EXPR VERSION_MIN_NOZERO "${VERSION_MIN}") +math(EXPR VERSION_SS_NOZERO "${VERSION_SS}") +math(EXPR VERSION_DOY_NOZERO "${VERSION_DOY}") + +if (VERSION_FULLDATE) + # Полная дата: YY.MM.DD.NNN + + # Считаем количество минут с начала суток + math(EXPR VERSION_NNN + "${VERSION_HH_NOZERO} * 60 + ${VERSION_MIN_NOZERO}" + ) + + set(PROJECT_VERSION_MAJOR ${VERSION_YY_NOZERO}) + set(PROJECT_VERSION_MINOR ${VERSION_MM_NOZERO}) + set(PROJECT_VERSION_PATCH ${VERSION_DD_NOZERO}) + set(BUILD_NUM ${VERSION_NNN}) + +else() + # Версия от MAJOR, MINOR + YY + день года + # MAJOR и MINOR должны быть заданы ранее через `project(... VERSION ...)` + + set(PROJECT_VERSION_PATCH ${VERSION_YY_NOZERO}) + set(BUILD_NUM ${VERSION_DOY_NOZERO}) +endif() + +set(ORIGINAL_FILE_NAME ${RUNTIME_OUTPUT_NAME}) + +message(STATUS "Project '${PROJECT_NAME}' version: ${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR}.${PROJECT_VERSION_PATCH}.${BUILD_NUM}") + diff --git a/_cmake/versioninfo.rc.in b/_cmake/versioninfo.rc.in new file mode 100644 index 0000000..14c4204 --- /dev/null +++ b/_cmake/versioninfo.rc.in @@ -0,0 +1,35 @@ +1 TYPELIB "versioninfo.rc" + +1 VERSIONINFO + FILEVERSION @PROJECT_VERSION_MAJOR@, @PROJECT_VERSION_MINOR@, @PROJECT_VERSION_PATCH@, @BUILD_NUM@ + PRODUCTVERSION @PROJECT_VERSION_MAJOR@, @PROJECT_VERSION_MINOR@, @PROJECT_VERSION_PATCH@, @BUILD_NUM@ + FILEFLAGSMASK 0x3fL +#ifdef _DEBUG + FILEFLAGS 0x1L +#else + FILEFLAGS 0x0L +#endif + FILEOS 0x4L + FILETYPE 0x2L + FILESUBTYPE 0x0L +BEGIN + BLOCK "StringFileInfo" + BEGIN + BLOCK "040904e4" + BEGIN + VALUE "CompanyName", "@SOFT_DEVELOPER@" + VALUE "FileDescription", "@PROJECT_DESCRIPTION@" + VALUE "FileVersion","@PROJECT_VERSION_MAJOR@.@PROJECT_VERSION_MINOR@.@PROJECT_VERSION_PATCH@.@BUILD_NUM@" + VALUE "InternalName", "@PROJECT_NAME@" + VALUE "LegalCopyright", "Copyright (c) @YEAR_STR@ @SOFT_DEVELOPER@" + VALUE "OriginalFilename", "@ORIGINAL_FILE_NAME@" + VALUE "ProductName", "@PROJECT_NAME@" + VALUE "ProductVersion","@PROJECT_VERSION_MAJOR@.@PROJECT_VERSION_MINOR@.@PROJECT_VERSION_PATCH@.@BUILD_NUM@" + VALUE "BuildDate", "@BUILD_DATE@" + END + END + BLOCK "VarFileInfo" + BEGIN + VALUE "Translation", 0x409, 1252 + END +END diff --git a/_include/application_config.cpp b/_include/application_config.cpp new file mode 100644 index 0000000..b5f0791 --- /dev/null +++ b/_include/application_config.cpp @@ -0,0 +1,159 @@ +/**************************************************************************** +** Copyright (c) 2025 Evgeny Teterin (nayk) +** All right reserved. +** +** Permission is hereby granted, free of charge, to any person obtaining +** a copy of this software and associated documentation files (the +** "Software"), to deal in the Software without restriction, including +** without limitation the rights to use, copy, modify, merge, publish, +** distribute, sublicense, and/or sell copies of the Software, and to +** permit persons to whom the Software is furnished to do so, subject to +** the following conditions: +** +** The above copyright notice and this permission notice shall be +** included in all copies or substantial portions of the Software. +** +** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +** NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +** LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +** OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +** WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +** +****************************************************************************/ +#include "application_config.h" +#include "config.h" +#include +#include +#include +#include +#include +#include + +#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0) +# include +#endif + +//============================================================================== +void Application::initialize() +{ +#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0) + QTextCodec::setCodecForLocale(QTextCodec::codecForName("UTF-8")); +#endif + +#if defined (PROG_NAME) + QApplication::setApplicationName( QString(PROG_NAME) ); +#endif + +#if defined (SOFT_DEVELOPER) + QApplication::setOrganizationName( QString(SOFT_DEVELOPER) ); +#endif + +#if defined (DEVELOPER_DOMAIN) + QApplication::setOrganizationDomain( QString(DEVELOPER_DOMAIN) ); +#endif + +#if defined (PROG_VERSION) + QApplication::setApplicationVersion( QString(PROG_VERSION) ); +#endif + +#if defined (BUILD_DATE) + qApp->setProperty( "buildDate", QString(BUILD_DATE) ); +#endif +} +//============================================================================== +QString Application::applicationRootPath() +{ + QString path { QApplication::applicationDirPath() }; + + if ( path.right(1) != "/" ) { + + path += "/"; + } + + if (path.right(5) == "/bin/") { + + path.remove( path.length() - 4, 4 ); + } + + return path; +} +//============================================================================== +void Application::installTranslations(const QString &lng) +{ + const QString dirName { applicationRootPath() + "translations/" }; + QDir translationsDir { dirName }; + + QStringList filesList = translationsDir.entryList( + QStringList() << QString("*_%1.qm").arg(lng), + QDir::Files + ); + + for (const QString &fileName: std::as_const(filesList)) { + + QTranslator *translator = new QTranslator(QApplication::instance()); + + if (translator->load( dirName + fileName )) { + + QApplication::instance()->installTranslator( translator ); + } + else { + + delete translator; + } + } +} +//============================================================================== +QWidget* mainWindow() +{ + QWidgetList list = QApplication::topLevelWidgets(); + + for ( auto widget : std::as_const(list) ) { + + if (widget && QString(widget->metaObject()->className()).contains("MainWindow")) + return widget; + } + + return list.isEmpty() ? nullptr : list.first(); +} +//============================================================================== +bool Application::moveToCenterMainWindow(QWidget *w) +{ + if (!w) return false; + + QRect targetRect; + QWidget *mainW = mainWindow(); + + if (mainW && mainW->isVisible()) { + + targetRect = mainW->geometry(); + } + else { + + QScreen *screen = mainW ? mainW->screen() : nullptr; + + if (mainW && !screen) { + + QPoint pos = mainW->geometry().center(); + screen = QGuiApplication::screenAt(pos); + } + + if (screen) { + + targetRect = screen->geometry(); + } + } + + if (targetRect.isValid()) { + + QSize dialogSize = w->size(); + QPoint centerPos = targetRect.center() - QPoint(dialogSize.width() / 2, dialogSize.height() / 2); + w->move(centerPos); + return true; + } + + return false; +} +//============================================================================== + diff --git a/_include/application_config.h b/_include/application_config.h new file mode 100644 index 0000000..bedc942 --- /dev/null +++ b/_include/application_config.h @@ -0,0 +1,47 @@ +/**************************************************************************** +** Copyright (c) 2025 Evgeny Teterin (nayk) +** All right reserved. +** +** Permission is hereby granted, free of charge, to any person obtaining +** a copy of this software and associated documentation files (the +** "Software"), to deal in the Software without restriction, including +** without limitation the rights to use, copy, modify, merge, publish, +** distribute, sublicense, and/or sell copies of the Software, and to +** permit persons to whom the Software is furnished to do so, subject to +** the following conditions: +** +** The above copyright notice and this permission notice shall be +** included in all copies or substantial portions of the Software. +** +** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +** NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +** LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +** OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +** WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +** +****************************************************************************/ +#pragma once +#ifndef APP_CONFIG_H +#define APP_CONFIG_H + +#include +#include + +//============================================================================== +class Application +{ + Q_DISABLE_COPY(Application) + +public: + static void initialize(); + static QString applicationRootPath(); + static void installTranslations(const QString &lng = "ru"); + static bool moveToCenterMainWindow(QWidget *w); +private: + Application() = delete; +}; + +#endif // APP_CONFIG_H +//============================================================================== diff --git a/_resources/icons.qrc b/_resources/icons.qrc new file mode 100644 index 0000000..1f177ec --- /dev/null +++ b/_resources/icons.qrc @@ -0,0 +1,12 @@ + + + icons/cancel-40.png + icons/change-theme-40.png + icons/close-40.png + icons/ok-40.png + icons/opened-folder-40.png + icons/restart-40.png + icons/save-as-40.png + icons/shutdown-40.png + + diff --git a/_resources/icons/cancel-40.png b/_resources/icons/cancel-40.png new file mode 100644 index 0000000000000000000000000000000000000000..13885e5f81bc702118b4ea4bd2e957407e96d91d GIT binary patch literal 1039 zcmV+q1n~QbP)_U^^N?#w7{(?rEYZL0nQ zLKS;bQS{=$RsW6NO^;r*%)&*CQfSf^HSto5iMz0eu9@bG2r3G*{F3w~FCj4Oelqjs zz3+Q2*Z*qV?S2(e)yY_Q_ZOY9G$$k*Q4|}F&w6+FFZ>oEWCCkj0=3!M`H&OxNvHHM z=Jgt>u`%l?7!;ZLd0{RsiQMvX-tigV9ZgM%)aYmqYdK>FTvdY`U0odw2ixfCy3Z*M z>Vz1H;oMf}PwIl>it%{#iqeomyR5eTZ-~VI_7Y!&D=Tb`cBTy3LLktD32?`;b!4N zG$ZD$YBA~e+d8GminklrKkoCLwi?bVc)Y*g)CrlmH3=inNu`q2)pK8we7WTMlWqWtGYHZIB25clmViA9na26!Cjaw0SUO` zdI?BW9G$WKtGnlRze2r4Ns`%(%Vt-Abh5VSnkJ%Nuen9YixQx!22uEBV@l@5b}euP zhrr;f8Ylun7D1Ibxp9>M>^k7!V2LueUIdIXmWDiX0(cvUT_+qo6AFnKV?RnqOsNSC z=M>Po0kU2=xUsY(IHg7@K`V-#lei#GAnh9A;MwJ6l)k^s1>D z783TvPJjR1NPbNd@xDHjQ(96nw=_*DG}WyJJQyFhIb+{G`+WCYl?>wuw18-;TLpKF zwv$rC-XoWcVI093%Qj*bW63m1j6tBjb~!POBhc}qscz=Z>5OF~guHjvVi-r@xDWjP z#>S+koyQ!drsJKvZWu?Py!Wh literal 0 HcmV?d00001 diff --git a/_resources/icons/change-theme-40.png b/_resources/icons/change-theme-40.png new file mode 100644 index 0000000000000000000000000000000000000000..84a31757df853022bd1cb3896dc0d35df24a8b5c GIT binary patch literal 237 zcmeAS@N?(olHy`uVBq!ia0vp^8X(NU1|)m_?Z^dEoCO|{#S9GG!XV7ZFl&wkP;kDd zi(^Q|oVU{rxf%?3T#GNwSyaJUzWkoEz%CK~M>95>U)bBR(Q)yk{~xwH$=lms5ONgn zOx|8Ki$P-I19oc*-IGUo4m@S$+;nN-UhkhzDjAG~OiB!RHm^R(bff?1QN{*kA)no{ zXEyD!h_L2x$n@AyHg~}`j-67`rz;u0m8(`fIqtrOv!RKF+p0oCr}Iy)=cez)-ogw| hn^@%kmN}(dW@AjuWIg4-^EA+@44$rjF6*2UngGf!Rxbbm literal 0 HcmV?d00001 diff --git a/_resources/icons/close-40.png b/_resources/icons/close-40.png new file mode 100644 index 0000000000000000000000000000000000000000..b0098afe1ecb86aa3741e0dee7fd0b0bb899d6b6 GIT binary patch literal 487 zcmV)b_n11;=E$rTI+ z&&OIH7*&a^S;<}NV>D8@*T()#6-iMt$r4fv_pSZLxs~=?thQCB{Z>IP$bN8~FQm$$ djl0BOiBBr)E4hw2@w@;4002ovPDHLkV1gh9*fjtE literal 0 HcmV?d00001 diff --git a/_resources/icons/ok-40.png b/_resources/icons/ok-40.png new file mode 100644 index 0000000000000000000000000000000000000000..81a445c61a8871ab91ff52d2add4b00891783895 GIT binary patch literal 1100 zcmV-S1he~zP)WW&!4IIu6DLbM?X+A)T4tjO zVq7j>>T&>PgA^Cq%3`E2LQ=&QK5$!sAgvLz_~M^s@E_b8F+z_U$(3X7cwg8d8=R`{j1 z!Gv*nBKfoLWs2N?GfEzPo+OitPb|fMT<&1H$E&p6g8eVPo-Wk}c94U>{t1D3}-J%J1M@<+ld|0$liZe-q# zy8_c}G`%oRIx^Rcu)=>lFLoZT3yzZ6b0L{C?>tw3*9)dq=&f1hcSzz)e?NP+Cb(9a z3DPQGxHtdMQ!s6v;@x3YChQuCp%i}EwwR+spa?e_BEK|C-u?Kn<$Ylk#hi<8wxGf<4ZY4b9L`uV3FQ42kf~Q0 zLMy_z4RC1Y=&fi;je~nej1|LzGgk^0tle{9h^k$tUyL1J1q_Hx9F2dc;k2^$OeBjz ziD_R2j1DAnm`Zj7oTkqZute3a$E$#}!s`#-jO+?HO`jq6=SN6npzF)J`p21=;dTR@ zrq7T^pK~N6bH-YU5t-8D;`RxG^5En{`E}WfUpH{j$*)gHKw^Hm0z_GG^1*zaaJGO> zTwLk0r#2tX*WuQxE_RwE)gbd8!PzDWwl6F=wFLjurCCqmpuI0rB%%syWd=)3kBdTG z8D~bFF;}UVCXz);WG}3BlK%LKsLNKj9@0xVFtiOM%s?M=Y(qcB@{QHd&CBv-*LvaB zf0~-J85STIaj>_#ePP~;L2uyxjawL;HvwWu#8QnV#;cEME_L|rD4`T?**_TDw+XOp z#g16|+K!C;Q~ES%AHHI4m||>~CWZfqrMlUGH)rKiSmxfh47cp@RTCUXptCe{?HqcY zB_WwNDY^5Y&xznTBCPO*X2fIq?HHjIz8DnQ(>^zX;|Lr}V5x4TC;xs!L6<>w;7Ti+XZ3vC?UO Se9Kn=0000qT-l$$#siwm)^Bc-H|d9Hq4bXEz%A3_q?urcBZmIve~g;j_Z)MWX4ve<1C#F zVV}R*N1wc=XrZB^7USwA3O~&lrcS7l4qtpVi|I%F)6xTb>YBdwz4KGeZjQOI zW~V_@cjeotN!@onJE|i!jxKxfw~Se;+|D=3I+F3?>1l=sPCbl?&Y$^(|6p)tsIfta z=4J-N@_HHOJ@+;r3e52N%x-oo$1v+JpY?As!vm8H7}Gl?A2qye_^JCQp~~>UpKBU- zo=@vwcC);Eep~a~gA9}RIab)kDszSJ|Ku>mxGpL9dqvLllMkIQojc~XolTqZ^vcW| z-}#0A@0pad;kZgt!}CR~T#4MVKpAf9#|4vTEkB*0nvhn^BFBBYL~;$w6!q6nFZoVC z$ninZn0ryXYF*XVv}QpCU14=o=^lp6nLCm;ALN)Yt<&2a#GSFDZ5EK**13AMB$zu3 z!kv7DXPWTCo)DiH!z9)-36_TZ-batfvYcs<)Ny~%GwZ+6Cs{G$h<-Wdn}3)ZE*k`f T#ypb-Ml^$`tDnm{r-UW|=U3WJ literal 0 HcmV?d00001 diff --git a/_resources/icons/restart-40.png b/_resources/icons/restart-40.png new file mode 100644 index 0000000000000000000000000000000000000000..a49c9ffbbb85260ad1791196d06772235d74cd71 GIT binary patch literal 1554 zcmV+t2JQKYP)lhR?)g9Kay=l2h!GT?5tT8IsG2h^MpVbs$>2ow8+V2B z5m#~OSw}#!qUz-djjnIGVg~e^(=Lyw{gW0Tro)ASjtD2|cX&+CdPF7H8IU+VNY5+) zE06qbR%^qi&~V9IwBcA75#xee&~oMt;EENeALS&iwV?9n(SUvw-6K4v=RM^=J~>BlO^o&v#{nwl*4*AC#t0=9^IE`1vp7=;m9i-(YuRkJ7OTq`e<+=glTm~;2^@h z{!nC-k`Mv{3o6?ptfcSF&u>})e4M240Ma9*&x5H1T0&TFD5yLhv4X4$UNd=O#5ghd z#>@ipn-(Cf4~h+!l3utpa3T&am7kLoo)wk5t~rtU5F*BbqT0@g)j}2f2TVlh#aXMz z;*D*$tUmH-{e^Lewsa|h5fwI@)P*oTw{GvnaqC?leswJD7PNQM9^{G9E$kmms9w2d zB21&XQt)NhJQE}73lXLfxMT9Z^6&e>)E(0v$Q6UnbCQ0$T1zD3)jN9bLIk=TB90jQ z)_&JJmT;#VCX#3j@~@4V6_l0Bx1Newea}mbh!fhIB#)rI#*N-Dfh(1G zOb>jv_u>?z+%yE{9dJ2JJf?q4=2Tc^d-_Zy(?&ZZG5Y1^Kdr%G@|f;&9H6Avm(}-8 z-AkH=zz=(Ej2zZ)Rt6L0XyvzEx54aA1N4Z>+Ev@SrpoDt!+(M0uG$z`Q5~&T69H0G z(|*e%XnBqU6oQM2Hg|@tMS=CHckGNlZPXgU#am8>8K1J)aezK;3EX9kWKfokk(2Z= zl$=S%lDh6OMo`x|4p3CeOSbn+r5fmZIEmh}G4lBT2@-_qZflT0_TY)}tBui1jKk&o z5@`lPpTqRB^8od$)-+STuix~_p@TL?kDz|CeCw&GwKnGYLt#!*UUdo_Bk2qC{YR(# zFYfzWPevI*DYh}c?^9mlu@SQdO6iVsBOKQEI|UG7+PG%t`O&0OhiQ!U(HEyZz!Q4b z+G;^h2os$XT4bPEAT(<2JE2kGiP4qz5ahjr%C;nxLz@n*(R*vO$L9-Nj@kzq7w@-U3vlmMG?q!>kUkD)K)g0E( zLz|S9&q?$bkYNP}3kEbK(YlOlj?K#Dpn87 z#%Jd=c1{lNFhH%IW^f1dLwd;bhr&prSD+d|S%kU@3-<60l5n2?Xc%~{E@K6Uus)Dm zp*%e&a8{5or+~SqyC5)8aiCPKuIm|tq7Mu9@a@Y()BoWFJ_qwLBF34l!KKWyJ7HE9 z8k3_tki~*%1z9XMw$ItDGZ8BU-v*OIo)j7e<5@qDAt>MlV2d}lg&~zNg8HV*34%Nc zvon|mkx&$BH_S0|^H97^y7%|ojrbnE!EeP|PDY`8@x(ao7F2H5JU3qi^^y^kVlOcc zLVE-~9P86YV8Nc3jXs{xW{;>XL!WCe{3oCukjqa00;CO5b?Pc(od5s;07*qoM6N<$ Ef-&jnrT_o{ literal 0 HcmV?d00001 diff --git a/_resources/icons/save-as-40.png b/_resources/icons/save-as-40.png new file mode 100644 index 0000000000000000000000000000000000000000..547c840a17307d8c9a73fa757ffe5bf12185c248 GIT binary patch literal 840 zcmV-O1GoH%P)(bdXE|{Zx@m z0{v8wOauL?kpBX3MrVhw_yR`Q9E`Eq7B7c$BBwy_U*P-quszeF``QhJ#A0kqrI_RM zqcJ2UV58WUa8buD+e~q^{^ejUehZn3gvnqEKMFt`1%nD@+OK=~>)E zO3K?vWTroLf+`gpj@iB57PA($%_dAPZD4rjD~bFhZ$L;QftSr*qXf)Vyze_8QMBTf za|{b>VKVN|%aF)5u=B4+Mp&#Xi~+|TMhuxRVP#&8nkFr}-P0s+^2-LQ8w_}UU-W_U zw>bMa6N!tisDO|G-vS*ZGB(L4EoM{`I;3^YC~z#QpFQ7_;4iNyN!))JjAmKhs*r$UQhnA+%5MD0K`xYW+VGl*J|6|EPs2vVZ>rz~joxtbPM_h3jqb SEQ6^40000E|HP)YGHO-Y+n%Lt#@PM9m4p z!BF57LdF!vs)(iC2B-a_u&q#9l?fRQ>^XqLaroWLn4jkj!S5hPt}wRwt0)fojyW7_ zP|q150X98Jh^i3sg(o;<77`*%%o%+Egcgq+sVj{A?wQ@75@cAIcry9~2z?QY!HZc} z5(YH`=$w?$l*^$gqAwa^e;8H1WE-&u@SXc-QP``AE zbJOJJvuBPU*wB~5!zwCH7eJJ+w;mP3xP6CgZPok*1yl zu;eA_CmSGRt8T=s&&=3HH#S_28h&UdmEzl_lKrvg&pWPrH!;EUl>TWSF(E2?IH$$6 z8#kH;&84NjdC**1vP1FeRmU}zsVOcqR%rsviK2-{({bauIeX)K_xc8C+`n(Ho11f7 zQ=OjXG9iXPfOqfu0;u`aPyjuT_}Vr5hzo_j0h(cs*mshYN}g3f>!qDZGBe|vBn8I) zXs4O6F?XY?Y8#!M4GmDAowYx-TB=0q{w znk3(Ombx=%dX_q^S8@a?br@3x;hXkmfw8sq0L_90GVQ~Y>2y0dynFMeXR`n--R%}3 zr!cpA1vpxzR;d?@J2B}LOR1Fgto2weCV2YPyWJWZsvzXL0HR4mv*)2#kQf$If(` z>*vl{Rl&G($MRI|`gOi__N;F@dW*!M6yE#X6I}DC1>qnj{vd<97E&=N;kr(y^!rE< z!F2>cdd(?Xp9;@e_lk@qB4GsA5pX?*>fHucOe9R$4(z#3!F2>Cehk$(j=qmHndHl{ zSOp2;JLYk2p?-?VBgW2>kT|H>7xlc1Q(qL@)AoyUNKrWc(#6u;5Wp=H7vSrotiD4_le Z`2fLOTJ@8?y^;U`002ovPDHLkV1fkwZA<_F literal 0 HcmV?d00001 diff --git a/_resources/images/main_icon.png b/_resources/images/main_icon.png new file mode 100644 index 0000000000000000000000000000000000000000..5770cc449ea2d5591c392cde89172247a93e5fec GIT binary patch literal 410 zcmV;L0cHM)P)?Uw8Cgd+{x?0#IXXn-U<@K1d&mmD(Km5)V8X!BB@p6obc+N8T4-tTJrEkXiDQ-Oe#l29A7k~^ z!ayGA79Q<*)7ZfMng)dlok_$hWeu#Qu>k-80P!FA1D0C#{UmF7@c;k-07*qoM6N<$ Ef*7!@8UO$Q literal 0 HcmV?d00001 diff --git a/_resources/images/main_title.png b/_resources/images/main_title.png new file mode 100644 index 0000000000000000000000000000000000000000..b0edb75308c671027b78da604ad7c043b525ac80 GIT binary patch literal 5469 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 MYplc2I)CYZ006#56#xJL literal 0 HcmV?d00001 diff --git a/_resources/images/screenshot.png b/_resources/images/screenshot.png new file mode 100644 index 0000000000000000000000000000000000000000..bcbf5831f9de6a34f21f4ed18054e1e605969825 GIT binary patch literal 113818 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 hE^NCBDO3fXv0AsLn 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%0AD@GD`YU3IZ(6h%FO+}Ct?wFwwXAku5EY;w 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 literal 0 HcmV?d00001 diff --git a/_resources/main.ico b/_resources/main.ico new file mode 100644 index 0000000000000000000000000000000000000000..e2713393f91790acfc88361df19b93e1866421d3 GIT binary patch literal 52014 zcmeI5O^g&p6vvyGz!C2p+=~fEPF@TP(Io=A#Do=Lmj#wAN`gQ%LIR2hg0ib7qKP41 z{5%|Hy?d+>&0Zh1DDfw#jzzktu<64I?2yh)#$I6?W zbD_o7A)5uPMU*+riJ2HH9kn&(*t!<+TIw9rYr}O4Lrx6l<@WFIt0HWn z{9!sAwv=2^zZqd)X zSZ1li`b%NRiNSP>em)ChR}R)+4qHktrt9(=vM!WAOozgd6NBl7WbD!kq7a%bSMltF_>;h#xAW;{xBU5TS_jb>tYhJE|fn^hr*B(gXxB3?9vM557XhW zrQ~9|E+!%CLixjVC=594s$N(hB7d z)8VkCq7a%bSMltF_>;h#xAW;{xBU5TS_jb>tYhJE|fn^hr*B( zgXxB3?9vM557XhWrQ~9|az5YhUkHEUUxYb8SwlE6Md)LZJ#g4ka*N#eB6y=P@#=wp#R zP#AJzTzy~r;u5v=vn{Ig&|tiEfBLFg`$8A`ywv|vuUc6CLCyW^pLknTI;_@g=t1K_ zd(Y5zb@j?+RjpQY*{=M3DfWPI;IO6SV!Hhso>g7LgKF_l?dA4H*xJuscaA}x?9G_N7+@SI3^_5F?$R%|Cb-+<0M|h}@0mltB)Hq-0M|h}-jof4 zy!XaWde31?$xZ8-a_9F$DE}_K9+^0^pL^k7lz;pATldAAyu7&^ed8y+r!eHir1ebM z#UJhmCeG|#{Na9J;?jH5|Gf8UU#84qOUX4l>3#R-ThRFr_vCc^qTwIW`49Kxbi66& z&E4o5Kj}S%AtxrSXUg#G)1~jV_PP(pa8HIh6KD4D?9+bk#(iS|_hhIuap}F>fARnS z2F`FDz*+_zCD9zB6fiqkOuol4v_hfi3GWE6gAH4Ir8o!#~^CyfyJOkJA2In|) zo02=wyWl3K-RkFo4TT{mW?gT`(N^b-^?#seLDPSKUXSr+OuyC75A<|2{oh~Mv~b~! zbv+%&Tb*^f|C;?VV8dBksJZJ`KQ&9n;NEixum>hoevOEOv4*v1pts|Q9*bM)`S8$} zb)VzDuXuV>sCnOrag#QLfDjM@LO=)z0U;m+gn$qb0zyCt2mv7=1i}(fMfAOwWKgF!%@ z*f)KmQXZ;S$`|wcUTCbXJ%E>bse$*reAmz&tk-{@+|&N6mC}WJ{o8H0epiKBm!&;B zNBr~t4N;qAmN66l!r#oH(DTRWHfk^a{a16NSl4PNG=Hj|E6(nRE6%R7bNs}U5q7TK zX4c~@?b$g=cm9%{o7JEbZAje#glO zJJcp``dw$2s2-^#IH{ZX8KA1Z2Zhl__`e4q(-h7{&v$xwzy7QOp z+y~wNs_ngc{_Kk95X>dhw-s;gQ1j1@$8!kgk~t6i(7Hg;0d8$6NOVNjMucd>Xqv}Ju z6#XLf-;7s1`$mpG=+?XW^r1Zpe;I$7|Jb!&>-@ub{nzRzcCH!ykK2U%3S~QUU~;V( z`38@lT2H9ge?9A7JcV1L|^V^`{0hqw=Y{NTg@Brn#dv@0K9@KE9 z>UV$qO8onzzyWd>A1KEjfCH4@8{DRDT)#&00KY*=)z|O!Moes@_xhdPsIUL4mUs4P i52H=c9_d@&<$eD4`IGvGi$MClg8tg(%w}$Bz5f9%%-|jX literal 0 HcmV?d00001 diff --git a/_resources/main.qrc b/_resources/main.qrc new file mode 100644 index 0000000..f13e3d1 --- /dev/null +++ b/_resources/main.qrc @@ -0,0 +1,6 @@ + + + images/main_icon.png + images/main_title.png + + diff --git a/_resources/main_icon.rc b/_resources/main_icon.rc new file mode 100644 index 0000000..59f679d --- /dev/null +++ b/_resources/main_icon.rc @@ -0,0 +1 @@ +IDI_ICON1 ICON "main.ico" diff --git a/application/CMakeLists.txt b/application/CMakeLists.txt new file mode 100644 index 0000000..27d34db --- /dev/null +++ b/application/CMakeLists.txt @@ -0,0 +1,82 @@ + +cmake_minimum_required(VERSION 4.0) + +project(circular_menu_example + VERSION 1.0 + DESCRIPTION "Example use Circular menu lib" + LANGUAGES CXX +) + +include(${CMAKE_CURRENT_SOURCE_DIR}/../_cmake/app_settings.cmake) + +find_package(Qt${QT_VERSION_MAJOR} REQUIRED COMPONENTS + Core Widgets +) + +set(PROJECT_SOURCES + main.cpp + main_window.cpp + main_window.h + main_window.ui + ${COMMON_SOURCES_DIR}/application_config.h + ${COMMON_SOURCES_DIR}/application_config.cpp +) + +set(PROJECT_RESOURCES + ${RESOURCES_DIR}/main.qrc + ${RESOURCES_DIR}/icons.qrc +) + +if(CMAKE_SYSTEM_NAME STREQUAL "Windows") + set(PROJECT_RC_FILES + ${RESOURCES_DIR}/main_icon.rc + ${CMAKE_CURRENT_BINARY_DIR}/versioninfo.rc + ) +endif() + +if(${QT_VERSION_MAJOR} GREATER_EQUAL 6) + qt_add_executable(${PROJECT_NAME} + MANUAL_FINALIZATION + ${PROJECT_SOURCES} + ${PROJECT_RESOURCES} + ${PROJECT_RC_FILES} + ) +else() + add_executable(${PROJECT_NAME} + ${PROJECT_SOURCES} + ${PROJECT_RESOURCES} + ${PROJECT_RC_FILES} + ) +endif() + +target_link_directories(${PROJECT_NAME} PRIVATE + ${DISTRIB_DIR} +) + +include(${CMAKE_INC_DIR}/target_options.cmake) + +target_link_libraries(${PROJECT_NAME} PRIVATE + Qt${QT_VERSION_MAJOR}::Core + Qt${QT_VERSION_MAJOR}::Widgets + _circular_menu +) + +target_include_directories(${PROJECT_NAME} PRIVATE + ${SYSTEM_INCLUDE_DIR} + ${CMAKE_CURRENT_BINARY_DIR} + ${COMMON_SOURCES_DIR} + ${ROOT_PROJECT_DIR}lib_circular_menu +) + +if(CMAKE_SYSTEM_NAME STREQUAL "Windows") + set_target_properties(${PROJECT_NAME} PROPERTIES + WIN32_EXECUTABLE TRUE + ) +endif() + +if(QT_VERSION_MAJOR EQUAL 6) + qt_finalize_executable(${PROJECT_NAME}) +endif() + +include(${CMAKE_INC_DIR}/post_build.cmake) + diff --git a/application/main.cpp b/application/main.cpp new file mode 100644 index 0000000..05941fa --- /dev/null +++ b/application/main.cpp @@ -0,0 +1,22 @@ +#include "main_window.h" +#include +#include "application_config.h" + +//============================================================================== +int main(int argc, char *argv[]) +{ + QApplication a(argc, argv); + + Application::initialize(); + Application::installTranslations(); + + // Создание главного окна: + MainWindow w; + + w.show(); + a.setQuitOnLastWindowClosed(true); + + return a.exec(); +} +//============================================================================== + diff --git a/application/main_window.cpp b/application/main_window.cpp new file mode 100644 index 0000000..1fe32e8 --- /dev/null +++ b/application/main_window.cpp @@ -0,0 +1,80 @@ +/**************************************************************************** +** Copyright (c) 2025 Evgeny Teterin (nayk) +** All right reserved. +** +** Permission is hereby granted, free of charge, to any person obtaining +** a copy of this software and associated documentation files (the +** "Software"), to deal in the Software without restriction, including +** without limitation the rights to use, copy, modify, merge, publish, +** distribute, sublicense, and/or sell copies of the Software, and to +** permit persons to whom the Software is furnished to do so, subject to +** the following conditions: +** +** The above copyright notice and this permission notice shall be +** included in all copies or substantial portions of the Software. +** +** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +** NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +** LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +** OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +** WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +** +****************************************************************************/ +#include "main_window.h" +#include "./ui_main_window.h" +#include + +#include "circular_menu.h" + +//============================================================================== +MainWindow::MainWindow(QWidget *parent) + : QMainWindow(parent) + , ui(new Ui::MainWindow) +{ + ui->setupUi(this); + initialize(); +} +//============================================================================== +MainWindow::~MainWindow() +{ + delete ui; +} +//============================================================================== +void MainWindow::initialize() +{ + setWindowTitle( QApplication::applicationName() ); + + const QList actions = this->findChildren(); + QList menuActions; + + for (QAction* action: actions) { + + if (!action || !action->objectName().contains("action")) + continue; + + if (action != ui->actionExit) + connect(action, &QAction::triggered, this, &MainWindow::actionClick); + + menuActions.append(action); + } + + connect(ui->actionExit, &QAction::triggered, this, &MainWindow::close); + + CircularMenu *circularMenu = new CircularMenu(this); + circularMenu->addActions(menuActions); + circularMenu->setHotKey(Qt::Key_Alt); +} +//============================================================================== +void MainWindow::actionClick() +{ + QAction *action = qobject_cast(sender()); + + if (action) { + + QMessageBox::information(this, tr("Информация"), + tr("Выбран пункт меню '%1'").arg(action->text())); + } +} +//============================================================================== diff --git a/application/main_window.h b/application/main_window.h new file mode 100644 index 0000000..2bdfca4 --- /dev/null +++ b/application/main_window.h @@ -0,0 +1,58 @@ +/**************************************************************************** +** Copyright (c) 2025 Evgeny Teterin (nayk) +** All right reserved. +** +** Permission is hereby granted, free of charge, to any person obtaining +** a copy of this software and associated documentation files (the +** "Software"), to deal in the Software without restriction, including +** without limitation the rights to use, copy, modify, merge, publish, +** distribute, sublicense, and/or sell copies of the Software, and to +** permit persons to whom the Software is furnished to do so, subject to +** the following conditions: +** +** The above copyright notice and this permission notice shall be +** included in all copies or substantial portions of the Software. +** +** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +** NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +** LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +** OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +** WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +** +****************************************************************************/ +#pragma once +#ifndef MAINWINDOW_H +#define MAINWINDOW_H + +#include + +//============================================================================== +QT_BEGIN_NAMESPACE +namespace Ui { +class MainWindow; +} +QT_END_NAMESPACE + +//============================================================================== +// Главное окно +//============================================================================== +class MainWindow : public QMainWindow +{ + Q_OBJECT + +public: + MainWindow(QWidget *parent = nullptr); + ~MainWindow(); + +private: + Ui::MainWindow *ui; + void initialize(); + +private slots: + void actionClick(); +}; + +#endif // MAINWINDOW_H +//============================================================================== diff --git a/application/main_window.ui b/application/main_window.ui new file mode 100644 index 0000000..09d3256 --- /dev/null +++ b/application/main_window.ui @@ -0,0 +1,154 @@ + + + MainWindow + + + + 0 + 0 + 561 + 345 + + + + MainWindow + + + + :/images/main_icon.png:/images/main_icon.png + + + + + + + Нажмите Alt чтобы вызвать круговое меню + + + Qt::AlignmentFlag::AlignCenter + + + + + + + + + + 0 + 0 + 561 + 21 + + + + + Файл + + + + + + + + Правка + + + + + + + Вид + + + + + + + + + + toolBar + + + + 32 + 32 + + + + TopToolBarArea + + + false + + + + + + + + + + + :/icons/opened-folder-40.png:/icons/opened-folder-40.png + + + Открыть... + + + + + + :/icons/save-as-40.png:/icons/save-as-40.png + + + Сохранить как... + + + + + + :/icons/shutdown-40.png:/icons/shutdown-40.png + + + Выход + + + + + + :/icons/restart-40.png:/icons/restart-40.png + + + Отменить последнее действие + + + + + + :/icons/change-theme-40.png:/icons/change-theme-40.png + + + Разделить + + + + + + :/icons/ok-40.png:/icons/ok-40.png + + + Применить всё + + + + + + + + + + + + diff --git a/lib_circular_menu/CMakeLists.txt b/lib_circular_menu/CMakeLists.txt new file mode 100644 index 0000000..8e0ef33 --- /dev/null +++ b/lib_circular_menu/CMakeLists.txt @@ -0,0 +1,57 @@ +cmake_minimum_required(VERSION 4.0) + +project(_circular_menu + VERSION 1.0 + DESCRIPTION "Circular menu library for Qt projects" + LANGUAGES CXX) + +include(${CMAKE_CURRENT_SOURCE_DIR}/../_cmake/lib_settings.cmake) + +find_package(Qt${QT_VERSION_MAJOR} REQUIRED COMPONENTS + Core Widgets +) + +set(PUBLIC_LIBRARY_HEADERS + circular_menu.h +) + +set(PROJECT_SOURCES + private/circular_menu.cpp + ${COMMON_SOURCES_DIR}/application_config.h + ${COMMON_SOURCES_DIR}/application_config.cpp +) + +if(CMAKE_SYSTEM_NAME STREQUAL "Windows") + set(PROJECT_RC_FILES + ${CMAKE_CURRENT_BINARY_DIR}/versioninfo.rc + ) +endif() + +add_library(${PROJECT_NAME} SHARED + ${PUBLIC_LIBRARY_HEADERS} + ${PROJECT_SOURCES} + ${PROJECT_RC_FILES} +) + +include(${CMAKE_INC_DIR}/target_options.cmake) + +target_include_directories(${PROJECT_NAME} PRIVATE + ${SYSTEM_INCLUDE_DIR} + ${CMAKE_CURRENT_BINARY_DIR} + ${COMMON_SOURCES_DIR} + ${CMAKE_CURRENT_SOURCE_DIR}/private +) + +target_link_directories(${PROJECT_NAME} PRIVATE + ${CMAKE_LIBRARY_OUTPUT_DIRECTORY} +) + +target_link_libraries(${PROJECT_NAME} PRIVATE + Qt${QT_VERSION_MAJOR}::Core + Qt${QT_VERSION_MAJOR}::Widgets +) + +target_compile_definitions(${PROJECT_NAME} PRIVATE + LIB_CIRCULAR_MENU +) + diff --git a/lib_circular_menu/circular_menu.h b/lib_circular_menu/circular_menu.h new file mode 100644 index 0000000..be309d1 --- /dev/null +++ b/lib_circular_menu/circular_menu.h @@ -0,0 +1,80 @@ +/**************************************************************************** +** Copyright (c) 2025 Evgeny Teterin (nayk) +** All right reserved. +** +** Permission is hereby granted, free of charge, to any person obtaining +** a copy of this software and associated documentation files (the +** "Software"), to deal in the Software without restriction, including +** without limitation the rights to use, copy, modify, merge, publish, +** distribute, sublicense, and/or sell copies of the Software, and to +** permit persons to whom the Software is furnished to do so, subject to +** the following conditions: +** +** The above copyright notice and this permission notice shall be +** included in all copies or substantial portions of the Software. +** +** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +** NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +** LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +** OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +** WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +** +****************************************************************************/ +#pragma once +#ifndef CIRCULAR_MENU_H +#define CIRCULAR_MENU_H + +#if defined (LIB_CIRCULAR_MENU) +# define CIRCULAR_MENU_EXPORT Q_DECL_EXPORT +#else +# define CIRCULAR_MENU_EXPORT Q_DECL_IMPORT +#endif + +#include +#include +#include + +#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0) +# include +#else +# include +#endif + +#include +#include +#include + +//============================================================================== + +class CircularMenuData; + +//============================================================================== +class CIRCULAR_MENU_EXPORT CircularMenu : public QWidget +{ + Q_OBJECT + +public: + explicit CircularMenu(QWidget *parent = nullptr); + virtual ~CircularMenu(); + void addAction(QAction *action); + void addActions(QList actions); + qsizetype count() const; + QList actions() const; + QAction *actionAt(qsizetype index) const; + bool removeAction(qsizetype index, qsizetype count = 1); + void clear(); + void setHotKey(Qt::Key key); + +protected: + bool eventFilter(QObject *obj, QEvent *event) override; + void paintEvent(QPaintEvent *event) override; + void resizeEvent(QResizeEvent *event) override; + +private: + CircularMenuData *d; +}; +//============================================================================== + +#endif // CIRCULAR_MENU_H diff --git a/lib_circular_menu/private/circular_menu.cpp b/lib_circular_menu/private/circular_menu.cpp new file mode 100644 index 0000000..e7da4ea --- /dev/null +++ b/lib_circular_menu/private/circular_menu.cpp @@ -0,0 +1,362 @@ +#include "circular_menu.h" + +#include +#include +#include +#include +#include +#include + +#include "application_config.h" + +//============================================================================== +class CircularMenuData +{ +public: + qsizetype activeIndex {-1}; + int radius {210}; + int buttonRadius {54}; + int iconSize {40}; + QList> actions; + QList> visibleActions; + Qt::Key key {Qt::Key_Alt}; + // + CircularMenuData() = default; + virtual ~CircularMenuData() = default; + void updateVisibleActions() + { + visibleActions.clear(); + + for (auto i = 0; i < actions.size(); ++i) { + + if (actions.at(i) && actions.at(i)->isVisible() + && !actions.at(i)->isCheckable()) { + + visibleActions.append(actions.at(i)); + } + } + }; +}; + +//============================================================================== +CircularMenu::CircularMenu(QWidget *parent) + : QWidget{parent} + , d{new CircularMenuData} +{ + setWindowFlags(windowFlags() + | Qt::Dialog + | Qt::FramelessWindowHint + | Qt::WindowStaysOnTopHint + ); + setAttribute(Qt::WA_TranslucentBackground); + setWindowModality(Qt::WindowModal); + setMouseTracking(true); + + setFixedSize(40 + 2 * (d->radius + d->buttonRadius), + 40 + 2 * (d->radius + d->buttonRadius)); + + if (parent) { + + parent->installEventFilter(this); + } + + this->installEventFilter(this); +} +//============================================================================== +CircularMenu::~CircularMenu() +{ + delete d; +} +//============================================================================== +void CircularMenu::addAction(QAction *action) +{ + if (action) { + + d->actions.append( QPointer(action) ); + d->updateVisibleActions(); + update(); + } +} +//============================================================================== +void CircularMenu::addActions(QList actions) +{ + for (auto action: actions) { + + if (action) { + + d->actions.append( QPointer(action) ); + } + } + + d->updateVisibleActions(); + update(); +} +//============================================================================== +qsizetype CircularMenu::count() const +{ + return d->actions.size(); +} +//============================================================================== +QList CircularMenu::actions() const +{ + QList actions; + + for (auto i = 0; i < d->actions.size(); ++i) { + + if (d->actions.at(i)) + actions.append(d->actions.at(i).data()); + } + + return actions; +} +//============================================================================== +QAction *CircularMenu::actionAt(qsizetype index) const +{ + if (index < 0) + return nullptr; + + if (index >= d->actions.size()) + return nullptr; + + return +#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0) + d->actions.at(index).data(); +#else + d->actions.at(static_cast(index)).data(); +#endif +} +//============================================================================== +bool CircularMenu::removeAction(qsizetype index, qsizetype count) +{ + if (index < 0) + return false; + + if (index >= d->actions.size()) + return false; + +#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0) + d->actions.remove(index, count); +#else + d->actions.erase(d->actions.begin() + index, + d->actions.begin() + index + count); +#endif + d->updateVisibleActions(); + update(); + return true; +} +//============================================================================== +void CircularMenu::clear() +{ + d->actions.clear(); + d->updateVisibleActions(); +} +//============================================================================== +void CircularMenu::setHotKey(Qt::Key key) +{ + d->key = key; +} +//============================================================================== +bool CircularMenu::eventFilter(QObject *obj, QEvent *event) +{ + if (!obj || !event) + return false; + + if ((obj != parent()) && (obj != this)) + return false; + + if ((event->type() == QMouseEvent::MouseMove) && isVisible()) { + + QMouseEvent *mouseEvent = static_cast(event); + + if (!mouseEvent) + return false; + + const QPoint center = rect().center(); + const QPoint mousePos = mouseEvent->pos(); + qsizetype newActiveIndex = -1; + const auto count = d->visibleActions.size(); + + for (auto i = 0; i < count; ++i) { + + if (!d->visibleActions.at(i) || !d->visibleActions.at(i)->isEnabled()) continue; + + // Вычисляем позицию кнопки + double angle = 2.0 * M_PI * static_cast(i) / static_cast(count) - M_PI / 2.0; + QPoint buttonCenter( + static_cast(center.x() + d->radius * cos(angle)), + static_cast(center.y() + d->radius * sin(angle)) + ); + + // Проверяем попадание курсора в круглую область кнопки + QPoint diff = mousePos - buttonCenter; + double distanceToButton = sqrt(diff.x()*diff.x() + diff.y()*diff.y()); + + if (distanceToButton <= (d->buttonRadius + 10)) { + + newActiveIndex = i; + break; // Курсор может быть только над одной кнопкой + } + } + + if ((newActiveIndex != d->activeIndex) && (newActiveIndex != -1) + && (newActiveIndex < d->visibleActions.size())) { + +#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0) + QAction *action = d->visibleActions.at(newActiveIndex); +#else + QAction *action = d->visibleActions.at(static_cast(newActiveIndex)); +#endif + + if (action && action->isEnabled()) { + + d->activeIndex = newActiveIndex; + update(); + } + } + } + else if ((event->type() == QMouseEvent::MouseButtonPress) && isVisible()) { + + QMouseEvent *mouseEvent = static_cast(event); + + if (!mouseEvent) + return false; + + if (mouseEvent->button() == Qt::LeftButton + && (d->activeIndex != -1) && (d->activeIndex < d->visibleActions.size())) { + +#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0) + QAction *action = d->visibleActions.at(d->activeIndex); +#else + QAction *action = d->visibleActions.at(static_cast(d->activeIndex)); +#endif + + this->hide(); + + if (action && action->isEnabled()) + action->trigger(); + + return true; + } + } + else if ((event->type() == QKeyEvent::KeyRelease) && isVisible()) { + + this->hide(); + return false; + } + else if (event->type() == QKeyEvent::KeyPress) { + + QKeyEvent *keyEvent = static_cast(event); + + if (!keyEvent) + return false; + + if (keyEvent->key() != d->key) { + + this->hide(); + return false; + } + + d->updateVisibleActions(); + d->activeIndex = d->visibleActions.isEmpty() ? -1 : 0; + + Application::moveToCenterMainWindow(this); + this->show(); + return true; + } + + return false; +} +//============================================================================== +void CircularMenu::paintEvent(QPaintEvent *event) +{ + Q_UNUSED(event) + + QPainter painter(this); + painter.setRenderHint(QPainter::Antialiasing); + + // Рисуем круглый фон + painter.setBrush(QBrush(QColor(0, 0, 0, 50))); + painter.setPen(QPen(QColor(255, 255, 255, 60), 4)); + painter.drawEllipse(rect()); + + // Draw menu circle + painter.setPen(Qt::NoPen); + painter.setBrush(QColor(0, 5, 10, 130)); + painter.drawEllipse(rect().center(), + d->radius - d->buttonRadius / 2 - 30, + d->radius - d->buttonRadius / 2 - 30); + + // Draw buttons + const auto count = d->visibleActions.size(); + const QPoint center = rect().center(); + + for (auto i = 0; i < count; ++i) { + + if (!d->visibleActions.at(i)) continue; + + // Calculate button position + double angle = 2.0 * M_PI * static_cast(i) / static_cast(count) - M_PI / 2.0; + int x = static_cast(center.x() + d->radius * cos(angle) - d->buttonRadius); + int y = static_cast(center.y() + d->radius * sin(angle) - d->buttonRadius); + + // Draw button + if (i == d->activeIndex) { + + painter.setBrush(QColor(0, 15, 50, 200)); + painter.setPen(QPen(QColor(0, 180, 255, 200), 5)); + } + else { + + painter.setBrush(QColor(0, 5, 10, 200)); + painter.setPen(QPen(QColor(255, 255, 255, 180), 3)); + } + + painter.drawEllipse(QPoint(x + d->buttonRadius, y + d->buttonRadius), + d->buttonRadius, d->buttonRadius); + + if (!d->visibleActions.at(i)->icon().isNull()) { + + QRect iconRect(x + d->buttonRadius - d->iconSize / 2, + y + d->buttonRadius - d->iconSize / 2, + d->iconSize, d->iconSize); + + if (d->visibleActions.at(i)->isEnabled()) { + + d->visibleActions.at(i)->icon().paint(&painter, iconRect); + } + else { + + painter.save(); + painter.setOpacity(0.4); // Make icon semi-transparent + QIcon::Mode mode = QIcon::Disabled; + QIcon::State state = d->visibleActions.at(i)->isChecked() ? QIcon::On : QIcon::Off; + d->visibleActions.at(i)->icon().paint(&painter, iconRect, Qt::AlignCenter, mode, state); + painter.restore(); + } + } + + if (i == d->activeIndex) { + + QRect r(0, 0, d->radius * 2 - 20, d->radius * 2 - 20); + r.moveCenter(rect().center()); + + QFont font {painter.font()}; + font.setPointSize(14); + + painter.setFont(font); + painter.setBrush(Qt::NoBrush); + painter.setPen(Qt::white); + painter.drawText(r, + Qt::AlignCenter, + d->visibleActions.at(i)->text()); + } + } +} +//============================================================================== +void CircularMenu::resizeEvent(QResizeEvent *event) +{ + Q_UNUSED(event); + QRegion region(rect(), QRegion::Ellipse); + setMask(region); +} +//==============================================================================