diff --git a/README.md b/README.md index 95cdd75..f00bad4 100644 --- a/README.md +++ b/README.md @@ -60,18 +60,18 @@ Above blog posts contains step by step tutorial on how to do that for Qt5 versio ### qmake All you need to do is to follow these steps. -1. Add SCodes as submodule, by typing `git submodule add git@github.com:scytheStudio/SCodes.git` +1. Add SCodes as submodule, by typing `git submodule add git@github.com:somcosoftware/SCodes.git` 2. Update submodule `git submodule update --recursive --init` (you can also put wrapper files to your project manually without adding submodule) 3. Add `include(scodes/src/SCodes.pri)` to your .pro file 4. If you want to use barcode reader functionality you need to register `SBarcodeFilter` class for Qt5 or `SBarcodeScanner` class for Qt6. For both version, separate them with if directive to register as we did in barcode reader example([how to register reader class](#register-reader)). As for barcode generator functionality you just need to register `SBarcodeGenerator` class([how to register generator class](#register-generator)). -5. Import SCodes in your Qml file `import com.scythestudio.scodes 1.0` +5. Import SCodes in your Qml file `import com.somcosoftware.scodes 1.0` 6. Import multimedia module `import QtMultimedia 5.15` for Qt5 or `import QtMultimedia` for Qt6. 7. If build fails, try to add `CONFIG += c++17` to your .pro file -8. You are done. Get inspired by [Qt5 QML Barcode Reader demo](https://github.com/scytheStudio/SCodes/blob/master/examples/QmlBarcodeReader/qml/Qt5ScannerPage.qml) or [Qt6 QML Barcode Reader demo](https://github.com/scytheStudio/SCodes/blob/master/examples/QmlBarcodeReader/qml/Qt6ScannerPage.qml) to test wrapper. +8. You are done. Get inspired by [Qt5 QML Barcode Reader demo](https://github.com/somcosoftware/SCodes/blob/master/examples/QmlBarcodeApp/qml/Qt5ScannerPage.qml) or [Qt6 QML Barcode Reader demo](https://github.com/somcosoftware/SCodes/blob/master/examples/QmlBarcodeApp/qml/Qt6ScannerPage.qml) to test wrapper. ### CMake -1. Add SCodes as submodule, by typing `git submodule add git@gitlab.com:scythestudio/scodes.git` +1. Add SCodes as submodule, by typing `git submodule add git@gitlab.com:somcosoftware/scodes.git` 2. Update submodule `git submodule update --recursive --init` (you can also put wrapper files to your project manually without adding submodule) 3. Add to your project SCodes library @@ -88,10 +88,10 @@ All you need to do is to follow these steps. 5. Import SCodes in your Qml file ```qml - import com.scythestudio.scodes 1.0 + import com.somcosoftware.scodes 1.0 ``` -6. You are done. Get inspired by [QML Barcode Reader demo](https://github.com/scytheStudio/SCodes/blob/master/examples/QmlBarcodeReader/qml/ScannerPage.qml) to test wrapper. +6. You are done. Get inspired by [QML Barcode Reader demo](https://github.com/somcosoftware/SCodes/blob/master/examples/QmlBarcodeApp/qml/ScannerPage.qml) to test wrapper. ### How to do @@ -99,16 +99,16 @@ Registering the barcode reader classes with if directive: ```c++ #if QT_VERSION < QT_VERSION_CHECK(6, 0, 0) - qmlRegisterType("com.scythestudio.scodes", 1, 0, "SBarcodeScanner"); + qmlRegisterType("com.somcosoftware.scodes", 1, 0, "SBarcodeScanner"); #else - qmlRegisterType("com.scythestudio.scodes", 1, 0, "SBarcodeScanner"); + qmlRegisterType("com.somcosoftware.scodes", 1, 0, "SBarcodeScanner"); #endif ``` Registering the barcode generator class with associated enum: ```c++ - qmlRegisterType("com.scythestudio.scodes", 1, 0, "SBarcodeGenerator"); - qmlRegisterUncreatableMetaObject(SCodes::staticMetaObject, "com.scythestudio.scodes", 1, 0, "SCodes", "Error: only enums"); + qmlRegisterType("com.somcosoftware.scodes", 1, 0, "SBarcodeGenerator"); + qmlRegisterUncreatableMetaObject(SCodes::staticMetaObject, "com.somcosoftware.scodes", 1, 0, "SCodes", "Error: only enums"); ``` @@ -118,7 +118,7 @@ Qt's multimedia library has major changes. The most importants are, changes in Q SCodes library is using `SBarcodeFilter` class for Qt5 and `SBarcodesScanner` class for Qt6 version. -If you want to read more about implementation details of the library in Qt6 read the document: [Implementation Details in Qt6](https://github.com/scytheStudio/SCodes/blob/master/doc/detailsQt6.md) +If you want to read more about implementation details of the library in Qt6 read the document: [Implementation Details in Qt6](https://github.com/somcosoftware/SCodes/blob/master/doc/detailsQt6.md) ### Trying various formats @@ -131,7 +131,7 @@ Component.onCompleted: { barcodeFilter.format = SCodes.OneDCodes } ``` -See the enumeration values that represent supported formats in [SBarcodeFormat.h](https://github.com/scytheStudio/SCodes/blob/master/src/SBarcodeFormat.h) +See the enumeration values that represent supported formats in [SBarcodeFormat.h](https://github.com/somcosoftware/SCodes/blob/master/src/SBarcodeFormat.h) To accept all supported formats use `SCodes.Any`. ## Note @@ -145,63 +145,56 @@ Both build systems have their examples located in same directory. All you need t | PROJECT | BUILD SYSTEM | WINDOWS-MinGW | WINDOWS-MSVC | LINUX-GCC | ANDROID | | ------ | ------ | ------ | ------ | ------ | ------ | -| QmlBarcodeReader | qmake |
✔️
|
✔️
|
✔️
|
✔️
| -| QmlBarcodeGenerator | qmake |
✔️
|
✔️
|
✔️
|
✔️
| -| QmlBarcodeReader | CMake |
|
✔️
|
✔️
|
✔️
| -| QmlBarcodeGenerator | CMake |
|
✔️
|
✔️
|
✔️
| +| QmlBarcodeApp | qmake |
✔️
|
✔️
|
✔️
|
✔️
| +| QmlBarcodeApp | CMake |
✔️
|
✔️
|
✔️
|
✔️
| #### Qt6.3.0, | PROJECT | BUILD SYSTEM | WINDOWS-MinGW | WINDOWS-MSVC | LINUX-GCC | ANDROID | | ------ | ------ | ------ | ------ | ------ | ------ | -| QmlBarcodeReader | qmake |
✔️
|
✔️
|
✔️
|
✔️
| -| QmlBarcodeGenerator | qmake |
✔️
|
✔️
|
✔️
|
✔️
| -| QmlBarcodeReader | CMake |
✔️
|
✔️
|
✔️
|
✔️
| -| QmlBarcodeGenerator | CMake |
✔️
|
✔️
|
✔️
|
✔️
| +| QmlBarcodeApp | qmake |
✔️
|
✔️
|
✔️
|
✔️
| +| QmlBarcodeApp | CMake |
✔️
|
✔️
|
✔️
|
✔️
| Please ensure that proper Java & NDK version installed on your system. This examples tested w/ Java 11 and 22.1.7171670 Android NDK version. -## About Somco Software (previously Scythe Studio) -We’re a team of **Qt and C++ enthusiasts** dedicated to helping businesses build great cross-platform applications. As an official Qt Service Partner, we’ve earned the trust of companies across various industries by delivering high-quality, reliable solutions. With years of experience in **Qt and QML development**, we know how to turn ambitious ideas into outstanding products. +## About Somco Software +[Somco Software](https://somcosoftware.com/en/) (previously Scythe Studio) is an embedded and cross-platform software development company with a strong focus on Qt and C++, delivering reliable, high-quality solutions for regulated industries, with particular expertise in medical devices. We are an ISO 9001 and ISO 13485 certified software house, specializing in GUI development, Linux-based systems, and advanced connectivity solutions. Somco Software is an official Qt Service Partner and a trusted partner of leading hardware manufacturers.
- + - + - + - +
-We offer a wide range of services—from brainstorming ideas to delivering polished applications—always tailored to our clients’ needs. By combining deep knowledge of Qt modules and modern technologies with a practical, cost-effective approach, we create solutions that truly make a difference. +We support projects from design to delivery, offering UX/UI design, custom Yocto Linux images, and development in Qt as well as LVGL and TouchGFX. We also help with software modernization, training, and technical consulting. With a practical, developer-focused approach, we build efficient, reliable solutions that fit real project needs. ## Professional Support Need help with anything? We’ve got you covered. Our professional support services are here to assist you with. For more details about support options and pricing, just drop us a line at https://somcosoftware.com/en/contact. ## Follow us - Check out those links if you want to see Somco Software in action and follow the newest trends saying about Qt Qml development. * 🌐 [Somco Software Website](https://somcosoftware.com/en/) * ✍️ [Somco Software Blog Website](https://somcosoftware.com/en/blog) -* 👔 [Somco Software LinkedIn Profile](https://www.linkedin.com/company/scythestudio/mycompany/) -* 👔 [Somco Software Facebook Page](https://www.facebook.com/ScytheStudiio) +* 👔 [Somco Software LinkedIn Profile](https://www.linkedin.com/company/somcosoftware) * 🎥 [Somco Software Youtube Channel](https://www.youtube.com/channel/UCf4OHosddUYcfmLuGU9e-SQ/featured) diff --git a/doc/detailsQt6.md b/doc/detailsQt6.md index 2bdca10..9ea8daa 100644 --- a/doc/detailsQt6.md +++ b/doc/detailsQt6.md @@ -1,7 +1,7 @@ # Implementation details in Qt 6 -VideoOutput QML element has major changes and it is not possible to use same QML files for both version. If you want to implement barcode reader functionality for both version you need to create two separate QML file too(that's because of QML VideoOutput changes in multimedia module of Qt6). Check our [QmlBarcodeReader example](https://github.com/scytheStudio/SCodes/tree/master/examples/QmlBarcodeReader) for more details. +VideoOutput QML element has major changes and it is not possible to use same QML files for both version. If you want to implement barcode reader functionality for both version you need to create two separate QML file too(that's because of QML VideoOutput changes in multimedia module of Qt6). Check our [QmlBarcodeApp example](https://github.com/somcosoftware/SCodes/tree/master/examples/QmlBarcodeApp) for more details. -`SBarcodeFilter.cpp` and `SBarcodesScanner.cpp` files included/excluded according to the Qt version in the [SCodes CMakeLists file](https://github.com/scytheStudio/SCodes/blob/master/src/CMakeLists.txt). The idea of excluding the related class according to Qt version is prevent to get error from not existing libraries when you compile the project for Qt6(e.g. QVideoFilterRunnable, QAbstractVideoFilter). Likewise in Qt5 for QVideoSink. +`SBarcodeFilter.cpp` and `SBarcodesScanner.cpp` files included/excluded according to the Qt version in the [SCodes CMakeLists file](https://github.com/somcosoftware/SCodes/blob/master/src/CMakeLists.txt). The idea of excluding the related class according to Qt version is prevent to get error from not existing libraries when you compile the project for Qt6(e.g. QVideoFilterRunnable, QAbstractVideoFilter). Likewise in Qt5 for QVideoSink. SBarcodeScanner class is inherited from QVideoSink class. It's initiated in 2 phases: First, the constructor sets up the connections to processing threads. Then, after QmlEngine sets up properties, `forwardVideoSink` and `camera`, a `componentComplete()` function is called that instantiates a default `QCamera` if none is set. diff --git a/examples/QmlBarcodeGenerator/.gitignore b/examples/QmlBarcodeApp/.gitignore similarity index 100% rename from examples/QmlBarcodeGenerator/.gitignore rename to examples/QmlBarcodeApp/.gitignore diff --git a/examples/QmlBarcodeReader/CMakeLists.txt b/examples/QmlBarcodeApp/CMakeLists.txt similarity index 79% rename from examples/QmlBarcodeReader/CMakeLists.txt rename to examples/QmlBarcodeApp/CMakeLists.txt index 5567aca..f2e98d9 100644 --- a/examples/QmlBarcodeReader/CMakeLists.txt +++ b/examples/QmlBarcodeApp/CMakeLists.txt @@ -1,6 +1,6 @@ -cmake_minimum_required(VERSION 3.16) +cmake_minimum_required(VERSION 3.16.3) -project(QmlBarcodeReader LANGUAGES CXX) +project(QmlBarcodeApp LANGUAGES CXX) set(CMAKE_INCLUDE_CURRENT_DIR ON) @@ -13,6 +13,13 @@ set(CMAKE_CXX_STANDARD_REQUIRED ON) #Check this file for any *_DIR variable definitions and other include("cmake/Locations.cmake") +set(SOURCES + ColorController.h + ColorController.cpp + VersionHelper.h + main.cpp +) + if(QT_VERSION_MAJOR EQUAL 5) qt5_add_resources(RSCS Qt5qml.qrc) else() @@ -35,15 +42,15 @@ if(ANDROID) ${QT_ANDROID_PACKAGE_SOURCE_DIR}/gradlew ${QT_ANDROID_PACKAGE_SOURCE_DIR}/res/values/libs.xml ) - add_library(${PROJECT_NAME} SHARED main.cpp ${RSCS} ${ANDROID_SOURCES}) + add_library(${PROJECT_NAME} SHARED ${SOURCES} ${RSCS} ${ANDROID_SOURCES}) else() - qt_add_executable(${PROJECT_NAME} MANUAL_FINALIZATION main.cpp ${RSCS}) + qt_add_executable(${PROJECT_NAME} MANUAL_FINALIZATION ${SOURCES} ${RSCS}) set_target_properties(${PROJECT_NAME} PROPERTIES QT_ANDROID_PACKAGE_SOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/android" ) endif() else() - add_executable(${PROJECT_NAME} main.cpp ${RSCS}) + add_executable(${PROJECT_NAME} ${SOURCES} ${RSCS}) endif() target_link_libraries(${PROJECT_NAME} PRIVATE ${REQUIRED_QT_LIBS} SCodes) diff --git a/examples/QmlBarcodeGenerator/ColorController.cpp b/examples/QmlBarcodeApp/ColorController.cpp similarity index 100% rename from examples/QmlBarcodeGenerator/ColorController.cpp rename to examples/QmlBarcodeApp/ColorController.cpp diff --git a/examples/QmlBarcodeGenerator/ColorController.h b/examples/QmlBarcodeApp/ColorController.h similarity index 100% rename from examples/QmlBarcodeGenerator/ColorController.h rename to examples/QmlBarcodeApp/ColorController.h diff --git a/examples/QmlBarcodeReader/QmlBarcodeReader.pro b/examples/QmlBarcodeApp/QmlBarcodeApp.pro similarity index 89% rename from examples/QmlBarcodeReader/QmlBarcodeReader.pro rename to examples/QmlBarcodeApp/QmlBarcodeApp.pro index c31ff66..f50c39d 100644 --- a/examples/QmlBarcodeReader/QmlBarcodeReader.pro +++ b/examples/QmlBarcodeApp/QmlBarcodeApp.pro @@ -5,8 +5,13 @@ CONFIG += c++17 DEFINES += QT_DEPRECATED_WARNINGS +HEADERS += \ + ColorController.h \ + VersionHelper.h + SOURCES += \ - main.cpp + main.cpp \ + ColorController.cpp equals(QT_MAJOR_VERSION, 6) { RESOURCES += Qt6qml.qrc diff --git a/examples/QmlBarcodeApp/Qt5qml.qrc b/examples/QmlBarcodeApp/Qt5qml.qrc new file mode 100644 index 0000000..c099c30 --- /dev/null +++ b/examples/QmlBarcodeApp/Qt5qml.qrc @@ -0,0 +1,20 @@ + + + qml/Qt5ScannerPage.qml + qml/ScannerOverlay.qml + qml/Theme.qml + qml/main.qml + qml/GeneratorPage.qml + qml/CButton.qml + qml/CTextField.qml + qml/CComboBox.qml + icons/logo.png + qml/CTabButton.qml + qml/Subtrack.qml + icons/close.svg + icons/download.svg + icons/obraz.png + icons/arrow_drop_down.svg + icons/check.svg + + diff --git a/examples/QmlBarcodeApp/Qt6qml.qrc b/examples/QmlBarcodeApp/Qt6qml.qrc new file mode 100644 index 0000000..abfa28c --- /dev/null +++ b/examples/QmlBarcodeApp/Qt6qml.qrc @@ -0,0 +1,20 @@ + + + qml/Qt6ScannerPage.qml + qml/ScannerOverlay.qml + qml/Theme.qml + qml/GeneratorPage.qml + qml/CButton.qml + qml/CTextField.qml + qml/CComboBox.qml + icons/logo.png + icons/arrow_drop_down.svg + icons/check.svg + icons/close.svg + icons/download.svg + icons/obraz.png + qml/CTabButton.qml + qml/Subtrack.qml + qml/main.qml + + diff --git a/examples/QmlBarcodeApp/VersionHelper.h b/examples/QmlBarcodeApp/VersionHelper.h new file mode 100644 index 0000000..9f26e87 --- /dev/null +++ b/examples/QmlBarcodeApp/VersionHelper.h @@ -0,0 +1,21 @@ +#pragma once + +#include +#include + +class VersionHelper : public QObject +{ + Q_OBJECT + Q_PROPERTY(bool isQt6 READ isQt6 CONSTANT) + +public: + explicit VersionHelper(QObject *parent = nullptr) : QObject(parent) {} + + inline bool isQt6() const { +#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0) + return true; +#else + return false; +#endif + } +}; diff --git a/examples/QmlBarcodeReader/android/AndroidManifest.xml b/examples/QmlBarcodeApp/android/AndroidManifest.xml similarity index 100% rename from examples/QmlBarcodeReader/android/AndroidManifest.xml rename to examples/QmlBarcodeApp/android/AndroidManifest.xml diff --git a/examples/QmlBarcodeReader/android/build.gradle b/examples/QmlBarcodeApp/android/build.gradle similarity index 100% rename from examples/QmlBarcodeReader/android/build.gradle rename to examples/QmlBarcodeApp/android/build.gradle diff --git a/examples/QmlBarcodeReader/android/gradle.properties b/examples/QmlBarcodeApp/android/gradle.properties similarity index 100% rename from examples/QmlBarcodeReader/android/gradle.properties rename to examples/QmlBarcodeApp/android/gradle.properties diff --git a/examples/QmlBarcodeReader/android/gradle/wrapper/gradle-wrapper.jar b/examples/QmlBarcodeApp/android/gradle/wrapper/gradle-wrapper.jar similarity index 100% rename from examples/QmlBarcodeReader/android/gradle/wrapper/gradle-wrapper.jar rename to examples/QmlBarcodeApp/android/gradle/wrapper/gradle-wrapper.jar diff --git a/examples/QmlBarcodeGenerator/android/gradle/wrapper/gradle-wrapper.properties b/examples/QmlBarcodeApp/android/gradle/wrapper/gradle-wrapper.properties similarity index 100% rename from examples/QmlBarcodeGenerator/android/gradle/wrapper/gradle-wrapper.properties rename to examples/QmlBarcodeApp/android/gradle/wrapper/gradle-wrapper.properties diff --git a/examples/QmlBarcodeGenerator/android/gradlew b/examples/QmlBarcodeApp/android/gradlew similarity index 100% rename from examples/QmlBarcodeGenerator/android/gradlew rename to examples/QmlBarcodeApp/android/gradlew diff --git a/examples/QmlBarcodeReader/android/gradlew.bat b/examples/QmlBarcodeApp/android/gradlew.bat similarity index 96% rename from examples/QmlBarcodeReader/android/gradlew.bat rename to examples/QmlBarcodeApp/android/gradlew.bat index 4cc84e5..6a68175 100644 --- a/examples/QmlBarcodeReader/android/gradlew.bat +++ b/examples/QmlBarcodeApp/android/gradlew.bat @@ -1,89 +1,89 @@ -@rem -@rem Copyright 2015 the original author or authors. -@rem -@rem Licensed under the Apache License, Version 2.0 (the "License"); -@rem you may not use this file except in compliance with the License. -@rem You may obtain a copy of the License at -@rem -@rem https://www.apache.org/licenses/LICENSE-2.0 -@rem -@rem Unless required by applicable law or agreed to in writing, software -@rem distributed under the License is distributed on an "AS IS" BASIS, -@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -@rem See the License for the specific language governing permissions and -@rem limitations under the License. -@rem - -@if "%DEBUG%" == "" @echo off -@rem ########################################################################## -@rem -@rem Gradle startup script for Windows -@rem -@rem ########################################################################## - -@rem Set local scope for the variables with windows NT shell -if "%OS%"=="Windows_NT" setlocal - -set DIRNAME=%~dp0 -if "%DIRNAME%" == "" set DIRNAME=. -set APP_BASE_NAME=%~n0 -set APP_HOME=%DIRNAME% - -@rem Resolve any "." and ".." in APP_HOME to make it shorter. -for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi - -@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. -set DEFAULT_JVM_OPTS=-Dfile.encoding=UTF-8 "-Xmx64m" "-Xms64m" - -@rem Find java.exe -if defined JAVA_HOME goto findJavaFromJavaHome - -set JAVA_EXE=java.exe -%JAVA_EXE% -version >NUL 2>&1 -if "%ERRORLEVEL%" == "0" goto execute - -echo. -echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. -echo. -echo Please set the JAVA_HOME variable in your environment to match the -echo location of your Java installation. - -goto fail - -:findJavaFromJavaHome -set JAVA_HOME=%JAVA_HOME:"=% -set JAVA_EXE=%JAVA_HOME%/bin/java.exe - -if exist "%JAVA_EXE%" goto execute - -echo. -echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% -echo. -echo Please set the JAVA_HOME variable in your environment to match the -echo location of your Java installation. - -goto fail - -:execute -@rem Setup the command line - -set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar - - -@rem Execute Gradle -"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* - -:end -@rem End local scope for the variables with windows NT shell -if "%ERRORLEVEL%"=="0" goto mainEnd - -:fail -rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of -rem the _cmd.exe /c_ return code! -if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 -exit /b 1 - -:mainEnd -if "%OS%"=="Windows_NT" endlocal - -:omega +@rem +@rem Copyright 2015 the original author or authors. +@rem +@rem Licensed under the Apache License, Version 2.0 (the "License"); +@rem you may not use this file except in compliance with the License. +@rem You may obtain a copy of the License at +@rem +@rem https://www.apache.org/licenses/LICENSE-2.0 +@rem +@rem Unless required by applicable law or agreed to in writing, software +@rem distributed under the License is distributed on an "AS IS" BASIS, +@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +@rem See the License for the specific language governing permissions and +@rem limitations under the License. +@rem + +@if "%DEBUG%" == "" @echo off +@rem ########################################################################## +@rem +@rem Gradle startup script for Windows +@rem +@rem ########################################################################## + +@rem Set local scope for the variables with windows NT shell +if "%OS%"=="Windows_NT" setlocal + +set DIRNAME=%~dp0 +if "%DIRNAME%" == "" set DIRNAME=. +set APP_BASE_NAME=%~n0 +set APP_HOME=%DIRNAME% + +@rem Resolve any "." and ".." in APP_HOME to make it shorter. +for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi + +@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +set DEFAULT_JVM_OPTS=-Dfile.encoding=UTF-8 "-Xmx64m" "-Xms64m" + +@rem Find java.exe +if defined JAVA_HOME goto findJavaFromJavaHome + +set JAVA_EXE=java.exe +%JAVA_EXE% -version >NUL 2>&1 +if "%ERRORLEVEL%" == "0" goto execute + +echo. +echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:findJavaFromJavaHome +set JAVA_HOME=%JAVA_HOME:"=% +set JAVA_EXE=%JAVA_HOME%/bin/java.exe + +if exist "%JAVA_EXE%" goto execute + +echo. +echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:execute +@rem Setup the command line + +set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar + + +@rem Execute Gradle +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* + +:end +@rem End local scope for the variables with windows NT shell +if "%ERRORLEVEL%"=="0" goto mainEnd + +:fail +rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of +rem the _cmd.exe /c_ return code! +if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 +exit /b 1 + +:mainEnd +if "%OS%"=="Windows_NT" endlocal + +:omega diff --git a/examples/QmlBarcodeGenerator/android/res/drawable-hdpi/icon.png b/examples/QmlBarcodeApp/android/res/drawable-hdpi/icon.png similarity index 100% rename from examples/QmlBarcodeGenerator/android/res/drawable-hdpi/icon.png rename to examples/QmlBarcodeApp/android/res/drawable-hdpi/icon.png diff --git a/examples/QmlBarcodeGenerator/android/res/drawable-ldpi/icon.png b/examples/QmlBarcodeApp/android/res/drawable-ldpi/icon.png similarity index 100% rename from examples/QmlBarcodeGenerator/android/res/drawable-ldpi/icon.png rename to examples/QmlBarcodeApp/android/res/drawable-ldpi/icon.png diff --git a/examples/QmlBarcodeGenerator/android/res/drawable-mdpi/icon.png b/examples/QmlBarcodeApp/android/res/drawable-mdpi/icon.png similarity index 100% rename from examples/QmlBarcodeGenerator/android/res/drawable-mdpi/icon.png rename to examples/QmlBarcodeApp/android/res/drawable-mdpi/icon.png diff --git a/examples/QmlBarcodeGenerator/android/res/drawable-xhdpi/icon.png b/examples/QmlBarcodeApp/android/res/drawable-xhdpi/icon.png similarity index 100% rename from examples/QmlBarcodeGenerator/android/res/drawable-xhdpi/icon.png rename to examples/QmlBarcodeApp/android/res/drawable-xhdpi/icon.png diff --git a/examples/QmlBarcodeGenerator/android/res/drawable-xxhdpi/icon.png b/examples/QmlBarcodeApp/android/res/drawable-xxhdpi/icon.png similarity index 100% rename from examples/QmlBarcodeGenerator/android/res/drawable-xxhdpi/icon.png rename to examples/QmlBarcodeApp/android/res/drawable-xxhdpi/icon.png diff --git a/examples/QmlBarcodeGenerator/android/res/drawable-xxxhdpi/icon.png b/examples/QmlBarcodeApp/android/res/drawable-xxxhdpi/icon.png similarity index 100% rename from examples/QmlBarcodeGenerator/android/res/drawable-xxxhdpi/icon.png rename to examples/QmlBarcodeApp/android/res/drawable-xxxhdpi/icon.png diff --git a/examples/QmlBarcodeGenerator/android/res/values/libs.xml b/examples/QmlBarcodeApp/android/res/values/libs.xml similarity index 100% rename from examples/QmlBarcodeGenerator/android/res/values/libs.xml rename to examples/QmlBarcodeApp/android/res/values/libs.xml diff --git a/examples/QmlBarcodeReader/cmake/Locations.cmake b/examples/QmlBarcodeApp/cmake/Locations.cmake similarity index 83% rename from examples/QmlBarcodeReader/cmake/Locations.cmake rename to examples/QmlBarcodeApp/cmake/Locations.cmake index 0c773e7..7fead81 100644 --- a/examples/QmlBarcodeReader/cmake/Locations.cmake +++ b/examples/QmlBarcodeApp/cmake/Locations.cmake @@ -1,6 +1,6 @@ -set(COMPANY "Scythe Studio") -set(COPYRIGHT "Copyright (c) 2022 Scythe Studio. Licensed under the Apache License, Version 2.0.") -set(IDENTIFIER "com.scythestudio.scodes.example") +set(COMPANY "Somco Software (prev Scythe Studio)") +set(COPYRIGHT "Copyright (c) 2026 Somco Software. Licensed under the Apache License, Version 2.0.") +set(IDENTIFIER "com.somcosoftware.scodes.example") # ---CONFIGURATION--- option(USE_QML "Add QML support" ON) diff --git a/examples/QmlBarcodeApp/icons/arrow_drop_down.svg b/examples/QmlBarcodeApp/icons/arrow_drop_down.svg new file mode 100644 index 0000000..44c3613 --- /dev/null +++ b/examples/QmlBarcodeApp/icons/arrow_drop_down.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/examples/QmlBarcodeApp/icons/check.svg b/examples/QmlBarcodeApp/icons/check.svg new file mode 100644 index 0000000..a5659dc --- /dev/null +++ b/examples/QmlBarcodeApp/icons/check.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/examples/QmlBarcodeApp/icons/close.svg b/examples/QmlBarcodeApp/icons/close.svg new file mode 100644 index 0000000..fa5fce3 --- /dev/null +++ b/examples/QmlBarcodeApp/icons/close.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/examples/QmlBarcodeApp/icons/download.svg b/examples/QmlBarcodeApp/icons/download.svg new file mode 100644 index 0000000..7602369 --- /dev/null +++ b/examples/QmlBarcodeApp/icons/download.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/examples/QmlBarcodeApp/icons/logo.png b/examples/QmlBarcodeApp/icons/logo.png new file mode 100644 index 0000000..178f824 Binary files /dev/null and b/examples/QmlBarcodeApp/icons/logo.png differ diff --git a/examples/QmlBarcodeApp/icons/obraz.png b/examples/QmlBarcodeApp/icons/obraz.png new file mode 100644 index 0000000..effa3a6 Binary files /dev/null and b/examples/QmlBarcodeApp/icons/obraz.png differ diff --git a/examples/QmlBarcodeApp/main.cpp b/examples/QmlBarcodeApp/main.cpp new file mode 100644 index 0000000..f1e866a --- /dev/null +++ b/examples/QmlBarcodeApp/main.cpp @@ -0,0 +1,51 @@ +#include +#include + +#include "ColorController.h" +#include "VersionHelper.h" + +#include "SBarcodeGenerator.h" +#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0) +#include "SBarcodeFilter.h" +#else +#include "SBarcodeScanner.h" +#endif + +int main(int argc, char* argv[]) +{ + QCoreApplication::setAttribute(Qt::AA_UseDesktopOpenGL); + +#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0) + QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling); +#else + qputenv("QT_QUICK_CONTROLS_STYLE", QByteArray("Basic")); +#endif + + QGuiApplication app(argc, argv); + QQmlApplicationEngine engine; + +#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0) + qmlRegisterType("com.somcosoftware.scodes", 1, 0, "SBarcodeScanner"); +#else + qmlRegisterType("com.somcosoftware.scodes", 1, 0, "SBarcodeScanner"); +#endif + + qmlRegisterType("com.somcosoftware.scodes", 1, 0, "SBarcodeGenerator"); + ColorController colorController; + qmlRegisterSingletonInstance("com.somcosoftware.scodes", 1, 0, "ColorController", &colorController); + VersionHelper versionHelper; + qmlRegisterSingletonInstance("com.somcosoftware.scodes", 1, 0, "VersionHelper", &versionHelper); + + qmlRegisterUncreatableMetaObject( + SCodes::staticMetaObject, "com.somcosoftware.scodes", 1, 0, "SCodes", "Error, enum type"); + + qmlRegisterSingletonType(QUrl("qrc:/qml/Theme.qml"), "Theme", 1, 0, "Theme"); + + engine.load(QUrl(QStringLiteral("qrc:/qml/main.qml"))); + + if (engine.rootObjects().isEmpty()) { + return -1; + } + + return app.exec(); +} diff --git a/examples/QmlBarcodeApp/qml/CButton.qml b/examples/QmlBarcodeApp/qml/CButton.qml new file mode 100644 index 0000000..c1b5d66 --- /dev/null +++ b/examples/QmlBarcodeApp/qml/CButton.qml @@ -0,0 +1,56 @@ +import QtQuick 2.12 +import QtQuick.Controls 2.12 +import QtQuick.Layouts 1.12 + +Button { + id: root + + required property color backgroundColor + required property color textColor + + implicitHeight: 54 + icon.source: "" + + background: Rectangle { + radius: 72 + color: Theme.getButtonBackground(root.backgroundColor, root.enabled, + root.down) + } + + font { + family: Theme.fontFamily + pixelSize: 16 + bold: true + } + + contentItem: Item { + anchors.fill: parent + RowLayout { + anchors.centerIn: parent + spacing: 16 + + implicitWidth: (img.visible ? 24 + 16 : 0) + txt.paintedWidth + Text { + id: txt + Layout.preferredWidth: paintedWidth + text: root.text + color: root.textColor + horizontalAlignment: Text.AlignHCenter + font { + pixelSize: 16 + family: Theme.fontFamily + bold: true + } + } + + Image { + id: img + visible: status == Image.Ready + Layout.preferredHeight: 24 + Layout.preferredWidth: 24 + fillMode: Image.PreserveAspectFit + source: root.icon.source + } + } + } +} diff --git a/examples/QmlBarcodeApp/qml/CComboBox.qml b/examples/QmlBarcodeApp/qml/CComboBox.qml new file mode 100644 index 0000000..08deba6 --- /dev/null +++ b/examples/QmlBarcodeApp/qml/CComboBox.qml @@ -0,0 +1,140 @@ +import QtQuick 2.15 +import QtQuick.Controls 2.15 +import QtQuick.Layouts 1.15 + +ComboBox { + id: root + implicitHeight: 44 + + implicitWidth: leftPadding + contentItem.implicitWidth + 6 + indicator.width + rightPadding + + topPadding: 12 + bottomPadding: 12 + leftPadding: 12 + rightPadding: 16 + editable: false + + background: Rectangle { + radius: 72 + color: Theme.white + } + + contentItem: Text { + anchors { + fill: parent + rightMargin: root.rightPadding + 6 + root.indicator.width + } + text: root.displayText + color: Theme.black + horizontalAlignment: Text.AlignLeft + verticalAlignment: Text.AlignVCenter + leftPadding: 10 + font.pixelSize: 16 + } + + indicator: Item { + x: root.width - width - root.rightPadding + y: root.topPadding + (root.availableHeight - height) / 2 + width: 32 + height: 32 + + Image { + anchors.fill: parent + + fillMode: Image.PreserveAspectFit + source: "qrc:/icons/arrow_drop_down.svg" + rotation: root.down ? 180 : 0 + + Behavior on rotation { + NumberAnimation { + duration: 300 + easing.type: Easing.Linear + } + } + } + } + + popup: Popup { + id: popup + y: root.height + width: root.width + implicitHeight: Math.min(contentItem.implicitHeight + 24, 272) + + contentItem: ListView { + id: listView + clip: true + implicitHeight: contentHeight + model: root.visible ? root.delegateModel : null + currentIndex: root.highlightedIndex + boundsBehavior: Flickable.StopAtBounds + highlightMoveDuration: 0 + snapMode: ListView.SnapToItem + spacing: 8 + + ScrollBar.vertical: ScrollBar { + id: scrollBar + active: listView.contentHeight > popup.implicitHeight + } + } + + background: Rectangle { + color: Theme.white + radius: 22 + } + } + + delegate: Rectangle { + id: comboBoxDelegate + required property var model + required property int index + + property bool isCurrentItem: ListView.view.currentIndex === index + + height: 36 + width: ListView.view.width - scrollBar.width + color: Theme.white + Rectangle { + anchors { + left: parent.left + right: parent.right + bottom: parent.bottom + } + height: 1 + color: Theme.shadowGreen + opacity: 0.2 + } + + RowLayout { + spacing: 16 + anchors { + fill: parent + leftMargin: root.leftPadding + rightMargin: root.rightPadding + } + + Text { + Layout.fillWidth: true + text: comboBoxDelegate.model[root.textRole] + font.pixelSize: 16 + font.bold: comboBoxDelegate.isCurrentItem + color: Theme.black + } + + Image { + Layout.preferredHeight: 32 + Layout.preferredWidth: 32 + fillMode: Image.PreserveAspectFit + source: "qrc:/icons/check.svg" + visible: comboBoxDelegate.isCurrentItem + } + } + + MouseArea { + anchors.fill: parent + onClicked: { + root.currentIndex = index + root.popup.close() + } + } + } +} diff --git a/examples/QmlBarcodeApp/qml/CTabButton.qml b/examples/QmlBarcodeApp/qml/CTabButton.qml new file mode 100644 index 0000000..335b3b9 --- /dev/null +++ b/examples/QmlBarcodeApp/qml/CTabButton.qml @@ -0,0 +1,33 @@ +import QtQuick 2.15 +import QtQuick.Controls 2.15 + +TabButton { + id: root + implicitHeight: 59 + background: Item { + anchors.fill: parent + Rectangle { + anchors { + left: parent.left + leftMargin: 36 + right: parent.right + rightMargin: 36 + bottom: parent.bottom + } + implicitHeight: 4 + visible: root.checked + color: Theme.tabbar.activeBorderColor + } + } + + contentItem: Text { + text: root.text + font.bold: root.checked + font.family: Theme.fontFamily + font.pixelSize: 16 + horizontalAlignment: Text.AlignHCenter + verticalAlignment: Text.AlignVCenter + + color: Theme.black + } +} diff --git a/examples/QmlBarcodeApp/qml/CTextField.qml b/examples/QmlBarcodeApp/qml/CTextField.qml new file mode 100644 index 0000000..785c417 --- /dev/null +++ b/examples/QmlBarcodeApp/qml/CTextField.qml @@ -0,0 +1,30 @@ +import QtQuick 2.15 +import QtQuick.Controls 2.15 + + +/*! + Field for setting width, height, margin & error correction code level parameters. + */ +TextField { + id: root + + background: Item { + anchors.fill: parent + + Rectangle { + anchors { + left: parent.left + right: parent.right + bottom: parent.bottom + } + height: 2 + color: Theme.textField.borderColor + } + } + + font.pixelSize: 16 + font.family: Theme.fontFamily + + placeholderTextColor: Theme.textField.placeholderTextColor + color: Theme.textField.textColor +} diff --git a/examples/QmlBarcodeApp/qml/GeneratorPage.qml b/examples/QmlBarcodeApp/qml/GeneratorPage.qml new file mode 100644 index 0000000..bc05c1e --- /dev/null +++ b/examples/QmlBarcodeApp/qml/GeneratorPage.qml @@ -0,0 +1,260 @@ +import QtQuick 2.12 +import QtQuick.Controls 2.12 +import QtMultimedia 5.12 +import QtQuick.Layouts 1.12 + +import com.somcosoftware.scodes 1.0 + +Item { + SBarcodeGenerator { + id: barcodeGenerator + + onGenerationFinished: function (error) { + resultStack.currentIndex = 1 + if (error === "") { + console.log(barcodeGenerator.filePath) + resultImage.source = "file:///" + barcodeGenerator.filePath + } else { + errorLabel.text = error + } + } + } + + StackLayout { + id: resultStack + anchors { + fill: parent + margins: 16 + } + + Item { + ColumnLayout { + anchors.fill: parent + spacing: 32 + + ColumnLayout { + Layout.fillWidth: true + + spacing: 8 + Text { + Layout.fillWidth: true + text: qsTr("Select format to generate") + color: Theme.textColor + font { + pixelSize: 14 + family: Theme.fontFamily + bold: true + } + } + + CComboBox { + id: formatDropDown + Layout.fillWidth: true + textRole: "text" + + model: ListModel { + ListElement { + text: "Aztec" + } + ListElement { + text: "Codabar" + } + ListElement { + text: "Code39" + } + ListElement { + text: "Code93" + } + ListElement { + text: "Code128" + } + ListElement { + text: "DataMatrix" + } + ListElement { + text: "EAN-8" + } + ListElement { + text: "EAN-13" + } + ListElement { + text: "ITF" + } + ListElement { + text: "PDF417" + } + ListElement { + text: "QRCode" + } + ListElement { + text: "UPC-A" + } + ListElement { + text: "UPC-E" + } + } + + onCurrentTextChanged: function () { + barcodeGenerator.setFormat(currentText) + } + } + } + + ColumnLayout { + Layout.fillWidth: true + spacing: 8 + Text { + Layout.fillWidth: true + text: qsTr("Enter text") + color: Theme.textColor + font { + pixelSize: 14 + family: Theme.fontFamily + bold: true + } + } + + CTextField { + id: textField + Layout.fillWidth: true + placeholderText: qsTr("Input") + } + } + + Item { + Layout.fillWidth: true + Layout.fillHeight: true + Image { + anchors { + fill: parent + margins: 16 + } + fillMode: Image.PreserveAspectFit + source: "qrc:/icons/obraz.png" + } + } + + CButton { + Layout.fillWidth: true + text: qsTr("Generate") + backgroundColor: Theme.teal + textColor: Theme.white + enabled: textField.text !== "" + onClicked: { + barcodeGenerator.generate(textField.text) + } + } + } + } + + Item { + ColumnLayout { + anchors.fill: parent + spacing: 32 + + Text { + id: generateLabel + Layout.fillWidth: true + text: qsTr("Your code has been generated!") + font.family: Theme.fontFamily + font.pixelSize: 16 + visible: !errorLabel.visible + horizontalAlignment: Text.AlignHCenter + } + + Text { + id: errorLabel + Layout.fillWidth: true + Layout.topMargin: 40 + color: Theme.red + visible: text !== "" + font.pixelSize: 18 + horizontalAlignment: Text.AlignHCenter + } + + Item { + Layout.fillHeight: true + } + + Item { + Layout.fillHeight: true + Layout.fillWidth: true + Layout.leftMargin: 50 + Layout.rightMargin: 50 + Layout.preferredHeight: width + Image { + id: resultImage + anchors.fill: parent + fillMode: Image.PreserveAspectFit + cache: false + } + } + + Item { + Layout.fillHeight: true + } + + ColumnLayout { + Layout.fillWidth: true + CButton { + Layout.fillWidth: true + text: qsTr("Clear") + backgroundColor: Theme.white + textColor: Theme.red + icon.source: "qrc:/icons/close.svg" + onClicked: { + errorLabel.text = "" + resultImage.source = "" + resultStack.currentIndex = 0 + } + } + + CButton { + Layout.fillWidth: true + enabled: !errorLabel.visible + text: qsTr("Download") + backgroundColor: Theme.teal + textColor: Theme.white + icon.source: "qrc:/icons/download.svg" + onClicked: { + if (barcodeGenerator.saveImage()) { + messagePopup.showMessage( + qsTr("File successfully saved: " + + barcodeGenerator.filePath)) + } else { + messagePopup.showMessage( + qsTr("There was an error while saving file")) + } + } + } + } + } + } + } + + Popup { + id: messagePopup + anchors.centerIn: parent + + function showMessage(message) { + messagePopupLabel.text = message + messagePopup.open() + } + + dim: true + modal: true + + implicitWidth: messagePopupLabel.paintedWidth + 40 + implicitHeight: messagePopupLabel.paintedHeight + 80 + + background: Rectangle { + color: Theme.white + radius: 20 + } + + Label { + id: messagePopupLabel + anchors.centerIn: parent + } + } +} diff --git a/examples/QmlBarcodeApp/qml/Qt5ScannerPage.qml b/examples/QmlBarcodeApp/qml/Qt5ScannerPage.qml new file mode 100644 index 0000000..54ef9c4 --- /dev/null +++ b/examples/QmlBarcodeApp/qml/Qt5ScannerPage.qml @@ -0,0 +1,111 @@ +import QtQuick 2.12 +import QtQuick.Controls 2.12 +import QtQuick.Layouts 1.15 +import QtMultimedia 5.12 + +import com.somcosoftware.scodes 1.0 + +Item { + id: root + + Camera { + id: camera + + focus { + focusMode: CameraFocus.FocusAuto + focusPointMode: CameraFocus.FocusPointAuto + } + } + + VideoOutput { + id: videoOutput + + anchors.fill: parent + source: camera + autoOrientation: true + fillMode: VideoOutput.PreserveAspectCrop + filters: [barcodeScanner] + + ScannerOverlay { + id: scannerOverlay + anchors.fill: parent + + captureRect: barcodeScanner.captureRect + } + + // used to get camera focus on touched point + MouseArea { + id: focusTouchArea + anchors.fill: parent + enabled: camera.focus.isFocusPointModeSupported(Camera.FocusMacro) + + onClicked: { + camera.focus.customFocusPoint = Qt.point(mouse.x / width, + mouse.y / height) + camera.focus.focusMode = CameraFocus.FocusMacro + camera.focus.focusPointMode = CameraFocus.FocusPointCustom + } + } + } + + SBarcodeScanner { + id: barcodeScanner + + captureRect: Qt.rect(0.25, 0.25, 0.5, 0.5) + + onCapturedChanged: captured => { + active = false + console.log("captured: " + captured) + } + } + + Rectangle { + id: resultScreen + anchors.centerIn: parent + + visible: !barcodeScanner.active + + x: barcodeScanner.captureRect.x * parent.width + y: barcodeScanner.captureRect.y * parent.height + width: barcodeScanner.captureRect.width * parent.width + height: Math.max(barcodeScanner.captureRect.height * parent.height, + popupLayout.implicitHeight + 64) + + color: Theme.white + + ColumnLayout { + id: popupLayout + anchors { + fill: parent + margins: 32 + } + spacing: 20 + + Text { + id: capturedText + Layout.fillWidth: true + Layout.fillHeight: true + wrapMode: Text.WordWrap + font { + family: Theme.fontFamily + pixelSize: 14 + } + horizontalAlignment: Text.AlignHCenter + verticalAlignment: Text.AlignVCenter + + text: barcodeScanner.captured + } + + CButton { + Layout.fillWidth: true + text: qsTr("Scan again") + backgroundColor: Theme.teal + textColor: Theme.white + + onClicked: { + barcodeScanner.active = true + } + } + } + } +} diff --git a/examples/QmlBarcodeReader/qml/Qt6ScannerOverlay.qml b/examples/QmlBarcodeApp/qml/Qt6ScannerOverlay.qml similarity index 100% rename from examples/QmlBarcodeReader/qml/Qt6ScannerOverlay.qml rename to examples/QmlBarcodeApp/qml/Qt6ScannerOverlay.qml diff --git a/examples/QmlBarcodeApp/qml/Qt6ScannerPage.qml b/examples/QmlBarcodeApp/qml/Qt6ScannerPage.qml new file mode 100644 index 0000000..95c8590 --- /dev/null +++ b/examples/QmlBarcodeApp/qml/Qt6ScannerPage.qml @@ -0,0 +1,89 @@ +import QtQuick +import QtQuick.Layouts +import QtMultimedia + +import com.somcosoftware.scodes 1.0 + +Item { + id: root + + SBarcodeScanner { + id: barcodeScanner + + forwardVideoSink: videoOutput.videoSink + + captureRect: Qt.rect(0.25, 0.25, 0.5, 0.5) + + onCapturedChanged: function (captured) { + scanning = false + capturedText.text = captured + resultScreen.visible = true + } + } + + VideoOutput { + id: videoOutput + + anchors.fill: parent + + width: root.width + + focus: visible + fillMode: VideoOutput.PreserveAspectCrop + } + + ScannerOverlay { + id: scannerOverlay + + anchors.fill: parent + captureRect: barcodeScanner.captureRect + } + + Rectangle { + id: resultScreen + anchors.centerIn: parent + + visible: false + + x: barcodeScanner.captureRect.x * parent.width + y: barcodeScanner.captureRect.y * parent.height + width: barcodeScanner.captureRect.width * parent.width + height: Math.max(barcodeScanner.captureRect.height * parent.height, + popupLayout.implicitHeight + 64) + + ColumnLayout { + id: popupLayout + anchors { + fill: parent + margins: 32 + } + spacing: 20 + + Text { + id: capturedText + Layout.fillWidth: true + Layout.fillHeight: true + wrapMode: Text.WordWrap + font { + family: Theme.fontFamily + pixelSize: 14 + } + horizontalAlignment: Text.AlignHCenter + verticalAlignment: Text.AlignVCenter + } + + CButton { + Layout.fillWidth: true + text: qsTr("Scan again") + backgroundColor: Theme.teal + textColor: Theme.white + + onClicked: { + resultScreen.visible = false + capturedText.text = "" + barcodeScanner.scanning = true + } + } + } + } +} diff --git a/examples/QmlBarcodeApp/qml/ScannerOverlay.qml b/examples/QmlBarcodeApp/qml/ScannerOverlay.qml new file mode 100644 index 0000000..9a8c461 --- /dev/null +++ b/examples/QmlBarcodeApp/qml/ScannerOverlay.qml @@ -0,0 +1,31 @@ +import QtQuick 2.12 + +Item { + id: root + + property rect captureRect + + Subtrack { + anchors.fill: parent + captureRect: root.captureRect + } + + Text { + id: scanCapsuleText + + anchors { + top: parent.top + topMargin: 19 + left: parent.left + leftMargin: 32 + right: parent.right + rightMargin: 32 + } + text: qsTr("Place the QR code to be scanned inside the frame") + font.family: Theme.fontFamily + font.pixelSize: 16 + horizontalAlignment: Text.AlignHCenter + color: Theme.white + wrapMode: Text.WordWrap + } +} diff --git a/examples/QmlBarcodeApp/qml/Subtrack.qml b/examples/QmlBarcodeApp/qml/Subtrack.qml new file mode 100644 index 0000000..8711350 --- /dev/null +++ b/examples/QmlBarcodeApp/qml/Subtrack.qml @@ -0,0 +1,38 @@ +// Subtrack.qml +import QtQuick 2.15 + +import com.somcosoftware.scodes 1.0 + +Canvas { + id: root + anchors.fill: parent + antialiasing: true + + property color baseColor: Theme.subtrack.backgroundColor + property real outerOpacity: Theme.subtrack.opacity + property rect captureRect: Qt.rect(0.25, 0.25, 0.5, 0.5) + + onPaint: { + var ctx = getContext("2d") + ctx.reset() + + // Background overlay + ctx.fillStyle = Qt.rgba(root.baseColor.r, root.baseColor.g, + root.baseColor.b, root.outerOpacity) + + ctx.fillRect(0, 0, width, height) + + var rx = root.captureRect.x * width + var ry = root.captureRect.y * height + var rw = root.captureRect.width * width + var rh = root.captureRect.height * height + + ctx.clearRect(rx, ry, rw, rh) + } + + onWidthChanged: requestPaint() + onHeightChanged: requestPaint() + onCaptureRectChanged: requestPaint() + onBaseColorChanged: requestPaint() + onOuterOpacityChanged: requestPaint() +} diff --git a/examples/QmlBarcodeApp/qml/Theme.qml b/examples/QmlBarcodeApp/qml/Theme.qml new file mode 100644 index 0000000..6652521 --- /dev/null +++ b/examples/QmlBarcodeApp/qml/Theme.qml @@ -0,0 +1,57 @@ +pragma Singleton + +import QtQuick 2.12 + +QtObject { + id: root + + readonly property string fontFamily: "Inter" + + readonly property color black: "#000000" + readonly property color white: "#FFFFFF" + readonly property color transparent: "transparent" + readonly property color teal: "#1DCA9B" + readonly property color shadowGreen: "#A3C8BF" + readonly property color red: "#E64646" + + readonly property QtObject tabbar: QtObject { + readonly property color inactiveBorderColor: root.shadowGreen + readonly property color activeBorderColor: root.teal + } + + readonly property QtObject subtrack: QtObject { + readonly property color backgroundColor: "#535353" + readonly property real opacity: 0.71 + } + + readonly property QtObject background: QtObject { + readonly property color color1: root.white + readonly property color color2: "#E8E8E8" + } + + readonly property QtObject textField: QtObject { + readonly property color borderColor: "#D9D9D9" + readonly property color placeholderTextColor: "#B8B8B8" + readonly property color textColor: root.black + } + + readonly property color textColor: "#676767" + + function getButtonBackground(baseColor, enabled, pressed) { + if (!enabled) { + if (baseColor === root.white) + return "#E6E6E6" // disabled white + if (baseColor === root.teal) + return "#8FD9C7" // disabled teal + } + + if (pressed) { + if (baseColor === root.white) + return "#F2F2F2" // pressed white + if (baseColor === root.teal) + return "#17A884" // pressed teal + } + + return baseColor + } +} diff --git a/examples/QmlBarcodeApp/qml/main.qml b/examples/QmlBarcodeApp/qml/main.qml new file mode 100644 index 0000000..b6a2cbf --- /dev/null +++ b/examples/QmlBarcodeApp/qml/main.qml @@ -0,0 +1,92 @@ +import QtQuick 2.15 +import QtQuick.Controls 2.15 +import QtQuick.Layouts 1.15 + +import com.somcosoftware.scodes 1.0 + +ApplicationWindow { + id: appWindow + + visible: true + + width: Qt.platform.os === "android" + || Qt.platform.os === "ios" ? Screen.width : 800 + height: Qt.platform.os === "android" + || Qt.platform.os === "ios" ? Screen.height : 800 + + background: Rectangle { + gradient: Gradient { + GradientStop { + position: 0.0 + color: Theme.background.color1 + } + GradientStop { + position: 1.0 + color: Theme.background.color2 + } + } + } + + MouseArea { + id: hideKeyboard + anchors.fill: parent + onClicked: { + Qt.inputMethod.hide() + } + } + + ColumnLayout { + anchors.fill: parent + + Image { + Layout.fillWidth: true + Layout.alignment: Qt.AlignCenter + Layout.preferredHeight: 28 + Layout.topMargin: 16 + Layout.bottomMargin: 16 + fillMode: Image.PreserveAspectFit + source: "qrc:/icons/logo.png" + } + + TabBar { + id: tabBar + Layout.fillWidth: true + + background: Item { + anchors.fill: parent + Rectangle { + anchors { + left: parent.left + right: parent.right + bottom: parent.bottom + } + implicitHeight: 1 + color: Theme.tabbar.inactiveBorderColor + } + } + + CTabButton { + text: qsTr("Scan") + } + + CTabButton { + text: qsTr("Generate") + } + } + + StackLayout { + id: stackLayout + currentIndex: tabBar.currentIndex + Layout.fillWidth: true + Layout.fillHeight: true + + Loader { + source: VersionHelper.isQt6 ? "Qt6ScannerPage.qml" : "Qt5ScannerPage.qml" + } + + Loader { + source: "GeneratorPage.qml" + } + } + } +} diff --git a/examples/QmlBarcodeReader/qrScanner/QrDecoder.cpp b/examples/QmlBarcodeApp/qrScanner/QrDecoder.cpp similarity index 100% rename from examples/QmlBarcodeReader/qrScanner/QrDecoder.cpp rename to examples/QmlBarcodeApp/qrScanner/QrDecoder.cpp diff --git a/examples/QmlBarcodeReader/qrScanner/QrDecoder.h b/examples/QmlBarcodeApp/qrScanner/QrDecoder.h similarity index 100% rename from examples/QmlBarcodeReader/qrScanner/QrDecoder.h rename to examples/QmlBarcodeApp/qrScanner/QrDecoder.h diff --git a/examples/QmlBarcodeReader/qrScanner/QrScannerFilter.cpp b/examples/QmlBarcodeApp/qrScanner/QrScannerFilter.cpp similarity index 100% rename from examples/QmlBarcodeReader/qrScanner/QrScannerFilter.cpp rename to examples/QmlBarcodeApp/qrScanner/QrScannerFilter.cpp diff --git a/examples/QmlBarcodeReader/qrScanner/QrScannerFilter.h b/examples/QmlBarcodeApp/qrScanner/QrScannerFilter.h similarity index 100% rename from examples/QmlBarcodeReader/qrScanner/QrScannerFilter.h rename to examples/QmlBarcodeApp/qrScanner/QrScannerFilter.h diff --git a/examples/QmlBarcodeGenerator/CMakeLists.txt b/examples/QmlBarcodeGenerator/CMakeLists.txt deleted file mode 100644 index 13461b9..0000000 --- a/examples/QmlBarcodeGenerator/CMakeLists.txt +++ /dev/null @@ -1,51 +0,0 @@ -cmake_minimum_required(VERSION 3.16) - -project(QmlBarcodeGenerator LANGUAGES CXX) - -set(CMAKE_INCLUDE_CURRENT_DIR ON) - -set(CMAKE_AUTOMOC ON) -set(CMAKE_AUTORCC ON) - -set(CMAKE_CXX_STANDARD 17) -set(CMAKE_CXX_STANDARD_REQUIRED ON) - -#Check this file for any *_DIR variable definitions and other -include("cmake/Locations.cmake") - -qt_add_resources(RSCS qml.qrc) - -add_subdirectory(${LIB_DIR} ${CMAKE_BINARY_DIR}/SCodes) - -if(ANDROID) - if(QT_VERSION_MAJOR EQUAL 5) - set(ANDROID_MIN_SDK_VERSION 21) - set(ANDROID_ABI "armeabi-v7a") - set(QT_ANDROID_PACKAGE_SOURCE_DIR ${PROJECT_SOURCE_DIR}/android) - - set(ANDROID_SOURCES - ${QT_ANDROID_PACKAGE_SOURCE_DIR}/AndroidManifest.xml - ${QT_ANDROID_PACKAGE_SOURCE_DIR}/build.gradle - ${QT_ANDROID_PACKAGE_SOURCE_DIR}/gradle/wrapper/gradle-wrapper.jar - ${QT_ANDROID_PACKAGE_SOURCE_DIR}/gradle/wrapper/gradle-wrapper.properties - ${QT_ANDROID_PACKAGE_SOURCE_DIR}/gradlew - ${QT_ANDROID_PACKAGE_SOURCE_DIR}/res/values/libs.xml - ) - add_library(${PROJECT_NAME} SHARED main.cpp ${RSCS} ${ANDROID_SOURCES}) - else() - qt_add_executable(${PROJECT_NAME} MANUAL_FINALIZATION main.cpp ${RSCS}) - set_target_properties(${PROJECT_NAME} PROPERTIES - QT_ANDROID_PACKAGE_SOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/android" - ) - endif() -else() - add_executable(${PROJECT_NAME} main.cpp ${RSCS} ColorController.h ColorController.cpp) -endif() - -target_link_libraries(${PROJECT_NAME} PRIVATE ${REQUIRED_QT_LIBS} SCodes) - -if(QT_VERSION_MAJOR EQUAL 6) - qt_import_qml_plugins(${PROJECT_NAME}) - qt_finalize_executable(${PROJECT_NAME}) - qt_finalize_project(${PROJECT_NAME}) -endif() diff --git a/examples/QmlBarcodeGenerator/QmlBarcodeGenerator.pro b/examples/QmlBarcodeGenerator/QmlBarcodeGenerator.pro deleted file mode 100644 index e92445c..0000000 --- a/examples/QmlBarcodeGenerator/QmlBarcodeGenerator.pro +++ /dev/null @@ -1,37 +0,0 @@ -include("../../src/SCodes.pri") - -QT += quick -CONFIG += c++17 - -DEFINES += QT_DEPRECATED_WARNINGS - - -HEADERS += \ - ColorController.h - -SOURCES += \ - ColorController.cpp \ - main.cpp - -RESOURCES += qml.qrc - -# Default rules for deployment. -qnx: target.path = /tmp/$${TARGET}/bin -else: unix:!android: target.path = /opt/$${TARGET}/bin -!isEmpty(target.path): INSTALLS += target - -android { - DISTFILES += \ - android/AndroidManifest.xml \ - android/build.gradle \ - android/gradle/wrapper/gradle-wrapper.jar \ - android/gradle/wrapper/gradle-wrapper.properties \ - android/gradlew \ - android/gradlew.bat \ - android/res/values/libs.xml - - ANDROID_PACKAGE_SOURCE_DIR = $$PWD/android - - ANDROID_ABIS = armeabi-v7a -} - diff --git a/examples/QmlBarcodeGenerator/android.7z b/examples/QmlBarcodeGenerator/android.7z deleted file mode 100644 index d5c1bb7..0000000 Binary files a/examples/QmlBarcodeGenerator/android.7z and /dev/null differ diff --git a/examples/QmlBarcodeGenerator/android/AndroidManifest.xml b/examples/QmlBarcodeGenerator/android/AndroidManifest.xml deleted file mode 100644 index 1deca45..0000000 --- a/examples/QmlBarcodeGenerator/android/AndroidManifest.xml +++ /dev/null @@ -1,17 +0,0 @@ - - - - - - - - - - - - - - - - - diff --git a/examples/QmlBarcodeGenerator/android/build.gradle b/examples/QmlBarcodeGenerator/android/build.gradle deleted file mode 100644 index 275b825..0000000 --- a/examples/QmlBarcodeGenerator/android/build.gradle +++ /dev/null @@ -1,82 +0,0 @@ -buildscript { - repositories { - google() - mavenCentral() - } - - dependencies { - classpath 'com.android.tools.build:gradle:7.0.2' - } -} - -repositories { - google() - mavenCentral() -} - -apply plugin: 'com.android.application' - -dependencies { - implementation fileTree(dir: 'libs', include: ['*.jar', '*.aar']) -} - -android { - /******************************************************* - * The following variables: - * - androidBuildToolsVersion, - * - androidCompileSdkVersion - * - qtAndroidDir - holds the path to qt android files - * needed to build any Qt application - * on Android. - * - * are defined in gradle.properties file. This file is - * updated by QtCreator and androiddeployqt tools. - * Changing them manually might break the compilation! - *******************************************************/ - - compileSdkVersion androidCompileSdkVersion.toInteger() - buildToolsVersion androidBuildToolsVersion - ndkVersion androidNdkVersion - - sourceSets { - main { - manifest.srcFile 'AndroidManifest.xml' - java.srcDirs = [qtAndroidDir + '/src', 'src', 'java'] - aidl.srcDirs = [qtAndroidDir + '/src', 'src', 'aidl'] - res.srcDirs = [qtAndroidDir + '/res', 'res'] - resources.srcDirs = ['resources'] - renderscript.srcDirs = ['src'] - assets.srcDirs = ['assets'] - jniLibs.srcDirs = ['libs'] - } - } - - tasks.withType(JavaCompile) { - options.incremental = true - } - - compileOptions { - sourceCompatibility JavaVersion.VERSION_1_8 - targetCompatibility JavaVersion.VERSION_1_8 - } - - lintOptions { - abortOnError false - } - - // Do not compress Qt binary resources file - aaptOptions { - noCompress 'rcc' - } - - defaultConfig { - resConfig "en" - minSdkVersion qtMinSdkVersion - targetSdkVersion qtTargetSdkVersion - ndk.abiFilters = qtTargetAbiList.split(",") - - ndk { - abiFilters 'armeabi-v7a' - } - } -} diff --git a/examples/QmlBarcodeGenerator/android/gradle.properties b/examples/QmlBarcodeGenerator/android/gradle.properties deleted file mode 100644 index 263d702..0000000 --- a/examples/QmlBarcodeGenerator/android/gradle.properties +++ /dev/null @@ -1,14 +0,0 @@ -# Project-wide Gradle settings. -# For more details on how to configure your build environment visit -# http://www.gradle.org/docs/current/userguide/build_environment.html -# Specifies the JVM arguments used for the daemon process. -# The setting is particularly useful for tweaking memory settings. -org.gradle.jvmargs=-Xmx2500m -XX:MaxMetaspaceSize=512m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8 - -# Enable building projects in parallel -org.gradle.parallel=true - -# Gradle caching allows reusing the build artifacts from a previous -# build with the same inputs. However, over time, the cache size will -# grow. Uncomment the following line to enable it. -#org.gradle.caching=true diff --git a/examples/QmlBarcodeGenerator/android/gradle/wrapper/gradle-wrapper.jar b/examples/QmlBarcodeGenerator/android/gradle/wrapper/gradle-wrapper.jar deleted file mode 100644 index 41d9927..0000000 Binary files a/examples/QmlBarcodeGenerator/android/gradle/wrapper/gradle-wrapper.jar and /dev/null differ diff --git a/examples/QmlBarcodeGenerator/android/gradlew.bat b/examples/QmlBarcodeGenerator/android/gradlew.bat deleted file mode 100644 index 4cc84e5..0000000 --- a/examples/QmlBarcodeGenerator/android/gradlew.bat +++ /dev/null @@ -1,89 +0,0 @@ -@rem -@rem Copyright 2015 the original author or authors. -@rem -@rem Licensed under the Apache License, Version 2.0 (the "License"); -@rem you may not use this file except in compliance with the License. -@rem You may obtain a copy of the License at -@rem -@rem https://www.apache.org/licenses/LICENSE-2.0 -@rem -@rem Unless required by applicable law or agreed to in writing, software -@rem distributed under the License is distributed on an "AS IS" BASIS, -@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -@rem See the License for the specific language governing permissions and -@rem limitations under the License. -@rem - -@if "%DEBUG%" == "" @echo off -@rem ########################################################################## -@rem -@rem Gradle startup script for Windows -@rem -@rem ########################################################################## - -@rem Set local scope for the variables with windows NT shell -if "%OS%"=="Windows_NT" setlocal - -set DIRNAME=%~dp0 -if "%DIRNAME%" == "" set DIRNAME=. -set APP_BASE_NAME=%~n0 -set APP_HOME=%DIRNAME% - -@rem Resolve any "." and ".." in APP_HOME to make it shorter. -for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi - -@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. -set DEFAULT_JVM_OPTS=-Dfile.encoding=UTF-8 "-Xmx64m" "-Xms64m" - -@rem Find java.exe -if defined JAVA_HOME goto findJavaFromJavaHome - -set JAVA_EXE=java.exe -%JAVA_EXE% -version >NUL 2>&1 -if "%ERRORLEVEL%" == "0" goto execute - -echo. -echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. -echo. -echo Please set the JAVA_HOME variable in your environment to match the -echo location of your Java installation. - -goto fail - -:findJavaFromJavaHome -set JAVA_HOME=%JAVA_HOME:"=% -set JAVA_EXE=%JAVA_HOME%/bin/java.exe - -if exist "%JAVA_EXE%" goto execute - -echo. -echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% -echo. -echo Please set the JAVA_HOME variable in your environment to match the -echo location of your Java installation. - -goto fail - -:execute -@rem Setup the command line - -set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar - - -@rem Execute Gradle -"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* - -:end -@rem End local scope for the variables with windows NT shell -if "%ERRORLEVEL%"=="0" goto mainEnd - -:fail -rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of -rem the _cmd.exe /c_ return code! -if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 -exit /b 1 - -:mainEnd -if "%OS%"=="Windows_NT" endlocal - -:omega diff --git a/examples/QmlBarcodeGenerator/cmake/Locations.cmake b/examples/QmlBarcodeGenerator/cmake/Locations.cmake deleted file mode 100644 index 0c773e7..0000000 --- a/examples/QmlBarcodeGenerator/cmake/Locations.cmake +++ /dev/null @@ -1,37 +0,0 @@ -set(COMPANY "Scythe Studio") -set(COPYRIGHT "Copyright (c) 2022 Scythe Studio. Licensed under the Apache License, Version 2.0.") -set(IDENTIFIER "com.scythestudio.scodes.example") - -# ---CONFIGURATION--- -option(USE_QML "Add QML support" ON) -option(USE_LIBS "Use external libraries" ON) - -# Locations - directories in project structure -set(LIB_DIR ${CMAKE_SOURCE_DIR}/../../src) - -set(SRC_DIR ".") -set(RES_DIR ".") -set(QML_DIR "qml") - -# Check Qt version -find_package(QT NAMES Qt6 Qt5 REQUIRED COMPONENTS Core) -find_package(Qt${QT_VERSION_MAJOR} REQUIRED COMPONENTS Core) - -# ---PACKAGES SECTION--- -list(APPEND REQUIRED_QT_PACKAGES Core Quick Gui Multimedia) - -if(USE_QML) - list(APPEND REQUIRED_QT_PACKAGES Quick) - list(APPEND QML_IMPORT_PATH "${CMAKE_SOURCE_DIR}/${QML_DIR}") - set(QML_IMPORT_PATH ${QML_IMPORT_PATH} - CACHE STRING "Qt Creator Import Path" - FORCE) -endif() - -foreach(QT_PACKAGE ${REQUIRED_QT_PACKAGES}) - list(APPEND REQUIRED_QT_LIBS Qt${QT_VERSION_MAJOR}::${QT_PACKAGE}) -endforeach() - -find_package(QT NAMES Qt${QT_VERSION_MAJOR} COMPONENTS ${REQUIRED_QT_PACKAGES} REQUIRED) -find_package(Qt${QT_VERSION_MAJOR} COMPONENTS ${REQUIRED_QT_PACKAGES} REQUIRED) - diff --git a/examples/QmlBarcodeGenerator/main.cpp b/examples/QmlBarcodeGenerator/main.cpp deleted file mode 100644 index 047d179..0000000 --- a/examples/QmlBarcodeGenerator/main.cpp +++ /dev/null @@ -1,30 +0,0 @@ -#include -#include - -#include "SBarcodeGenerator.h" -#include "ColorController.h" - -int main(int argc, char *argv[]) -{ - -#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0) - QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling); -#endif - - QGuiApplication app(argc, argv); - - QQmlApplicationEngine engine; - - qmlRegisterSingletonType(QUrl("qrc:/qml/Theme.qml"), "Theme", 1, 0, "Theme"); - - qmlRegisterType("com.scythestudio.scodes", 1, 0, "SBarcodeGenerator"); - qmlRegisterType("com.scythestudio.scodes", 1, 0, "ColorController"); - - engine.load(QUrl(QStringLiteral("qrc:/qml/GeneratorPage.qml"))); - - if (engine.rootObjects().isEmpty()) { - return -1; - } - - return app.exec(); -} diff --git a/examples/QmlBarcodeGenerator/qml.qrc b/examples/QmlBarcodeGenerator/qml.qrc deleted file mode 100644 index 35d6725..0000000 --- a/examples/QmlBarcodeGenerator/qml.qrc +++ /dev/null @@ -1,9 +0,0 @@ - - - qml/GeneratorPage.qml - qml/CButton.qml - qml/CTextField.qml - qml/CComboBox.qml - qml/Theme.qml - - diff --git a/examples/QmlBarcodeGenerator/qml/CButton.qml b/examples/QmlBarcodeGenerator/qml/CButton.qml deleted file mode 100644 index 5c687ce..0000000 --- a/examples/QmlBarcodeGenerator/qml/CButton.qml +++ /dev/null @@ -1,25 +0,0 @@ -import QtQuick 2.12 -import QtQuick.Controls 2.12 -import QtQuick.Layouts 1.12 -import QtQuick.Window 2.12 - - -/*! - Classic push button for configure, generate & save operations. - */ -Button { - id: root - - height: 100 - implicitWidth: appWindow.width / 4 - - checkable: true - - palette.buttonText: Theme.textColor - - background: Rectangle { - radius: 10 - color: root.pressed ? Qt.darker( - Theme.backgroundColor) : Theme.backgroundColor - } -} diff --git a/examples/QmlBarcodeGenerator/qml/CComboBox.qml b/examples/QmlBarcodeGenerator/qml/CComboBox.qml deleted file mode 100644 index 5811a57..0000000 --- a/examples/QmlBarcodeGenerator/qml/CComboBox.qml +++ /dev/null @@ -1,19 +0,0 @@ -import QtQuick 2.12 -import QtQuick.Controls 2.12 - - -/*! - Drop-down menu for barcode format selection & save file format extension - */ -ComboBox { - id: root - - background: Rectangle { - radius: 2 - - border { - color: Theme.borderColor - width: 1 - } - } -} diff --git a/examples/QmlBarcodeGenerator/qml/CTextField.qml b/examples/QmlBarcodeGenerator/qml/CTextField.qml deleted file mode 100644 index 7a9e83b..0000000 --- a/examples/QmlBarcodeGenerator/qml/CTextField.qml +++ /dev/null @@ -1,25 +0,0 @@ -import QtQuick 2.12 -import QtQuick.Controls 2.12 - - -/*! - Field for setting width, height, margin & error correction code level parameters. - */ -TextField { - id: root - - property bool inputIsValid: true - - selectByMouse: true - - leftPadding: 5 - - background: Rectangle { - radius: 2 - - border { - color: inputIsValid ? Theme.borderColor : Theme.invalidInputBorderColor - width: 1 - } - } -} diff --git a/examples/QmlBarcodeGenerator/qml/GeneratorPage.qml b/examples/QmlBarcodeGenerator/qml/GeneratorPage.qml deleted file mode 100644 index 971eb22..0000000 --- a/examples/QmlBarcodeGenerator/qml/GeneratorPage.qml +++ /dev/null @@ -1,459 +0,0 @@ -import QtQuick 2.12 -import QtQuick.Controls 2.12 -import QtMultimedia 5.12 -import QtQuick.Layouts 1.12 -import com.scythestudio.scodes 1.0 - - -/*! - Barcode generator main page. All QML elements managing from here. - */ -ApplicationWindow { - id: appWindow - - visible: true - - width: 400 - height: 800 - - MouseArea { - id: hideKeyboard - anchors.fill: parent - onClicked: { - Qt.inputMethod.hide() - } - } - - ColorController { - id: colorController - } - - SBarcodeGenerator { - id: barcodeGenerator - - onForegroundColorChanged: { - image.source = "" - barcodeGenerator.generate(textField.text) - } - - onBackgroundColorChanged: { - image.source = "" - barcodeGenerator.generate(textField.text) - } - - onGenerationFinished: function (error) { - if (error === "") { - console.log(barcodeGenerator.filePath) - image.source = "file:///" + barcodeGenerator.filePath - } else { - generateLabel.text = error - generatePopup.open() - } - } - } - - Rectangle { - id: dashboard - - anchors.fill: parent - - height: parent.height - width: parent.width - - Rectangle { - id: inputRect - z: 100 - - height: 40 - - anchors { - top: parent.top - left: parent.left - right: parent.right - } - - CTextField { - id: textField - - anchors.fill: parent - - selectByMouse: true - - placeholderText: qsTr("Input") - } - } - - Image { - id: image - - width: parent.width - height: image.width - - anchors { - left: parent.left - right: parent.right - verticalCenter: parent.verticalCenter - } - - cache: false - } - - Rectangle { - id: buttonsRect - - height: 40 - - anchors { - bottom: parent.bottom - left: parent.left - right: parent.right - } - - RowLayout { - id: buttonsLayout - - spacing: 5 - - anchors.fill: parent - - CButton { - id: settingsButton - - Layout.alignment: Qt.AlignHCenter - Layout.bottomMargin: 10 - - text: qsTr("Settings") - - onClicked: { - settingsPopup.open() - } - } - - CButton { - id: generateButton - - Layout.alignment: Qt.AlignHCenter - Layout.bottomMargin: 10 - checkable: false - - text: qsTr("Generate") - - onClicked: { - image.source = "" - if (textField.text === "") { - generateLabel.text = "Input is empty" - generatePopup.open() - } else { - barcodeGenerator.generate(textField.text) - } - } - } - - CButton { - id: saveButton - - Layout.alignment: Qt.AlignHCenter - Layout.bottomMargin: 10 - - text: qsTr("Save") - - onClicked: { - if (barcodeGenerator.saveImage()) { - saveLabel.text = "File successfully saved" - } else { - saveLabel.text = "There was an error while saving file" - } - - imageSavedPopup.open() - } - } - } - } - - Popup { - id: generatePopup - - anchors.centerIn: parent - - dim: true - - modal: true - - Label { - id: generateLabel - - anchors.centerIn: parent - } - - onClosed: { - generateButton.checked = false - } - } - - Popup { - id: imageSavedPopup - - anchors.centerIn: parent - - dim: true - - modal: true - - Label { - id: saveLabel - - anchors.centerIn: parent - } - - onClosed: { - saveButton.checked = false - } - } - - Popup { - id: settingsPopup - - width: parent.width * 0.6 - height: parent.height * 0.6 - - anchors.centerIn: parent - - dim: true - - modal: true - - ColumnLayout { - anchors.fill: parent - - spacing: 5 - - CTextField { - id: widthField - - implicitWidth: parent.width - implicitHeight: parent.height / 10 - - placeholderText: "Current width: " + barcodeGenerator.width - - onEditingFinished: function () { - - var parsedWidth = parseInt(text) - - if (isNaN(parsedWidth) != true && parsedWidth > 0) { - barcodeGenerator.width = parsedWidth - } - } - } - - CTextField { - id: heightField - - implicitWidth: parent.width - implicitHeight: parent.height / 10 - - placeholderText: "Current height: " + barcodeGenerator.height - - onEditingFinished: function () { - - var parsedHeight = parseInt(text) - - if (isNaN(parsedHeight) != true && parsedHeight > 0) { - barcodeGenerator.height = parsedHeight - } - } - } - - CTextField { - id: marginField - - implicitWidth: parent.width - implicitHeight: parent.height / 10 - - placeholderText: "Current margin: " + barcodeGenerator.margin - - onEditingFinished: function () { - - var parsedMargin = parseInt(text) - - if (isNaN(parsedMargin) != true) { - barcodeGenerator.margin = parsedMargin - } - } - } - - CTextField { - id: eccLevelField - - implicitWidth: parent.width - implicitHeight: parent.height / 10 - - placeholderText: "Current ECC Level: " + barcodeGenerator.eccLevel - - onEditingFinished: function () { - barcodeGenerator.eccLevel = text - } - } - - CTextField { - id: foregroundColorField - - implicitWidth: parent.width - implicitHeight: parent.height / 10 - - placeholderText: "Current foreground color: " + barcodeGenerator.foregroundColor - - onTextChanged: function () { - foregroundColorField.inputIsValid = colorController.checkColor(foregroundColorField.text) - - if (colorController.checkColor(foregroundColorField.text)) { - barcodeGenerator.setForegroundColor(colorController.convertStringToColor(foregroundColorField.text)) - } - } - } - - CTextField { - id: backgroundColorField - - implicitWidth: parent.width - implicitHeight: parent.height / 10 - - placeholderText: "Current background color: " + barcodeGenerator.backgroundColor - - onTextChanged: function () { - backgroundColorField.inputIsValid = colorController.checkColor(backgroundColorField.text) - - if (colorController.checkColor(backgroundColorField.text)) { - barcodeGenerator.setBackgroundColor(colorController.convertStringToColor(backgroundColorField.text)) - } - } - } - - CComboBox { - id: formatDropDown - - implicitWidth: parent.width - implicitHeight: parent.height / 10 - - model: ListModel { - id: formats - - ListElement { - text: "Aztec" - } - ListElement { - text: "Codabar" - } - ListElement { - text: "Code39" - } - ListElement { - text: "Code93" - } - ListElement { - text: "Code128" - } - ListElement { - text: "DataMatrix" - } - ListElement { - text: "EAN-8" - } - ListElement { - text: "EAN-13" - } - ListElement { - text: "ITF" - } - ListElement { - text: "PDF417" - } - ListElement { - text: "QRCode" - } - ListElement { - text: "UPC-A" - } - ListElement { - text: "UPC-E" - } - } - onCurrentIndexChanged: function () { - var formatAsText = formats.get(currentIndex).text - // a separate method was used because of qml error - // when try to use it as overloaded setter - barcodeGenerator.setFormat(formatAsText) - } - } - - CComboBox { - id: imageFormat - - implicitWidth: parent.width - implicitHeight: parent.height / 10 - - model: ListModel { - id: extensions - - ListElement { - text: "png" - } - - ListElement { - text: "jpg" - } - } - onCurrentIndexChanged: function () { - barcodeGenerator.extension = extensions.get(currentIndex).text - } - } - - CTextField { - id: fileNameField - - text: qsTr(barcodeGenerator.fileName) - - implicitWidth: parent.width - implicitHeight: parent.height / 10 - - onEditingFinished: { - barcodeGenerator.fileName = text - } - } - - CTextField { - id: imagePathField - - text: qsTr(barcodeGenerator.imagePath) - - implicitWidth: parent.width - implicitHeight: parent.height / 10 - - placeholderText: "Current image path: " + barcodeGenerator.imagePath - - onEditingFinished: { - barcodeGenerator.imagePath = text - } - } - - CTextField { - id: centerImageRatioField - - text: qsTr(barcodeGenerator.centerImageRatio.toString()) - - implicitWidth: parent.width - implicitHeight: parent.height / 10 - - placeholderText: "Current center image ratio: " + barcodeGenerator.centerImageRatio - - onEditingFinished: { - barcodeGenerator.centerImageRatio = parseInt(text) - } - } - } - - onClosed: { - settingsButton.checked = false - } - } - } -} diff --git a/examples/QmlBarcodeGenerator/qml/Theme.qml b/examples/QmlBarcodeGenerator/qml/Theme.qml deleted file mode 100644 index c62b2fd..0000000 --- a/examples/QmlBarcodeGenerator/qml/Theme.qml +++ /dev/null @@ -1,16 +0,0 @@ -pragma Singleton - -import QtQuick 2.12 - - -/** - Contains common used colors - */ -QtObject { - id: root - - readonly property color backgroundColor: "#218165" - readonly property color textColor: "#bdbdbd" - readonly property color borderColor: "#333" - readonly property color invalidInputBorderColor: "#F00" -} diff --git a/examples/QmlBarcodeReader/.gitignore b/examples/QmlBarcodeReader/.gitignore deleted file mode 100644 index ed2dcca..0000000 --- a/examples/QmlBarcodeReader/.gitignore +++ /dev/null @@ -1,4 +0,0 @@ -*.pro.user -*.pro.user* -build-* -*DS_Store diff --git a/examples/QmlBarcodeReader/Qt5qml.qrc b/examples/QmlBarcodeReader/Qt5qml.qrc deleted file mode 100644 index 556d120..0000000 --- a/examples/QmlBarcodeReader/Qt5qml.qrc +++ /dev/null @@ -1,7 +0,0 @@ - - - qml/Qt5ScannerPage.qml - qml/Qt5ScannerOverlay.qml - qml/Theme.qml - - diff --git a/examples/QmlBarcodeReader/Qt6qml.qrc b/examples/QmlBarcodeReader/Qt6qml.qrc deleted file mode 100644 index a0a4561..0000000 --- a/examples/QmlBarcodeReader/Qt6qml.qrc +++ /dev/null @@ -1,7 +0,0 @@ - - - qml/Qt6ScannerPage.qml - qml/Qt6ScannerOverlay.qml - qml/Theme.qml - - diff --git a/examples/QmlBarcodeReader/android/gradle/wrapper/gradle-wrapper.properties b/examples/QmlBarcodeReader/android/gradle/wrapper/gradle-wrapper.properties deleted file mode 100644 index 41dfb87..0000000 --- a/examples/QmlBarcodeReader/android/gradle/wrapper/gradle-wrapper.properties +++ /dev/null @@ -1,5 +0,0 @@ -distributionBase=GRADLE_USER_HOME -distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-7.4-bin.zip -zipStoreBase=GRADLE_USER_HOME -zipStorePath=wrapper/dists diff --git a/examples/QmlBarcodeReader/android/gradlew b/examples/QmlBarcodeReader/android/gradlew deleted file mode 100644 index 005bcde..0000000 --- a/examples/QmlBarcodeReader/android/gradlew +++ /dev/null @@ -1,234 +0,0 @@ -#!/bin/sh - -# -# Copyright © 2015-2021 the original authors. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# https://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -############################################################################## -# -# Gradle start up script for POSIX generated by Gradle. -# -# Important for running: -# -# (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is -# noncompliant, but you have some other compliant shell such as ksh or -# bash, then to run this script, type that shell name before the whole -# command line, like: -# -# ksh Gradle -# -# Busybox and similar reduced shells will NOT work, because this script -# requires all of these POSIX shell features: -# * functions; -# * expansions «$var», «${var}», «${var:-default}», «${var+SET}», -# «${var#prefix}», «${var%suffix}», and «$( cmd )»; -# * compound commands having a testable exit status, especially «case»; -# * various built-in commands including «command», «set», and «ulimit». -# -# Important for patching: -# -# (2) This script targets any POSIX shell, so it avoids extensions provided -# by Bash, Ksh, etc; in particular arrays are avoided. -# -# The "traditional" practice of packing multiple parameters into a -# space-separated string is a well documented source of bugs and security -# problems, so this is (mostly) avoided, by progressively accumulating -# options in "$@", and eventually passing that to Java. -# -# Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS, -# and GRADLE_OPTS) rely on word-splitting, this is performed explicitly; -# see the in-line comments for details. -# -# There are tweaks for specific operating systems such as AIX, CygWin, -# Darwin, MinGW, and NonStop. -# -# (3) This script is generated from the Groovy template -# https://github.com/gradle/gradle/blob/master/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt -# within the Gradle project. -# -# You can find Gradle at https://github.com/gradle/gradle/. -# -############################################################################## - -# Attempt to set APP_HOME - -# Resolve links: $0 may be a link -app_path=$0 - -# Need this for daisy-chained symlinks. -while - APP_HOME=${app_path%"${app_path##*/}"} # leaves a trailing /; empty if no leading path - [ -h "$app_path" ] -do - ls=$( ls -ld "$app_path" ) - link=${ls#*' -> '} - case $link in #( - /*) app_path=$link ;; #( - *) app_path=$APP_HOME$link ;; - esac -done - -APP_HOME=$( cd "${APP_HOME:-./}" && pwd -P ) || exit - -APP_NAME="Gradle" -APP_BASE_NAME=${0##*/} - -# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. -DEFAULT_JVM_OPTS='-Dfile.encoding=UTF-8 "-Xmx64m" "-Xms64m"' - -# Use the maximum available, or set MAX_FD != -1 to use that value. -MAX_FD=maximum - -warn () { - echo "$*" -} >&2 - -die () { - echo - echo "$*" - echo - exit 1 -} >&2 - -# OS specific support (must be 'true' or 'false'). -cygwin=false -msys=false -darwin=false -nonstop=false -case "$( uname )" in #( - CYGWIN* ) cygwin=true ;; #( - Darwin* ) darwin=true ;; #( - MSYS* | MINGW* ) msys=true ;; #( - NONSTOP* ) nonstop=true ;; -esac - -CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar - - -# Determine the Java command to use to start the JVM. -if [ -n "$JAVA_HOME" ] ; then - if [ -x "$JAVA_HOME/jre/sh/java" ] ; then - # IBM's JDK on AIX uses strange locations for the executables - JAVACMD=$JAVA_HOME/jre/sh/java - else - JAVACMD=$JAVA_HOME/bin/java - fi - if [ ! -x "$JAVACMD" ] ; then - die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME - -Please set the JAVA_HOME variable in your environment to match the -location of your Java installation." - fi -else - JAVACMD=java - which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. - -Please set the JAVA_HOME variable in your environment to match the -location of your Java installation." -fi - -# Increase the maximum file descriptors if we can. -if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then - case $MAX_FD in #( - max*) - MAX_FD=$( ulimit -H -n ) || - warn "Could not query maximum file descriptor limit" - esac - case $MAX_FD in #( - '' | soft) :;; #( - *) - ulimit -n "$MAX_FD" || - warn "Could not set maximum file descriptor limit to $MAX_FD" - esac -fi - -# Collect all arguments for the java command, stacking in reverse order: -# * args from the command line -# * the main class name -# * -classpath -# * -D...appname settings -# * --module-path (only if needed) -# * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables. - -# For Cygwin or MSYS, switch paths to Windows format before running java -if "$cygwin" || "$msys" ; then - APP_HOME=$( cygpath --path --mixed "$APP_HOME" ) - CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" ) - - JAVACMD=$( cygpath --unix "$JAVACMD" ) - - # Now convert the arguments - kludge to limit ourselves to /bin/sh - for arg do - if - case $arg in #( - -*) false ;; # don't mess with options #( - /?*) t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath - [ -e "$t" ] ;; #( - *) false ;; - esac - then - arg=$( cygpath --path --ignore --mixed "$arg" ) - fi - # Roll the args list around exactly as many times as the number of - # args, so each arg winds up back in the position where it started, but - # possibly modified. - # - # NB: a `for` loop captures its iteration list before it begins, so - # changing the positional parameters here affects neither the number of - # iterations, nor the values presented in `arg`. - shift # remove old arg - set -- "$@" "$arg" # push replacement arg - done -fi - -# Collect all arguments for the java command; -# * $DEFAULT_JVM_OPTS, $JAVA_OPTS, and $GRADLE_OPTS can contain fragments of -# shell script including quotes and variable substitutions, so put them in -# double quotes to make sure that they get re-expanded; and -# * put everything else in single quotes, so that it's not re-expanded. - -set -- \ - "-Dorg.gradle.appname=$APP_BASE_NAME" \ - -classpath "$CLASSPATH" \ - org.gradle.wrapper.GradleWrapperMain \ - "$@" - -# Use "xargs" to parse quoted args. -# -# With -n1 it outputs one arg per line, with the quotes and backslashes removed. -# -# In Bash we could simply go: -# -# readarray ARGS < <( xargs -n1 <<<"$var" ) && -# set -- "${ARGS[@]}" "$@" -# -# but POSIX shell has neither arrays nor command substitution, so instead we -# post-process each arg (as a line of input to sed) to backslash-escape any -# character that might be a shell metacharacter, then use eval to reverse -# that process (while maintaining the separation between arguments), and wrap -# the whole thing up as a single "set" statement. -# -# This will of course break if any of these variables contains a newline or -# an unmatched quote. -# - -eval "set -- $( - printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" | - xargs -n1 | - sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' | - tr '\n' ' ' - )" '"$@"' - -exec "$JAVACMD" "$@" diff --git a/examples/QmlBarcodeReader/android/res/drawable-hdpi/icon.png b/examples/QmlBarcodeReader/android/res/drawable-hdpi/icon.png deleted file mode 100644 index ca8fc26..0000000 Binary files a/examples/QmlBarcodeReader/android/res/drawable-hdpi/icon.png and /dev/null differ diff --git a/examples/QmlBarcodeReader/android/res/drawable-ldpi/icon.png b/examples/QmlBarcodeReader/android/res/drawable-ldpi/icon.png deleted file mode 100644 index b900afd..0000000 Binary files a/examples/QmlBarcodeReader/android/res/drawable-ldpi/icon.png and /dev/null differ diff --git a/examples/QmlBarcodeReader/android/res/drawable-mdpi/icon.png b/examples/QmlBarcodeReader/android/res/drawable-mdpi/icon.png deleted file mode 100644 index 53222fb..0000000 Binary files a/examples/QmlBarcodeReader/android/res/drawable-mdpi/icon.png and /dev/null differ diff --git a/examples/QmlBarcodeReader/android/res/drawable-xhdpi/icon.png b/examples/QmlBarcodeReader/android/res/drawable-xhdpi/icon.png deleted file mode 100644 index 5463f40..0000000 Binary files a/examples/QmlBarcodeReader/android/res/drawable-xhdpi/icon.png and /dev/null differ diff --git a/examples/QmlBarcodeReader/android/res/drawable-xxhdpi/icon.png b/examples/QmlBarcodeReader/android/res/drawable-xxhdpi/icon.png deleted file mode 100644 index c7e7830..0000000 Binary files a/examples/QmlBarcodeReader/android/res/drawable-xxhdpi/icon.png and /dev/null differ diff --git a/examples/QmlBarcodeReader/android/res/drawable-xxxhdpi/icon.png b/examples/QmlBarcodeReader/android/res/drawable-xxxhdpi/icon.png deleted file mode 100644 index 100474e..0000000 Binary files a/examples/QmlBarcodeReader/android/res/drawable-xxxhdpi/icon.png and /dev/null differ diff --git a/examples/QmlBarcodeReader/android/res/values/libs.xml b/examples/QmlBarcodeReader/android/res/values/libs.xml deleted file mode 100644 index beb15ca..0000000 --- a/examples/QmlBarcodeReader/android/res/values/libs.xml +++ /dev/null @@ -1,20 +0,0 @@ - - - - - - - - - - - - - - - - - - - - diff --git a/examples/QmlBarcodeReader/main.cpp b/examples/QmlBarcodeReader/main.cpp deleted file mode 100644 index a52332b..0000000 --- a/examples/QmlBarcodeReader/main.cpp +++ /dev/null @@ -1,38 +0,0 @@ -#include -#include - -#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0) -#include "SBarcodeFilter.h" -#else -#include "SBarcodeScanner.h" -#endif - -int main(int argc, char* argv[]) -{ - QCoreApplication::setAttribute(Qt::AA_UseDesktopOpenGL); - -#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0) - QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling); -#endif - QGuiApplication app(argc, argv); - - QQmlApplicationEngine engine; - - qmlRegisterSingletonType(QUrl("qrc:/qml/Theme.qml"), "Theme", 1, 0, "Theme"); - qmlRegisterUncreatableMetaObject( - SCodes::staticMetaObject, "com.scythestudio.scodes", 1, 0, "SCodes", "Error, enum type"); - -#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0) - qmlRegisterType("com.scythestudio.scodes", 1, 0, "SBarcodeScanner"); - engine.load(QUrl(QStringLiteral("qrc:/qml/Qt5ScannerPage.qml"))); -#else - qmlRegisterType("com.scythestudio.scodes", 1, 0, "SBarcodeScanner"); - engine.load(QUrl(QStringLiteral("qrc:/qml/Qt6ScannerPage.qml"))); -#endif - - if (engine.rootObjects().isEmpty()) { - return -1; - } - - return app.exec(); -} diff --git a/examples/QmlBarcodeReader/qml/Qt5ScannerOverlay.qml b/examples/QmlBarcodeReader/qml/Qt5ScannerOverlay.qml deleted file mode 100644 index 5c560a0..0000000 --- a/examples/QmlBarcodeReader/qml/Qt5ScannerOverlay.qml +++ /dev/null @@ -1,209 +0,0 @@ -import QtQuick 2.12 -import QtGraphicalEffects 1.12 - -/*! - Area for scanning barcodes - */ -Item { - id: root - - property rect captureRect - - Item { - id: captureZoneCorners - - x: root.captureRect.x - y: root.captureRect.y - - width: root.captureRect.width - height: root.captureRect.height - - Rectangle { - id: topLeftCornerH - - anchors { - top: parent.top - left: parent.left - } - - width: 20 - height: 5 - - color: Theme.borderColor - radius: height / 2 - } - - Rectangle { - id: topLeftCornerV - anchors { - top: parent.top - left: parent.left - } - - width: 5 - height: 20 - - color: Theme.borderColor - radius: width / 2 - } - - // ---------------------- - Rectangle { - id: bottomLeftCornerH - - anchors { - bottom: parent.bottom - left: parent.left - } - - width: 20 - height: 5 - - color: Theme.borderColor - radius: height / 2 - } - - Rectangle { - id: bottomLeftCornerV - - anchors { - bottom: parent.bottom - left: parent.left - } - - width: 5 - height: 20 - - color: Theme.borderColor - radius: width / 2 - } - - // ---------------------- - Rectangle { - id: topRightCornerH - - anchors { - top: parent.top - right: parent.right - } - - width: 20 - height: 5 - - color: Theme.borderColor - radius: height / 2 - } - - Rectangle { - id: topRightCornerV - - anchors { - top: parent.top - right: parent.right - } - - width: 5 - height: 20 - - color: Theme.borderColor - radius: width / 2 - } - - // ---------------------- - Rectangle { - id: bottomRightCornerH - - anchors { - bottom: parent.bottom - right: parent.right - } - - width: 20 - height: 5 - - color: Theme.borderColor - radius: height / 2 - } - - Rectangle { - id: bottomRightCornerV - - anchors { - bottom: parent.bottom - right: parent.right - } - - width: 5 - height: 20 - - color: Theme.borderColor - radius: width / 2 - } - - Rectangle { - id: scanIndicator - - //y: captureZoneCorners.height/2 - width: parent.width - height: 1 - - anchors { - horizontalCenter: parent.horizontalCenter - } - - color: Theme.borderColor - - SequentialAnimation { - id: scanIndicatorAnimation - - loops: Animation.Infinite - - PropertyAnimation { - id: toTopAnimation - target: scanIndicator - property: "y" - duration: 2000 - } - - PropertyAnimation { - id: toBottomAnimation - target: scanIndicator - property: "y" - duration: 2000 - } - } - } - - RectangularGlow { - id: effect - - width: scanIndicator.width / 2 - height: scanIndicator.height - - anchors.centerIn: scanIndicator - - glowRadius: 50 - spread: 0.2 - color: Theme.borderColor - cornerRadius: glowRadius - } - } - - Text { - id: scanCapsuleText - - anchors { - verticalCenter: captureZoneCorners.bottom - horizontalCenter: captureZoneCorners.horizontalCenter - } - - text: qsTr("Scan barcode") - color: Theme.borderColor - } - - onCaptureRectChanged: { - toTopAnimation.to = 5 - toBottomAnimation.to = captureRect.height - 5 - scanIndicatorAnimation.start() - } -} diff --git a/examples/QmlBarcodeReader/qml/Qt5ScannerPage.qml b/examples/QmlBarcodeReader/qml/Qt5ScannerPage.qml deleted file mode 100644 index 5a59081..0000000 --- a/examples/QmlBarcodeReader/qml/Qt5ScannerPage.qml +++ /dev/null @@ -1,116 +0,0 @@ -import QtQuick 2.12 -import QtQuick.Controls 2.12 -import QtQuick.Window 2.12 -import QtMultimedia 5.12 -import com.scythestudio.scodes 1.0 - - -/*! - Barcode scanner main page. All QML elements managing from here. - */ -ApplicationWindow { - id: root - - visible: true - - width: Qt.platform.os == "android" - || Qt.platform.os == "ios" ? Screen.width : camera.viewfinder.resolution.width - height: Qt.platform.os == "android" - || Qt.platform.os == "ios" ? Screen.height : camera.viewfinder.resolution.height - - Camera { - id: camera - - focus { - focusMode: CameraFocus.FocusContinuous - focusPointMode: CameraFocus.FocusPointAuto - } - } - - VideoOutput { - id: videoOutput - - anchors.fill: parent - - source: camera - - autoOrientation: true - - fillMode: VideoOutput.PreserveAspectCrop - - // add barcodeScanner to videoOutput's filters to enable catching barcodes - filters: [barcodeScanner] - - onSourceRectChanged: { - barcodeScanner.captureRect = videoOutput.mapRectToSource(videoOutput.mapNormalizedRectToItem(Qt.rect(0.25, 0.25, 0.5, 0.5))) - } - - Qt5ScannerOverlay { - id: scannerOverlay - - anchors.fill: parent - - captureRect: videoOutput.mapRectToItem(barcodeScanner.captureRect) - } - - // used to get camera focus on touched point - MouseArea { - id: focusTouchArea - - anchors.fill: parent - - onClicked: { - camera.focus.customFocusPoint = Qt.point(mouse.x / width, - mouse.y / height) - camera.focus.focusMode = CameraFocus.FocusMacro - camera.focus.focusPointMode = CameraFocus.FocusPointCustom - } - } - } - - SBarcodeScanner { - id: barcodeScanner - - // you can adjust capture rect (scan area) ne changing these Qt.rect() parameters - captureRect: videoOutput.mapRectToSource(videoOutput.mapNormalizedRectToItem(Qt.rect(0.25, 0.25, 0.5, 0.5))) - - onCapturedChanged: { - active = false - console.log("captured: " + captured) - } - } - - Rectangle { - id: resultScreen - - anchors.fill: parent - - visible: !barcodeScanner.active - - Column { - anchors.centerIn: parent - - spacing: 20 - - Text { - id: scanResultText - - anchors.horizontalCenter: parent.horizontalCenter - - text: barcodeScanner.captured - } - - Button { - id: scanButton - - anchors.horizontalCenter: parent.horizontalCenter - - text: qsTr("Scan again") - - onClicked: { - barcodeScanner.active = true - } - } - } - } -} diff --git a/examples/QmlBarcodeReader/qml/Qt6ScannerPage.qml b/examples/QmlBarcodeReader/qml/Qt6ScannerPage.qml deleted file mode 100644 index 2d8149f..0000000 --- a/examples/QmlBarcodeReader/qml/Qt6ScannerPage.qml +++ /dev/null @@ -1,94 +0,0 @@ -import QtQuick -import QtQuick.Controls -import QtMultimedia -import com.scythestudio.scodes 1.0 - - -/*! - Barcode scanner main page. All QML elements managing from here. - */ -ApplicationWindow { - id: root - - width: Qt.platform.os === "android" - || Qt.platform.os === "ios" ? Screen.width : 1280 - height: Qt.platform.os === "android" - || Qt.platform.os === "ios" ? Screen.height : 720 - - visible: true - - SBarcodeScanner { - id: barcodeScanner - - forwardVideoSink: videoOutput.videoSink - scanning: !resultScreen.visible - - captureRect: Qt.rect(1 / 4, 1 / 4, 1 / 2, 1 / 2) - - onCapturedChanged: function (captured) { - scanResultText.text = captured - resultScreen.visible = true - } - } - - VideoOutput { - id: videoOutput - - anchors.fill: parent - - width: root.width - - focus: visible - fillMode: VideoOutput.PreserveAspectCrop - } - - Qt6ScannerOverlay { - id: scannerOverlay - - anchors.fill: parent - - captureRect: barcodeScanner.captureRect - } - - Rectangle { - id: resultScreen - - anchors.fill: parent - - visible: false - - Column { - anchors.centerIn: parent - - spacing: 20 - - Text { - id: scanResultText - - anchors.horizontalCenter: parent.horizontalCenter - - color: Theme.textColor - } - - Button { - id: scanButton - - anchors.horizontalCenter: parent.horizontalCenter - - implicitWidth: 100 - implicitHeight: 50 - - Text { - anchors.centerIn: parent - - text: qsTr("Scan again") - color: Theme.textColor - } - - onClicked: { - resultScreen.visible = false - } - } - } - } -} diff --git a/examples/QmlBarcodeReader/qml/Theme.qml b/examples/QmlBarcodeReader/qml/Theme.qml deleted file mode 100644 index 3c9f7e4..0000000 --- a/examples/QmlBarcodeReader/qml/Theme.qml +++ /dev/null @@ -1,13 +0,0 @@ -pragma Singleton - -import QtQuick 2.12 - -/** - Contains common used colors - */ -QtObject { - id: root - - readonly property color borderColor: "#218165" - readonly property color textColor: "#000000" -} diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 31db4b3..bf66f14 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -312,7 +312,7 @@ add_library(${PROJECT_NAME} STATIC ${HEADER_FILES} ${SRC_FILES}) target_sources(${PROJECT_NAME} PRIVATE private/debug.h) set_target_properties(${PROJECT_NAME} PROPERTIES QT_QML_MODULE_VERSION 1.0 - QT_QML_MODULE_URI com.scythestudio.scodes + QT_QML_MODULE_URI com.somcosoftware.scodes ) if(SCODES_DEBUG) diff --git a/src/SBarcodeFilter.cpp b/src/SBarcodeFilter.cpp index ed8e3c2..69afd6e 100644 --- a/src/SBarcodeFilter.cpp +++ b/src/SBarcodeFilter.cpp @@ -49,9 +49,15 @@ class SBarcodeFilterRunnable : public QVideoFilterRunnable if (_filter->getImageFuture().isRunning()) { return *input; } + const QSize frameSize = input->size(); + const QRectF normRect = _filter->captureRect(); + const QRectF pixelRect(normRect.x() * frameSize.width(), + normRect.y() * frameSize.height(), + normRect.width() * frameSize.width(), + normRect.height() * frameSize.height()); const QImage croppedCapturedImage = - _filter->getDecoder()->videoFrameToImage(*input, _filter->captureRect().toRect()); + _filter->getDecoder()->videoFrameToImage(*input, pixelRect.toRect()); _filter->getImageFuture() = QtConcurrent::run(processImage, _filter->getDecoder(), croppedCapturedImage, SCodes::toZXingFormat(_filter->format())); diff --git a/src/SBarcodeFilter.h b/src/SBarcodeFilter.h index e74e765..d19cdf3 100644 --- a/src/SBarcodeFilter.h +++ b/src/SBarcodeFilter.h @@ -113,7 +113,7 @@ private slots: void clean(); private: - QString m_captured = ""; + QString m_captured; QRectF m_captureRect; @@ -121,7 +121,7 @@ private slots: QFuture _imageFuture; - SCodes::SBarcodeFormats m_format = SCodes::SBarcodeFormat::Basic; + SCodes::SBarcodeFormats m_format{SCodes::SBarcodeFormat::Any}; }; #endif // QRSCANNERFILTER_H diff --git a/src/SBarcodeScanner.h b/src/SBarcodeScanner.h index 43b9235..0c784f0 100644 --- a/src/SBarcodeScanner.h +++ b/src/SBarcodeScanner.h @@ -79,7 +79,7 @@ public slots: /// Subsection of videoframe to capture, in normalized coordinates QRectF m_captureRect; /// Last captured string from QrCode - QString m_captured = ""; + QString m_captured; /// QMediaCaptureSession instance to actually perform the camera recording QMediaCaptureSession m_capture; /// Separate thread for Qr code processing and detection diff --git a/src/SCodes.pri b/src/SCodes.pri index 6e7e14a..32061a3 100644 --- a/src/SCodes.pri +++ b/src/SCodes.pri @@ -2,7 +2,7 @@ QT += multimedia concurrent CONFIG += qmltypes -QML_IMPORT_NAME = com.scythestudio.scodes +QML_IMPORT_NAME = com.somcosoftware.scodes QML_IMPORT_MAJOR_VERSION = 1 INCLUDEPATH += \