├── .gitignore
├── .idea
├── compiler.xml
├── gradle.xml
├── migrations.xml
├── misc.xml
└── vcs.xml
├── CODE_OF_CONDUCT.md
├── LICENSE.txt
├── README.md
├── assets
├── CMP_QRKit_Barcode_Generator.png
├── CMP_QRKit_QR_Customisation.png
├── CMP_QRKit_QR_Generator.png
├── CMP_QRKit_scanner.gif
└── CMP_QRKit_scanner_genrator_banner.png
├── build.gradle.kts
├── composeApp
├── build.gradle.kts
└── src
│ ├── androidMain
│ ├── AndroidManifest.xml
│ ├── kotlin
│ │ └── org
│ │ │ └── qrcodedemo
│ │ │ └── app
│ │ │ ├── App.android.kt
│ │ │ ├── Platform.android.kt
│ │ │ └── theme
│ │ │ └── Theme.android.kt
│ └── res
│ │ └── xml
│ │ ├── file_paths.xml
│ │ └── path_provider.xml
│ ├── commonMain
│ ├── composeResources
│ │ ├── drawable
│ │ │ ├── bg.png
│ │ │ ├── ic_arrow_row.png
│ │ │ ├── ic_calendar.png
│ │ │ ├── ic_camera_switch.png
│ │ │ ├── ic_check_icon.png
│ │ │ ├── ic_circle.png
│ │ │ ├── ic_circle_eyes.png
│ │ │ ├── ic_circle_pixel.png
│ │ │ ├── ic_circle_round_eyes.png
│ │ │ ├── ic_circle_shape.png
│ │ │ ├── ic_done.png
│ │ │ ├── ic_drop_down.png
│ │ │ ├── ic_email.png
│ │ │ ├── ic_flash_icon.xml
│ │ │ ├── ic_gallery_icon.xml
│ │ │ ├── ic_hexagon.png
│ │ │ ├── ic_horizontal_line_pixel.png
│ │ │ ├── ic_instagram.png
│ │ │ ├── ic_kotlin.png
│ │ │ ├── ic_linkedin.png
│ │ │ ├── ic_magic_tool.png
│ │ │ ├── ic_next.png
│ │ │ ├── ic_pentagon.png
│ │ │ ├── ic_person_circle.xml
│ │ │ ├── ic_phone.png
│ │ │ ├── ic_pinterest.png
│ │ │ ├── ic_qr_code.xml
│ │ │ ├── ic_rectangle.xml
│ │ │ ├── ic_round_corner_pixel.png
│ │ │ ├── ic_rounded_circle_eyes.png
│ │ │ ├── ic_rounded_eyes.png
│ │ │ ├── ic_rounded_square_eyes.png
│ │ │ ├── ic_scanner.png
│ │ │ ├── ic_sms.png
│ │ │ ├── ic_square.png
│ │ │ ├── ic_square_border.xml
│ │ │ ├── ic_square_circle_eyes.png
│ │ │ ├── ic_square_pixel.png
│ │ │ ├── ic_square_round_eyes.png
│ │ │ ├── ic_swift.png
│ │ │ ├── ic_temp.jpg
│ │ │ ├── ic_text.png
│ │ │ ├── ic_text_blue.png
│ │ │ ├── ic_tiktok.png
│ │ │ ├── ic_vertical_line_pixel.png
│ │ │ ├── ic_website.png
│ │ │ ├── ic_wifi.png
│ │ │ ├── ic_youtube.png
│ │ │ ├── img_barcode.png
│ │ │ ├── img_curved_arrow.png
│ │ │ ├── img_dotted_box.png
│ │ │ ├── img_mobile_innovation.png
│ │ │ ├── img_qr_lines.png
│ │ │ ├── img_qr_thumb.png
│ │ │ ├── img_scanner.png
│ │ │ ├── message.png
│ │ │ ├── text.xml
│ │ │ ├── website.png
│ │ │ └── wifi.png
│ │ └── font
│ │ │ ├── Aeonik-Bold.otf
│ │ │ ├── Aeonik-Regular.otf
│ │ │ ├── SofiaSansCondensed-Bold.ttf
│ │ │ ├── SofiaSansCondensed-Light.ttf
│ │ │ ├── SofiaSansCondensed-Medium.ttf
│ │ │ ├── SofiaSansCondensed-Regular.ttf
│ │ │ ├── SofiaSansCondensed-SemiBold.ttf
│ │ │ ├── poppins_bold.ttf
│ │ │ ├── poppins_medium.ttf
│ │ │ ├── poppins_regular.ttf
│ │ │ ├── poppins_semibold.ttf
│ │ │ ├── sf_pro.otf
│ │ │ ├── sf_pro_bold.otf
│ │ │ ├── sf_pro_medium.otf
│ │ │ └── sf_pro_semibold.ttf
│ └── kotlin
│ │ └── org
│ │ └── qrcodedemo
│ │ └── app
│ │ ├── App.kt
│ │ ├── Platform.kt
│ │ ├── theme
│ │ ├── Color.kt
│ │ └── Theme.kt
│ │ └── ui
│ │ ├── BarCodeDataTypes.kt
│ │ ├── BarCodeGeneratorScreen.kt
│ │ ├── Navigation.kt
│ │ ├── QRCustomizationScreen.kt
│ │ ├── QRDataTypes.kt
│ │ ├── QRKitMainScreen.kt
│ │ ├── QrGeneratorScreen.kt
│ │ └── QrScannerScreen.kt
│ ├── iosMain
│ └── kotlin
│ │ ├── main.kt
│ │ └── org
│ │ └── qrcodedemo
│ │ └── app
│ │ ├── App.ios.kt
│ │ ├── Platform.ios.kt
│ │ └── theme
│ │ └── Theme.ios.kt
│ └── jvmMain
│ └── kotlin
│ ├── main.kt
│ └── org
│ └── qrcodedemo
│ └── app
│ ├── Platform.jvm.kt
│ └── theme
│ └── Theme.jvm.kt
├── gradle.properties
├── gradle
├── libs.versions.toml
└── wrapper
│ ├── gradle-wrapper.jar
│ └── gradle-wrapper.properties
├── gradlew
├── gradlew.bat
├── iosApp
├── iosApp.xcodeproj
│ ├── project.pbxproj
│ └── project.xcworkspace
│ │ ├── contents.xcworkspacedata
│ │ └── xcshareddata
│ │ └── IDEWorkspaceChecks.plist
└── iosApp
│ ├── Assets.xcassets
│ ├── AccentColor.colorset
│ │ └── Contents.json
│ ├── AppIcon.appiconset
│ │ └── Contents.json
│ └── Contents.json
│ ├── Preview Content
│ └── Preview Assets.xcassets
│ │ └── Contents.json
│ └── iosApp.swift
└── settings.gradle.kts
/.gitignore:
--------------------------------------------------------------------------------
1 |
2 | *.iml
3 | .gradle
4 | .idea
5 | .kotlin
6 | .DS_Store
7 | build
8 | */build
9 | captures
10 | .externalNativeBuild
11 | .cxx
12 | local.properties
13 | xcuserdata/
14 | Pods/
15 | *.jks
16 | *yarn.lock
17 |
--------------------------------------------------------------------------------
/.idea/compiler.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/.idea/gradle.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
--------------------------------------------------------------------------------
/.idea/migrations.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
--------------------------------------------------------------------------------
/.idea/misc.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/.idea/vcs.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/CODE_OF_CONDUCT.md:
--------------------------------------------------------------------------------
1 | ## 🛡️ Code of Conduct
2 |
3 | We are dedicated to providing a welcoming, inclusive, and respectful environment for all contributors. By participating in this project, you agree to uphold the following values:
4 |
5 | ### 1. **Respect and Consideration**
6 | - Be respectful and considerate of other community members, regardless of their experience level, background, or opinions.
7 | - Constructive criticism is encouraged, but personal attacks, trolling, and other disrespectful behavior will not be tolerated.
8 |
9 | ### 2. **Inclusivity**
10 | - We strive to be an inclusive community. Discrimination or harassment based on gender, race, sexual orientation, disability, religion, or other personal attributes is unacceptable.
11 | - Celebrate diversity and create an environment where everyone feels valued and included.
12 |
13 | ### 3. **Collaboration and Openness**
14 | - Share knowledge and help others. Collaboration is the foundation of open-source projects.
15 | - Welcome new ideas and be open to feedback. Constructive discussions help improve the project and its community.
16 | - Value contributions of all sizes. Small fixes and improvements are just as important as major features.
17 |
18 | ### 4. **Professionalism**
19 | - Maintain professionalism in all interactions. Be patient, supportive, and keep the discussion focused on the task at hand.
20 | - Use welcoming and inclusive language. Avoid unnecessary jargon, and be mindful of how your words may affect others.
21 |
22 | ### 5. **Zero Tolerance for Harassment**
23 | - Harassment of any form will not be tolerated. This includes, but is not limited to, offensive comments, inappropriate language, and unwelcome attention or behavior.
24 | - If you witness or experience harassment, report it immediately.
25 |
26 | ### 6. **Focus on Growth and Learning**
27 | - Open-source is a learning environment. Encourage others, especially beginners, to contribute and grow.
28 | - Share your knowledge and experience with patience and enthusiasm. Everyone learns at their own pace.
29 |
30 | ### 7. **Reporting Issues**
31 | - If you see a violation of this Code of Conduct or experience any inappropriate behavior, report it to [rehan.t@chaintech.network](mailto:rehan.t@chaintech.network).
32 | - All reports will be reviewed and investigated confidentially, and the maintainers are committed to resolving issues fairly and promptly.
33 |
34 | We expect all participants in the project to follow these guidelines in all community spaces, including GitHub issues, pull requests, discussions, and interactions on social media.
35 |
--------------------------------------------------------------------------------
/LICENSE.txt:
--------------------------------------------------------------------------------
1 | Apache License
2 | Version 2.0, January 2004
3 | http://www.apache.org/licenses/
4 |
5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
6 |
7 | 1. Definitions.
8 |
9 | "License" shall mean the terms and conditions for use, reproduction,
10 | and distribution as defined by Sections 1 through 9 of this document.
11 |
12 | "Licensor" shall mean the copyright owner or entity authorized by
13 | the copyright owner that is granting the License.
14 |
15 | "Legal Entity" shall mean the union of the acting entity and all
16 | other entities that control, are controlled by, or are under common
17 | control with that entity. For the purposes of this definition,
18 | "control" means (i) the power, direct or indirect, to cause the
19 | direction or management of such entity, whether by contract or
20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the
21 | outstanding shares, or (iii) beneficial ownership of such entity.
22 |
23 | "You" (or "Your") shall mean an individual or Legal Entity
24 | exercising permissions granted by this License.
25 |
26 | "Source" form shall mean the preferred form for making modifications,
27 | including but not limited to software source code, documentation
28 | source, and configuration files.
29 |
30 | "Object" form shall mean any form resulting from mechanical
31 | transformation or translation of a Source form, including but
32 | not limited to compiled object code, generated documentation,
33 | and conversions to other media types.
34 |
35 | "Work" shall mean the work of authorship, whether in Source or
36 | Object form, made available under the License, as indicated by a
37 | copyright notice that is included in or attached to the work
38 | (an example is provided in the Appendix below).
39 |
40 | "Derivative Works" shall mean any work, whether in Source or Object
41 | form, that is based on (or derived from) the Work and for which the
42 | editorial revisions, annotations, elaborations, or other modifications
43 | represent, as a whole, an original work of authorship. For the purposes
44 | of this License, Derivative Works shall not include works that remain
45 | separable from, or merely link (or bind by name) to the interfaces of,
46 | the Work and Derivative Works thereof.
47 |
48 | "Contribution" shall mean any work of authorship, including
49 | the original version of the Work and any modifications or additions
50 | to that Work or Derivative Works thereof, that is intentionally
51 | submitted to Licensor for inclusion in the Work by the copyright owner
52 | or by an individual or Legal Entity authorized to submit on behalf of
53 | the copyright owner. For the purposes of this definition, "submitted"
54 | means any form of electronic, verbal, or written communication sent
55 | to the Licensor or its representatives, including but not limited to
56 | communication on electronic mailing lists, source code control systems,
57 | and issue tracking systems that are managed by, or on behalf of, the
58 | Licensor for the purpose of discussing and improving the Work, but
59 | excluding communication that is conspicuously marked or otherwise
60 | designated in writing by the copyright owner as "Not a Contribution."
61 |
62 | "Contributor" shall mean Licensor and any individual or Legal Entity
63 | on behalf of whom a Contribution has been received by Licensor and
64 | subsequently incorporated within the Work.
65 |
66 | 2. Grant of Copyright License. Subject to the terms and conditions of
67 | this License, each Contributor hereby grants to You a perpetual,
68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable
69 | copyright license to reproduce, prepare Derivative Works of,
70 | publicly display, publicly perform, sublicense, and distribute the
71 | Work and such Derivative Works in Source or Object form.
72 |
73 | 3. Grant of Patent License. Subject to the terms and conditions of
74 | this License, each Contributor hereby grants to You a perpetual,
75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable
76 | (except as stated in this section) patent license to make, have made,
77 | use, offer to sell, sell, import, and otherwise transfer the Work,
78 | where such license applies only to those patent claims licensable
79 | by such Contributor that are necessarily infringed by their
80 | Contribution(s) alone or by combination of their Contribution(s)
81 | with the Work to which such Contribution(s) was submitted. If You
82 | institute patent litigation against any entity (including a
83 | cross-claim or counterclaim in a lawsuit) alleging that the Work
84 | or a Contribution incorporated within the Work constitutes direct
85 | or contributory patent infringement, then any patent licenses
86 | granted to You under this License for that Work shall terminate
87 | as of the date such litigation is filed.
88 |
89 | 4. Redistribution. You may reproduce and distribute copies of the
90 | Work or Derivative Works thereof in any medium, with or without
91 | modifications, and in Source or Object form, provided that You
92 | meet the following conditions:
93 |
94 | (a) You must give any other recipients of the Work or
95 | Derivative Works a copy of this License; and
96 |
97 | (b) You must cause any modified files to carry prominent notices
98 | stating that You changed the files; and
99 |
100 | (c) You must retain, in the Source form of any Derivative Works
101 | that You distribute, all copyright, patent, trademark, and
102 | attribution notices from the Source form of the Work,
103 | excluding those notices that do not pertain to any part of
104 | the Derivative Works; and
105 |
106 | (d) If the Work includes a "NOTICE" text file as part of its
107 | distribution, then any Derivative Works that You distribute must
108 | include a readable copy of the attribution notices contained
109 | within such NOTICE file, excluding those notices that do not
110 | pertain to any part of the Derivative Works, in at least one
111 | of the following places: within a NOTICE text file distributed
112 | as part of the Derivative Works; within the Source form or
113 | documentation, if provided along with the Derivative Works; or,
114 | within a display generated by the Derivative Works, if and
115 | wherever such third-party notices normally appear. The contents
116 | of the NOTICE file are for informational purposes only and
117 | do not modify the License. You may add Your own attribution
118 | notices within Derivative Works that You distribute, alongside
119 | or as an addendum to the NOTICE text from the Work, provided
120 | that such additional attribution notices cannot be construed
121 | as modifying the License.
122 |
123 | You may add Your own copyright statement to Your modifications and
124 | may provide additional or different license terms and conditions
125 | for use, reproduction, or distribution of Your modifications, or
126 | for any such Derivative Works as a whole, provided Your use,
127 | reproduction, and distribution of the Work otherwise complies with
128 | the conditions stated in this License.
129 |
130 | 5. Submission of Contributions. Unless You explicitly state otherwise,
131 | any Contribution intentionally submitted for inclusion in the Work
132 | by You to the Licensor shall be under the terms and conditions of
133 | this License, without any additional terms or conditions.
134 | Notwithstanding the above, nothing herein shall supersede or modify
135 | the terms of any separate license agreement you may have executed
136 | with Licensor regarding such Contributions.
137 |
138 | 6. Trademarks. This License does not grant permission to use the trade
139 | names, trademarks, service marks, or product names of the Licensor,
140 | except as required for reasonable and customary use in describing the
141 | origin of the Work and reproducing the content of the NOTICE file.
142 |
143 | 7. Disclaimer of Warranty. Unless required by applicable law or
144 | agreed to in writing, Licensor provides the Work (and each
145 | Contributor provides its Contributions) on an "AS IS" BASIS,
146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
147 | implied, including, without limitation, any warranties or conditions
148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
149 | PARTICULAR PURPOSE. You are solely responsible for determining the
150 | appropriateness of using or redistributing the Work and assume any
151 | risks associated with Your exercise of permissions under this License.
152 |
153 | 8. Limitation of Liability. In no event and under no legal theory,
154 | whether in tort (including negligence), contract, or otherwise,
155 | unless required by applicable law (such as deliberate and grossly
156 | negligent acts) or agreed to in writing, shall any Contributor be
157 | liable to You for damages, including any direct, indirect, special,
158 | incidental, or consequential damages of any character arising as a
159 | result of this License or out of the use or inability to use the
160 | Work (including but not limited to damages for loss of goodwill,
161 | work stoppage, computer failure or malfunction, or any and all
162 | other commercial damages or losses), even if such Contributor
163 | has been advised of the possibility of such damages.
164 |
165 | 9. Accepting Warranty or Additional Liability. While redistributing
166 | the Work or Derivative Works thereof, You may choose to offer,
167 | and charge a fee for, acceptance of support, warranty, indemnity,
168 | or other liability obligations and/or rights consistent with this
169 | License. However, in accepting such obligations, You may act only
170 | on Your own behalf and on Your sole responsibility, not on behalf
171 | of any other Contributor, and only if You agree to indemnify,
172 | defend, and hold each Contributor harmless for any liability
173 | incurred by, or claims asserted against, such Contributor by reason
174 | of your accepting any such warranty or additional liability.
175 |
176 | END OF TERMS AND CONDITIONS
177 |
178 | APPENDIX: How to apply the Apache License to your work.
179 |
180 | To apply the Apache License to your work, attach the following
181 | boilerplate notice, with the fields enclosed by brackets "[]"
182 | replaced with your own identifying information. (Don't include
183 | the brackets!) The text should be enclosed in the appropriate
184 | comment syntax for the file format. We also recommend that a
185 | file or class name and description of purpose be included on the
186 | same "printed page" as the copyright notice for easier
187 | identification within third-party archives.
188 |
189 | Copyright 2024 Mobile Innovation Network
190 |
191 | Licensed under the Apache License, Version 2.0 (the "License");
192 | you may not use this file except in compliance with the License.
193 | You may obtain a copy of the License at
194 |
195 | http://www.apache.org/licenses/LICENSE-2.0
196 |
197 | Unless required by applicable law or agreed to in writing, software
198 | distributed under the License is distributed on an "AS IS" BASIS,
199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
200 | See the License for the specific language governing permissions and
201 | limitations under the License.
202 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | [](https://central.sonatype.com/artifact/network.chaintech/qr-kit)
2 | [](http://kotlinlang.org)
3 | [](https://github.com/JetBrains/compose-multiplatform)
4 | [](http://www.apache.org/licenses/LICENSE-2.0)
5 |
6 | 
7 | 
8 | 
9 |
10 | # QRKit - Compose Multiplatform
11 | QRKit is a Compose Multiplatform library designed for seamless QR code scanning & QR code Generating across Android, iOS, and Desktop applications.
12 |
13 |
14 |
15 | ## 📦 Installation
16 |
17 | To use QRKit in your Compose Multiplatform project, add the following dependency to your `build.gradle.kts` file
18 |
19 | ```kotlin
20 | commonMain.dependencies {
21 | implementation("network.chaintech:qr-kit:3.1.1")
22 | }
23 | ```
24 |
25 |
26 | ## 🚀 Usage
27 |
28 | ### 🔒 Add Permissions in Android and iOS
29 |
30 | - **Android**: Include this at the root level in your `AndroidManifest.xml`:
31 |
32 | ```xml
33 |
34 |
35 |
36 |
37 | ```
38 |
39 | - **iOS**: Add the following keys to the `Info.plist` in your Xcode project:
40 |
41 | ```xml
42 | NSCameraUsageDescription $(PRODUCT_NAME) camera description.
43 | NSPhotoLibraryUsageDescription $(PRODUCT_NAME) photos description.
44 | ```
45 |
46 | - **Important Note**: if you are getting Manifest Merger Failed issue, add the following to your Android Manifest file:
47 |
48 | ```kotlin
49 | tools:replace="android:name"
50 | ```
51 | ```kotlin
52 | tools:replace="android:allowBackup"
53 | ```
54 |
55 |
56 |
57 | ### 📷 QR Code Scanner
58 |
59 |
60 |
61 | ```kotlin
62 | QrScanner(
63 | modifier: Modifier,
64 | flashlightOn: Boolean,
65 | cameraLens: CameraLens,
66 | openImagePicker: Boolean,
67 | onCompletion: (String) -> Unit,
68 | imagePickerHandler: (Boolean) -> Unit,
69 | onFailure: (String) -> Unit,
70 | overlayShape = OverlayShape.Square,
71 | overlayColor = Color(0x88000000),
72 | overlayBorderColor = Color.White,
73 | zoomLevel: Float = 1f,
74 | maxZoomLevel: Float = 3f,
75 | imagePickerDialogStyle: ImagePickerDialogStyle = ImagePickerDialogStyle(),
76 | customOverlay: (ContentDrawScope.() -> Unit)? = null,
77 | permissionDeniedView: @Composable (() -> Unit?)? = null
78 | )
79 | ```
80 |
81 | * `modifier`: Modifier for modifying the layout of the QR scanner.
82 | * `flashlightOn`: Boolean indicating whether the flashlight is turned on.
83 | * `cameraLens`: This parameter allows users to switch between the front and back cameras.
84 | * `openImagePicker`: Boolean indicating whether to launch the picker for selecting images.
85 | * `imagePickerHandler`: Callback invoked to indicate the status of the gallery, whether it's open or closed.
86 | * `onFailure`: Callback invoked when there's a failure during QR code scanning.
87 | * `overlayShape`: Defines the shape of the overlay that appears over the camera view. Square and Rectangle
88 | * `overlayColor`: The color of the overlay that dims the area around the scanning region. The default is a semi-transparent black color.
89 | * `overlayBorderColor`: The color of the border around the scanning region. The default is white.
90 | * `zoomLevel`: Defines the zoom level of the camera (1f, 2f, 3f ...).
91 | * `maxZoomLevel`: Defines the maximum zoom ratio the scanner will reach. It acts as an upper bound for the zoomLevel parameter.
92 | * `imagePickerDialogStyle`: Pass ImagePicker dialog customisation like title, color, icon etc.
93 | * `customOverlay`: Allows the user to provide a custom overlay design. If no custom overlay is provided, a default one is applied.
94 | * `permissionDeniedView`: Allows the user to provide a custom view when camera permission is denied. If no custom view is provided, a default one is shown.
95 |
96 | 🔗 For more details, follow the implementation in [QrScannerScreen.kt](https://github.com/Chaintech-Network/QRKitComposeMultiplatform_org/blob/qrkit/composeApp/src/commonMain/kotlin/org/qrcodedemo/app/ui/QrScannerScreen.kt)
97 |
98 |
99 |
100 | ### 🖼️ QR Code Generator
101 |
102 |
103 |
104 |
105 | - ### Basic QR Code Generation
106 | Generating a basic QR code is as simple as using the rememberQrKitPainter function:
107 |
108 | ```kotlin
109 | val painter = rememberQrKitPainter(data = inputText)
110 |
111 | Image(
112 | painter = painter,
113 | contentDescription = null,
114 | modifier = Modifier.size(100.dp)
115 | )
116 | ```
117 |
118 | - ### Sharable QR Code Generation
119 | Generate a Sharable QR code using the QRCodeImage function. Here you will get a bitmap file which can be shared:
120 |
121 | ```kotlin
122 | var qrImageBitmap: ImageBitmap? = null
123 |
124 | QRCodeImage(
125 | modifier = Modifier.size(130.sdp),
126 | url = inputText,
127 | contentDescription = "Sharable QR Code",
128 | onSuccess = { qrImage ->
129 | qrImage?.let {
130 | qrImageBitmap = it
131 | }
132 | }
133 | )
134 |
135 | // To share the QR Code use the below code
136 | shareQrCodeImage(qrImageBitmap, "QR Code")
137 | ```
138 |
139 | - ### Designed QR Code Generation
140 | To create a more customized QR code, you can use rememberQrKitPainter function with additional options:
141 |
142 | ```kotlin
143 | val centerLogo = painterResource(Res.drawable.ic_youtube)
144 |
145 | val painter = rememberQrKitPainter(inputText) {
146 | shapes = QrKitShapes(
147 | ballShape = getSelectedQrBall(QrBallType.SquareQrBall()),
148 | darkPixelShape = getSelectedPixel(QrPixelType.SquarePixel()),
149 | frameShape = getSelectedFrameShape(QrFrameType.SquareFrame()),
150 | codeShape = getSelectedPattern(PatternType.SquarePattern),
151 | )
152 | colors = QrKitColors(
153 | darkBrush = QrKitBrush.customBrush {
154 | Brush.linearGradient(
155 | 0f to color[0],
156 | 1f to color[1],
157 | end = Offset(it, it)
158 | )
159 | }
160 | )
161 | logo = QrKitLogo(centerLogo)
162 | }
163 | ```
164 |
165 | ### 📖 Step by Step Implementation
166 |
167 | #### 1. Creating a QR Code Painter
168 | - Use the `rememberQrKitPainter` function to create a QR code painter with the specified input text.
169 |
170 | ```kotlin
171 | val painter = rememberQrKitPainter(inputText)
172 | ```
173 |
174 | #### 2. Setting the Center Logo
175 | - Set the center logo of the QR code using the `QrKitLogo` function.
176 |
177 | ```kotlin
178 | QrKitLogo(centerLogo)
179 | ```
180 |
181 | #### 3. Configuring Colors
182 | - Use the `qrColors` function to configure the colors of the QR code.
183 |
184 | ```kotlin
185 | qrColors {
186 | // configure colors here
187 | darkBrush = QrKitBrush.customBrush {
188 | Brush.linearGradient(
189 | 0f to Color.White,
190 | 1f to Color.White,
191 | end = Offset(it, it)
192 | )
193 | }
194 | frameBrush = QrKitBrush.solidBrush(Color.Blue)
195 | }
196 | ```
197 |
198 | #### 4. Configuring Shapes
199 | - Use the `qrShapes` function to configure the shapes used in the QR code.
200 |
201 | ```kotlin
202 | qrShapes {
203 | // configure shapes here
204 | }
205 | ```
206 |
207 | Within the `qrShapes` block, you can configure the following properties:
208 |
209 | | Property | Description | Example Code |
210 | |---------------------|---------------------------------------------|-------------------------------------------------------------------|
211 | | **ballShape** | Sets the ball shape to a square QR ball. | `ballShape = getSelectedQrBall(QrBallType.SquareQrBall())` |
212 | | **darkPixelShape** | Sets the dark pixel shape to a square pixel.| `darkPixelShape = getSelectedPixel(PixelType.SquarePixel())` |
213 | | **frameShape** | Sets the frame shape to a square QR frame. | `frameShape = getSelectedQrFrame(QrFrameType.SquareQrFrame())` |
214 | | **codeShape** | Sets the QR code pattern to a square pattern.| `codeShape = getSelectedPattern(PatternType.SquarePattern)` |
215 |
216 |
217 |
218 | - ### Supported Data Types for QR Codes
219 | The QR code generator supports a wide range of data types, allowing you to encode various forms of information effortlessly.
220 |
221 |
222 | | Data Type | Description |
223 | |-----------|---------------------------------------------|
224 | | **Text** | Simple text data type. |
225 | | **Phone** | Telephone number data type. |
226 | | **Email** | Email address data type. |
227 | | **SMS** | Short message service data. |
228 | | **Wi-Fi** | Wireless network configuration data. |
229 | | **Event** | Calendar event data type. |
230 | | **Location** | Geographic location data type. |
231 |
232 | Below is an example of how to create a QR code for an email address:
233 |
234 | ```kotlin
235 | val email: String = email("developer@gmail.com", "addeveloper@gmail.com", "Lorem ipsum", "Lorem ipsum")
236 |
237 | val painter = rememberQrKitPainter(data = email)
238 |
239 | Image(
240 | painter = painter, contentDescription = null, modifier = Modifier.size(100.dp)
241 | )
242 | ```
243 |
244 |
245 |
246 | ## 🏷️ Barcode Generator
247 |
248 |
249 | You can easily generate and display barcodes using the `rememberBarcodePainter` function in your Compose application.
250 |
251 | ```kotlin
252 | val barCodePainter = rememberBarcodePainter(
253 | content = data,
254 | format = type,
255 | brush = SolidColor(Color.White),
256 | onError = { throwable ->
257 | scope.launch {
258 | snackbarHostState.showSnackbar("Error occurred: ${throwable.message}")
259 | }
260 | // Return a fallback painter, for example, an empty painter
261 | EmptyPainter()
262 | }
263 | )
264 |
265 | Image(
266 | painter = barCodePainter,
267 | contentDescription = null,
268 | modifier = Modifier
269 | .fillMaxWidth()
270 | .height(100.sdp)
271 | )
272 | ```
273 |
274 | 🔗 For more details, follow the implementation in [BarCodeGeneratorScreen.kt](https://github.com/Chaintech-Network/QRKitComposeMultiplatform_org/blob/qrkit/composeApp/src/commonMain/kotlin/org/qrcodedemo/app/ui/BarCodeGeneratorScreen.kt)
275 |
276 | The following table explains the parameters used in the `rememberBarcodePainter` function.
277 |
278 | | Parameter | Description |
279 | |-----------------|-------------------------------------------------------------------------------------------------------------------|
280 | | `content` | The string data to be encoded into the barcode. |
281 | | `format` | The format of the barcode to be generated (e.g., `BarcodeFormat.QR_CODE`, `CODE_128`, etc.). |
282 | | `brush` | The `Brush` used to paint the barcode. By default, it uses `SolidColor(Color.Black)`. |
283 | | `onError` | A callback function that handles errors during barcode generation. It returns a `Painter` to display in case of failure.|
284 | | `pathGenerator` | Function that generates the path for the barcode. It defines how the barcode lines or patterns are drawn. The default is `::defaultBarcodePathGenerator`. |
285 | | `factory` | A `PainterFactory` used to create the `Painter` for rendering the barcode. The default is `DefaultPainterFactory()`.|
286 |
287 |
288 |
289 | ### 🧩 Barcode Formats
290 |
291 | | Barcode Format | Description | Limitations |
292 | |----------------|-------------|-------------|
293 | | `Codabar` | **Codabar** is a simple barcode used for libraries, blood banks, and airbills. | Can encode numbers and a few special characters (A, B, C, D, +, -, $, /, :). Limited character set. |
294 | | `Code39` | **Code 39** is widely used in industrial applications. It can encode alphanumeric characters and a few special symbols. | Lower data density compared to other formats. |
295 | | `Code93` | **Code 93** is an enhanced version of Code 39, offering higher density and encoding of additional characters. | Limited to alphanumeric data, but can encode more characters than Code 39. |
296 | | `Code128` | **Code 128** is a high-density barcode used for logistics and shipping. It can encode all 128 ASCII characters. | More complex and longer compared to simpler formats like Code 39. |
297 | | `EAN8` | **EAN-8** is a shorter version of EAN-13, used on smaller products where space is limited. | Can encode only 8 digits, limiting the amount of information. |
298 | | `EAN13` | **EAN-13** is the standard barcode for products, mainly used in retail. | Can encode only numeric digits, no letters or symbols. |
299 | | `ITF` | **ITF (Interleaved 2 of 5)** is used in packaging and logistics. | Can encode only numeric digits and may be prone to misreading without proper scanning equipment. |
300 | | `UPCA` | **UPC-A** is a barcode format used for retail products in the US, encoding 12 digits. | Can encode only numeric digits and space is limited to 12 characters. |
301 | | `UPCE` | **UPC-E** is a compressed version of UPC-A, used on smaller packages. | Limited to encoding fewer digits (6–8) and primarily used in specific retail scenarios. |
302 |
303 |
304 |
305 |
306 |
307 |
308 |
309 | ## 📖 Detailed Explanation
310 |
311 | ✨ **See the QR Code Generator in Action!**
312 | - Check out the full implementation in [QrGeneratorScreen.kt](https://github.com/Chaintech-Network/QRKitComposeMultiplatform_org/blob/qrkit/composeApp/src/commonMain/kotlin/org/qrcodedemo/app/ui/QrGeneratorScreen.kt) to witness the magic of generating QR codes in real-time! 🚀
313 |
314 | 💡 **Need to Pick and Crop Images?**
315 | - We’ve integrated the powerful **CMP Pick n Crop Library** for seamless image handling. Head over to [App.kt](https://github.com/Chaintech-Network/QRKitComposeMultiplatform/blob/main/composeApp/src/commonMain/kotlin/org/qrcodedemo/app/App.kt) for all the details! 📸
316 |
317 | 📖 **Want to Learn More?**
318 | Explore our detailed Medium articles for a deeper dive:
319 |
320 | - [**QRCodeGenerator**](https://medium.com/mobile-innovation-network/qrkit-2-0-scan-genrate-customize-716d870c3eae) 🛠️ — Everything you need to know about generating QR codes!
321 | - [**QRCodeScanner**](https://medium.com/mobile-innovation-network/qrkit-barcode-scanning-in-compose-multiplatform-for-android-and-ios-77cf5d84f719) 🔍 — Learn how to implement QR code scanning across platforms!
322 |
323 |
324 | ## 🌐 Stay Connected with Us
325 | Stay connected and keep up with our latest innovations! 💼 Let's innovate together!
326 | [](https://www.linkedin.com/showcase/mobile-innovation-network)
327 | [](https://medium.com/mobile-innovation-network)
328 |
329 |
330 | ## 📄 License
331 | ```
332 | Copyright 2023 Mobile Innovation Network
333 |
334 | Licensed under the Apache License, Version 2.0 (the "License");
335 | you may not use this file except in compliance with the License.
336 | You may obtain a copy of the License at
337 |
338 | http://www.apache.org/licenses/LICENSE-2.0
339 |
340 | Unless required by applicable law or agreed to in writing, software
341 | distributed under the License is distributed on an "AS IS" BASIS,
342 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
343 | See the License for the specific language governing permissions and
344 | limitations under the License.
345 | ```
--------------------------------------------------------------------------------
/assets/CMP_QRKit_Barcode_Generator.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Chaintech-Network/QRKitComposeMultiplatform/822f1f8a6ea0114494f53c12074400f130295973/assets/CMP_QRKit_Barcode_Generator.png
--------------------------------------------------------------------------------
/assets/CMP_QRKit_QR_Customisation.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Chaintech-Network/QRKitComposeMultiplatform/822f1f8a6ea0114494f53c12074400f130295973/assets/CMP_QRKit_QR_Customisation.png
--------------------------------------------------------------------------------
/assets/CMP_QRKit_QR_Generator.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Chaintech-Network/QRKitComposeMultiplatform/822f1f8a6ea0114494f53c12074400f130295973/assets/CMP_QRKit_QR_Generator.png
--------------------------------------------------------------------------------
/assets/CMP_QRKit_scanner.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Chaintech-Network/QRKitComposeMultiplatform/822f1f8a6ea0114494f53c12074400f130295973/assets/CMP_QRKit_scanner.gif
--------------------------------------------------------------------------------
/assets/CMP_QRKit_scanner_genrator_banner.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Chaintech-Network/QRKitComposeMultiplatform/822f1f8a6ea0114494f53c12074400f130295973/assets/CMP_QRKit_scanner_genrator_banner.png
--------------------------------------------------------------------------------
/build.gradle.kts:
--------------------------------------------------------------------------------
1 | plugins {
2 | alias(libs.plugins.multiplatform).apply(false)
3 | alias(libs.plugins.compose).apply(false)
4 | alias(libs.plugins.android.application).apply(false)
5 | alias(libs.plugins.android.library).apply(false)
6 | alias(libs.plugins.mavenPublish).apply(false)
7 | alias(libs.plugins.compose.compiler).apply(false)
8 | }
9 |
--------------------------------------------------------------------------------
/composeApp/build.gradle.kts:
--------------------------------------------------------------------------------
1 | import org.jetbrains.kotlin.gradle.ExperimentalKotlinGradlePluginApi
2 | import org.jetbrains.kotlin.gradle.dsl.JvmTarget
3 | import org.jetbrains.kotlin.gradle.plugin.KotlinSourceSetTree
4 |
5 | plugins {
6 | alias(libs.plugins.multiplatform)
7 | alias(libs.plugins.compose)
8 | alias(libs.plugins.android.application)
9 | alias(libs.plugins.compose.compiler)
10 | }
11 |
12 | kotlin {
13 | androidTarget {
14 | compilations.all {
15 | compileTaskProvider {
16 | compilerOptions {
17 | jvmTarget.set(JvmTarget.JVM_17)
18 | freeCompilerArgs.add("-Xjdk-release=${JavaVersion.VERSION_17}")
19 | }
20 | }
21 | }
22 | //https://www.jetbrains.com/help/kotlin-multiplatform-dev/compose-test.html
23 | @OptIn(ExperimentalKotlinGradlePluginApi::class)
24 | instrumentedTestVariant {
25 | sourceSetTree.set(KotlinSourceSetTree.test)
26 | dependencies {
27 | debugImplementation(libs.androidx.testManifest)
28 | implementation(libs.androidx.junit4)
29 | }
30 | }
31 | }
32 |
33 | listOf(
34 | iosX64(),
35 | iosArm64(),
36 | iosSimulatorArm64()
37 | ).forEach {
38 | it.binaries.framework {
39 | baseName = "ComposeApp"
40 | isStatic = true
41 | }
42 | }
43 |
44 | jvm {
45 | compilations.all {
46 | kotlinOptions {
47 | jvmTarget = "17"
48 | }
49 | }
50 | }
51 |
52 | sourceSets {
53 | all {
54 | languageSettings {
55 | optIn("org.jetbrains.compose.resources.ExperimentalResourceApi")
56 | }
57 | }
58 | commonMain.dependencies {
59 | implementation(compose.runtime)
60 | implementation(compose.material3)
61 | implementation(compose.materialIconsExtended)
62 | @OptIn(org.jetbrains.compose.ExperimentalComposeLibrary::class)
63 | implementation(compose.components.resources)
64 |
65 | implementation(libs.qr.kit)
66 |
67 | implementation(libs.navigation.compose)
68 | implementation(libs.sdp.ssp.compose.multiplatform)
69 | }
70 |
71 | commonTest.dependencies {
72 | implementation(kotlin("test"))
73 | }
74 |
75 | androidMain.dependencies {
76 | implementation(libs.androidx.appcompat)
77 | implementation(libs.androidx.activityCompose)
78 | implementation(libs.compose.uitooling)
79 | }
80 |
81 | iosMain.dependencies {
82 | }
83 |
84 | jvmMain.dependencies {
85 | implementation(compose.desktop.currentOs)
86 | }
87 | }
88 | }
89 |
90 | android {
91 | namespace = "org.qrcodedemo.app"
92 | compileSdk = 35
93 |
94 | defaultConfig {
95 | minSdk = 24
96 | targetSdk = 35
97 |
98 | applicationId = "org.qrcodedemo.app.androidApp"
99 | versionCode = 1
100 | versionName = "1.0.0"
101 | }
102 | sourceSets["main"].apply {
103 | manifest.srcFile("src/androidMain/AndroidManifest.xml")
104 | res.srcDirs("src/androidMain/resources")
105 | resources.srcDirs("src/commonMain/resources")
106 | }
107 | compileOptions {
108 | sourceCompatibility = JavaVersion.VERSION_17
109 | targetCompatibility = JavaVersion.VERSION_17
110 | }
111 | buildFeatures {
112 | compose = true
113 | }
114 | }
115 |
--------------------------------------------------------------------------------
/composeApp/src/androidMain/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
6 |
7 |
8 |
9 |
11 |
12 |
18 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
35 |
38 |
39 |
40 |
41 |
--------------------------------------------------------------------------------
/composeApp/src/androidMain/kotlin/org/qrcodedemo/app/App.android.kt:
--------------------------------------------------------------------------------
1 | package org.qrcodedemo.app
2 |
3 | import android.app.Application
4 | import android.os.Bundle
5 | import androidx.activity.ComponentActivity
6 | import androidx.activity.compose.setContent
7 | import androidx.activity.enableEdgeToEdge
8 | import qrgenerator.AppContext
9 |
10 | class AndroidApp : Application() {
11 | companion object {
12 | lateinit var INSTANCE: AndroidApp
13 | }
14 |
15 | override fun onCreate() {
16 | super.onCreate()
17 | INSTANCE = this
18 | AppContext.apply { set(applicationContext) }
19 | }
20 | }
21 |
22 | class AppActivity : ComponentActivity() {
23 | override fun onCreate(savedInstanceState: Bundle?) {
24 | super.onCreate(savedInstanceState)
25 | setContent {
26 | enableEdgeToEdge()
27 | AppHome()
28 | }
29 | }
30 | }
31 |
32 |
--------------------------------------------------------------------------------
/composeApp/src/androidMain/kotlin/org/qrcodedemo/app/Platform.android.kt:
--------------------------------------------------------------------------------
1 | package org.qrcodedemo.app
2 |
3 | actual fun platformName(): String = "Android"
--------------------------------------------------------------------------------
/composeApp/src/androidMain/kotlin/org/qrcodedemo/app/theme/Theme.android.kt:
--------------------------------------------------------------------------------
1 | package org.qrcodedemo.app.theme
2 |
3 | import android.app.Activity
4 | import android.graphics.Color
5 | import androidx.compose.runtime.Composable
6 | import androidx.compose.runtime.LaunchedEffect
7 | import androidx.compose.ui.platform.LocalView
8 | import androidx.core.view.WindowCompat
9 |
10 | @Composable
11 | internal actual fun SystemAppearance(isDark: Boolean) {
12 | val view = LocalView.current
13 | val systemBarColor = Color.TRANSPARENT
14 | LaunchedEffect(isDark) {
15 | val window = (view.context as Activity).window
16 | WindowCompat.setDecorFitsSystemWindows(window, false)
17 | window.statusBarColor = systemBarColor
18 | window.navigationBarColor = systemBarColor
19 | WindowCompat.getInsetsController(window, window.decorView).apply {
20 | isAppearanceLightStatusBars = isDark
21 | isAppearanceLightNavigationBars = isDark
22 | }
23 | }
24 | }
--------------------------------------------------------------------------------
/composeApp/src/androidMain/res/xml/file_paths.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/composeApp/src/androidMain/res/xml/path_provider.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
6 |
9 |
--------------------------------------------------------------------------------
/composeApp/src/commonMain/composeResources/drawable/bg.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Chaintech-Network/QRKitComposeMultiplatform/822f1f8a6ea0114494f53c12074400f130295973/composeApp/src/commonMain/composeResources/drawable/bg.png
--------------------------------------------------------------------------------
/composeApp/src/commonMain/composeResources/drawable/ic_arrow_row.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Chaintech-Network/QRKitComposeMultiplatform/822f1f8a6ea0114494f53c12074400f130295973/composeApp/src/commonMain/composeResources/drawable/ic_arrow_row.png
--------------------------------------------------------------------------------
/composeApp/src/commonMain/composeResources/drawable/ic_calendar.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Chaintech-Network/QRKitComposeMultiplatform/822f1f8a6ea0114494f53c12074400f130295973/composeApp/src/commonMain/composeResources/drawable/ic_calendar.png
--------------------------------------------------------------------------------
/composeApp/src/commonMain/composeResources/drawable/ic_camera_switch.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Chaintech-Network/QRKitComposeMultiplatform/822f1f8a6ea0114494f53c12074400f130295973/composeApp/src/commonMain/composeResources/drawable/ic_camera_switch.png
--------------------------------------------------------------------------------
/composeApp/src/commonMain/composeResources/drawable/ic_check_icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Chaintech-Network/QRKitComposeMultiplatform/822f1f8a6ea0114494f53c12074400f130295973/composeApp/src/commonMain/composeResources/drawable/ic_check_icon.png
--------------------------------------------------------------------------------
/composeApp/src/commonMain/composeResources/drawable/ic_circle.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Chaintech-Network/QRKitComposeMultiplatform/822f1f8a6ea0114494f53c12074400f130295973/composeApp/src/commonMain/composeResources/drawable/ic_circle.png
--------------------------------------------------------------------------------
/composeApp/src/commonMain/composeResources/drawable/ic_circle_eyes.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Chaintech-Network/QRKitComposeMultiplatform/822f1f8a6ea0114494f53c12074400f130295973/composeApp/src/commonMain/composeResources/drawable/ic_circle_eyes.png
--------------------------------------------------------------------------------
/composeApp/src/commonMain/composeResources/drawable/ic_circle_pixel.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Chaintech-Network/QRKitComposeMultiplatform/822f1f8a6ea0114494f53c12074400f130295973/composeApp/src/commonMain/composeResources/drawable/ic_circle_pixel.png
--------------------------------------------------------------------------------
/composeApp/src/commonMain/composeResources/drawable/ic_circle_round_eyes.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Chaintech-Network/QRKitComposeMultiplatform/822f1f8a6ea0114494f53c12074400f130295973/composeApp/src/commonMain/composeResources/drawable/ic_circle_round_eyes.png
--------------------------------------------------------------------------------
/composeApp/src/commonMain/composeResources/drawable/ic_circle_shape.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Chaintech-Network/QRKitComposeMultiplatform/822f1f8a6ea0114494f53c12074400f130295973/composeApp/src/commonMain/composeResources/drawable/ic_circle_shape.png
--------------------------------------------------------------------------------
/composeApp/src/commonMain/composeResources/drawable/ic_done.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Chaintech-Network/QRKitComposeMultiplatform/822f1f8a6ea0114494f53c12074400f130295973/composeApp/src/commonMain/composeResources/drawable/ic_done.png
--------------------------------------------------------------------------------
/composeApp/src/commonMain/composeResources/drawable/ic_drop_down.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Chaintech-Network/QRKitComposeMultiplatform/822f1f8a6ea0114494f53c12074400f130295973/composeApp/src/commonMain/composeResources/drawable/ic_drop_down.png
--------------------------------------------------------------------------------
/composeApp/src/commonMain/composeResources/drawable/ic_email.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Chaintech-Network/QRKitComposeMultiplatform/822f1f8a6ea0114494f53c12074400f130295973/composeApp/src/commonMain/composeResources/drawable/ic_email.png
--------------------------------------------------------------------------------
/composeApp/src/commonMain/composeResources/drawable/ic_flash_icon.xml:
--------------------------------------------------------------------------------
1 |
6 |
13 |
14 |
--------------------------------------------------------------------------------
/composeApp/src/commonMain/composeResources/drawable/ic_gallery_icon.xml:
--------------------------------------------------------------------------------
1 |
7 |
14 |
16 |
17 |
23 |
24 |
25 |
26 |
27 |
28 |
35 |
36 |
--------------------------------------------------------------------------------
/composeApp/src/commonMain/composeResources/drawable/ic_hexagon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Chaintech-Network/QRKitComposeMultiplatform/822f1f8a6ea0114494f53c12074400f130295973/composeApp/src/commonMain/composeResources/drawable/ic_hexagon.png
--------------------------------------------------------------------------------
/composeApp/src/commonMain/composeResources/drawable/ic_horizontal_line_pixel.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Chaintech-Network/QRKitComposeMultiplatform/822f1f8a6ea0114494f53c12074400f130295973/composeApp/src/commonMain/composeResources/drawable/ic_horizontal_line_pixel.png
--------------------------------------------------------------------------------
/composeApp/src/commonMain/composeResources/drawable/ic_instagram.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Chaintech-Network/QRKitComposeMultiplatform/822f1f8a6ea0114494f53c12074400f130295973/composeApp/src/commonMain/composeResources/drawable/ic_instagram.png
--------------------------------------------------------------------------------
/composeApp/src/commonMain/composeResources/drawable/ic_kotlin.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Chaintech-Network/QRKitComposeMultiplatform/822f1f8a6ea0114494f53c12074400f130295973/composeApp/src/commonMain/composeResources/drawable/ic_kotlin.png
--------------------------------------------------------------------------------
/composeApp/src/commonMain/composeResources/drawable/ic_linkedin.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Chaintech-Network/QRKitComposeMultiplatform/822f1f8a6ea0114494f53c12074400f130295973/composeApp/src/commonMain/composeResources/drawable/ic_linkedin.png
--------------------------------------------------------------------------------
/composeApp/src/commonMain/composeResources/drawable/ic_magic_tool.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Chaintech-Network/QRKitComposeMultiplatform/822f1f8a6ea0114494f53c12074400f130295973/composeApp/src/commonMain/composeResources/drawable/ic_magic_tool.png
--------------------------------------------------------------------------------
/composeApp/src/commonMain/composeResources/drawable/ic_next.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Chaintech-Network/QRKitComposeMultiplatform/822f1f8a6ea0114494f53c12074400f130295973/composeApp/src/commonMain/composeResources/drawable/ic_next.png
--------------------------------------------------------------------------------
/composeApp/src/commonMain/composeResources/drawable/ic_pentagon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Chaintech-Network/QRKitComposeMultiplatform/822f1f8a6ea0114494f53c12074400f130295973/composeApp/src/commonMain/composeResources/drawable/ic_pentagon.png
--------------------------------------------------------------------------------
/composeApp/src/commonMain/composeResources/drawable/ic_person_circle.xml:
--------------------------------------------------------------------------------
1 |
6 |
9 |
13 |
14 |
--------------------------------------------------------------------------------
/composeApp/src/commonMain/composeResources/drawable/ic_phone.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Chaintech-Network/QRKitComposeMultiplatform/822f1f8a6ea0114494f53c12074400f130295973/composeApp/src/commonMain/composeResources/drawable/ic_phone.png
--------------------------------------------------------------------------------
/composeApp/src/commonMain/composeResources/drawable/ic_pinterest.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Chaintech-Network/QRKitComposeMultiplatform/822f1f8a6ea0114494f53c12074400f130295973/composeApp/src/commonMain/composeResources/drawable/ic_pinterest.png
--------------------------------------------------------------------------------
/composeApp/src/commonMain/composeResources/drawable/ic_qr_code.xml:
--------------------------------------------------------------------------------
1 |
6 |
11 |
12 |
--------------------------------------------------------------------------------
/composeApp/src/commonMain/composeResources/drawable/ic_rectangle.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/composeApp/src/commonMain/composeResources/drawable/ic_round_corner_pixel.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Chaintech-Network/QRKitComposeMultiplatform/822f1f8a6ea0114494f53c12074400f130295973/composeApp/src/commonMain/composeResources/drawable/ic_round_corner_pixel.png
--------------------------------------------------------------------------------
/composeApp/src/commonMain/composeResources/drawable/ic_rounded_circle_eyes.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Chaintech-Network/QRKitComposeMultiplatform/822f1f8a6ea0114494f53c12074400f130295973/composeApp/src/commonMain/composeResources/drawable/ic_rounded_circle_eyes.png
--------------------------------------------------------------------------------
/composeApp/src/commonMain/composeResources/drawable/ic_rounded_eyes.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Chaintech-Network/QRKitComposeMultiplatform/822f1f8a6ea0114494f53c12074400f130295973/composeApp/src/commonMain/composeResources/drawable/ic_rounded_eyes.png
--------------------------------------------------------------------------------
/composeApp/src/commonMain/composeResources/drawable/ic_rounded_square_eyes.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Chaintech-Network/QRKitComposeMultiplatform/822f1f8a6ea0114494f53c12074400f130295973/composeApp/src/commonMain/composeResources/drawable/ic_rounded_square_eyes.png
--------------------------------------------------------------------------------
/composeApp/src/commonMain/composeResources/drawable/ic_scanner.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Chaintech-Network/QRKitComposeMultiplatform/822f1f8a6ea0114494f53c12074400f130295973/composeApp/src/commonMain/composeResources/drawable/ic_scanner.png
--------------------------------------------------------------------------------
/composeApp/src/commonMain/composeResources/drawable/ic_sms.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Chaintech-Network/QRKitComposeMultiplatform/822f1f8a6ea0114494f53c12074400f130295973/composeApp/src/commonMain/composeResources/drawable/ic_sms.png
--------------------------------------------------------------------------------
/composeApp/src/commonMain/composeResources/drawable/ic_square.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Chaintech-Network/QRKitComposeMultiplatform/822f1f8a6ea0114494f53c12074400f130295973/composeApp/src/commonMain/composeResources/drawable/ic_square.png
--------------------------------------------------------------------------------
/composeApp/src/commonMain/composeResources/drawable/ic_square_border.xml:
--------------------------------------------------------------------------------
1 |
6 |
10 |
11 |
--------------------------------------------------------------------------------
/composeApp/src/commonMain/composeResources/drawable/ic_square_circle_eyes.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Chaintech-Network/QRKitComposeMultiplatform/822f1f8a6ea0114494f53c12074400f130295973/composeApp/src/commonMain/composeResources/drawable/ic_square_circle_eyes.png
--------------------------------------------------------------------------------
/composeApp/src/commonMain/composeResources/drawable/ic_square_pixel.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Chaintech-Network/QRKitComposeMultiplatform/822f1f8a6ea0114494f53c12074400f130295973/composeApp/src/commonMain/composeResources/drawable/ic_square_pixel.png
--------------------------------------------------------------------------------
/composeApp/src/commonMain/composeResources/drawable/ic_square_round_eyes.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Chaintech-Network/QRKitComposeMultiplatform/822f1f8a6ea0114494f53c12074400f130295973/composeApp/src/commonMain/composeResources/drawable/ic_square_round_eyes.png
--------------------------------------------------------------------------------
/composeApp/src/commonMain/composeResources/drawable/ic_swift.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Chaintech-Network/QRKitComposeMultiplatform/822f1f8a6ea0114494f53c12074400f130295973/composeApp/src/commonMain/composeResources/drawable/ic_swift.png
--------------------------------------------------------------------------------
/composeApp/src/commonMain/composeResources/drawable/ic_temp.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Chaintech-Network/QRKitComposeMultiplatform/822f1f8a6ea0114494f53c12074400f130295973/composeApp/src/commonMain/composeResources/drawable/ic_temp.jpg
--------------------------------------------------------------------------------
/composeApp/src/commonMain/composeResources/drawable/ic_text.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Chaintech-Network/QRKitComposeMultiplatform/822f1f8a6ea0114494f53c12074400f130295973/composeApp/src/commonMain/composeResources/drawable/ic_text.png
--------------------------------------------------------------------------------
/composeApp/src/commonMain/composeResources/drawable/ic_text_blue.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Chaintech-Network/QRKitComposeMultiplatform/822f1f8a6ea0114494f53c12074400f130295973/composeApp/src/commonMain/composeResources/drawable/ic_text_blue.png
--------------------------------------------------------------------------------
/composeApp/src/commonMain/composeResources/drawable/ic_tiktok.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Chaintech-Network/QRKitComposeMultiplatform/822f1f8a6ea0114494f53c12074400f130295973/composeApp/src/commonMain/composeResources/drawable/ic_tiktok.png
--------------------------------------------------------------------------------
/composeApp/src/commonMain/composeResources/drawable/ic_vertical_line_pixel.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Chaintech-Network/QRKitComposeMultiplatform/822f1f8a6ea0114494f53c12074400f130295973/composeApp/src/commonMain/composeResources/drawable/ic_vertical_line_pixel.png
--------------------------------------------------------------------------------
/composeApp/src/commonMain/composeResources/drawable/ic_website.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Chaintech-Network/QRKitComposeMultiplatform/822f1f8a6ea0114494f53c12074400f130295973/composeApp/src/commonMain/composeResources/drawable/ic_website.png
--------------------------------------------------------------------------------
/composeApp/src/commonMain/composeResources/drawable/ic_wifi.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Chaintech-Network/QRKitComposeMultiplatform/822f1f8a6ea0114494f53c12074400f130295973/composeApp/src/commonMain/composeResources/drawable/ic_wifi.png
--------------------------------------------------------------------------------
/composeApp/src/commonMain/composeResources/drawable/ic_youtube.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Chaintech-Network/QRKitComposeMultiplatform/822f1f8a6ea0114494f53c12074400f130295973/composeApp/src/commonMain/composeResources/drawable/ic_youtube.png
--------------------------------------------------------------------------------
/composeApp/src/commonMain/composeResources/drawable/img_barcode.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Chaintech-Network/QRKitComposeMultiplatform/822f1f8a6ea0114494f53c12074400f130295973/composeApp/src/commonMain/composeResources/drawable/img_barcode.png
--------------------------------------------------------------------------------
/composeApp/src/commonMain/composeResources/drawable/img_curved_arrow.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Chaintech-Network/QRKitComposeMultiplatform/822f1f8a6ea0114494f53c12074400f130295973/composeApp/src/commonMain/composeResources/drawable/img_curved_arrow.png
--------------------------------------------------------------------------------
/composeApp/src/commonMain/composeResources/drawable/img_dotted_box.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Chaintech-Network/QRKitComposeMultiplatform/822f1f8a6ea0114494f53c12074400f130295973/composeApp/src/commonMain/composeResources/drawable/img_dotted_box.png
--------------------------------------------------------------------------------
/composeApp/src/commonMain/composeResources/drawable/img_mobile_innovation.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Chaintech-Network/QRKitComposeMultiplatform/822f1f8a6ea0114494f53c12074400f130295973/composeApp/src/commonMain/composeResources/drawable/img_mobile_innovation.png
--------------------------------------------------------------------------------
/composeApp/src/commonMain/composeResources/drawable/img_qr_lines.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Chaintech-Network/QRKitComposeMultiplatform/822f1f8a6ea0114494f53c12074400f130295973/composeApp/src/commonMain/composeResources/drawable/img_qr_lines.png
--------------------------------------------------------------------------------
/composeApp/src/commonMain/composeResources/drawable/img_qr_thumb.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Chaintech-Network/QRKitComposeMultiplatform/822f1f8a6ea0114494f53c12074400f130295973/composeApp/src/commonMain/composeResources/drawable/img_qr_thumb.png
--------------------------------------------------------------------------------
/composeApp/src/commonMain/composeResources/drawable/img_scanner.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Chaintech-Network/QRKitComposeMultiplatform/822f1f8a6ea0114494f53c12074400f130295973/composeApp/src/commonMain/composeResources/drawable/img_scanner.png
--------------------------------------------------------------------------------
/composeApp/src/commonMain/composeResources/drawable/message.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Chaintech-Network/QRKitComposeMultiplatform/822f1f8a6ea0114494f53c12074400f130295973/composeApp/src/commonMain/composeResources/drawable/message.png
--------------------------------------------------------------------------------
/composeApp/src/commonMain/composeResources/drawable/text.xml:
--------------------------------------------------------------------------------
1 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/composeApp/src/commonMain/composeResources/drawable/website.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Chaintech-Network/QRKitComposeMultiplatform/822f1f8a6ea0114494f53c12074400f130295973/composeApp/src/commonMain/composeResources/drawable/website.png
--------------------------------------------------------------------------------
/composeApp/src/commonMain/composeResources/drawable/wifi.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Chaintech-Network/QRKitComposeMultiplatform/822f1f8a6ea0114494f53c12074400f130295973/composeApp/src/commonMain/composeResources/drawable/wifi.png
--------------------------------------------------------------------------------
/composeApp/src/commonMain/composeResources/font/Aeonik-Bold.otf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Chaintech-Network/QRKitComposeMultiplatform/822f1f8a6ea0114494f53c12074400f130295973/composeApp/src/commonMain/composeResources/font/Aeonik-Bold.otf
--------------------------------------------------------------------------------
/composeApp/src/commonMain/composeResources/font/Aeonik-Regular.otf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Chaintech-Network/QRKitComposeMultiplatform/822f1f8a6ea0114494f53c12074400f130295973/composeApp/src/commonMain/composeResources/font/Aeonik-Regular.otf
--------------------------------------------------------------------------------
/composeApp/src/commonMain/composeResources/font/SofiaSansCondensed-Bold.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Chaintech-Network/QRKitComposeMultiplatform/822f1f8a6ea0114494f53c12074400f130295973/composeApp/src/commonMain/composeResources/font/SofiaSansCondensed-Bold.ttf
--------------------------------------------------------------------------------
/composeApp/src/commonMain/composeResources/font/SofiaSansCondensed-Light.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Chaintech-Network/QRKitComposeMultiplatform/822f1f8a6ea0114494f53c12074400f130295973/composeApp/src/commonMain/composeResources/font/SofiaSansCondensed-Light.ttf
--------------------------------------------------------------------------------
/composeApp/src/commonMain/composeResources/font/SofiaSansCondensed-Medium.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Chaintech-Network/QRKitComposeMultiplatform/822f1f8a6ea0114494f53c12074400f130295973/composeApp/src/commonMain/composeResources/font/SofiaSansCondensed-Medium.ttf
--------------------------------------------------------------------------------
/composeApp/src/commonMain/composeResources/font/SofiaSansCondensed-Regular.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Chaintech-Network/QRKitComposeMultiplatform/822f1f8a6ea0114494f53c12074400f130295973/composeApp/src/commonMain/composeResources/font/SofiaSansCondensed-Regular.ttf
--------------------------------------------------------------------------------
/composeApp/src/commonMain/composeResources/font/SofiaSansCondensed-SemiBold.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Chaintech-Network/QRKitComposeMultiplatform/822f1f8a6ea0114494f53c12074400f130295973/composeApp/src/commonMain/composeResources/font/SofiaSansCondensed-SemiBold.ttf
--------------------------------------------------------------------------------
/composeApp/src/commonMain/composeResources/font/poppins_bold.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Chaintech-Network/QRKitComposeMultiplatform/822f1f8a6ea0114494f53c12074400f130295973/composeApp/src/commonMain/composeResources/font/poppins_bold.ttf
--------------------------------------------------------------------------------
/composeApp/src/commonMain/composeResources/font/poppins_medium.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Chaintech-Network/QRKitComposeMultiplatform/822f1f8a6ea0114494f53c12074400f130295973/composeApp/src/commonMain/composeResources/font/poppins_medium.ttf
--------------------------------------------------------------------------------
/composeApp/src/commonMain/composeResources/font/poppins_regular.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Chaintech-Network/QRKitComposeMultiplatform/822f1f8a6ea0114494f53c12074400f130295973/composeApp/src/commonMain/composeResources/font/poppins_regular.ttf
--------------------------------------------------------------------------------
/composeApp/src/commonMain/composeResources/font/poppins_semibold.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Chaintech-Network/QRKitComposeMultiplatform/822f1f8a6ea0114494f53c12074400f130295973/composeApp/src/commonMain/composeResources/font/poppins_semibold.ttf
--------------------------------------------------------------------------------
/composeApp/src/commonMain/composeResources/font/sf_pro.otf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Chaintech-Network/QRKitComposeMultiplatform/822f1f8a6ea0114494f53c12074400f130295973/composeApp/src/commonMain/composeResources/font/sf_pro.otf
--------------------------------------------------------------------------------
/composeApp/src/commonMain/composeResources/font/sf_pro_bold.otf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Chaintech-Network/QRKitComposeMultiplatform/822f1f8a6ea0114494f53c12074400f130295973/composeApp/src/commonMain/composeResources/font/sf_pro_bold.otf
--------------------------------------------------------------------------------
/composeApp/src/commonMain/composeResources/font/sf_pro_medium.otf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Chaintech-Network/QRKitComposeMultiplatform/822f1f8a6ea0114494f53c12074400f130295973/composeApp/src/commonMain/composeResources/font/sf_pro_medium.otf
--------------------------------------------------------------------------------
/composeApp/src/commonMain/composeResources/font/sf_pro_semibold.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Chaintech-Network/QRKitComposeMultiplatform/822f1f8a6ea0114494f53c12074400f130295973/composeApp/src/commonMain/composeResources/font/sf_pro_semibold.ttf
--------------------------------------------------------------------------------
/composeApp/src/commonMain/kotlin/org/qrcodedemo/app/App.kt:
--------------------------------------------------------------------------------
1 | package org.qrcodedemo.app
2 |
3 | import androidx.compose.foundation.layout.padding
4 | import androidx.compose.material3.Scaffold
5 | import androidx.compose.material3.SnackbarHost
6 | import androidx.compose.material3.SnackbarHostState
7 | import androidx.compose.runtime.Composable
8 | import androidx.compose.runtime.CompositionLocalProvider
9 | import androidx.compose.runtime.compositionLocalOf
10 | import androidx.compose.runtime.remember
11 | import androidx.compose.ui.Modifier
12 | import androidx.compose.ui.unit.dp
13 | import org.qrcodedemo.app.ui.QRKitNav
14 |
15 | val LocalSnackBarHostState =
16 | compositionLocalOf { error("No SnackBarHostState provided") }
17 |
18 | @Composable
19 | fun CompositionProvider(content: @Composable (SnackbarHostState) -> Unit) {
20 | val snackBarHostState = remember { SnackbarHostState() }
21 |
22 | CompositionLocalProvider(
23 | LocalSnackBarHostState provides snackBarHostState,
24 | ) {
25 | content(snackBarHostState)
26 | }
27 | }
28 |
29 | @Composable
30 | internal fun AppHome() {
31 | CompositionProvider { snackBarHostState ->
32 | Scaffold(
33 | snackbarHost = {
34 | SnackbarHost(snackBarHostState, Modifier.padding(bottom = 30.dp))
35 | }
36 | ) {
37 | QRKitNav()
38 | }
39 | }
40 | }
41 |
42 |
43 |
--------------------------------------------------------------------------------
/composeApp/src/commonMain/kotlin/org/qrcodedemo/app/Platform.kt:
--------------------------------------------------------------------------------
1 | package org.qrcodedemo.app
2 |
3 | expect fun platformName(): String
--------------------------------------------------------------------------------
/composeApp/src/commonMain/kotlin/org/qrcodedemo/app/theme/Color.kt:
--------------------------------------------------------------------------------
1 | package org.qrcodedemo.app.theme
2 |
3 | import androidx.compose.ui.graphics.Color
4 |
5 | //generated by https://m3.material.io/theme-builder#/custom
6 | //Color palette was taken here: https://colorhunt.co/palettes/popular
7 |
8 | internal val md_theme_light_primary = Color(0xFF00687A)
9 | internal val md_theme_light_onPrimary = Color(0xFFFFFFFF)
10 | internal val md_theme_light_primaryContainer = Color(0xFFABEDFF)
11 | internal val md_theme_light_onPrimaryContainer = Color(0xFF001F26)
12 | internal val md_theme_light_secondary = Color(0xFF00696E)
13 | internal val md_theme_light_onSecondary = Color(0xFFFFFFFF)
14 | internal val md_theme_light_secondaryContainer = Color(0xFF6FF6FE)
15 | internal val md_theme_light_onSecondaryContainer = Color(0xFF002022)
16 | internal val md_theme_light_tertiary = Color(0xFF904D00)
17 | internal val md_theme_light_onTertiary = Color(0xFFFFFFFF)
18 | internal val md_theme_light_tertiaryContainer = Color(0xFFFFDCC2)
19 | internal val md_theme_light_onTertiaryContainer = Color(0xFF2E1500)
20 | internal val md_theme_light_error = Color(0xFFBA1A1A)
21 | internal val md_theme_light_errorContainer = Color(0xFFFFDAD6)
22 | internal val md_theme_light_onError = Color(0xFFFFFFFF)
23 | internal val md_theme_light_onErrorContainer = Color(0xFF410002)
24 | internal val md_theme_light_background = Color(0xFFFFFBFF)
25 | internal val md_theme_light_onBackground = Color(0xFF221B00)
26 | internal val md_theme_light_surface = Color(0xFFFFFBFF)
27 | internal val md_theme_light_onSurface = Color(0xFF221B00)
28 | internal val md_theme_light_surfaceVariant = Color(0xFFDBE4E7)
29 | internal val md_theme_light_onSurfaceVariant = Color(0xFF3F484B)
30 | internal val md_theme_light_outline = Color(0xFF70797B)
31 | internal val md_theme_light_inverseOnSurface = Color(0xFFFFF0C0)
32 | internal val md_theme_light_inverseSurface = Color(0xFF3A3000)
33 | internal val md_theme_light_inversePrimary = Color(0xFF55D6F4)
34 | internal val md_theme_light_surfaceTint = Color(0xFF00687A)
35 | internal val md_theme_light_outlineVariant = Color(0xFFBFC8CB)
36 | internal val md_theme_light_scrim = Color(0xFF000000)
37 |
38 | internal val md_theme_dark_primary = Color(0xFF55D6F4)
39 | internal val md_theme_dark_onPrimary = Color(0xFF003640)
40 | internal val md_theme_dark_primaryContainer = Color(0xFF004E5C)
41 | internal val md_theme_dark_onPrimaryContainer = Color(0xFFABEDFF)
42 | internal val md_theme_dark_secondary = Color(0xFF4CD9E2)
43 | internal val md_theme_dark_onSecondary = Color(0xFF00373A)
44 | internal val md_theme_dark_secondaryContainer = Color(0xFF004F53)
45 | internal val md_theme_dark_onSecondaryContainer = Color(0xFF6FF6FE)
46 | internal val md_theme_dark_tertiary = Color(0xFFFFB77C)
47 | internal val md_theme_dark_onTertiary = Color(0xFF4D2700)
48 | internal val md_theme_dark_tertiaryContainer = Color(0xFF6D3900)
49 | internal val md_theme_dark_onTertiaryContainer = Color(0xFFFFDCC2)
50 | internal val md_theme_dark_error = Color(0xFFFFB4AB)
51 | internal val md_theme_dark_errorContainer = Color(0xFF93000A)
52 | internal val md_theme_dark_onError = Color(0xFF690005)
53 | internal val md_theme_dark_onErrorContainer = Color(0xFFFFDAD6)
54 | internal val md_theme_dark_background = Color(0xFF221B00)
55 | internal val md_theme_dark_onBackground = Color(0xFFFFE264)
56 | internal val md_theme_dark_surface = Color(0xFF221B00)
57 | internal val md_theme_dark_onSurface = Color(0xFFFFE264)
58 | internal val md_theme_dark_surfaceVariant = Color(0xFF3F484B)
59 | internal val md_theme_dark_onSurfaceVariant = Color(0xFFBFC8CB)
60 | internal val md_theme_dark_outline = Color(0xFF899295)
61 | internal val md_theme_dark_inverseOnSurface = Color(0xFF221B00)
62 | internal val md_theme_dark_inverseSurface = Color(0xFFFFE264)
63 | internal val md_theme_dark_inversePrimary = Color(0xFF00687A)
64 | internal val md_theme_dark_surfaceTint = Color(0xFF55D6F4)
65 | internal val md_theme_dark_outlineVariant = Color(0xFF3F484B)
66 | internal val md_theme_dark_scrim = Color(0xFF000000)
67 |
68 |
69 |
--------------------------------------------------------------------------------
/composeApp/src/commonMain/kotlin/org/qrcodedemo/app/theme/Theme.kt:
--------------------------------------------------------------------------------
1 | package org.qrcodedemo.app.theme
2 |
3 | import androidx.compose.foundation.isSystemInDarkTheme
4 | import androidx.compose.foundation.shape.RoundedCornerShape
5 | import androidx.compose.material3.lightColorScheme
6 | import androidx.compose.material3.darkColorScheme
7 | import androidx.compose.material3.MaterialTheme
8 | import androidx.compose.material3.Shapes
9 | import androidx.compose.material3.Surface
10 | import androidx.compose.material3.Typography
11 | import androidx.compose.runtime.Composable
12 | import androidx.compose.runtime.CompositionLocalProvider
13 | import androidx.compose.runtime.compositionLocalOf
14 | import androidx.compose.runtime.getValue
15 | import androidx.compose.runtime.mutableStateOf
16 | import androidx.compose.runtime.remember
17 | import androidx.compose.ui.text.TextStyle
18 | import androidx.compose.ui.text.font.FontFamily
19 | import androidx.compose.ui.text.font.FontWeight
20 | import androidx.compose.ui.unit.dp
21 | import androidx.compose.ui.unit.sp
22 |
23 | private val LightColorScheme = lightColorScheme(
24 | primary = md_theme_light_primary,
25 | onPrimary = md_theme_light_onPrimary,
26 | primaryContainer = md_theme_light_primaryContainer,
27 | onPrimaryContainer = md_theme_light_onPrimaryContainer,
28 | secondary = md_theme_light_secondary,
29 | onSecondary = md_theme_light_onSecondary,
30 | secondaryContainer = md_theme_light_secondaryContainer,
31 | onSecondaryContainer = md_theme_light_onSecondaryContainer,
32 | tertiary = md_theme_light_tertiary,
33 | onTertiary = md_theme_light_onTertiary,
34 | tertiaryContainer = md_theme_light_tertiaryContainer,
35 | onTertiaryContainer = md_theme_light_onTertiaryContainer,
36 | error = md_theme_light_error,
37 | errorContainer = md_theme_light_errorContainer,
38 | onError = md_theme_light_onError,
39 | onErrorContainer = md_theme_light_onErrorContainer,
40 | background = md_theme_light_background,
41 | onBackground = md_theme_light_onBackground,
42 | surface = md_theme_light_surface,
43 | onSurface = md_theme_light_onSurface,
44 | surfaceVariant = md_theme_light_surfaceVariant,
45 | onSurfaceVariant = md_theme_light_onSurfaceVariant,
46 | outline = md_theme_light_outline,
47 | inverseOnSurface = md_theme_light_inverseOnSurface,
48 | inverseSurface = md_theme_light_inverseSurface,
49 | inversePrimary = md_theme_light_inversePrimary,
50 | surfaceTint = md_theme_light_surfaceTint,
51 | outlineVariant = md_theme_light_outlineVariant,
52 | scrim = md_theme_light_scrim,
53 | )
54 |
55 | private val DarkColorScheme = darkColorScheme(
56 | primary = md_theme_dark_primary,
57 | onPrimary = md_theme_dark_onPrimary,
58 | primaryContainer = md_theme_dark_primaryContainer,
59 | onPrimaryContainer = md_theme_dark_onPrimaryContainer,
60 | secondary = md_theme_dark_secondary,
61 | onSecondary = md_theme_dark_onSecondary,
62 | secondaryContainer = md_theme_dark_secondaryContainer,
63 | onSecondaryContainer = md_theme_dark_onSecondaryContainer,
64 | tertiary = md_theme_dark_tertiary,
65 | onTertiary = md_theme_dark_onTertiary,
66 | tertiaryContainer = md_theme_dark_tertiaryContainer,
67 | onTertiaryContainer = md_theme_dark_onTertiaryContainer,
68 | error = md_theme_dark_error,
69 | errorContainer = md_theme_dark_errorContainer,
70 | onError = md_theme_dark_onError,
71 | onErrorContainer = md_theme_dark_onErrorContainer,
72 | background = md_theme_dark_background,
73 | onBackground = md_theme_dark_onBackground,
74 | surface = md_theme_dark_surface,
75 | onSurface = md_theme_dark_onSurface,
76 | surfaceVariant = md_theme_dark_surfaceVariant,
77 | onSurfaceVariant = md_theme_dark_onSurfaceVariant,
78 | outline = md_theme_dark_outline,
79 | inverseOnSurface = md_theme_dark_inverseOnSurface,
80 | inverseSurface = md_theme_dark_inverseSurface,
81 | inversePrimary = md_theme_dark_inversePrimary,
82 | surfaceTint = md_theme_dark_surfaceTint,
83 | outlineVariant = md_theme_dark_outlineVariant,
84 | scrim = md_theme_dark_scrim,
85 | )
86 |
87 | private val AppShapes = Shapes(
88 | extraSmall = RoundedCornerShape(2.dp),
89 | small = RoundedCornerShape(4.dp),
90 | medium = RoundedCornerShape(8.dp),
91 | large = RoundedCornerShape(16.dp),
92 | extraLarge = RoundedCornerShape(32.dp)
93 | )
94 |
95 | private val AppTypography = Typography(
96 | bodyMedium = TextStyle(
97 | fontFamily = FontFamily.Default,
98 | fontWeight = FontWeight.Medium,
99 | fontSize = 16.sp
100 | )
101 | )
102 |
103 | internal val LocalThemeIsDark = compositionLocalOf { mutableStateOf(true) }
104 |
105 | @Composable
106 | internal fun AppTheme(
107 | content: @Composable() () -> Unit
108 | ) {
109 | val systemIsDark = isSystemInDarkTheme()
110 | val isDarkState = remember { mutableStateOf(systemIsDark) }
111 | CompositionLocalProvider(
112 | LocalThemeIsDark provides isDarkState
113 | ) {
114 | val isDark by isDarkState
115 | SystemAppearance(!isDark)
116 | MaterialTheme(
117 | colorScheme = if (isDark) DarkColorScheme else LightColorScheme,
118 | typography = AppTypography,
119 | shapes = AppShapes,
120 | content = {
121 | Surface(content = content)
122 | }
123 | )
124 | }
125 | }
126 |
127 | @Composable
128 | internal expect fun SystemAppearance(isDark: Boolean)
129 |
--------------------------------------------------------------------------------
/composeApp/src/commonMain/kotlin/org/qrcodedemo/app/ui/BarCodeDataTypes.kt:
--------------------------------------------------------------------------------
1 | package org.qrcodedemo.app.ui
2 |
3 | import qrgenerator.barcodepainter.BarcodeFormat
4 |
5 | data class BarCodeDataType(
6 | val title: String,
7 | val type: BarcodeFormat,
8 | var isSelected: Boolean = false
9 | )
10 |
--------------------------------------------------------------------------------
/composeApp/src/commonMain/kotlin/org/qrcodedemo/app/ui/BarCodeGeneratorScreen.kt:
--------------------------------------------------------------------------------
1 | package org.qrcodedemo.app.ui
2 |
3 | import androidx.compose.foundation.Image
4 | import androidx.compose.foundation.background
5 | import androidx.compose.foundation.clickable
6 | import androidx.compose.foundation.layout.Arrangement
7 | import androidx.compose.foundation.layout.Box
8 | import androidx.compose.foundation.layout.Column
9 | import androidx.compose.foundation.layout.ColumnScope
10 | import androidx.compose.foundation.layout.Row
11 | import androidx.compose.foundation.layout.fillMaxSize
12 | import androidx.compose.foundation.layout.fillMaxWidth
13 | import androidx.compose.foundation.layout.height
14 | import androidx.compose.foundation.layout.padding
15 | import androidx.compose.foundation.layout.size
16 | import androidx.compose.foundation.layout.statusBarsPadding
17 | import androidx.compose.foundation.layout.width
18 | import androidx.compose.foundation.lazy.LazyColumn
19 | import androidx.compose.foundation.lazy.itemsIndexed
20 | import androidx.compose.foundation.rememberScrollState
21 | import androidx.compose.foundation.shape.RoundedCornerShape
22 | import androidx.compose.foundation.verticalScroll
23 | import androidx.compose.material.icons.Icons
24 | import androidx.compose.material.icons.filled.CalendarViewWeek
25 | import androidx.compose.material.icons.filled.Close
26 | import androidx.compose.material3.ExperimentalMaterial3Api
27 | import androidx.compose.material3.HorizontalDivider
28 | import androidx.compose.material3.Icon
29 | import androidx.compose.material3.ModalBottomSheet
30 | import androidx.compose.material3.OutlinedTextField
31 | import androidx.compose.material3.OutlinedTextFieldDefaults
32 | import androidx.compose.material3.Scaffold
33 | import androidx.compose.material3.SnackbarHost
34 | import androidx.compose.material3.SnackbarHostState
35 | import androidx.compose.material3.Text
36 | import androidx.compose.material3.rememberModalBottomSheetState
37 | import androidx.compose.runtime.Composable
38 | import androidx.compose.runtime.getValue
39 | import androidx.compose.runtime.mutableStateOf
40 | import androidx.compose.runtime.remember
41 | import androidx.compose.runtime.rememberCoroutineScope
42 | import androidx.compose.runtime.setValue
43 | import androidx.compose.ui.Alignment
44 | import androidx.compose.ui.Modifier
45 | import androidx.compose.ui.draw.clip
46 | import androidx.compose.ui.graphics.Color
47 | import androidx.compose.ui.graphics.SolidColor
48 | import androidx.compose.ui.graphics.painter.Painter
49 | import androidx.compose.ui.graphics.vector.EmptyPath
50 | import androidx.compose.ui.input.key.Key.Companion.R
51 | import androidx.compose.ui.layout.ContentScale
52 | import androidx.compose.ui.text.TextStyle
53 | import androidx.compose.ui.text.font.FontFamily
54 | import androidx.compose.ui.text.font.FontWeight
55 | import kotlinx.coroutines.launch
56 | import network.chaintech.sdpcomposemultiplatform.sdp
57 | import network.chaintech.sdpcomposemultiplatform.ssp
58 | import org.jetbrains.compose.resources.Font
59 | import org.jetbrains.compose.resources.painterResource
60 | import qrcodedemo.composeapp.generated.resources.Aeonik_Bold
61 | import qrcodedemo.composeapp.generated.resources.Aeonik_Regular
62 | import qrcodedemo.composeapp.generated.resources.Res
63 | import qrcodedemo.composeapp.generated.resources.bg
64 | import qrcodedemo.composeapp.generated.resources.ic_done
65 | import qrcodedemo.composeapp.generated.resources.ic_drop_down
66 | import qrcodedemo.composeapp.generated.resources.img_qr_thumb
67 | import qrcodedemo.composeapp.generated.resources.poppins_bold
68 | import qrcodedemo.composeapp.generated.resources.poppins_medium
69 | import qrcodedemo.composeapp.generated.resources.poppins_regular
70 | import qrcodedemo.composeapp.generated.resources.poppins_semibold
71 | import qrgenerator.barcodepainter.BarcodeFormat
72 | import qrgenerator.barcodepainter.EmptyPainter
73 | import qrgenerator.barcodepainter.rememberBarcodePainter
74 |
75 | @Composable
76 | fun BarCodeGeneratorScreen(onNavigate: (String) -> Unit) {
77 | var selectedTypeTitle by remember { mutableStateOf("ITF") }
78 | var selectedTypeFormat by remember { mutableStateOf(BarcodeFormat.ITF) }
79 | var selectedIndex by remember { mutableStateOf(0) }
80 | var showSheet by remember { mutableStateOf(false) }
81 |
82 | val FontAeonik = FontFamily(
83 | Font(Res.font.Aeonik_Regular, FontWeight.Normal),
84 | Font(Res.font.Aeonik_Bold, FontWeight.Bold)
85 | )
86 |
87 | val FontPoppins = FontFamily(
88 | Font(Res.font.poppins_regular, FontWeight.Normal),
89 | Font(Res.font.poppins_medium, FontWeight.Medium),
90 | Font(Res.font.poppins_semibold, FontWeight.SemiBold),
91 | Font(Res.font.poppins_bold, FontWeight.Bold)
92 | )
93 |
94 | var inputText by remember { mutableStateOf("512345678901") }
95 |
96 | val snackbarHostState = remember { SnackbarHostState() }
97 |
98 | Scaffold(
99 | snackbarHost = {
100 | SnackbarHost(hostState = snackbarHostState)
101 | }
102 | ) { contentPadding ->
103 | Box(
104 | modifier = Modifier
105 | .background(Color(0xFF1D1C22))
106 | .statusBarsPadding()
107 | .fillMaxSize()
108 | ) {
109 | Image(
110 | modifier = Modifier.fillMaxSize(),
111 | painter = painterResource(resource = Res.drawable.bg),
112 | contentScale = ContentScale.Fit,
113 | contentDescription = ""
114 | )
115 | Column(
116 | modifier = Modifier
117 | .fillMaxSize()
118 | .verticalScroll(rememberScrollState())
119 | .padding(bottom = 120.sdp)
120 | ) {
121 | Row(
122 | modifier = Modifier
123 | .fillMaxWidth()
124 | .padding(end = 16.sdp),
125 | horizontalArrangement = Arrangement.SpaceBetween,
126 | verticalAlignment = Alignment.CenterVertically
127 | ) {
128 | Column {
129 | Text(
130 | text = "Bar Code",
131 | modifier = Modifier
132 | .padding(horizontal = 14.sdp)
133 | .padding(top = 20.sdp),
134 | style = TextStyle(
135 | color = Color(0xFF4D8EFF),
136 | fontFamily = FontAeonik,
137 | fontWeight = FontWeight.Bold
138 | ),
139 | fontSize = 14.ssp
140 | )
141 |
142 | Text(
143 | text = "Generator",
144 | modifier = Modifier
145 | .padding(horizontal = 14.sdp)
146 | .padding(top = 2.sdp),
147 | fontSize = 26.ssp,
148 | style = TextStyle(
149 | color = Color(0xFF00FFA7),
150 | fontFamily = FontAeonik,
151 | fontWeight = FontWeight.Bold
152 | )
153 | )
154 | }
155 |
156 | Icon(
157 | Icons.Filled.Close,
158 | "close",
159 | modifier = Modifier
160 | .size(28.sdp)
161 | .clickable {
162 | onNavigate(AppConstants.BACK_CLICK_ROUTE)
163 | },
164 | tint = Color.White
165 | )
166 | }
167 |
168 | Text(
169 | text = "Choose Bar Code Type",
170 | modifier = Modifier
171 | .padding(horizontal = 14.sdp)
172 | .padding(top = 22.sdp),
173 | fontSize = 10.ssp,
174 | style = TextStyle(
175 | color = Color(0xFFAFAFAF),
176 | fontFamily = FontPoppins,
177 | fontWeight = FontWeight.Medium
178 | )
179 | )
180 |
181 | OutlinedTextField(value = selectedTypeTitle,
182 | modifier = Modifier
183 | .padding(horizontal = 14.sdp)
184 | .padding(top = 10.sdp)
185 | .fillMaxWidth()
186 | .clickable {
187 | showSheet = true
188 | },
189 | onValueChange = {
190 | selectedTypeTitle = it
191 | },
192 | enabled = false,
193 | singleLine = true,
194 | placeholder = {
195 | Text(
196 | text = "Text",
197 | modifier = Modifier,
198 | fontSize = 12.ssp,
199 | style = TextStyle(
200 | color = Color(0xFF747474),
201 | fontFamily = FontPoppins,
202 | fontWeight = FontWeight.Medium
203 | )
204 | )
205 | },
206 | textStyle = TextStyle(
207 | fontSize = 12.ssp, color = Color.White, fontFamily = FontPoppins, fontWeight = FontWeight.Medium
208 | ),
209 | shape = RoundedCornerShape(6.sdp),
210 | colors = OutlinedTextFieldDefaults.colors(
211 | unfocusedBorderColor = Color(0xFF3E3D46),
212 | focusedBorderColor = Color(0xFF3E3D46),
213 | cursorColor = Color.White,
214 | disabledBorderColor = Color(0xFF3E3D46),
215 | ),
216 | leadingIcon = {
217 | Icon(
218 | modifier = Modifier.padding(start = 10.sdp, end = 10.sdp).size(18.sdp),
219 | imageVector = Icons.Filled.CalendarViewWeek,
220 | tint = Color.White,
221 | contentDescription = ""
222 | )
223 | },
224 | trailingIcon = {
225 | Image(
226 | modifier = Modifier.padding(end = 8.sdp).size(8.sdp),
227 | painter = painterResource(resource = Res.drawable.ic_drop_down),
228 | contentScale = ContentScale.Fit,
229 | contentDescription = ""
230 | )
231 | })
232 |
233 | BarCodeEditTextView("Please Enter Text", "Text", inputText, onValueChange = {
234 | inputText = it
235 | })
236 |
237 | if (inputText.isEmpty().not()) {
238 | BarCodePreview(
239 | data = inputText,
240 | type = selectedTypeFormat,
241 | snackbarHostState = snackbarHostState
242 | )
243 | }
244 | }
245 | }
246 |
247 | if (showSheet) {
248 | BarCodeTypeBottomSheet(
249 | selectedIndex = selectedIndex,
250 | callBack = { index, data ->
251 | showSheet = false
252 | selectedIndex = index
253 | selectedTypeTitle = data.title
254 | selectedTypeFormat = data.type
255 | },
256 | onDismiss = { showSheet = false }
257 | )
258 | }
259 | }
260 | }
261 |
262 | @OptIn(ExperimentalMaterial3Api::class)
263 | @Composable
264 | fun BarCodeTypeBottomSheet(
265 | selectedIndex: Int,
266 | callBack: (Int, BarCodeDataType) -> Unit,
267 | onDismiss: () -> Unit
268 | ) {
269 | val FontPoppins = FontFamily(
270 | Font(Res.font.poppins_regular, FontWeight.Normal),
271 | Font(Res.font.poppins_medium, FontWeight.Medium),
272 | Font(Res.font.poppins_semibold, FontWeight.SemiBold),
273 | Font(Res.font.poppins_bold, FontWeight.Bold)
274 | )
275 |
276 | val modalBottomSheetState = rememberModalBottomSheetState(skipPartiallyExpanded = true)
277 |
278 | ModalBottomSheet(
279 | onDismissRequest = { onDismiss() },
280 | sheetState = modalBottomSheetState,
281 | containerColor = Color.Transparent,
282 | dragHandle = {}
283 | ) {
284 | val list = arrayListOf()
285 | list.add(BarCodeDataType("ITF", BarcodeFormat.ITF))
286 | list.add(BarCodeDataType("Codebar", BarcodeFormat.Codabar))
287 | list.add(BarCodeDataType("Code39", BarcodeFormat.Code39))
288 | list.add(BarCodeDataType("Code128", BarcodeFormat.Code128))
289 | list.add(BarCodeDataType("UPC E", BarcodeFormat.UPCE))
290 | list.add(BarCodeDataType("UPC A", BarcodeFormat.UPCA))
291 | list.add(BarCodeDataType("EAN 13", BarcodeFormat.EAN13))
292 | list.add(BarCodeDataType("EAN 8", BarcodeFormat.EAN8))
293 | list.add(BarCodeDataType("Code 93", BarcodeFormat.Code93))
294 |
295 | Column(
296 | modifier = Modifier
297 | .padding(14.sdp)
298 | .background(Color(0xFF18171C), RoundedCornerShape(12.sdp))
299 | .padding(14.sdp)
300 | ) {
301 | HorizontalDivider(
302 | modifier = Modifier
303 | .width(40.sdp)
304 | .clip(RoundedCornerShape(50.sdp))
305 | .align(Alignment.CenterHorizontally), 3.sdp, color = Color(0xFF383737)
306 | )
307 |
308 | Text(
309 | text = "Choose Bar Code Type",
310 | modifier = Modifier.padding(top = 20.sdp),
311 | fontSize = 14.ssp,
312 | style = TextStyle(
313 | color = Color(0xFF7A7AD9),
314 | fontFamily = FontPoppins,
315 | fontWeight = FontWeight.SemiBold
316 | )
317 | )
318 |
319 | LazyColumn(modifier = Modifier.padding(top = 20.sdp)) {
320 | itemsIndexed(list) { index, data ->
321 | Column(modifier = Modifier.fillMaxWidth().padding(top = 4.sdp).clickable {
322 | callBack(index, data)
323 | }) {
324 | Row(
325 | modifier = Modifier.fillMaxWidth()
326 | .padding(vertical = 8.sdp, horizontal = 4.sdp),
327 | verticalAlignment = Alignment.CenterVertically
328 | ) {
329 | Icon(
330 | modifier = Modifier.size(18.sdp),
331 | imageVector = Icons.Filled.CalendarViewWeek,
332 | tint = Color.White,
333 | contentDescription = ""
334 | )
335 | Text(
336 | text = data.title,
337 | modifier = Modifier.padding(start = 14.sdp).weight(1f),
338 | fontSize = 12.ssp,
339 | style = TextStyle(
340 | color = Color(0xFFAFAFAF),
341 | fontFamily = FontPoppins,
342 | fontWeight = FontWeight.Medium
343 | )
344 | )
345 | if (selectedIndex == index) Image(
346 | modifier = Modifier.size(16.sdp),
347 | painter = painterResource(resource = Res.drawable.ic_done),
348 | contentScale = ContentScale.Fit,
349 | contentDescription = ""
350 | )
351 | }
352 | HorizontalDivider(
353 | modifier = Modifier.padding(top = 4.sdp).fillMaxWidth(),
354 | 1.sdp,
355 | color = Color(0xFF24222C)
356 | )
357 | }
358 | }
359 | }
360 | }
361 | }
362 | }
363 |
364 | @Composable
365 | fun BarCodeEditTextView(
366 | labelText: String, placeHolder: String, inputText: String, onValueChange: (String) -> Unit
367 | ) {
368 | val FontPoppins = FontFamily(
369 | Font(Res.font.poppins_regular, FontWeight.Normal),
370 | Font(Res.font.poppins_medium, FontWeight.Medium),
371 | Font(Res.font.poppins_semibold, FontWeight.SemiBold),
372 | Font(Res.font.poppins_bold, FontWeight.Bold)
373 | )
374 |
375 | Text(
376 | text = labelText,
377 | modifier = Modifier.padding(horizontal = 14.sdp).padding(top = 20.sdp),
378 | fontSize = 10.ssp,
379 | style = TextStyle(
380 | color = Color(0xFFAFAFAF),
381 | fontFamily = FontPoppins,
382 | fontWeight = FontWeight.Medium
383 | )
384 | )
385 |
386 | OutlinedTextField(
387 | value = inputText,
388 | modifier = Modifier
389 | .padding(horizontal = 14.sdp)
390 | .padding(top = 10.sdp)
391 | .fillMaxWidth(),
392 | onValueChange = {
393 | onValueChange(it)
394 | },
395 | singleLine = true,
396 | placeholder = {
397 | Text(
398 | text = placeHolder,
399 | modifier = Modifier,
400 | fontSize = 12.ssp,
401 | color = Color(0xFF747474),
402 | fontFamily = FontFamily.Serif
403 | )
404 | },
405 | textStyle = TextStyle(
406 | fontSize = 12.ssp,
407 | color = Color.White,
408 | fontFamily = FontPoppins,
409 | fontWeight = FontWeight.Medium
410 | ),
411 | shape = RoundedCornerShape(8.sdp),
412 | colors = OutlinedTextFieldDefaults.colors(
413 | unfocusedBorderColor = Color(0xFF3E3D46),
414 | focusedBorderColor = Color(0xFF3E3D46),
415 | cursorColor = Color.White
416 | ),
417 | )
418 | }
419 |
420 | @Composable
421 | fun ColumnScope.BarCodePreview(
422 | data: String,
423 | type: BarcodeFormat,
424 | snackbarHostState: SnackbarHostState
425 | ) {
426 | val scope = rememberCoroutineScope()
427 | val FontPoppins = FontFamily(
428 | Font(Res.font.poppins_regular, FontWeight.Normal),
429 | Font(Res.font.poppins_medium, FontWeight.Medium),
430 | Font(Res.font.poppins_semibold, FontWeight.SemiBold),
431 | Font(Res.font.poppins_bold, FontWeight.Bold)
432 | )
433 |
434 | Text(
435 | text = "Bar Code Preview",
436 | modifier = Modifier.padding(top = 24.sdp)
437 | .background(Color(0xFF006588), RoundedCornerShape(topEnd = 50.sdp, bottomEnd = 50.sdp))
438 | .padding(vertical = 4.sdp)
439 | .padding(start = 14.sdp, end = 24.sdp),
440 | style = TextStyle(
441 | color = Color.White,
442 | fontFamily = FontPoppins,
443 | fontWeight = FontWeight.SemiBold
444 | ),
445 | fontSize = 12.ssp
446 | )
447 |
448 | val barCodePainter = rememberBarcodePainter(data, type, brush = SolidColor(Color.White), onError = { throwable ->
449 | scope.launch {
450 | snackbarHostState.showSnackbar("Error occurred: ${throwable.message}")
451 | }
452 | // Return a fallback painter, for example, an empty painter
453 | EmptyPainter()
454 | })
455 |
456 | Box(
457 | modifier = Modifier
458 | .padding(top = 42.sdp, start = 20.sdp, end = 20.sdp)
459 | .background(
460 | color = Color(0xFF252528),
461 | shape = RoundedCornerShape(10.sdp)
462 | )
463 | .padding(horizontal = 20.sdp)
464 | .align(Alignment.CenterHorizontally)
465 | ) {
466 | Image(
467 | painter = barCodePainter,
468 | contentDescription = null,
469 | modifier = Modifier
470 | .fillMaxWidth()
471 | .height(100.sdp)
472 | )
473 | }
474 | }
475 |
476 |
477 |
478 |
479 |
--------------------------------------------------------------------------------
/composeApp/src/commonMain/kotlin/org/qrcodedemo/app/ui/Navigation.kt:
--------------------------------------------------------------------------------
1 | package org.qrcodedemo.app.ui
2 |
3 | import androidx.compose.animation.AnimatedContentTransitionScope
4 | import androidx.compose.animation.core.tween
5 | import androidx.compose.foundation.layout.fillMaxSize
6 | import androidx.compose.runtime.Composable
7 | import androidx.compose.ui.Modifier
8 | import androidx.navigation.NavController
9 | import androidx.navigation.NavHostController
10 | import androidx.navigation.NavType
11 | import androidx.navigation.compose.NavHost
12 | import androidx.navigation.compose.composable
13 | import androidx.navigation.compose.rememberNavController
14 | import androidx.navigation.navArgument
15 |
16 | object AppConstants {
17 | const val BACK_CLICK_ROUTE = "BACK_CLICK_ROUTE"
18 | const val QR_TEXT = "qr_text"
19 | }
20 |
21 | @Composable
22 | fun QRKitNav() {
23 | val navController = rememberNavController()
24 |
25 | NavHostMain(
26 | navController = navController,
27 | onNavigate = { routeName ->
28 | navigateTo(routeName, navController)
29 | }
30 | )
31 | }
32 |
33 | @Composable
34 | fun NavHostMain(
35 | navController: NavHostController = rememberNavController(),
36 | onNavigate: (rootName: String) -> Unit,
37 | ) {
38 | NavHost(
39 | navController = navController,
40 | startDestination = AppScreen.QRKitMainScreen.route,
41 | modifier = Modifier
42 | .fillMaxSize(),
43 | enterTransition = {
44 | slideIntoContainer(
45 | AnimatedContentTransitionScope.SlideDirection.Left,
46 | animationSpec = tween(500)
47 | )
48 | },
49 | exitTransition = {
50 | slideOutOfContainer(
51 | AnimatedContentTransitionScope.SlideDirection.Left,
52 | animationSpec = tween(500)
53 | )
54 | },
55 | popEnterTransition = {
56 | slideIntoContainer(
57 | AnimatedContentTransitionScope.SlideDirection.Right,
58 | animationSpec = tween(500)
59 | )
60 | },
61 | popExitTransition = {
62 | slideOutOfContainer(
63 | AnimatedContentTransitionScope.SlideDirection.Right,
64 | animationSpec = tween(500)
65 | )
66 | }
67 | ) {
68 | composable(route = AppScreen.QRKitMainScreen.route) {
69 | QRKitMainScreen(onNavigate)
70 | }
71 | composable(route = AppScreen.QRGenerator.route) {
72 | QrGeneratorView(onNavigate)
73 | }
74 | composable(route = AppScreen.QRCustomization.route, arguments = listOf(
75 | navArgument(AppConstants.QR_TEXT) {
76 | type = NavType.StringType
77 | }
78 | )) {
79 | val inputText = (it.arguments?.getString(AppConstants.QR_TEXT) ?: "")
80 | QRCustomizationView(inputText, onNavigate)
81 | }
82 | composable(route = AppScreen.QRScanner.route) {
83 | QrScannerView(onNavigate = onNavigate)
84 | }
85 | composable(route = AppScreen.BarCodeGenerator.route) {
86 | BarCodeGeneratorScreen(onNavigate = onNavigate)
87 | }
88 | }
89 | }
90 |
91 | fun navigateTo(
92 | routeName: String,
93 | navController: NavController
94 | ) {
95 | when (routeName) {
96 | AppConstants.BACK_CLICK_ROUTE -> {
97 | navController.popBackStack()
98 | }
99 |
100 | else -> {
101 | navController.navigate(routeName)
102 | }
103 | }
104 | }
105 |
106 | sealed class AppScreen(val route: String) {
107 | data object QRKitMainScreen : AppScreen("nav_qr_main_screen")
108 | data object QRGenerator : AppScreen("nav_qr_generator")
109 | data object QRCustomization : AppScreen("nav_qr_customization{${AppConstants.QR_TEXT}}")
110 | data object QRScanner : AppScreen("nav_qr_scanner")
111 | data object BarCodeGenerator : AppScreen("nav_qr_barcode_generator")
112 | }
113 |
114 |
--------------------------------------------------------------------------------
/composeApp/src/commonMain/kotlin/org/qrcodedemo/app/ui/QRDataTypes.kt:
--------------------------------------------------------------------------------
1 | package org.qrcodedemo.app.ui
2 |
3 | import androidx.compose.foundation.layout.ColumnScope
4 | import androidx.compose.runtime.Composable
5 | import androidx.compose.runtime.getValue
6 | import androidx.compose.runtime.mutableStateOf
7 | import androidx.compose.runtime.remember
8 | import androidx.compose.runtime.saveable.rememberSaveable
9 | import androidx.compose.runtime.setValue
10 | import org.jetbrains.compose.resources.DrawableResource
11 | import qrgenerator.qrkitpainter.email
12 | import qrgenerator.qrkitpainter.event
13 | import qrgenerator.qrkitpainter.phone
14 | import qrgenerator.qrkitpainter.sms
15 | import qrgenerator.qrkitpainter.wifi
16 |
17 | data class QRType(val icon: DrawableResource, val title: String, var isSelected: Boolean = false)
18 |
19 | @Composable
20 | fun ColumnScope.TextQR(onNavigate: (String) -> Unit) {
21 | var inputText by remember { mutableStateOf("Lorem Ipsum is simply dummy text of the printing and typesetting industry.") }
22 |
23 | QREditTextView("Please Enter Text", "Text", inputText, onValueChange = {
24 | inputText = it
25 | })
26 |
27 | if (inputText.isEmpty().not()) {
28 | QRCodePreview(inputText, onNavigate)
29 | }
30 | }
31 |
32 | @Composable
33 | fun ColumnScope.WebsiteQR(onNavigate: (String) -> Unit) {
34 | var websiteText by rememberSaveable { mutableStateOf("https://github.com/Chaintech-Network/QRKitComposeMultiplatform.git") }
35 |
36 | QREditTextView("Please Enter Website", "Website", websiteText, onValueChange = {
37 | websiteText = it
38 | })
39 |
40 | if (websiteText.isEmpty().not()) {
41 | QRCodePreview(websiteText, onNavigate)
42 | }
43 | }
44 |
45 | @Composable
46 | fun ColumnScope.EmailQR(onNavigate: (String) -> Unit) {
47 | var emailText by rememberSaveable { mutableStateOf("developer@gmail.com") }
48 | var copyToText by rememberSaveable { mutableStateOf("addeveloper@gmail.com") }
49 | var subjectText by rememberSaveable { mutableStateOf("Lorem ipsum") }
50 | var bodyText by rememberSaveable { mutableStateOf("Lorem ipsum") }
51 |
52 | QREditTextView("Please Enter Email", "Email", emailText, onValueChange = {
53 | emailText = it
54 | })
55 |
56 | QREditTextView("Please Enter Copy To", "Copy To", copyToText, onValueChange = {
57 | copyToText = it
58 | })
59 |
60 | QREditTextView("Please Enter Subject", "Subject", subjectText, onValueChange = {
61 | subjectText = it
62 | })
63 |
64 | QREditTextView("Please Enter Body", "Body", bodyText, onValueChange = {
65 | bodyText = it
66 | })
67 |
68 | if (emailText.isNotEmpty()) {
69 | QRCodePreview(email(emailText, copyToText, subjectText, bodyText), onNavigate)
70 | }
71 | }
72 |
73 | @Composable
74 | fun ColumnScope.SMSQR(onNavigate: (String) -> Unit) {
75 | var phoneNumberText by rememberSaveable { mutableStateOf("7665565456") }
76 | var subjectText by rememberSaveable { mutableStateOf("Lorem ipsum") }
77 |
78 | QREditTextView("Please Enter Phone Number", "Phone Number", phoneNumberText, onValueChange = {
79 | phoneNumberText = it
80 | })
81 |
82 | QREditTextView("Please Enter Subject", "Subject", subjectText, onValueChange = {
83 | subjectText = it
84 | })
85 |
86 | if (phoneNumberText.isNotEmpty() && subjectText.isNotEmpty()) {
87 | QRCodePreview(sms(phoneNumberText, subjectText, false), onNavigate)
88 | }
89 | }
90 |
91 | @Composable
92 | fun ColumnScope.WifiQR(onNavigate: (String) -> Unit) {
93 | var authenticationText by rememberSaveable { mutableStateOf("Android@123") }
94 | var ssidText by rememberSaveable { mutableStateOf("Android Framework") }
95 | var pskText by rememberSaveable { mutableStateOf("") }
96 |
97 | QREditTextView(
98 | "Please Enter Authentication",
99 | "Authentication",
100 | authenticationText,
101 | onValueChange = {
102 | authenticationText = it
103 | })
104 |
105 | QREditTextView("Please Enter SSID", "SSID", ssidText, onValueChange = {
106 | ssidText = it
107 | })
108 |
109 | QREditTextView("Please Enter PSK", "PSK", pskText, onValueChange = {
110 | pskText = it
111 | })
112 |
113 | QRCodePreview(wifi(authenticationText, ssidText, pskText), onNavigate)
114 | }
115 |
116 | @Composable
117 | fun ColumnScope.PhoneQR(onNavigate: (String) -> Unit) {
118 | var phoneNumberText by rememberSaveable { mutableStateOf("7889965675") }
119 |
120 | QREditTextView(
121 | "Please Enter Phone Number",
122 | "Phone Number",
123 | phoneNumberText,
124 | onValueChange = {
125 | phoneNumberText = it
126 | })
127 |
128 | if (phoneNumberText.isNotEmpty()) {
129 | QRCodePreview(phone(phoneNumberText), onNavigate)
130 | }
131 | }
132 |
133 | @Composable
134 | fun ColumnScope.CalendarQR(onNavigate: (String) -> Unit) {
135 | var uidText by rememberSaveable { mutableStateOf("54543") }
136 | var stampText by rememberSaveable { mutableStateOf("STORE") }
137 | var organizerText by rememberSaveable { mutableStateOf("Angry Film Studio") }
138 | var startText by rememberSaveable { mutableStateOf("24/08/2024") }
139 | var endText by rememberSaveable { mutableStateOf("30/08/2024") }
140 | var summaryText by rememberSaveable { mutableStateOf("Lorem ipsum") }
141 |
142 | QREditTextView(
143 | "Please Enter uid",
144 | "uid",
145 | uidText,
146 | onValueChange = {
147 | uidText = it
148 | })
149 |
150 | QREditTextView(
151 | "Please Enter Stamp",
152 | "Stamp",
153 | stampText,
154 | onValueChange = {
155 | stampText = it
156 | })
157 |
158 | QREditTextView(
159 | "Please Enter Organizer",
160 | "Organizer",
161 | organizerText,
162 | onValueChange = {
163 | organizerText = it
164 | })
165 |
166 | QREditTextView(
167 | "Please Enter Start",
168 | "Start",
169 | startText,
170 | onValueChange = {
171 | startText = it
172 | })
173 |
174 | QREditTextView(
175 | "Please Enter End",
176 | "End",
177 | endText,
178 | onValueChange = {
179 | endText = it
180 | })
181 |
182 | QREditTextView(
183 | "Please Enter Summary",
184 | "Summary",
185 | summaryText,
186 | onValueChange = {
187 | summaryText = it
188 | })
189 |
190 | QRCodePreview(event(uidText, stampText, organizerText, startText, endText, summaryText), onNavigate)
191 | }
192 |
193 |
--------------------------------------------------------------------------------
/composeApp/src/commonMain/kotlin/org/qrcodedemo/app/ui/QRKitMainScreen.kt:
--------------------------------------------------------------------------------
1 | package org.qrcodedemo.app.ui
2 |
3 | import androidx.compose.foundation.Image
4 | import androidx.compose.foundation.background
5 | import androidx.compose.foundation.clickable
6 | import androidx.compose.foundation.layout.Arrangement
7 | import androidx.compose.foundation.layout.Box
8 | import androidx.compose.foundation.layout.Column
9 | import androidx.compose.foundation.layout.IntrinsicSize
10 | import androidx.compose.foundation.layout.Row
11 | import androidx.compose.foundation.layout.fillMaxHeight
12 | import androidx.compose.foundation.layout.fillMaxSize
13 | import androidx.compose.foundation.layout.fillMaxWidth
14 | import androidx.compose.foundation.layout.height
15 | import androidx.compose.foundation.layout.padding
16 | import androidx.compose.foundation.layout.size
17 | import androidx.compose.foundation.layout.statusBarsPadding
18 | import androidx.compose.foundation.layout.width
19 | import androidx.compose.foundation.rememberScrollState
20 | import androidx.compose.foundation.shape.RoundedCornerShape
21 | import androidx.compose.foundation.verticalScroll
22 | import androidx.compose.material3.MaterialTheme
23 | import androidx.compose.material3.Text
24 | import androidx.compose.runtime.Composable
25 | import androidx.compose.ui.Alignment
26 | import androidx.compose.ui.Modifier
27 | import androidx.compose.ui.graphics.Color
28 | import androidx.compose.ui.layout.ContentScale
29 | import androidx.compose.ui.text.TextStyle
30 | import androidx.compose.ui.text.font.FontFamily
31 | import androidx.compose.ui.text.font.FontWeight
32 | import androidx.compose.ui.text.style.TextAlign
33 | import network.chaintech.sdpcomposemultiplatform.sdp
34 | import network.chaintech.sdpcomposemultiplatform.ssp
35 | import org.jetbrains.compose.resources.Font
36 | import org.jetbrains.compose.resources.painterResource
37 | import qrcodedemo.composeapp.generated.resources.Res
38 | import qrcodedemo.composeapp.generated.resources.SofiaSansCondensed_Bold
39 | import qrcodedemo.composeapp.generated.resources.SofiaSansCondensed_Light
40 | import qrcodedemo.composeapp.generated.resources.SofiaSansCondensed_Medium
41 | import qrcodedemo.composeapp.generated.resources.SofiaSansCondensed_Regular
42 | import qrcodedemo.composeapp.generated.resources.SofiaSansCondensed_SemiBold
43 | import qrcodedemo.composeapp.generated.resources.ic_arrow_row
44 | import qrcodedemo.composeapp.generated.resources.img_barcode
45 | import qrcodedemo.composeapp.generated.resources.img_curved_arrow
46 | import qrcodedemo.composeapp.generated.resources.img_dotted_box
47 | import qrcodedemo.composeapp.generated.resources.img_mobile_innovation
48 | import qrcodedemo.composeapp.generated.resources.img_qr_lines
49 | import qrcodedemo.composeapp.generated.resources.img_qr_thumb
50 | import qrcodedemo.composeapp.generated.resources.img_scanner
51 |
52 | @Composable
53 | fun QRKitMainScreen(onNavigate: (String) -> Unit) {
54 | val FontSofia = FontFamily(
55 | Font(Res.font.SofiaSansCondensed_Light, FontWeight.Light),
56 | Font(Res.font.SofiaSansCondensed_Regular, FontWeight.Normal),
57 | Font(Res.font.SofiaSansCondensed_Medium, FontWeight.Medium),
58 | Font(Res.font.SofiaSansCondensed_SemiBold, FontWeight.SemiBold),
59 | Font(Res.font.SofiaSansCondensed_Bold, FontWeight.Bold)
60 | )
61 |
62 | MaterialTheme {
63 | Column(
64 | modifier = Modifier
65 | .background(color = Color(0xFF1D1C22))
66 | .statusBarsPadding()
67 | .fillMaxSize()
68 | .padding(16.sdp)
69 | .verticalScroll(rememberScrollState()),
70 | horizontalAlignment = Alignment.Start
71 | ) {
72 | Box(
73 | modifier = Modifier
74 | .fillMaxWidth()
75 | .background(
76 | color = Color(0xFF6265DE),
77 | shape = RoundedCornerShape(topStart = 22.sdp, topEnd = 22.sdp, bottomStart = 22.sdp, bottomEnd = 48.sdp)
78 | )
79 | ) {
80 | Image(
81 | modifier = Modifier
82 | .size(90.sdp)
83 | .align(Alignment.TopEnd)
84 | .padding(end = 4.sdp, top = 4.sdp),
85 | painter = painterResource(resource = Res.drawable.img_mobile_innovation),
86 | contentScale = ContentScale.FillBounds,
87 | contentDescription = ""
88 | )
89 |
90 | Column(
91 | modifier = Modifier
92 | .align(Alignment.TopStart)
93 | .padding(start = 16.sdp, top = 12.sdp, bottom = 26.sdp)
94 | ) {
95 | Image(
96 | painter = painterResource(resource = Res.drawable.ic_arrow_row),
97 | contentScale = ContentScale.Fit,
98 | contentDescription = ""
99 | )
100 |
101 | Text(
102 | text = "QRKit",
103 | modifier = Modifier
104 | .padding(top = 22.sdp),
105 | style = TextStyle(
106 | color = Color.White,
107 | fontFamily = FontSofia,
108 | fontWeight = FontWeight.Bold
109 | ),
110 | fontSize = 45.ssp
111 | )
112 |
113 | Row(
114 | modifier = Modifier
115 | .fillMaxWidth()
116 | .padding(top = 12.sdp, end = 16.sdp),
117 | horizontalArrangement = Arrangement.SpaceBetween
118 | ) {
119 | Text(
120 | text = "Compose\nMultiplatform",
121 | style = TextStyle(
122 | color = Color.White,
123 | fontFamily = FontSofia,
124 | fontWeight = FontWeight.Normal
125 | ),
126 | fontSize = 30.ssp
127 | )
128 |
129 | Image(
130 | modifier = Modifier
131 | .size(40.sdp),
132 | painter = painterResource(resource = Res.drawable.img_dotted_box),
133 | contentScale = ContentScale.Fit,
134 | contentDescription = ""
135 | )
136 | }
137 | }
138 | }
139 |
140 | Row(
141 | modifier = Modifier
142 | .fillMaxWidth()
143 | .height(IntrinsicSize.Max)
144 | .padding(top = 20.sdp),
145 | horizontalArrangement = Arrangement.spacedBy(12.sdp)
146 | ) {
147 | Box(
148 | modifier = Modifier
149 | .weight(0.5f)
150 | .fillMaxHeight()
151 | .background(
152 | color = Color(0xFF0B2447),
153 | shape = RoundedCornerShape(topStart = 20.sdp, topEnd = 60.sdp, bottomStart = 20.sdp, bottomEnd = 60.sdp)
154 | )
155 | .clickable {
156 | onNavigate(AppScreen.QRGenerator.route)
157 | }
158 | ) {
159 | Image(
160 | modifier = Modifier
161 | .padding(top = 2.sdp, end = 20.sdp)
162 | .align(Alignment.TopEnd),
163 | painter = painterResource(resource = Res.drawable.img_qr_lines),
164 | contentDescription = ""
165 | )
166 |
167 | Column(
168 | modifier = Modifier
169 | .align(Alignment.BottomStart)
170 | .padding(start = 16.sdp, top = 12.sdp)
171 | ) {
172 | Text(
173 | text = "QR Code",
174 | modifier = Modifier,
175 | style = TextStyle(
176 | color = Color.White,
177 | fontFamily = FontSofia,
178 | fontWeight = FontWeight.Bold
179 | ),
180 | fontSize = 16.ssp
181 | )
182 |
183 | Text(
184 | text = "Generator",
185 | modifier = Modifier
186 | .fillMaxWidth(),
187 | style = TextStyle(
188 | color = Color.White,
189 | fontFamily = FontSofia,
190 | fontWeight = FontWeight.Normal
191 | ),
192 | fontSize = 25.ssp
193 | )
194 |
195 | Image(
196 | modifier = Modifier
197 | .padding(top = 8.sdp)
198 | .width(52.sdp)
199 | .height(32.sdp),
200 | contentScale = ContentScale.FillBounds,
201 | painter = painterResource(resource = Res.drawable.img_qr_thumb),
202 | contentDescription = ""
203 | )
204 | }
205 | }
206 |
207 | Column(
208 | modifier = Modifier
209 | .weight(0.5f)
210 | .background(
211 | color = Color(0xFF327D6A),
212 | shape = RoundedCornerShape(18.sdp)
213 | )
214 | .padding(horizontal = 16.sdp, vertical = 12.sdp)
215 | .clickable {
216 | onNavigate(AppScreen.QRScanner.route)
217 | },
218 | horizontalAlignment = Alignment.CenterHorizontally
219 | ) {
220 | Image(
221 | modifier = Modifier
222 | .width(50.sdp)
223 | .height(40.sdp),
224 | painter = painterResource(resource = Res.drawable.img_scanner),
225 | contentScale = ContentScale.FillBounds,
226 | contentDescription = ""
227 | )
228 |
229 | Text(
230 | text = "QR & Barcode",
231 | modifier = Modifier
232 | .padding(top = 12.sdp),
233 | style = TextStyle(
234 | color = Color.White,
235 | fontFamily = FontSofia,
236 | fontWeight = FontWeight.Bold,
237 | textAlign = TextAlign.Center
238 | ),
239 | fontSize = 14.ssp
240 | )
241 |
242 | Text(
243 | text = "Scanner",
244 | modifier = Modifier
245 | .fillMaxWidth(),
246 | style = TextStyle(
247 | color = Color.White,
248 | fontFamily = FontSofia,
249 | fontWeight = FontWeight.Normal,
250 | textAlign = TextAlign.Center
251 | ),
252 | fontSize = 22.ssp
253 | )
254 | }
255 | }
256 |
257 | Box(
258 | modifier = Modifier
259 | .fillMaxWidth()
260 | .padding(top = 20.sdp)
261 | .background(
262 | color = Color(0xFF1C3754),
263 | shape = RoundedCornerShape(18.sdp)
264 | )
265 | .clickable {
266 | onNavigate(AppScreen.BarCodeGenerator.route)
267 | }
268 | ) {
269 | Column(
270 | modifier = Modifier
271 | .align(Alignment.TopStart)
272 | .padding(start = 16.sdp, top = 12.sdp)
273 | ) {
274 | Text(
275 | text = "Bar Code",
276 | modifier = Modifier,
277 | style = TextStyle(
278 | color = Color.White,
279 | fontFamily = FontSofia,
280 | fontWeight = FontWeight.Bold
281 | ),
282 | fontSize = 16.ssp
283 | )
284 |
285 | Text(
286 | text = "Generator",
287 | modifier = Modifier
288 | .fillMaxWidth(),
289 | style = TextStyle(
290 | color = Color.White,
291 | fontFamily = FontSofia,
292 | fontWeight = FontWeight.Normal
293 | ),
294 | fontSize = 25.ssp
295 | )
296 | }
297 |
298 | Image(
299 | modifier = Modifier
300 | .align(Alignment.Center),
301 | painter = painterResource(resource = Res.drawable.img_curved_arrow),
302 | contentDescription = ""
303 | )
304 |
305 | Image(
306 | modifier = Modifier
307 | .padding(end = 16.sdp, top = 45.sdp, bottom = 16.sdp)
308 | .width(80.sdp)
309 | .height(40.sdp)
310 | .align(Alignment.BottomEnd),
311 | painter = painterResource(resource = Res.drawable.img_barcode),
312 | contentScale = ContentScale.FillBounds,
313 | contentDescription = ""
314 | )
315 | }
316 | }
317 | }
318 | }
319 |
320 |
321 |
322 |
--------------------------------------------------------------------------------
/composeApp/src/commonMain/kotlin/org/qrcodedemo/app/ui/QrGeneratorScreen.kt:
--------------------------------------------------------------------------------
1 | package org.qrcodedemo.app.ui
2 |
3 | import androidx.compose.foundation.Image
4 | import androidx.compose.foundation.background
5 | import androidx.compose.foundation.clickable
6 | import androidx.compose.foundation.layout.Arrangement
7 | import androidx.compose.foundation.layout.Box
8 | import androidx.compose.foundation.layout.Column
9 | import androidx.compose.foundation.layout.ColumnScope
10 | import androidx.compose.foundation.layout.Row
11 | import androidx.compose.foundation.layout.Spacer
12 | import androidx.compose.foundation.layout.fillMaxSize
13 | import androidx.compose.foundation.layout.fillMaxWidth
14 | import androidx.compose.foundation.layout.padding
15 | import androidx.compose.foundation.layout.size
16 | import androidx.compose.foundation.layout.statusBarsPadding
17 | import androidx.compose.foundation.layout.width
18 | import androidx.compose.foundation.lazy.LazyColumn
19 | import androidx.compose.foundation.lazy.itemsIndexed
20 | import androidx.compose.foundation.rememberScrollState
21 | import androidx.compose.foundation.shape.RoundedCornerShape
22 | import androidx.compose.foundation.verticalScroll
23 | import androidx.compose.material.icons.Icons
24 | import androidx.compose.material.icons.filled.Close
25 | import androidx.compose.material.icons.filled.Share
26 | import androidx.compose.material3.ExperimentalMaterial3Api
27 | import androidx.compose.material3.HorizontalDivider
28 | import androidx.compose.material3.Icon
29 | import androidx.compose.material3.ModalBottomSheet
30 | import androidx.compose.material3.OutlinedTextField
31 | import androidx.compose.material3.OutlinedTextFieldDefaults
32 | import androidx.compose.material3.Switch
33 | import androidx.compose.material3.Text
34 | import androidx.compose.material3.rememberModalBottomSheetState
35 | import androidx.compose.runtime.Composable
36 | import androidx.compose.runtime.getValue
37 | import androidx.compose.runtime.mutableStateOf
38 | import androidx.compose.runtime.remember
39 | import androidx.compose.runtime.setValue
40 | import androidx.compose.ui.Alignment
41 | import androidx.compose.ui.Modifier
42 | import androidx.compose.ui.draw.clip
43 | import androidx.compose.ui.graphics.Color
44 | import androidx.compose.ui.graphics.ImageBitmap
45 | import androidx.compose.ui.graphics.SolidColor
46 | import androidx.compose.ui.layout.ContentScale
47 | import androidx.compose.ui.text.TextStyle
48 | import androidx.compose.ui.text.font.FontFamily
49 | import androidx.compose.ui.text.font.FontWeight
50 | import network.chaintech.sdpcomposemultiplatform.sdp
51 | import network.chaintech.sdpcomposemultiplatform.ssp
52 | import org.jetbrains.compose.resources.Font
53 | import org.jetbrains.compose.resources.painterResource
54 | import qrcodedemo.composeapp.generated.resources.Aeonik_Bold
55 | import qrcodedemo.composeapp.generated.resources.Aeonik_Regular
56 | import qrcodedemo.composeapp.generated.resources.Res
57 | import qrcodedemo.composeapp.generated.resources.bg
58 | import qrcodedemo.composeapp.generated.resources.ic_calendar
59 | import qrcodedemo.composeapp.generated.resources.ic_done
60 | import qrcodedemo.composeapp.generated.resources.ic_drop_down
61 | import qrcodedemo.composeapp.generated.resources.ic_email
62 | import qrcodedemo.composeapp.generated.resources.ic_magic_tool
63 | import qrcodedemo.composeapp.generated.resources.ic_phone
64 | import qrcodedemo.composeapp.generated.resources.ic_sms
65 | import qrcodedemo.composeapp.generated.resources.ic_text
66 | import qrcodedemo.composeapp.generated.resources.ic_text_blue
67 | import qrcodedemo.composeapp.generated.resources.ic_website
68 | import qrcodedemo.composeapp.generated.resources.ic_wifi
69 | import qrcodedemo.composeapp.generated.resources.poppins_bold
70 | import qrcodedemo.composeapp.generated.resources.poppins_medium
71 | import qrcodedemo.composeapp.generated.resources.poppins_regular
72 | import qrcodedemo.composeapp.generated.resources.poppins_semibold
73 | import qrgenerator.QRCodeImage
74 | import qrgenerator.qrkitpainter.QrKitBrush
75 | import qrgenerator.qrkitpainter.QrKitColors
76 | import qrgenerator.qrkitpainter.customBrush
77 | import qrgenerator.qrkitpainter.rememberQrKitPainter
78 | import qrgenerator.shareQrCodeImage
79 |
80 | @Composable
81 | fun QrGeneratorView(onNavigate: (String) -> Unit) {
82 | var selectedType by remember { mutableStateOf("Text") }
83 | var selectedIndex by remember { mutableStateOf(0) }
84 | var showSheet by remember { mutableStateOf(false) }
85 |
86 | val FontAeonik = FontFamily(
87 | Font(Res.font.Aeonik_Regular, FontWeight.Normal),
88 | Font(Res.font.Aeonik_Bold, FontWeight.Bold)
89 | )
90 |
91 | val FontPoppins = FontFamily(
92 | Font(Res.font.poppins_regular, FontWeight.Normal),
93 | Font(Res.font.poppins_medium, FontWeight.Medium),
94 | Font(Res.font.poppins_semibold, FontWeight.SemiBold),
95 | Font(Res.font.poppins_bold, FontWeight.Bold)
96 | )
97 |
98 | Box(
99 | modifier = Modifier
100 | .background(Color(0xFF1D1C22))
101 | .statusBarsPadding()
102 | .fillMaxSize()
103 | ) {
104 | Image(
105 | modifier = Modifier.fillMaxSize(),
106 | painter = painterResource(resource = Res.drawable.bg),
107 | contentScale = ContentScale.Fit,
108 | contentDescription = ""
109 | )
110 | Column(
111 | modifier = Modifier
112 | .fillMaxSize()
113 | .verticalScroll(rememberScrollState())
114 | .padding(bottom = 120.sdp)
115 | ) {
116 | Row(
117 | modifier = Modifier
118 | .fillMaxWidth()
119 | .padding(end = 16.sdp),
120 | horizontalArrangement = Arrangement.SpaceBetween,
121 | verticalAlignment = Alignment.CenterVertically
122 | ) {
123 | Column {
124 | Text(
125 | text = "QR Code",
126 | modifier = Modifier
127 | .padding(horizontal = 14.sdp)
128 | .padding(top = 20.sdp),
129 | style = TextStyle(
130 | color = Color(0xFFFD66B5),
131 | fontFamily = FontAeonik,
132 | fontWeight = FontWeight.Bold
133 | ),
134 | fontSize = 14.ssp
135 | )
136 |
137 | Text(
138 | text = "Generator",
139 | modifier = Modifier
140 | .padding(horizontal = 14.sdp)
141 | .padding(top = 2.sdp),
142 | fontSize = 26.ssp,
143 | style = TextStyle(
144 | color = Color(0xFFFF8066),
145 | fontFamily = FontAeonik,
146 | fontWeight = FontWeight.Bold
147 | )
148 | )
149 | }
150 |
151 | Icon(
152 | Icons.Filled.Close,
153 | "close",
154 | modifier = Modifier
155 | .size(28.sdp)
156 | .clickable {
157 | onNavigate(AppConstants.BACK_CLICK_ROUTE)
158 | },
159 | tint = Color.White
160 | )
161 | }
162 |
163 | Text(
164 | text = "Choose QR Code type",
165 | modifier = Modifier
166 | .padding(horizontal = 14.sdp)
167 | .padding(top = 22.sdp),
168 | fontSize = 10.ssp,
169 | style = TextStyle(
170 | color = Color(0xFFAFAFAF),
171 | fontFamily = FontPoppins,
172 | fontWeight = FontWeight.Medium
173 | )
174 | )
175 |
176 | OutlinedTextField(value = selectedType,
177 | modifier = Modifier
178 | .padding(horizontal = 14.sdp)
179 | .padding(top = 10.sdp)
180 | .fillMaxWidth()
181 | .clickable {
182 | showSheet = true
183 | },
184 | onValueChange = {
185 | selectedType = it
186 | },
187 | enabled = false,
188 | singleLine = true,
189 | placeholder = {
190 | Text(
191 | text = "Text",
192 | modifier = Modifier,
193 | fontSize = 12.ssp,
194 | style = TextStyle(
195 | color = Color(0xFF747474),
196 | fontFamily = FontPoppins,
197 | fontWeight = FontWeight.Medium
198 | )
199 | )
200 | },
201 | textStyle = TextStyle(
202 | fontSize = 12.ssp, color = Color.White, fontFamily = FontPoppins, fontWeight = FontWeight.Medium
203 | ),
204 | shape = RoundedCornerShape(6.sdp),
205 | colors = OutlinedTextFieldDefaults.colors(
206 | unfocusedBorderColor = Color(0xFF3E3D46),
207 | focusedBorderColor = Color(0xFF3E3D46),
208 | cursorColor = Color.White,
209 | disabledBorderColor = Color(0xFF3E3D46),
210 | ),
211 | leadingIcon = {
212 | Image(
213 | modifier = Modifier.padding(start = 10.sdp, end = 10.sdp).size(18.sdp),
214 | painter = painterResource(resource = Res.drawable.ic_text),
215 | contentScale = ContentScale.Fit,
216 | contentDescription = ""
217 | )
218 | },
219 | trailingIcon = {
220 | Image(
221 | modifier = Modifier.padding(end = 8.sdp).size(8.sdp),
222 | painter = painterResource(resource = Res.drawable.ic_drop_down),
223 | contentScale = ContentScale.Fit,
224 | contentDescription = ""
225 | )
226 | })
227 |
228 | when (selectedType) {
229 | "Text" -> {
230 | TextQR(onNavigate)
231 | }
232 |
233 | "Website" -> {
234 | WebsiteQR(onNavigate)
235 | }
236 |
237 | "Email" -> {
238 | EmailQR(onNavigate)
239 | }
240 |
241 | "SMS" -> {
242 | SMSQR(onNavigate)
243 | }
244 |
245 | "Wi-Fi" -> {
246 | WifiQR(onNavigate)
247 | }
248 |
249 | "Phone" -> {
250 | PhoneQR(onNavigate)
251 | }
252 |
253 | "Calendar" -> {
254 | CalendarQR(onNavigate)
255 | }
256 | }
257 | }
258 | }
259 |
260 | if (showSheet) {
261 | QRTypeBottomSheet(
262 | selectedIndex = selectedIndex,
263 | callBack = { index, data ->
264 | showSheet = false
265 | selectedIndex = index
266 | selectedType = data.title
267 | },
268 | onDismiss = { showSheet = false }
269 | )
270 | }
271 | }
272 |
273 | @OptIn(ExperimentalMaterial3Api::class)
274 | @Composable
275 | fun QRTypeBottomSheet(
276 | selectedIndex: Int,
277 | callBack: (Int, QRType) -> Unit,
278 | onDismiss: () -> Unit
279 | ) {
280 | val FontPoppins = FontFamily(
281 | Font(Res.font.poppins_regular, FontWeight.Normal),
282 | Font(Res.font.poppins_medium, FontWeight.Medium),
283 | Font(Res.font.poppins_semibold, FontWeight.SemiBold),
284 | Font(Res.font.poppins_bold, FontWeight.Bold)
285 | )
286 |
287 | val modalBottomSheetState = rememberModalBottomSheetState(skipPartiallyExpanded = true)
288 |
289 | ModalBottomSheet(
290 | onDismissRequest = { onDismiss() },
291 | sheetState = modalBottomSheetState,
292 | containerColor = Color.Transparent,
293 | dragHandle = {}
294 | ) {
295 | val list = arrayListOf()
296 | list.add(QRType(Res.drawable.ic_text_blue, "Text"))
297 | list.add(QRType(Res.drawable.ic_website, "Website"))
298 | list.add(QRType(Res.drawable.ic_email, "Email"))
299 | list.add(QRType(Res.drawable.ic_sms, "SMS"))
300 | list.add(QRType(Res.drawable.ic_wifi, "Wi-Fi"))
301 | list.add(QRType(Res.drawable.ic_phone, "Phone"))
302 | list.add(QRType(Res.drawable.ic_calendar, "Calendar"))
303 |
304 | Column(
305 | modifier = Modifier
306 | .padding(14.sdp)
307 | .background(Color(0xFF18171C), RoundedCornerShape(12.sdp))
308 | .padding(14.sdp)
309 | ) {
310 | HorizontalDivider(
311 | modifier = Modifier
312 | .width(40.sdp)
313 | .clip(RoundedCornerShape(50.sdp))
314 | .align(Alignment.CenterHorizontally), 3.sdp, color = Color(0xFF383737)
315 | )
316 |
317 | Text(
318 | text = "Choose QR Code type",
319 | modifier = Modifier.padding(top = 20.sdp),
320 | fontSize = 14.ssp,
321 | style = TextStyle(
322 | color = Color(0xFF7A7AD9),
323 | fontFamily = FontPoppins,
324 | fontWeight = FontWeight.SemiBold
325 | )
326 | )
327 |
328 | LazyColumn(modifier = Modifier.padding(top = 20.sdp)) {
329 | itemsIndexed(list) { index, data ->
330 | Column(modifier = Modifier.fillMaxWidth().padding(top = 4.sdp).clickable {
331 | callBack(index, data)
332 | }) {
333 | Row(
334 | modifier = Modifier.fillMaxWidth()
335 | .padding(vertical = 8.sdp, horizontal = 4.sdp),
336 | verticalAlignment = Alignment.CenterVertically
337 | ) {
338 | Image(
339 | modifier = Modifier.size(18.sdp),
340 | painter = painterResource(resource = data.icon),
341 | contentScale = ContentScale.Fit,
342 | contentDescription = ""
343 | )
344 | Text(
345 | text = data.title,
346 | modifier = Modifier.padding(start = 14.sdp).weight(1f),
347 | fontSize = 12.ssp,
348 | style = TextStyle(
349 | color = Color(0xFFAFAFAF),
350 | fontFamily = FontPoppins,
351 | fontWeight = FontWeight.Medium
352 | )
353 | )
354 | if (selectedIndex == index) Image(
355 | modifier = Modifier.size(16.sdp),
356 | painter = painterResource(resource = Res.drawable.ic_done),
357 | contentScale = ContentScale.Fit,
358 | contentDescription = ""
359 | )
360 | }
361 | HorizontalDivider(
362 | modifier = Modifier.padding(top = 4.sdp).fillMaxWidth(),
363 | 1.sdp,
364 | color = Color(0xFF24222C)
365 | )
366 | }
367 | }
368 | }
369 | }
370 | }
371 | }
372 |
373 | @Composable
374 | fun QREditTextView(
375 | labelText: String, placeHolder: String, inputText: String, onValueChange: (String) -> Unit
376 | ) {
377 | val FontPoppins = FontFamily(
378 | Font(Res.font.poppins_regular, FontWeight.Normal),
379 | Font(Res.font.poppins_medium, FontWeight.Medium),
380 | Font(Res.font.poppins_semibold, FontWeight.SemiBold),
381 | Font(Res.font.poppins_bold, FontWeight.Bold)
382 | )
383 |
384 | Text(
385 | text = labelText,
386 | modifier = Modifier.padding(horizontal = 14.sdp).padding(top = 20.sdp),
387 | fontSize = 10.ssp,
388 | style = TextStyle(
389 | color = Color(0xFFAFAFAF),
390 | fontFamily = FontPoppins,
391 | fontWeight = FontWeight.Medium
392 | )
393 | )
394 |
395 | OutlinedTextField(
396 | value = inputText,
397 | modifier = Modifier
398 | .padding(horizontal = 14.sdp)
399 | .padding(top = 10.sdp)
400 | .fillMaxWidth(),
401 | onValueChange = {
402 | onValueChange(it)
403 | },
404 | singleLine = true,
405 | placeholder = {
406 | Text(
407 | text = placeHolder,
408 | modifier = Modifier,
409 | fontSize = 12.ssp,
410 | color = Color(0xFF747474),
411 | fontFamily = FontFamily.Serif
412 | )
413 | },
414 | textStyle = TextStyle(
415 | fontSize = 12.ssp,
416 | color = Color.White,
417 | fontFamily = FontPoppins,
418 | fontWeight = FontWeight.Medium
419 | ),
420 | shape = RoundedCornerShape(8.sdp),
421 | colors = OutlinedTextFieldDefaults.colors(
422 | unfocusedBorderColor = Color(0xFF3E3D46),
423 | focusedBorderColor = Color(0xFF3E3D46),
424 | cursorColor = Color.White
425 | ),
426 | )
427 | }
428 |
429 | @Composable
430 | fun ColumnScope.QRCodePreview(inputText: String, onNavigate: (String) -> Unit) {
431 | val FontPoppins = FontFamily(
432 | Font(Res.font.poppins_regular, FontWeight.Normal),
433 | Font(Res.font.poppins_medium, FontWeight.Medium),
434 | Font(Res.font.poppins_semibold, FontWeight.SemiBold),
435 | Font(Res.font.poppins_bold, FontWeight.Bold)
436 | )
437 |
438 | Text(
439 | text = "QR Code Preview",
440 | modifier = Modifier.padding(top = 24.sdp)
441 | .background(Color(0xFF006588), RoundedCornerShape(topEnd = 50.sdp, bottomEnd = 50.sdp))
442 | .padding(vertical = 4.sdp)
443 | .padding(start = 14.sdp, end = 24.sdp),
444 | style = TextStyle(
445 | color = Color.White,
446 | fontFamily = FontPoppins,
447 | fontWeight = FontWeight.SemiBold
448 | ),
449 | fontSize = 12.ssp
450 | )
451 |
452 | var showSharable by remember { mutableStateOf(false) }
453 |
454 | /** Painter for displaying QR Code */
455 | val painter = rememberQrKitPainter(inputText) {
456 | colors = QrKitColors(
457 | darkBrush = QrKitBrush.customBrush { SolidColor(Color.White) }
458 | )
459 | }
460 |
461 | var qrImageBitmap: ImageBitmap? = null
462 |
463 | Column(
464 | modifier = Modifier
465 | .padding(top = 20.sdp)
466 | .align(Alignment.CenterHorizontally)
467 | ) {
468 | Row(
469 | modifier = Modifier
470 | .align(Alignment.CenterHorizontally),
471 | verticalAlignment = Alignment.CenterVertically
472 | ) {
473 | Text("Show sharable QR code", color = Color.White)
474 | Spacer(modifier = Modifier.width(8.sdp))
475 | Switch(
476 | checked = showSharable,
477 | onCheckedChange = {
478 | showSharable = it
479 | }
480 | )
481 | }
482 |
483 | Box(
484 | modifier = Modifier
485 | .size(170.sdp)
486 | .padding(top = 10.sdp)
487 | ) {
488 | Box(
489 | modifier = Modifier
490 | .background(Color(0xFF252528), RoundedCornerShape(6.sdp))
491 | .clip(RoundedCornerShape(6.sdp))
492 | .align(Alignment.Center)
493 | .size(150.sdp),
494 | contentAlignment = Alignment.Center
495 | ) {
496 | if (showSharable) {
497 | /** Use this if you just want to display a Sharable QR Code */
498 | QRCodeImage(
499 | modifier = Modifier.size(130.sdp),
500 | url = inputText,
501 | contentDescription = "Sharable QR Code",
502 | onSuccess = { qrImage ->
503 | qrImage?.let {
504 | qrImageBitmap = it
505 | }
506 | }
507 | )
508 | } else {
509 | /** Use this if you just want to display the QR Code */
510 | Image(
511 | painter = painter, contentDescription = null, modifier = Modifier.size(130.sdp)
512 | )
513 | }
514 | }
515 |
516 | Row(
517 | modifier = Modifier
518 | .background(Color(0xFF007AFF), RoundedCornerShape(50.sdp))
519 | .padding(top = 5.sdp, bottom = 5.sdp, start = 10.sdp, end = 12.sdp)
520 | .align(Alignment.BottomCenter)
521 | .clickable {
522 | onNavigate(
523 | AppScreen.QRCustomization.route.replace(
524 | "{${AppConstants.QR_TEXT}}", inputText
525 | )
526 | )
527 | },
528 | verticalAlignment = Alignment.CenterVertically
529 | ) {
530 | Image(
531 | modifier = Modifier.size(14.sdp),
532 | painter = painterResource(resource = Res.drawable.ic_magic_tool),
533 | contentScale = ContentScale.Fit,
534 | contentDescription = ""
535 | )
536 |
537 | Text(
538 | text = "Customize",
539 | modifier = Modifier.padding(start = 6.sdp),
540 | fontSize = 10.ssp,
541 | style = TextStyle(
542 | color = Color.White,
543 | fontFamily = FontPoppins,
544 | fontWeight = FontWeight.Medium
545 | )
546 | )
547 | }
548 | }
549 |
550 | if (showSharable) {
551 | Row(
552 | modifier = Modifier
553 | .padding(top = 14.sdp, bottom = 5.sdp)
554 | .align(Alignment.CenterHorizontally)
555 | .clickable {
556 | qrImageBitmap?.let {
557 | shareQrCodeImage(qrImageBitmap, "QR Code")
558 | }
559 | },
560 | verticalAlignment = Alignment.CenterVertically
561 | ) {
562 | Icon(
563 | Icons.Default.Share,
564 | modifier = Modifier.size(16.sdp),
565 | tint = Color.White,
566 | contentDescription = ""
567 | )
568 |
569 | Text(
570 | text = "Share QR Code",
571 | modifier = Modifier.padding(start = 6.sdp),
572 | fontSize = 12.ssp,
573 | style = TextStyle(
574 | color = Color.White,
575 | fontFamily = FontPoppins,
576 | fontWeight = FontWeight.Medium
577 | )
578 | )
579 | }
580 | }
581 | }
582 | }
583 |
584 |
585 |
586 |
587 |
--------------------------------------------------------------------------------
/composeApp/src/commonMain/kotlin/org/qrcodedemo/app/ui/QrScannerScreen.kt:
--------------------------------------------------------------------------------
1 | package org.qrcodedemo.app.ui
2 |
3 | import androidx.compose.foundation.Image
4 | import androidx.compose.foundation.background
5 | import androidx.compose.foundation.clickable
6 | import androidx.compose.foundation.layout.Arrangement
7 | import androidx.compose.foundation.layout.Box
8 | import androidx.compose.foundation.layout.BoxScope
9 | import androidx.compose.foundation.layout.Column
10 | import androidx.compose.foundation.layout.Row
11 | import androidx.compose.foundation.layout.fillMaxSize
12 | import androidx.compose.foundation.layout.fillMaxWidth
13 | import androidx.compose.foundation.layout.height
14 | import androidx.compose.foundation.layout.padding
15 | import androidx.compose.foundation.layout.size
16 | import androidx.compose.foundation.layout.statusBarsPadding
17 | import androidx.compose.foundation.shape.RoundedCornerShape
18 | import androidx.compose.material.icons.Icons
19 | import androidx.compose.material.icons.filled.Close
20 | import androidx.compose.material.icons.filled.CopyAll
21 | import androidx.compose.material.icons.filled.FlashOff
22 | import androidx.compose.material.icons.filled.FlashOn
23 | import androidx.compose.material.icons.filled.ZoomIn
24 | import androidx.compose.material3.Button
25 | import androidx.compose.material3.ButtonDefaults
26 | import androidx.compose.material3.Icon
27 | import androidx.compose.material3.Scaffold
28 | import androidx.compose.material3.SnackbarHost
29 | import androidx.compose.material3.SnackbarHostState
30 | import androidx.compose.material3.Text
31 | import androidx.compose.material3.VerticalDivider
32 | import androidx.compose.runtime.Composable
33 | import androidx.compose.runtime.getValue
34 | import androidx.compose.runtime.mutableStateOf
35 | import androidx.compose.runtime.remember
36 | import androidx.compose.runtime.rememberCoroutineScope
37 | import androidx.compose.runtime.setValue
38 | import androidx.compose.ui.Alignment
39 | import androidx.compose.ui.Modifier
40 | import androidx.compose.ui.graphics.Color
41 | import androidx.compose.ui.platform.ClipboardManager
42 | import androidx.compose.ui.platform.LocalClipboardManager
43 | import androidx.compose.ui.text.AnnotatedString
44 | import androidx.compose.ui.text.font.FontFamily
45 | import androidx.compose.ui.text.font.FontWeight
46 | import androidx.compose.ui.text.style.TextOverflow
47 | import kotlinx.coroutines.launch
48 | import network.chaintech.sdpcomposemultiplatform.sdp
49 | import network.chaintech.sdpcomposemultiplatform.ssp
50 | import org.jetbrains.compose.resources.painterResource
51 | import org.qrcodedemo.app.platformName
52 | import qrcodedemo.composeapp.generated.resources.Res
53 | import qrcodedemo.composeapp.generated.resources.ic_camera_switch
54 | import qrcodedemo.composeapp.generated.resources.ic_gallery_icon
55 | import qrcodedemo.composeapp.generated.resources.ic_rectangle
56 | import qrcodedemo.composeapp.generated.resources.ic_square_border
57 | import qrscanner.CameraLens
58 | import qrscanner.OverlayShape
59 | import qrscanner.QrScanner
60 |
61 | @Composable
62 | fun QrScannerView(onNavigate: (String) -> Unit) {
63 | val coroutineScope = rememberCoroutineScope()
64 | val clipboardManager: ClipboardManager = LocalClipboardManager.current
65 | val snackbarHostState = remember { SnackbarHostState() }
66 | val zoomLevels = listOf(1f, 2f, 3f)
67 | var selectedZoomIndex = 0
68 |
69 | var qrCodeURL by remember { mutableStateOf("") }
70 | var flashlightOn by remember { mutableStateOf(false) }
71 | var openImagePicker by remember { mutableStateOf(false) }
72 | var overlayShape by remember { mutableStateOf(OverlayShape.Square) }
73 | var cameraLens by remember { mutableStateOf(CameraLens.Back) }
74 | var currentZoomLevel by remember { mutableStateOf(zoomLevels[selectedZoomIndex]) }
75 |
76 | Scaffold(
77 | snackbarHost = { SnackbarHost(snackbarHostState) }
78 | ) { contentPadding ->
79 | Box(
80 | modifier = Modifier
81 | .background(Color(0xFF1D1C22))
82 | .fillMaxSize()
83 | .statusBarsPadding()
84 | ) {
85 | // QR Scanner Camera Preview
86 | QrScanner(
87 | modifier = Modifier.fillMaxSize(),
88 | flashlightOn = flashlightOn,
89 | cameraLens = cameraLens,
90 | openImagePicker = openImagePicker,
91 | onCompletion = { qrCodeURL = it },
92 | zoomLevel = currentZoomLevel,
93 | maxZoomLevel = 3f,
94 | imagePickerHandler = { openImagePicker = it },
95 | onFailure = {
96 | coroutineScope.launch {
97 | snackbarHostState.showSnackbar(it.ifEmpty { "Invalid QR Code" })
98 | }
99 | },
100 | overlayShape = overlayShape
101 | )
102 |
103 | if (platformName() != "Desktop") {
104 | BottomActions(
105 | flashlightOn = flashlightOn,
106 | onToggleFlash = {
107 | if (cameraLens == CameraLens.Front) {
108 | coroutineScope.launch {
109 | snackbarHostState.showSnackbar("Flash not available in front camera")
110 | }
111 | } else {
112 | flashlightOn = !flashlightOn
113 | }
114 | },
115 | onSwitchCamera = {
116 | cameraLens = if (cameraLens == CameraLens.Front) {
117 | flashlightOn = false
118 | CameraLens.Back
119 | } else CameraLens.Front
120 | },
121 | onOpenGallery = { openImagePicker = true },
122 | onShapeChange = { overlayShape = it },
123 | onZoomLevelChange = {
124 | if (selectedZoomIndex == (zoomLevels.size-1)) {
125 | selectedZoomIndex = 0
126 | } else {
127 | selectedZoomIndex+= 1
128 | }
129 | currentZoomLevel = zoomLevels[selectedZoomIndex]
130 | }
131 | )
132 | } else {
133 | Button(
134 | modifier = Modifier.align(Alignment.Center).padding(top = 12.sdp),
135 | onClick = { openImagePicker = true },
136 | colors = ButtonDefaults.buttonColors(containerColor = Color(0xFF5144D8))
137 | ) {
138 | Text(
139 | text = "Select Image",
140 | fontSize = 16.ssp,
141 | fontFamily = FontFamily.Serif,
142 | modifier = Modifier
143 | .background(Color.Transparent)
144 | .padding(horizontal = 12.sdp, vertical = 12.sdp)
145 | )
146 | }
147 | }
148 |
149 | if (qrCodeURL.isNotEmpty()) {
150 | ResultDisplay(
151 | result = qrCodeURL,
152 | onCopy = {
153 | clipboardManager.setText(AnnotatedString(qrCodeURL))
154 | coroutineScope.launch {
155 | snackbarHostState.showSnackbar("Copied")
156 | }
157 | }
158 | )
159 | }
160 |
161 | TopBar(onClose = { onNavigate(AppConstants.BACK_CLICK_ROUTE) })
162 | }
163 | }
164 | }
165 |
166 |
167 | @Composable
168 | fun BoxScope.BottomActions(
169 | flashlightOn: Boolean,
170 | onToggleFlash: () -> Unit,
171 | onSwitchCamera: () -> Unit,
172 | onOpenGallery: () -> Unit,
173 | onShapeChange: (OverlayShape) -> Unit,
174 | onZoomLevelChange: () -> Unit
175 | ) {
176 | Column(
177 | modifier = Modifier
178 | .padding(start = 20.sdp, end = 20.sdp, top = 20.sdp, bottom = 150.sdp)
179 | .align(Alignment.BottomCenter)
180 | ) {
181 | Box(
182 | modifier = Modifier
183 | .background(Color(0xFFF9F9F9), RoundedCornerShape(25.sdp))
184 | .height(35.sdp),
185 | contentAlignment = Alignment.Center
186 | ) {
187 | Row(
188 | modifier = Modifier.padding(vertical = 4.sdp, horizontal = 16.sdp),
189 | verticalAlignment = Alignment.CenterVertically,
190 | horizontalArrangement = Arrangement.spacedBy(8.sdp)
191 | ) {
192 | Icon(
193 | imageVector = if (flashlightOn) Icons.Filled.FlashOn else Icons.Filled.FlashOff,
194 | contentDescription = "Flash",
195 | modifier = Modifier.size(20.sdp).clickable(onClick = onToggleFlash)
196 | )
197 | DividerDot()
198 | Icon(
199 | imageVector = Icons.Filled.ZoomIn,
200 | contentDescription = "Zoom",
201 | modifier = Modifier.size(20.sdp).clickable(onClick = {
202 | onZoomLevelChange()
203 | })
204 | )
205 | DividerDot()
206 | Image(
207 | painter = painterResource(Res.drawable.ic_camera_switch),
208 | contentDescription = "Switch",
209 | modifier = Modifier.size(20.sdp).clickable(onClick = onSwitchCamera)
210 | )
211 | DividerDot()
212 | Image(
213 | painter = painterResource(Res.drawable.ic_gallery_icon),
214 | contentDescription = "Gallery",
215 | modifier = Modifier.size(20.sdp).clickable(onClick = onOpenGallery)
216 | )
217 | DividerDot()
218 | Icon(
219 | painter = painterResource(Res.drawable.ic_square_border),
220 | contentDescription = "Square",
221 | modifier = Modifier.size(20.sdp).clickable { onShapeChange(OverlayShape.Square) }
222 | )
223 | DividerDot()
224 | Icon(
225 | painter = painterResource(Res.drawable.ic_rectangle),
226 | contentDescription = "Rectangle",
227 | modifier = Modifier.size(20.sdp).clickable { onShapeChange(OverlayShape.Rectangle) }
228 | )
229 | }
230 | }
231 | }
232 | }
233 |
234 | @Composable
235 | private fun DividerDot() {
236 | VerticalDivider(
237 | thickness = 1.sdp,
238 | color = Color(0xFFD8D8D8)
239 | )
240 | }
241 |
242 | @Composable
243 | fun BoxScope.ResultDisplay(result: String, onCopy: () -> Unit) {
244 | Row(
245 | modifier = Modifier
246 | .padding(horizontal = 14.sdp)
247 | .padding(bottom = 30.sdp)
248 | .fillMaxWidth()
249 | .align(Alignment.BottomCenter),
250 | verticalAlignment = Alignment.CenterVertically
251 | ) {
252 | Text(
253 | text = result,
254 | modifier = Modifier
255 | .padding(end = 8.sdp)
256 | .weight(1f),
257 | fontSize = 12.ssp,
258 | color = Color.White,
259 | fontFamily = FontFamily.Serif,
260 | fontWeight = FontWeight.Bold,
261 | maxLines = 4,
262 | overflow = TextOverflow.Ellipsis
263 | )
264 | Icon(
265 | imageVector = Icons.Filled.CopyAll,
266 | contentDescription = "Copy",
267 | modifier = Modifier.size(20.sdp).clickable(onClick = onCopy),
268 | tint = Color.White
269 | )
270 | }
271 | }
272 |
273 | @Composable
274 | fun TopBar(onClose: () -> Unit) {
275 | Row(
276 | modifier = Modifier
277 | .padding(horizontal = 14.sdp, vertical = 20.sdp)
278 | .fillMaxWidth(),
279 | verticalAlignment = Alignment.CenterVertically
280 | ) {
281 | Text(
282 | text = "QRScanner",
283 | modifier = Modifier.weight(1f),
284 | fontSize = 18.ssp,
285 | color = Color.White,
286 | fontWeight = FontWeight.Bold,
287 | fontFamily = FontFamily.Serif
288 | )
289 | Icon(
290 | imageVector = Icons.Filled.Close,
291 | contentDescription = "Close",
292 | modifier = Modifier.size(20.sdp).clickable(onClick = onClose),
293 | tint = Color.White
294 | )
295 | }
296 | }
297 |
--------------------------------------------------------------------------------
/composeApp/src/iosMain/kotlin/main.kt:
--------------------------------------------------------------------------------
1 | import androidx.compose.ui.window.ComposeUIViewController
2 | import org.qrcodedemo.app.AppHome
3 | import platform.UIKit.UIViewController
4 |
5 | fun MainViewController(): UIViewController = ComposeUIViewController(
6 | configure = {
7 | enforceStrictPlistSanityCheck = false
8 | }
9 | ) { AppHome() }
10 |
--------------------------------------------------------------------------------
/composeApp/src/iosMain/kotlin/org/qrcodedemo/app/App.ios.kt:
--------------------------------------------------------------------------------
1 | package org.qrcodedemo.app
2 |
3 |
--------------------------------------------------------------------------------
/composeApp/src/iosMain/kotlin/org/qrcodedemo/app/Platform.ios.kt:
--------------------------------------------------------------------------------
1 | package org.qrcodedemo.app
2 |
3 | actual fun platformName(): String = "iOS"
--------------------------------------------------------------------------------
/composeApp/src/iosMain/kotlin/org/qrcodedemo/app/theme/Theme.ios.kt:
--------------------------------------------------------------------------------
1 | package org.qrcodedemo.app.theme
2 |
3 | import androidx.compose.runtime.Composable
4 | import androidx.compose.runtime.LaunchedEffect
5 | import platform.UIKit.UIApplication
6 | import platform.UIKit.UIStatusBarStyleDarkContent
7 | import platform.UIKit.UIStatusBarStyleLightContent
8 | import platform.UIKit.setStatusBarStyle
9 |
10 | @Composable
11 | internal actual fun SystemAppearance(isDark: Boolean) {
12 | LaunchedEffect(isDark) {
13 | UIApplication.sharedApplication.setStatusBarStyle(
14 | if (isDark) UIStatusBarStyleDarkContent else UIStatusBarStyleLightContent
15 | )
16 | }
17 | }
--------------------------------------------------------------------------------
/composeApp/src/jvmMain/kotlin/main.kt:
--------------------------------------------------------------------------------
1 | import androidx.compose.ui.unit.dp
2 | import androidx.compose.ui.window.Window
3 | import androidx.compose.ui.window.application
4 | import androidx.compose.ui.window.rememberWindowState
5 | import java.awt.Dimension
6 | import org.qrcodedemo.app.AppHome
7 |
8 | fun main() = application {
9 | Window(
10 | title = "QRCodeDemo",
11 | state = rememberWindowState(width = 800.dp, height = 600.dp),
12 | onCloseRequest = ::exitApplication,
13 | ) {
14 | window.minimumSize = Dimension(150, 150)
15 | AppHome()
16 | // scanQRCodeImage()
17 | }
18 | }
--------------------------------------------------------------------------------
/composeApp/src/jvmMain/kotlin/org/qrcodedemo/app/Platform.jvm.kt:
--------------------------------------------------------------------------------
1 | package org.qrcodedemo.app
2 |
3 | actual fun platformName(): String = "Desktop"
--------------------------------------------------------------------------------
/composeApp/src/jvmMain/kotlin/org/qrcodedemo/app/theme/Theme.jvm.kt:
--------------------------------------------------------------------------------
1 | package org.qrcodedemo.app.theme
2 |
3 | import androidx.compose.runtime.Composable
4 |
5 | @Composable
6 | internal actual fun SystemAppearance(isDark: Boolean) {
7 | }
--------------------------------------------------------------------------------
/gradle.properties:
--------------------------------------------------------------------------------
1 | #Gradle
2 | org.gradle.jvmargs=-Xmx2048M -Dfile.encoding=UTF-8 -Dkotlin.daemon.jvm.options\="-Xmx2048M"
3 | org.gradle.caching=false
4 | org.gradle.configuration-cache=false
5 |
6 | #Kotlin
7 | kotlin.code.style=official
8 | kotlin.js.compiler=ir
9 |
10 | #Android
11 | android.useAndroidX=true
12 | android.nonTransitiveRClass=true
13 |
14 | #Compose
15 | org.jetbrains.compose.experimental.uikit.enabled=true
16 | org.jetbrains.compose.experimental.jscanvas.enabled=true
17 |
--------------------------------------------------------------------------------
/gradle/libs.versions.toml:
--------------------------------------------------------------------------------
1 | [versions]
2 |
3 | accompanistPermissions = "0.36.0"
4 | agp = "8.6.1"
5 | barcodeScanning = "17.3.0"
6 | cameraCore = "1.4.2"
7 | cmpImagePickNCrop = "1.0.9"
8 | core = "3.5.2"
9 | coreKtx = "1.16.0"
10 | imageLoader = "1.9.0"
11 | javase = "3.4.1"
12 | jna = "5.14.0"
13 | kotlin = "2.1.20"
14 | compose = "1.8.0"
15 | androidx-activityCompose = "1.10.1"
16 | androidx-appcompat = "1.7.1"
17 | compose-uitooling = "1.8.2"
18 | navigationCompose = "2.8.0-alpha02"
19 | androidx-uiTest = "1.8.2"
20 |
21 | qrKit = "3.1.1"
22 | sdpSspComposeMultiplatform = "1.0.4"
23 |
24 | [libraries]
25 | accompanist-permissions = { module = "com.google.accompanist:accompanist-permissions", version.ref = "accompanistPermissions" }
26 | androidx-appcompat = { module = "androidx.appcompat:appcompat", version.ref = "androidx-appcompat" }
27 | androidx-activityCompose = { module = "androidx.activity:activity-compose", version.ref = "androidx-activityCompose" }
28 | androidx-camera-camera2 = { module = "androidx.camera:camera-camera2", version.ref = "cameraCore" }
29 | androidx-camera-core = { module = "androidx.camera:camera-core", version.ref = "cameraCore" }
30 | androidx-camera-lifecycle = { module = "androidx.camera:camera-lifecycle", version.ref = "cameraCore" }
31 | androidx-camera-view = { module = "androidx.camera:camera-view", version.ref = "cameraCore" }
32 | androidx-core-ktx = { module = "androidx.core:core-ktx", version.ref = "coreKtx" }
33 | barcode-scanning = { module = "com.google.mlkit:barcode-scanning", version.ref = "barcodeScanning" }
34 | cmp-image-pick-n-crop = { module = "network.chaintech:cmp-image-pick-n-crop", version.ref = "cmpImagePickNCrop" }
35 | compose-uitooling = { module = "androidx.compose.ui:ui-tooling", version.ref = "compose-uitooling" }
36 | core = { module = "com.google.zxing:core", version.ref = "core" }
37 | image-loader = { module = "io.github.qdsfdhvh:image-loader", version.ref = "imageLoader" }
38 | javase = { module = "com.google.zxing:javase", version.ref = "javase" }
39 | jna = { module = "net.java.dev.jna:jna", version.ref = "jna" }
40 | navigation-compose = { module = "org.jetbrains.androidx.navigation:navigation-compose", version.ref = "navigationCompose" }
41 | androidx-testManifest = { module = "androidx.compose.ui:ui-test-manifest", version.ref = "androidx-uiTest" }
42 | androidx-junit4 = { module = "androidx.compose.ui:ui-test-junit4", version.ref = "androidx-uiTest" }
43 | qr-kit = { module = "network.chaintech:qr-kit", version.ref = "qrKit" }
44 | sdp-ssp-compose-multiplatform = { module = "network.chaintech:sdp-ssp-compose-multiplatform", version.ref = "sdpSspComposeMultiplatform" }
45 |
46 | [plugins]
47 | multiplatform = { id = "org.jetbrains.kotlin.multiplatform", version.ref = "kotlin" }
48 | compose = { id = "org.jetbrains.compose", version.ref = "compose" }
49 | android-application = { id = "com.android.application", version.ref = "agp" }
50 | android-library = { id = "com.android.library", version.ref = "agp" }
51 | mavenPublish = { id = "com.vanniktech.maven.publish", version = "0.28.0" }
52 | compose-compiler = { id = "org.jetbrains.kotlin.plugin.compose", version.ref = "kotlin" }
53 |
54 |
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Chaintech-Network/QRKitComposeMultiplatform/822f1f8a6ea0114494f53c12074400f130295973/gradle/wrapper/gradle-wrapper.jar
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.properties:
--------------------------------------------------------------------------------
1 | distributionBase=GRADLE_USER_HOME
2 | distributionPath=wrapper/dists
3 | distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-bin.zip
4 | networkTimeout=10000
5 | validateDistributionUrl=true
6 | zipStoreBase=GRADLE_USER_HOME
7 | zipStorePath=wrapper/dists
8 |
--------------------------------------------------------------------------------
/gradlew:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 |
3 | #
4 | # Copyright © 2015-2021 the original authors.
5 | #
6 | # Licensed under the Apache License, Version 2.0 (the "License");
7 | # you may not use this file except in compliance with the License.
8 | # You may obtain a copy of the License at
9 | #
10 | # https://www.apache.org/licenses/LICENSE-2.0
11 | #
12 | # Unless required by applicable law or agreed to in writing, software
13 | # distributed under the License is distributed on an "AS IS" BASIS,
14 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 | # See the License for the specific language governing permissions and
16 | # limitations under the License.
17 | #
18 |
19 | ##############################################################################
20 | #
21 | # Gradle start up script for POSIX generated by Gradle.
22 | #
23 | # Important for running:
24 | #
25 | # (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is
26 | # noncompliant, but you have some other compliant shell such as ksh or
27 | # bash, then to run this script, type that shell name before the whole
28 | # command line, like:
29 | #
30 | # ksh Gradle
31 | #
32 | # Busybox and similar reduced shells will NOT work, because this script
33 | # requires all of these POSIX shell features:
34 | # * functions;
35 | # * expansions «$var», «${var}», «${var:-default}», «${var+SET}»,
36 | # «${var#prefix}», «${var%suffix}», and «$( cmd )»;
37 | # * compound commands having a testable exit status, especially «case»;
38 | # * various built-in commands including «command», «set», and «ulimit».
39 | #
40 | # Important for patching:
41 | #
42 | # (2) This script targets any POSIX shell, so it avoids extensions provided
43 | # by Bash, Ksh, etc; in particular arrays are avoided.
44 | #
45 | # The "traditional" practice of packing multiple parameters into a
46 | # space-separated string is a well documented source of bugs and security
47 | # problems, so this is (mostly) avoided, by progressively accumulating
48 | # options in "$@", and eventually passing that to Java.
49 | #
50 | # Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS,
51 | # and GRADLE_OPTS) rely on word-splitting, this is performed explicitly;
52 | # see the in-line comments for details.
53 | #
54 | # There are tweaks for specific operating systems such as AIX, CygWin,
55 | # Darwin, MinGW, and NonStop.
56 | #
57 | # (3) This script is generated from the Groovy template
58 | # https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt
59 | # within the Gradle project.
60 | #
61 | # You can find Gradle at https://github.com/gradle/gradle/.
62 | #
63 | ##############################################################################
64 |
65 | # Attempt to set APP_HOME
66 |
67 | # Resolve links: $0 may be a link
68 | app_path=$0
69 |
70 | # Need this for daisy-chained symlinks.
71 | while
72 | APP_HOME=${app_path%"${app_path##*/}"} # leaves a trailing /; empty if no leading path
73 | [ -h "$app_path" ]
74 | do
75 | ls=$( ls -ld "$app_path" )
76 | link=${ls#*' -> '}
77 | case $link in #(
78 | /*) app_path=$link ;; #(
79 | *) app_path=$APP_HOME$link ;;
80 | esac
81 | done
82 |
83 | # This is normally unused
84 | # shellcheck disable=SC2034
85 | APP_BASE_NAME=${0##*/}
86 | # Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036)
87 | APP_HOME=$( cd "${APP_HOME:-./}" > /dev/null && pwd -P ) || exit
88 |
89 | # Use the maximum available, or set MAX_FD != -1 to use that value.
90 | MAX_FD=maximum
91 |
92 | warn () {
93 | echo "$*"
94 | } >&2
95 |
96 | die () {
97 | echo
98 | echo "$*"
99 | echo
100 | exit 1
101 | } >&2
102 |
103 | # OS specific support (must be 'true' or 'false').
104 | cygwin=false
105 | msys=false
106 | darwin=false
107 | nonstop=false
108 | case "$( uname )" in #(
109 | CYGWIN* ) cygwin=true ;; #(
110 | Darwin* ) darwin=true ;; #(
111 | MSYS* | MINGW* ) msys=true ;; #(
112 | NONSTOP* ) nonstop=true ;;
113 | esac
114 |
115 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
116 |
117 |
118 | # Determine the Java command to use to start the JVM.
119 | if [ -n "$JAVA_HOME" ] ; then
120 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
121 | # IBM's JDK on AIX uses strange locations for the executables
122 | JAVACMD=$JAVA_HOME/jre/sh/java
123 | else
124 | JAVACMD=$JAVA_HOME/bin/java
125 | fi
126 | if [ ! -x "$JAVACMD" ] ; then
127 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
128 |
129 | Please set the JAVA_HOME variable in your environment to match the
130 | location of your Java installation."
131 | fi
132 | else
133 | JAVACMD=java
134 | if ! command -v java >/dev/null 2>&1
135 | then
136 | die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
137 |
138 | Please set the JAVA_HOME variable in your environment to match the
139 | location of your Java installation."
140 | fi
141 | fi
142 |
143 | # Increase the maximum file descriptors if we can.
144 | if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then
145 | case $MAX_FD in #(
146 | max*)
147 | # In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked.
148 | # shellcheck disable=SC2039,SC3045
149 | MAX_FD=$( ulimit -H -n ) ||
150 | warn "Could not query maximum file descriptor limit"
151 | esac
152 | case $MAX_FD in #(
153 | '' | soft) :;; #(
154 | *)
155 | # In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked.
156 | # shellcheck disable=SC2039,SC3045
157 | ulimit -n "$MAX_FD" ||
158 | warn "Could not set maximum file descriptor limit to $MAX_FD"
159 | esac
160 | fi
161 |
162 | # Collect all arguments for the java command, stacking in reverse order:
163 | # * args from the command line
164 | # * the main class name
165 | # * -classpath
166 | # * -D...appname settings
167 | # * --module-path (only if needed)
168 | # * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables.
169 |
170 | # For Cygwin or MSYS, switch paths to Windows format before running java
171 | if "$cygwin" || "$msys" ; then
172 | APP_HOME=$( cygpath --path --mixed "$APP_HOME" )
173 | CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" )
174 |
175 | JAVACMD=$( cygpath --unix "$JAVACMD" )
176 |
177 | # Now convert the arguments - kludge to limit ourselves to /bin/sh
178 | for arg do
179 | if
180 | case $arg in #(
181 | -*) false ;; # don't mess with options #(
182 | /?*) t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath
183 | [ -e "$t" ] ;; #(
184 | *) false ;;
185 | esac
186 | then
187 | arg=$( cygpath --path --ignore --mixed "$arg" )
188 | fi
189 | # Roll the args list around exactly as many times as the number of
190 | # args, so each arg winds up back in the position where it started, but
191 | # possibly modified.
192 | #
193 | # NB: a `for` loop captures its iteration list before it begins, so
194 | # changing the positional parameters here affects neither the number of
195 | # iterations, nor the values presented in `arg`.
196 | shift # remove old arg
197 | set -- "$@" "$arg" # push replacement arg
198 | done
199 | fi
200 |
201 |
202 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
203 | DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
204 |
205 | # Collect all arguments for the java command:
206 | # * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments,
207 | # and any embedded shellness will be escaped.
208 | # * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be
209 | # treated as '${Hostname}' itself on the command line.
210 |
211 | set -- \
212 | "-Dorg.gradle.appname=$APP_BASE_NAME" \
213 | -classpath "$CLASSPATH" \
214 | org.gradle.wrapper.GradleWrapperMain \
215 | "$@"
216 |
217 | # Stop when "xargs" is not available.
218 | if ! command -v xargs >/dev/null 2>&1
219 | then
220 | die "xargs is not available"
221 | fi
222 |
223 | # Use "xargs" to parse quoted args.
224 | #
225 | # With -n1 it outputs one arg per line, with the quotes and backslashes removed.
226 | #
227 | # In Bash we could simply go:
228 | #
229 | # readarray ARGS < <( xargs -n1 <<<"$var" ) &&
230 | # set -- "${ARGS[@]}" "$@"
231 | #
232 | # but POSIX shell has neither arrays nor command substitution, so instead we
233 | # post-process each arg (as a line of input to sed) to backslash-escape any
234 | # character that might be a shell metacharacter, then use eval to reverse
235 | # that process (while maintaining the separation between arguments), and wrap
236 | # the whole thing up as a single "set" statement.
237 | #
238 | # This will of course break if any of these variables contains a newline or
239 | # an unmatched quote.
240 | #
241 |
242 | eval "set -- $(
243 | printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" |
244 | xargs -n1 |
245 | sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' |
246 | tr '\n' ' '
247 | )" '"$@"'
248 |
249 | exec "$JAVACMD" "$@"
250 |
--------------------------------------------------------------------------------
/gradlew.bat:
--------------------------------------------------------------------------------
1 | @rem
2 | @rem Copyright 2015 the original author or authors.
3 | @rem
4 | @rem Licensed under the Apache License, Version 2.0 (the "License");
5 | @rem you may not use this file except in compliance with the License.
6 | @rem You may obtain a copy of the License at
7 | @rem
8 | @rem https://www.apache.org/licenses/LICENSE-2.0
9 | @rem
10 | @rem Unless required by applicable law or agreed to in writing, software
11 | @rem distributed under the License is distributed on an "AS IS" BASIS,
12 | @rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | @rem See the License for the specific language governing permissions and
14 | @rem limitations under the License.
15 | @rem
16 |
17 | @if "%DEBUG%"=="" @echo off
18 | @rem ##########################################################################
19 | @rem
20 | @rem Gradle startup script for Windows
21 | @rem
22 | @rem ##########################################################################
23 |
24 | @rem Set local scope for the variables with windows NT shell
25 | if "%OS%"=="Windows_NT" setlocal
26 |
27 | set DIRNAME=%~dp0
28 | if "%DIRNAME%"=="" set DIRNAME=.
29 | @rem This is normally unused
30 | set APP_BASE_NAME=%~n0
31 | set APP_HOME=%DIRNAME%
32 |
33 | @rem Resolve any "." and ".." in APP_HOME to make it shorter.
34 | for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi
35 |
36 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
37 | set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
38 |
39 | @rem Find java.exe
40 | if defined JAVA_HOME goto findJavaFromJavaHome
41 |
42 | set JAVA_EXE=java.exe
43 | %JAVA_EXE% -version >NUL 2>&1
44 | if %ERRORLEVEL% equ 0 goto execute
45 |
46 | echo.
47 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
48 | echo.
49 | echo Please set the JAVA_HOME variable in your environment to match the
50 | echo location of your Java installation.
51 |
52 | goto fail
53 |
54 | :findJavaFromJavaHome
55 | set JAVA_HOME=%JAVA_HOME:"=%
56 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe
57 |
58 | if exist "%JAVA_EXE%" goto execute
59 |
60 | echo.
61 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
62 | echo.
63 | echo Please set the JAVA_HOME variable in your environment to match the
64 | echo location of your Java installation.
65 |
66 | goto fail
67 |
68 | :execute
69 | @rem Setup the command line
70 |
71 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
72 |
73 |
74 | @rem Execute Gradle
75 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %*
76 |
77 | :end
78 | @rem End local scope for the variables with windows NT shell
79 | if %ERRORLEVEL% equ 0 goto mainEnd
80 |
81 | :fail
82 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
83 | rem the _cmd.exe /c_ return code!
84 | set EXIT_CODE=%ERRORLEVEL%
85 | if %EXIT_CODE% equ 0 set EXIT_CODE=1
86 | if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE%
87 | exit /b %EXIT_CODE%
88 |
89 | :mainEnd
90 | if "%OS%"=="Windows_NT" endlocal
91 |
92 | :omega
93 |
--------------------------------------------------------------------------------
/iosApp/iosApp.xcodeproj/project.pbxproj:
--------------------------------------------------------------------------------
1 | // !$*UTF8*$!
2 | {
3 | archiveVersion = 1;
4 | classes = {
5 | };
6 | objectVersion = 56;
7 | objects = {
8 |
9 | /* Begin PBXBuildFile section */
10 | A93A953B29CC810C00F8E227 /* iosApp.swift in Sources */ = {isa = PBXBuildFile; fileRef = A93A953A29CC810C00F8E227 /* iosApp.swift */; };
11 | A93A953F29CC810D00F8E227 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = A93A953E29CC810D00F8E227 /* Assets.xcassets */; };
12 | A93A954229CC810D00F8E227 /* Preview Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = A93A954129CC810D00F8E227 /* Preview Assets.xcassets */; };
13 | /* End PBXBuildFile section */
14 |
15 | /* Begin PBXFileReference section */
16 | A93A953729CC810C00F8E227 /* QRCodeDemo.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = QRCodeDemo.app; sourceTree = BUILT_PRODUCTS_DIR; };
17 | A93A953A29CC810C00F8E227 /* iosApp.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = iosApp.swift; sourceTree = ""; };
18 | A93A953E29CC810D00F8E227 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; };
19 | A93A954129CC810D00F8E227 /* Preview Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = "Preview Assets.xcassets"; sourceTree = ""; };
20 | /* End PBXFileReference section */
21 |
22 | /* Begin PBXFrameworksBuildPhase section */
23 | A93A953429CC810C00F8E227 /* Frameworks */ = {
24 | isa = PBXFrameworksBuildPhase;
25 | buildActionMask = 2147483647;
26 | files = (
27 | );
28 | runOnlyForDeploymentPostprocessing = 0;
29 | };
30 | /* End PBXFrameworksBuildPhase section */
31 |
32 | /* Begin PBXGroup section */
33 | A93A952E29CC810C00F8E227 = {
34 | isa = PBXGroup;
35 | children = (
36 | A93A953929CC810C00F8E227 /* iosApp */,
37 | A93A953829CC810C00F8E227 /* Products */,
38 | C4127409AE3703430489E7BC /* Frameworks */,
39 | );
40 | sourceTree = "";
41 | };
42 | A93A953829CC810C00F8E227 /* Products */ = {
43 | isa = PBXGroup;
44 | children = (
45 | A93A953729CC810C00F8E227 /* QRCodeDemo.app */,
46 | );
47 | name = Products;
48 | sourceTree = "";
49 | };
50 | A93A953929CC810C00F8E227 /* iosApp */ = {
51 | isa = PBXGroup;
52 | children = (
53 | A93A953A29CC810C00F8E227 /* iosApp.swift */,
54 | A93A953E29CC810D00F8E227 /* Assets.xcassets */,
55 | A93A954029CC810D00F8E227 /* Preview Content */,
56 | );
57 | path = iosApp;
58 | sourceTree = "";
59 | };
60 | A93A954029CC810D00F8E227 /* Preview Content */ = {
61 | isa = PBXGroup;
62 | children = (
63 | A93A954129CC810D00F8E227 /* Preview Assets.xcassets */,
64 | );
65 | path = "Preview Content";
66 | sourceTree = "";
67 | };
68 | C4127409AE3703430489E7BC /* Frameworks */ = {
69 | isa = PBXGroup;
70 | children = (
71 | );
72 | name = Frameworks;
73 | sourceTree = "";
74 | };
75 | /* End PBXGroup section */
76 |
77 | /* Begin PBXNativeTarget section */
78 | A93A953629CC810C00F8E227 /* iosApp */ = {
79 | isa = PBXNativeTarget;
80 | buildConfigurationList = A93A954529CC810D00F8E227 /* Build configuration list for PBXNativeTarget "iosApp" */;
81 | buildPhases = (
82 | A9D80A052AAB5CDE006C8738 /* ShellScript */,
83 | A93A953329CC810C00F8E227 /* Sources */,
84 | A93A953429CC810C00F8E227 /* Frameworks */,
85 | A93A953529CC810C00F8E227 /* Resources */,
86 | );
87 | buildRules = (
88 | );
89 | dependencies = (
90 | );
91 | name = iosApp;
92 | productName = iosApp;
93 | productReference = A93A953729CC810C00F8E227 /* QRCodeDemo.app */;
94 | productType = "com.apple.product-type.application";
95 | };
96 | /* End PBXNativeTarget section */
97 |
98 | /* Begin PBXProject section */
99 | A93A952F29CC810C00F8E227 /* Project object */ = {
100 | isa = PBXProject;
101 | attributes = {
102 | LastSwiftUpdateCheck = 1420;
103 | LastUpgradeCheck = 1420;
104 | TargetAttributes = {
105 | A93A953629CC810C00F8E227 = {
106 | CreatedOnToolsVersion = 14.2;
107 | };
108 | };
109 | };
110 | buildConfigurationList = A93A953229CC810C00F8E227 /* Build configuration list for PBXProject "iosApp" */;
111 | compatibilityVersion = "Xcode 14.0";
112 | developmentRegion = en;
113 | hasScannedForEncodings = 0;
114 | knownRegions = (
115 | en,
116 | Base,
117 | );
118 | mainGroup = A93A952E29CC810C00F8E227;
119 | productRefGroup = A93A953829CC810C00F8E227 /* Products */;
120 | projectDirPath = "";
121 | projectRoot = "";
122 | targets = (
123 | A93A953629CC810C00F8E227 /* iosApp */,
124 | );
125 | };
126 | /* End PBXProject section */
127 |
128 | /* Begin PBXResourcesBuildPhase section */
129 | A93A953529CC810C00F8E227 /* Resources */ = {
130 | isa = PBXResourcesBuildPhase;
131 | buildActionMask = 2147483647;
132 | files = (
133 | A93A954229CC810D00F8E227 /* Preview Assets.xcassets in Resources */,
134 | A93A953F29CC810D00F8E227 /* Assets.xcassets in Resources */,
135 | );
136 | runOnlyForDeploymentPostprocessing = 0;
137 | };
138 | /* End PBXResourcesBuildPhase section */
139 |
140 | /* Begin PBXShellScriptBuildPhase section */
141 | A9D80A052AAB5CDE006C8738 /* ShellScript */ = {
142 | isa = PBXShellScriptBuildPhase;
143 | buildActionMask = 12;
144 | files = (
145 | );
146 | inputFileListPaths = (
147 | );
148 | inputPaths = (
149 | );
150 | outputFileListPaths = (
151 | );
152 | outputPaths = (
153 | );
154 | runOnlyForDeploymentPostprocessing = 0;
155 | shellPath = /bin/sh;
156 | shellScript = "cd \"$SRCROOT/..\"\n./gradlew :composeApp:embedAndSignAppleFrameworkForXcode\n";
157 | };
158 | /* End PBXShellScriptBuildPhase section */
159 |
160 | /* Begin PBXSourcesBuildPhase section */
161 | A93A953329CC810C00F8E227 /* Sources */ = {
162 | isa = PBXSourcesBuildPhase;
163 | buildActionMask = 2147483647;
164 | files = (
165 | A93A953B29CC810C00F8E227 /* iosApp.swift in Sources */,
166 | );
167 | runOnlyForDeploymentPostprocessing = 0;
168 | };
169 | /* End PBXSourcesBuildPhase section */
170 |
171 | /* Begin XCBuildConfiguration section */
172 | A93A954329CC810D00F8E227 /* Debug */ = {
173 | isa = XCBuildConfiguration;
174 | buildSettings = {
175 | ALWAYS_SEARCH_USER_PATHS = NO;
176 | CLANG_ANALYZER_NONNULL = YES;
177 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
178 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++20";
179 | CLANG_ENABLE_MODULES = YES;
180 | CLANG_ENABLE_OBJC_ARC = YES;
181 | CLANG_ENABLE_OBJC_WEAK = YES;
182 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
183 | CLANG_WARN_BOOL_CONVERSION = YES;
184 | CLANG_WARN_COMMA = YES;
185 | CLANG_WARN_CONSTANT_CONVERSION = YES;
186 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
187 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
188 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
189 | CLANG_WARN_EMPTY_BODY = YES;
190 | CLANG_WARN_ENUM_CONVERSION = YES;
191 | CLANG_WARN_INFINITE_RECURSION = YES;
192 | CLANG_WARN_INT_CONVERSION = YES;
193 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
194 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
195 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
196 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
197 | CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
198 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
199 | CLANG_WARN_STRICT_PROTOTYPES = YES;
200 | CLANG_WARN_SUSPICIOUS_MOVE = YES;
201 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
202 | CLANG_WARN_UNREACHABLE_CODE = YES;
203 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
204 | COPY_PHASE_STRIP = NO;
205 | DEBUG_INFORMATION_FORMAT = dwarf;
206 | ENABLE_STRICT_OBJC_MSGSEND = YES;
207 | ENABLE_TESTABILITY = YES;
208 | GCC_C_LANGUAGE_STANDARD = gnu11;
209 | GCC_DYNAMIC_NO_PIC = NO;
210 | GCC_NO_COMMON_BLOCKS = YES;
211 | GCC_OPTIMIZATION_LEVEL = 0;
212 | GCC_PREPROCESSOR_DEFINITIONS = (
213 | "DEBUG=1",
214 | "$(inherited)",
215 | );
216 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
217 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
218 | GCC_WARN_UNDECLARED_SELECTOR = YES;
219 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
220 | GCC_WARN_UNUSED_FUNCTION = YES;
221 | GCC_WARN_UNUSED_VARIABLE = YES;
222 | IPHONEOS_DEPLOYMENT_TARGET = 16.2;
223 | MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
224 | MTL_FAST_MATH = YES;
225 | ONLY_ACTIVE_ARCH = YES;
226 | SDKROOT = iphoneos;
227 | SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG;
228 | SWIFT_OPTIMIZATION_LEVEL = "-Onone";
229 | };
230 | name = Debug;
231 | };
232 | A93A954429CC810D00F8E227 /* Release */ = {
233 | isa = XCBuildConfiguration;
234 | buildSettings = {
235 | ALWAYS_SEARCH_USER_PATHS = NO;
236 | CLANG_ANALYZER_NONNULL = YES;
237 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
238 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++20";
239 | CLANG_ENABLE_MODULES = YES;
240 | CLANG_ENABLE_OBJC_ARC = YES;
241 | CLANG_ENABLE_OBJC_WEAK = YES;
242 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
243 | CLANG_WARN_BOOL_CONVERSION = YES;
244 | CLANG_WARN_COMMA = YES;
245 | CLANG_WARN_CONSTANT_CONVERSION = YES;
246 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
247 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
248 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
249 | CLANG_WARN_EMPTY_BODY = YES;
250 | CLANG_WARN_ENUM_CONVERSION = YES;
251 | CLANG_WARN_INFINITE_RECURSION = YES;
252 | CLANG_WARN_INT_CONVERSION = YES;
253 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
254 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
255 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
256 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
257 | CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
258 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
259 | CLANG_WARN_STRICT_PROTOTYPES = YES;
260 | CLANG_WARN_SUSPICIOUS_MOVE = YES;
261 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
262 | CLANG_WARN_UNREACHABLE_CODE = YES;
263 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
264 | COPY_PHASE_STRIP = NO;
265 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
266 | ENABLE_NS_ASSERTIONS = NO;
267 | ENABLE_STRICT_OBJC_MSGSEND = YES;
268 | GCC_C_LANGUAGE_STANDARD = gnu11;
269 | GCC_NO_COMMON_BLOCKS = YES;
270 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
271 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
272 | GCC_WARN_UNDECLARED_SELECTOR = YES;
273 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
274 | GCC_WARN_UNUSED_FUNCTION = YES;
275 | GCC_WARN_UNUSED_VARIABLE = YES;
276 | IPHONEOS_DEPLOYMENT_TARGET = 16.2;
277 | MTL_ENABLE_DEBUG_INFO = NO;
278 | MTL_FAST_MATH = YES;
279 | SDKROOT = iphoneos;
280 | SWIFT_COMPILATION_MODE = wholemodule;
281 | SWIFT_OPTIMIZATION_LEVEL = "-O";
282 | VALIDATE_PRODUCT = YES;
283 | };
284 | name = Release;
285 | };
286 | A93A954629CC810D00F8E227 /* Debug */ = {
287 | isa = XCBuildConfiguration;
288 | buildSettings = {
289 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
290 | ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
291 | CODE_SIGN_IDENTITY = "Apple Development";
292 | CODE_SIGN_STYLE = Automatic;
293 | CURRENT_PROJECT_VERSION = 1;
294 | DEVELOPMENT_ASSET_PATHS = "\"iosApp/Preview Content\"";
295 | DEVELOPMENT_TEAM = "";
296 | ENABLE_PREVIEWS = YES;
297 | FRAMEWORK_SEARCH_PATHS = (
298 | "${inherited}",
299 | "$(SRCROOT)/../composeApp/build/xcode-frameworks/$(CONFIGURATION)/$(SDK_NAME)",
300 | );
301 | GENERATE_INFOPLIST_FILE = YES;
302 | INFOPLIST_KEY_NSCameraUsageDescription = "Use camera for scan qr code";
303 | INFOPLIST_KEY_NSPhotoLibraryUsageDescription = "Select photo from photo libraray";
304 | INFOPLIST_KEY_UIApplicationSceneManifest_Generation = YES;
305 | INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents = YES;
306 | INFOPLIST_KEY_UILaunchScreen_Generation = YES;
307 | INFOPLIST_KEY_UISupportedInterfaceOrientations_iPad = "UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight";
308 | INFOPLIST_KEY_UISupportedInterfaceOrientations_iPhone = "UIInterfaceOrientationPortrait UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight";
309 | LD_RUNPATH_SEARCH_PATHS = (
310 | "$(inherited)",
311 | "@executable_path/Frameworks",
312 | );
313 | MARKETING_VERSION = 1.0;
314 | OTHER_LDFLAGS = (
315 | "${inherited}",
316 | "-framework",
317 | ComposeApp,
318 | );
319 | PRODUCT_BUNDLE_IDENTIFIER = com.chaintech.app;
320 | PRODUCT_NAME = QRCodeDemo;
321 | PROVISIONING_PROFILE_SPECIFIER = "";
322 | SWIFT_EMIT_LOC_STRINGS = YES;
323 | SWIFT_VERSION = 5.0;
324 | TARGETED_DEVICE_FAMILY = "1,2";
325 | };
326 | name = Debug;
327 | };
328 | A93A954729CC810D00F8E227 /* Release */ = {
329 | isa = XCBuildConfiguration;
330 | buildSettings = {
331 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
332 | ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
333 | CODE_SIGN_IDENTITY = "Apple Development";
334 | CODE_SIGN_STYLE = Automatic;
335 | CURRENT_PROJECT_VERSION = 1;
336 | DEVELOPMENT_ASSET_PATHS = "\"iosApp/Preview Content\"";
337 | DEVELOPMENT_TEAM = "";
338 | ENABLE_PREVIEWS = YES;
339 | FRAMEWORK_SEARCH_PATHS = (
340 | "${inherited}",
341 | "$(SRCROOT)/../composeApp/build/xcode-frameworks/$(CONFIGURATION)/$(SDK_NAME)",
342 | );
343 | GENERATE_INFOPLIST_FILE = YES;
344 | INFOPLIST_KEY_NSCameraUsageDescription = "Use camera for scan qr code";
345 | INFOPLIST_KEY_NSPhotoLibraryUsageDescription = "Select photo from photo libraray";
346 | INFOPLIST_KEY_UIApplicationSceneManifest_Generation = YES;
347 | INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents = YES;
348 | INFOPLIST_KEY_UILaunchScreen_Generation = YES;
349 | INFOPLIST_KEY_UISupportedInterfaceOrientations_iPad = "UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight";
350 | INFOPLIST_KEY_UISupportedInterfaceOrientations_iPhone = "UIInterfaceOrientationPortrait UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight";
351 | LD_RUNPATH_SEARCH_PATHS = (
352 | "$(inherited)",
353 | "@executable_path/Frameworks",
354 | );
355 | MARKETING_VERSION = 1.0;
356 | OTHER_LDFLAGS = (
357 | "${inherited}",
358 | "-framework",
359 | ComposeApp,
360 | );
361 | PRODUCT_BUNDLE_IDENTIFIER = com.chaintech.app;
362 | PRODUCT_NAME = QRCodeDemo;
363 | PROVISIONING_PROFILE_SPECIFIER = "";
364 | SWIFT_EMIT_LOC_STRINGS = YES;
365 | SWIFT_VERSION = 5.0;
366 | TARGETED_DEVICE_FAMILY = "1,2";
367 | };
368 | name = Release;
369 | };
370 | /* End XCBuildConfiguration section */
371 |
372 | /* Begin XCConfigurationList section */
373 | A93A953229CC810C00F8E227 /* Build configuration list for PBXProject "iosApp" */ = {
374 | isa = XCConfigurationList;
375 | buildConfigurations = (
376 | A93A954329CC810D00F8E227 /* Debug */,
377 | A93A954429CC810D00F8E227 /* Release */,
378 | );
379 | defaultConfigurationIsVisible = 0;
380 | defaultConfigurationName = Release;
381 | };
382 | A93A954529CC810D00F8E227 /* Build configuration list for PBXNativeTarget "iosApp" */ = {
383 | isa = XCConfigurationList;
384 | buildConfigurations = (
385 | A93A954629CC810D00F8E227 /* Debug */,
386 | A93A954729CC810D00F8E227 /* Release */,
387 | );
388 | defaultConfigurationIsVisible = 0;
389 | defaultConfigurationName = Release;
390 | };
391 | /* End XCConfigurationList section */
392 | };
393 | rootObject = A93A952F29CC810C00F8E227 /* Project object */;
394 | }
395 |
--------------------------------------------------------------------------------
/iosApp/iosApp.xcodeproj/project.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/iosApp/iosApp.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | IDEDidComputeMac32BitWarning
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/iosApp/iosApp/Assets.xcassets/AccentColor.colorset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "colors" : [
3 | {
4 | "idiom" : "universal"
5 | }
6 | ],
7 | "info" : {
8 | "author" : "xcode",
9 | "version" : 1
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/iosApp/iosApp/Assets.xcassets/AppIcon.appiconset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "platform" : "ios",
6 | "size" : "1024x1024"
7 | }
8 | ],
9 | "info" : {
10 | "author" : "xcode",
11 | "version" : 1
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/iosApp/iosApp/Assets.xcassets/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "info" : {
3 | "author" : "xcode",
4 | "version" : 1
5 | }
6 | }
7 |
--------------------------------------------------------------------------------
/iosApp/iosApp/Preview Content/Preview Assets.xcassets/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "info" : {
3 | "author" : "xcode",
4 | "version" : 1
5 | }
6 | }
7 |
--------------------------------------------------------------------------------
/iosApp/iosApp/iosApp.swift:
--------------------------------------------------------------------------------
1 | import UIKit
2 | import SwiftUI
3 | import ComposeApp
4 |
5 | @main
6 | struct iosApp: App {
7 | var body: some Scene {
8 | WindowGroup {
9 | ContentView()
10 | }
11 | }
12 | }
13 |
14 | struct ContentView: View {
15 | var body: some View {
16 | ComposeView().ignoresSafeArea(.all)
17 | }
18 | }
19 |
20 | struct ComposeView: UIViewControllerRepresentable {
21 | func makeUIViewController(context: Context) -> UIViewController {
22 | MainKt.MainViewController()
23 | }
24 |
25 | func updateUIViewController(_ uiViewController: UIViewController, context: Context) {}
26 | }
27 |
--------------------------------------------------------------------------------
/settings.gradle.kts:
--------------------------------------------------------------------------------
1 | rootProject.name = "QRCodeDemo"
2 | include(":composeApp")
3 |
4 | pluginManagement {
5 | repositories {
6 | google()
7 | gradlePluginPortal()
8 | mavenCentral()
9 | }
10 | }
11 |
12 | dependencyResolutionManagement {
13 | repositories {
14 | google()
15 | mavenCentral()
16 | }
17 | }
18 |
--------------------------------------------------------------------------------