From 2feee4c266c622a258e548ae10e1529f9ccd3bab Mon Sep 17 00:00:00 2001 From: fankesyooni Date: Tue, 31 Oct 2023 03:07:47 +0800 Subject: [PATCH] feat: support compose multiplatform --- .editorconfig | 17 + .github/workflows/publish.yml | 40 - .github/workflows/static-analysis.yml | 47 -- .gitignore | 10 +- .idea/.gitignore | 4 +- .idea/appInsightsSettings.xml | 26 + .idea/codeStyles/Project.xml | 205 ------ .idea/codeStyles/codeStyleConfig.xml | 5 - .idea/deploymentTargetDropDown.xml | 10 + .idea/gradle.xml | 35 - .../ic_launcher.png => .idea/icon.png | Bin .idea/inspectionProfiles/Project_Default.xml | 10 + .idea/kotlinc.xml | 6 + .idea/ktlint.xml | 6 + .idea/misc.xml | 16 - .idea/vcs.xml | 2 +- README.md | 137 +--- build-logic/convention/build.gradle.kts | 19 - .../kotlin/JvmToolchainConventionPlugin.kt | 18 - .../main/kotlin/utils/ProjectExtensions.kt | 9 - build-logic/settings.gradle.kts | 18 - build.gradle.kts | 27 +- config/detekt/detekt.yml | 684 ------------------ demo/build.gradle.kts | 61 -- .../kotlin/eu/wewox/pagecurl/MainActivity.kt | 63 -- gradle.properties | 63 +- gradle/libs.versions.toml | 34 - .../sweet-dependency-config.yaml | 65 ++ gradle/wrapper/gradle-wrapper.properties | 5 +- gradlew.bat | 178 ++--- pagecurl/build.gradle.kts | 75 +- pagecurl/src/androidMain/AndroidManifest.xml | 2 + .../wewox/pagecurl/page/CurlDraw.android.kt | 9 + .../pagecurl/page/CurlGesture.android.kt | 3 + .../wewox/pagecurl/ExperimentalPageCurlApi.kt | 0 .../wewox/pagecurl/config/PageCurlConfig.kt | 2 +- .../kotlin/eu/wewox/pagecurl/page/CurlDraw.kt | 63 +- .../eu/wewox/pagecurl/page/CurlGesture.kt | 78 +- .../kotlin/eu/wewox/pagecurl/page/PageCurl.kt | 0 .../eu/wewox/pagecurl/page/PageCurlState.kt | 0 .../eu/wewox/pagecurl/page/TapGesture.kt | 51 ++ .../eu/wewox/pagecurl/utils/MathUtils.kt | 0 .../kotlin/eu/wewox/pagecurl/utils/Polygon.kt | 0 .../eu/wewox/pagecurl/utils/RectUtils.kt | 0 .../wewox/pagecurl/page/CurlDraw.desktop.kt | 10 + .../pagecurl/page/CurlGesture.desktop.kt | 3 + .../eu/wewox/pagecurl/page/CurlDraw.ios.kt | 10 + .../eu/wewox/pagecurl/page/CurlGesture.ios.kt | 13 + pagecurl/src/main/AndroidManifest.xml | 2 - .../eu/wewox/pagecurl/page/TapGesture.kt | 53 -- {build-logic => samples}/.gitignore | 0 .../androidApp}/.gitignore | 0 samples/androidApp/build.gradle.kts | 45 ++ .../androidApp}/proguard-rules.pro | 2 +- .../src/androidMain}/AndroidManifest.xml | 3 +- .../androidMain}/ic_launcher-playstore.png | Bin .../kotlin/eu/wewox/pagecurl/MainActivity.kt | 26 + .../res/drawable/ic_launcher_foreground.xml | 0 .../src/androidMain}/res/drawable/img_sit.jpg | Bin .../androidMain}/res/drawable/img_sleep.jpg | Bin .../res/mipmap-anydpi-v26/ic_launcher.xml | 0 .../mipmap-anydpi-v26/ic_launcher_round.xml | 0 .../res/mipmap-hdpi/ic_launcher.png | Bin .../res/mipmap-hdpi/ic_launcher_round.png | Bin .../res/mipmap-mdpi/ic_launcher.png | Bin .../res/mipmap-mdpi/ic_launcher_round.png | Bin .../res/mipmap-xhdpi/ic_launcher.png | Bin .../res/mipmap-xhdpi/ic_launcher_round.png | Bin .../res/mipmap-xxhdpi/ic_launcher.png | Bin 0 -> 3829 bytes .../res/mipmap-xxhdpi/ic_launcher_round.png | Bin .../res/mipmap-xxxhdpi/ic_launcher.png | Bin .../res/mipmap-xxxhdpi/ic_launcher_round.png | Bin .../src/androidMain}/res/values/colors.xml | 0 .../src/androidMain}/res/values/strings.xml | 0 .../src/androidMain}/res/values/themes.xml | 0 {demo => samples/desktopApp}/.gitignore | 0 samples/desktopApp/build.gradle.kts | 29 + .../kotlin/eu/wewox/pagecurl/Main.kt | 14 + samples/iosApp/.gitignore | 6 + samples/iosApp/Configuration/Config.xcconfig | 3 + .../iosApp/iosApp.xcodeproj/project.pbxproj | 400 ++++++++++ .../xcshareddata/IDEWorkspaceChecks.plist | 8 + .../AccentColor.colorset/Contents.json | 11 + .../AppIcon.appiconset/Contents.json | 14 + .../AppIcon.appiconset/app-icon-512.png | Bin 0 -> 17077 bytes .../iosApp/Assets.xcassets/Contents.json | 6 + samples/iosApp/iosApp/ContentView.swift | 19 + samples/iosApp/iosApp/Info.plist | 50 ++ .../Preview Assets.xcassets/Contents.json | 6 + samples/iosApp/iosApp/iOSApp.swift | 10 + samples/shared/.gitignore | 1 + samples/shared/build.gradle.kts | 87 +++ .../kotlin/eu/wewox/pagecurl/App.android.kt | 8 + .../kotlin/eu/wewox/pagecurl/App.kt | 62 ++ .../kotlin/eu/wewox/pagecurl/Example.kt | 0 .../kotlin/eu/wewox/pagecurl/HowToPageData.kt | 0 .../kotlin/eu/wewox/pagecurl/RootScreen.kt | 0 .../eu/wewox/pagecurl/components/HowToPage.kt | 0 .../pagecurl/components/SettingsPopup.kt | 3 - .../eu/wewox/pagecurl/components/TopBar.kt | 0 .../pagecurl/components/ZoomOutLayout.kt | 3 - .../screens/BackPagePageCurlScreen.kt | 2 - .../screens/InteractionConfigInPageCurl.kt | 3 - .../pagecurl/screens/PagingPageCurlScreen.kt | 5 +- .../screens/SettingsPageCurlScreen.kt | 3 - .../screens/ShadowInPageCurlScreen.kt | 2 - .../pagecurl/screens/SimplePageCurlScreen.kt | 3 - .../pagecurl/screens/StateInPageCurlScreen.kt | 3 - .../kotlin/eu/wewox/pagecurl/ui/Spacing.kt | 0 .../eu/wewox/pagecurl/ui/theme/Color.kt | 0 .../eu/wewox/pagecurl/ui/theme/Theme.kt | 0 .../kotlin/eu/wewox/pagecurl/App.desktop.kt | 13 + samples/shared/src/iosMain/kotlin/Main.ios.kt | 6 + .../kotlin/eu/wewox/pagecurl/App.ios.kt | 13 + settings.gradle.kts | 28 +- 115 files changed, 1362 insertions(+), 1729 deletions(-) create mode 100644 .editorconfig delete mode 100644 .github/workflows/publish.yml delete mode 100644 .github/workflows/static-analysis.yml create mode 100644 .idea/appInsightsSettings.xml delete mode 100644 .idea/codeStyles/Project.xml delete mode 100644 .idea/codeStyles/codeStyleConfig.xml create mode 100644 .idea/deploymentTargetDropDown.xml delete mode 100644 .idea/gradle.xml rename demo/src/main/res/mipmap-xxhdpi/ic_launcher.png => .idea/icon.png (100%) create mode 100644 .idea/inspectionProfiles/Project_Default.xml create mode 100644 .idea/kotlinc.xml create mode 100644 .idea/ktlint.xml delete mode 100644 .idea/misc.xml delete mode 100644 build-logic/convention/build.gradle.kts delete mode 100644 build-logic/convention/src/main/kotlin/JvmToolchainConventionPlugin.kt delete mode 100644 build-logic/convention/src/main/kotlin/utils/ProjectExtensions.kt delete mode 100644 build-logic/settings.gradle.kts delete mode 100644 config/detekt/detekt.yml delete mode 100644 demo/build.gradle.kts delete mode 100644 demo/src/main/kotlin/eu/wewox/pagecurl/MainActivity.kt delete mode 100644 gradle/libs.versions.toml create mode 100644 gradle/sweet-dependency/sweet-dependency-config.yaml create mode 100644 pagecurl/src/androidMain/AndroidManifest.xml create mode 100644 pagecurl/src/androidMain/kotlin/eu/wewox/pagecurl/page/CurlDraw.android.kt create mode 100644 pagecurl/src/androidMain/kotlin/eu/wewox/pagecurl/page/CurlGesture.android.kt rename pagecurl/src/{main => commonMain}/kotlin/eu/wewox/pagecurl/ExperimentalPageCurlApi.kt (100%) rename pagecurl/src/{main => commonMain}/kotlin/eu/wewox/pagecurl/config/PageCurlConfig.kt (99%) rename pagecurl/src/{main => commonMain}/kotlin/eu/wewox/pagecurl/page/CurlDraw.kt (85%) rename pagecurl/src/{main => commonMain}/kotlin/eu/wewox/pagecurl/page/CurlGesture.kt (60%) rename pagecurl/src/{main => commonMain}/kotlin/eu/wewox/pagecurl/page/PageCurl.kt (100%) rename pagecurl/src/{main => commonMain}/kotlin/eu/wewox/pagecurl/page/PageCurlState.kt (100%) create mode 100644 pagecurl/src/commonMain/kotlin/eu/wewox/pagecurl/page/TapGesture.kt rename pagecurl/src/{main => commonMain}/kotlin/eu/wewox/pagecurl/utils/MathUtils.kt (100%) rename pagecurl/src/{main => commonMain}/kotlin/eu/wewox/pagecurl/utils/Polygon.kt (100%) rename pagecurl/src/{main => commonMain}/kotlin/eu/wewox/pagecurl/utils/RectUtils.kt (100%) create mode 100644 pagecurl/src/desktopMain/kotlin/eu/wewox/pagecurl/page/CurlDraw.desktop.kt create mode 100644 pagecurl/src/desktopMain/kotlin/eu/wewox/pagecurl/page/CurlGesture.desktop.kt create mode 100644 pagecurl/src/iosMain/kotlin/eu/wewox/pagecurl/page/CurlDraw.ios.kt create mode 100644 pagecurl/src/iosMain/kotlin/eu/wewox/pagecurl/page/CurlGesture.ios.kt delete mode 100644 pagecurl/src/main/AndroidManifest.xml delete mode 100644 pagecurl/src/main/kotlin/eu/wewox/pagecurl/page/TapGesture.kt rename {build-logic => samples}/.gitignore (100%) rename {build-logic/convention => samples/androidApp}/.gitignore (100%) create mode 100644 samples/androidApp/build.gradle.kts rename {demo => samples/androidApp}/proguard-rules.pro (88%) rename {demo/src/main => samples/androidApp/src/androidMain}/AndroidManifest.xml (95%) rename {demo/src/main => samples/androidApp/src/androidMain}/ic_launcher-playstore.png (100%) create mode 100644 samples/androidApp/src/androidMain/kotlin/eu/wewox/pagecurl/MainActivity.kt rename {demo/src/main => samples/androidApp/src/androidMain}/res/drawable/ic_launcher_foreground.xml (100%) rename {demo/src/main => samples/androidApp/src/androidMain}/res/drawable/img_sit.jpg (100%) rename {demo/src/main => samples/androidApp/src/androidMain}/res/drawable/img_sleep.jpg (100%) rename {demo/src/main => samples/androidApp/src/androidMain}/res/mipmap-anydpi-v26/ic_launcher.xml (100%) rename {demo/src/main => samples/androidApp/src/androidMain}/res/mipmap-anydpi-v26/ic_launcher_round.xml (100%) rename {demo/src/main => samples/androidApp/src/androidMain}/res/mipmap-hdpi/ic_launcher.png (100%) rename {demo/src/main => samples/androidApp/src/androidMain}/res/mipmap-hdpi/ic_launcher_round.png (100%) rename {demo/src/main => samples/androidApp/src/androidMain}/res/mipmap-mdpi/ic_launcher.png (100%) rename {demo/src/main => samples/androidApp/src/androidMain}/res/mipmap-mdpi/ic_launcher_round.png (100%) rename {demo/src/main => samples/androidApp/src/androidMain}/res/mipmap-xhdpi/ic_launcher.png (100%) rename {demo/src/main => samples/androidApp/src/androidMain}/res/mipmap-xhdpi/ic_launcher_round.png (100%) create mode 100644 samples/androidApp/src/androidMain/res/mipmap-xxhdpi/ic_launcher.png rename {demo/src/main => samples/androidApp/src/androidMain}/res/mipmap-xxhdpi/ic_launcher_round.png (100%) rename {demo/src/main => samples/androidApp/src/androidMain}/res/mipmap-xxxhdpi/ic_launcher.png (100%) rename {demo/src/main => samples/androidApp/src/androidMain}/res/mipmap-xxxhdpi/ic_launcher_round.png (100%) rename {demo/src/main => samples/androidApp/src/androidMain}/res/values/colors.xml (100%) rename {demo/src/main => samples/androidApp/src/androidMain}/res/values/strings.xml (100%) rename {demo/src/main => samples/androidApp/src/androidMain}/res/values/themes.xml (100%) rename {demo => samples/desktopApp}/.gitignore (100%) create mode 100644 samples/desktopApp/build.gradle.kts create mode 100644 samples/desktopApp/src/desktopMain/kotlin/eu/wewox/pagecurl/Main.kt create mode 100644 samples/iosApp/.gitignore create mode 100644 samples/iosApp/Configuration/Config.xcconfig create mode 100644 samples/iosApp/iosApp.xcodeproj/project.pbxproj create mode 100644 samples/iosApp/iosApp.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist create mode 100644 samples/iosApp/iosApp/Assets.xcassets/AccentColor.colorset/Contents.json create mode 100644 samples/iosApp/iosApp/Assets.xcassets/AppIcon.appiconset/Contents.json create mode 100644 samples/iosApp/iosApp/Assets.xcassets/AppIcon.appiconset/app-icon-512.png create mode 100644 samples/iosApp/iosApp/Assets.xcassets/Contents.json create mode 100644 samples/iosApp/iosApp/ContentView.swift create mode 100644 samples/iosApp/iosApp/Info.plist create mode 100644 samples/iosApp/iosApp/Preview Content/Preview Assets.xcassets/Contents.json create mode 100644 samples/iosApp/iosApp/iOSApp.swift create mode 100644 samples/shared/.gitignore create mode 100644 samples/shared/build.gradle.kts create mode 100644 samples/shared/src/androidMain/kotlin/eu/wewox/pagecurl/App.android.kt create mode 100644 samples/shared/src/commonMain/kotlin/eu/wewox/pagecurl/App.kt rename {demo/src/main => samples/shared/src/commonMain}/kotlin/eu/wewox/pagecurl/Example.kt (100%) rename {demo/src/main => samples/shared/src/commonMain}/kotlin/eu/wewox/pagecurl/HowToPageData.kt (100%) rename {demo/src/main => samples/shared/src/commonMain}/kotlin/eu/wewox/pagecurl/RootScreen.kt (100%) rename {demo/src/main => samples/shared/src/commonMain}/kotlin/eu/wewox/pagecurl/components/HowToPage.kt (100%) rename {demo/src/main => samples/shared/src/commonMain}/kotlin/eu/wewox/pagecurl/components/SettingsPopup.kt (97%) rename {demo/src/main => samples/shared/src/commonMain}/kotlin/eu/wewox/pagecurl/components/TopBar.kt (100%) rename {demo/src/main => samples/shared/src/commonMain}/kotlin/eu/wewox/pagecurl/components/ZoomOutLayout.kt (97%) rename {demo/src/main => samples/shared/src/commonMain}/kotlin/eu/wewox/pagecurl/screens/BackPagePageCurlScreen.kt (98%) rename {demo/src/main => samples/shared/src/commonMain}/kotlin/eu/wewox/pagecurl/screens/InteractionConfigInPageCurl.kt (98%) rename {demo/src/main => samples/shared/src/commonMain}/kotlin/eu/wewox/pagecurl/screens/PagingPageCurlScreen.kt (96%) rename {demo/src/main => samples/shared/src/commonMain}/kotlin/eu/wewox/pagecurl/screens/SettingsPageCurlScreen.kt (95%) rename {demo/src/main => samples/shared/src/commonMain}/kotlin/eu/wewox/pagecurl/screens/ShadowInPageCurlScreen.kt (97%) rename {demo/src/main => samples/shared/src/commonMain}/kotlin/eu/wewox/pagecurl/screens/SimplePageCurlScreen.kt (87%) rename {demo/src/main => samples/shared/src/commonMain}/kotlin/eu/wewox/pagecurl/screens/StateInPageCurlScreen.kt (97%) rename {demo/src/main => samples/shared/src/commonMain}/kotlin/eu/wewox/pagecurl/ui/Spacing.kt (100%) rename {demo/src/main => samples/shared/src/commonMain}/kotlin/eu/wewox/pagecurl/ui/theme/Color.kt (100%) rename {demo/src/main => samples/shared/src/commonMain}/kotlin/eu/wewox/pagecurl/ui/theme/Theme.kt (100%) create mode 100644 samples/shared/src/desktopMain/kotlin/eu/wewox/pagecurl/App.desktop.kt create mode 100644 samples/shared/src/iosMain/kotlin/Main.ios.kt create mode 100644 samples/shared/src/iosMain/kotlin/eu/wewox/pagecurl/App.ios.kt diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 0000000..7101007 --- /dev/null +++ b/.editorconfig @@ -0,0 +1,17 @@ +# noinspection EditorConfigKeyCorrectness +[{*.kt,*.kts}] +ktlint_standard_annotation = disabled +ktlint_standard_filename = disabled +ktlint_standard_wrapping = disabled +ktlint_standard_import-ordering = enabled +ktlint_standard_max-line-length = disabled +ktlint_standard_multiline-if-else = disabled +ktlint_standard_argument-list-wrapping = disabled +ktlint_standard_parameter-list-wrapping = disabled +ktlint_standard_trailing-comma-on-declaration-site = disabled +ktlint_function_signature_body_expression_wrapping = multiline +ij_continuation_indent_size = 2 +indent_size = 4 +indent_style = space +insert_final_newline = false +max_line_length = 150 \ No newline at end of file diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml deleted file mode 100644 index 386c86b..0000000 --- a/.github/workflows/publish.yml +++ /dev/null @@ -1,40 +0,0 @@ -# This is a basic workflow to help you get started with Actions - -name: Publish To Maven Central - -# Controls when the workflow will run -on: - # Triggers the workflow when tag is pushed - push: - tags: - - 'v*' - - # Allows you to run this workflow manually from the Actions tab - workflow_dispatch: - -# A workflow run is made up of one or more jobs that can run sequentially or in parallel -jobs: - # This workflow contains a single job called "publish" - publish: - # The type of runner that the job will run on - runs-on: macos-latest - - # Steps represent a sequence of tasks that will be executed as part of the job - steps: - # Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it - - uses: actions/checkout@v3 - - name: Set up JDK 17 - uses: actions/setup-java@v3 - with: - java-version: '17' - distribution: 'temurin' - - # Runs a single command using the runners shell - - name: publish - run: ./gradlew publish --no-daemon --no-parallel - env: - ORG_GRADLE_PROJECT_mavenCentralUsername: ${{ secrets.MAVEN_CENTRAL_USERNAME }} - ORG_GRADLE_PROJECT_mavenCentralPassword: ${{ secrets.MAVEN_CENTRAL_PASSWORD }} - ORG_GRADLE_PROJECT_signingInMemoryKey: ${{ secrets.SIGNING_KEY }} - ORG_GRADLE_PROJECT_signingInMemoryKeyId: ${{ secrets.SIGNING_KEY_ID }} - ORG_GRADLE_PROJECT_signingInMemoryKeyPassword: ${{ secrets.SIGNING_KEY_PASSWORD }} diff --git a/.github/workflows/static-analysis.yml b/.github/workflows/static-analysis.yml deleted file mode 100644 index 370c0c3..0000000 --- a/.github/workflows/static-analysis.yml +++ /dev/null @@ -1,47 +0,0 @@ -# This is a workflow to verify PRs with static code analysis tools -name: Static Analysis - -# Controls when the workflow will run -on: - pull_request: - branches: [main] - - # Allows you to run this workflow manually from the Actions tab - workflow_dispatch: - -jobs: - detekt: - name: Detekt - runs-on: macos-latest - - # Steps represent a sequence of tasks that will be executed as part of the job - steps: - # Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it - - uses: actions/checkout@v3 - - name: Set up JDK 17 - uses: actions/setup-java@v3 - with: - java-version: '17' - distribution: 'temurin' - - # Runs a single command using the runners shell - - name: detekt - run: ./gradlew detekt - - spotless: - name: Spotless - runs-on: macos-latest - - # Steps represent a sequence of tasks that will be executed as part of the job - steps: - # Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it - - uses: actions/checkout@v3 - - name: Set up JDK 17 - uses: actions/setup-java@v3 - with: - java-version: '17' - distribution: 'temurin' - - # Runs a single command using the runners shell - - name: spotless - run: ./gradlew spotlessCheck diff --git a/.gitignore b/.gitignore index e44d96a..aa724b7 100644 --- a/.gitignore +++ b/.gitignore @@ -1,9 +1,15 @@ *.iml .gradle /local.properties -/.idea +/.idea/caches +/.idea/libraries +/.idea/modules.xml +/.idea/workspace.xml +/.idea/navEditor.xml +/.idea/assetWizardSettings.xml .DS_Store -build/ +/build /captures .externalNativeBuild .cxx +local.properties diff --git a/.idea/.gitignore b/.idea/.gitignore index 26d3352..3ad4a12 100644 --- a/.idea/.gitignore +++ b/.idea/.gitignore @@ -1,3 +1,5 @@ # Default ignored files /shelf/ -/workspace.xml +/gradle.xml +/misc.xml +/workspace.xml \ No newline at end of file diff --git a/.idea/appInsightsSettings.xml b/.idea/appInsightsSettings.xml new file mode 100644 index 0000000..371f2e2 --- /dev/null +++ b/.idea/appInsightsSettings.xml @@ -0,0 +1,26 @@ + + + + + + \ No newline at end of file diff --git a/.idea/codeStyles/Project.xml b/.idea/codeStyles/Project.xml deleted file mode 100644 index 1b4dd5a..0000000 --- a/.idea/codeStyles/Project.xml +++ /dev/null @@ -1,205 +0,0 @@ - - - - \ No newline at end of file diff --git a/.idea/codeStyles/codeStyleConfig.xml b/.idea/codeStyles/codeStyleConfig.xml deleted file mode 100644 index 79ee123..0000000 --- a/.idea/codeStyles/codeStyleConfig.xml +++ /dev/null @@ -1,5 +0,0 @@ - - - - \ No newline at end of file diff --git a/.idea/deploymentTargetDropDown.xml b/.idea/deploymentTargetDropDown.xml new file mode 100644 index 0000000..b1d56a7 --- /dev/null +++ b/.idea/deploymentTargetDropDown.xml @@ -0,0 +1,10 @@ + + + + + + + + + + \ No newline at end of file diff --git a/.idea/gradle.xml b/.idea/gradle.xml deleted file mode 100644 index 10965d5..0000000 --- a/.idea/gradle.xml +++ /dev/null @@ -1,35 +0,0 @@ - - - - - - - \ No newline at end of file diff --git a/demo/src/main/res/mipmap-xxhdpi/ic_launcher.png b/.idea/icon.png similarity index 100% rename from demo/src/main/res/mipmap-xxhdpi/ic_launcher.png rename to .idea/icon.png diff --git a/.idea/inspectionProfiles/Project_Default.xml b/.idea/inspectionProfiles/Project_Default.xml new file mode 100644 index 0000000..146ab09 --- /dev/null +++ b/.idea/inspectionProfiles/Project_Default.xml @@ -0,0 +1,10 @@ + + + + \ No newline at end of file diff --git a/.idea/kotlinc.xml b/.idea/kotlinc.xml new file mode 100644 index 0000000..f8467b4 --- /dev/null +++ b/.idea/kotlinc.xml @@ -0,0 +1,6 @@ + + + + + \ No newline at end of file diff --git a/.idea/ktlint.xml b/.idea/ktlint.xml new file mode 100644 index 0000000..92c4441 --- /dev/null +++ b/.idea/ktlint.xml @@ -0,0 +1,6 @@ + + + + false + + \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml deleted file mode 100644 index c9a2cd7..0000000 --- a/.idea/misc.xml +++ /dev/null @@ -1,16 +0,0 @@ - - - - - - - - - - \ No newline at end of file diff --git a/.idea/vcs.xml b/.idea/vcs.xml index 94a25f7..35eb1dd 100644 --- a/.idea/vcs.xml +++ b/.idea/vcs.xml @@ -1,6 +1,6 @@ - + \ No newline at end of file diff --git a/README.md b/README.md index 2e90b9c..da2d3fa 100644 --- a/README.md +++ b/README.md @@ -1,10 +1,18 @@ [![Maven Central](https://img.shields.io/maven-central/v/io.github.oleksandrbalan/pagecurl.svg?label=Maven%20Central)](https://mvnrepository.com/artifact/io.github.oleksandrbalan/pagecurl) - +LOGO -# Page Curl +# Page Curl (Multiplatform) -Page Curl library for Jetpack Compose. +Page Curl library for Jetpack Compose Multiplatform. + +Support for Android, iOS, Desktop (JVM): + +SHOT + +> Note + +This is just an attempt at multiplatform porting, and there may still be some problems. ## Motivation @@ -12,122 +20,19 @@ This library allows to create an effect of turning pages, which can be used in b ## Usage -### Get a dependency +> Note -**Step 1.** Add the MavenCentral repository to your build file. -Add it in your root `build.gradle.kts` at the end of repositories: -```kotlin -allprojects { - repositories { - ... - mavenCentral() - } -} -``` +This multiplatform library's artifact is not upload to any repositories, +you can clone this repository or use git submodule to use it. -Or in `settings.gradle.kts`: -```kotlin -pluginManagement { - repositories { - ... - mavenCentral() - } -} -``` +For an Android version and a sample usage, please visit: https://github.com/oleksandrbalan/pagecurl. -**Step 2.** Add the dependency. -Check latest version on the [releases page](https://github.com/oleksandrbalan/pagecurl/releases). -```kotlin -dependencies { - implementation("io.github.oleksandrbalan:pagecurl:$version") -} -``` +See Demo application +and [examples](https://github.com/fankes/pagecurl/blob/multiplatform/samples/shared/src/commonMain/kotlin/eu/wewox/pagecurl/screens) for more usage +examples. -### Use in Composable +## Thanks -The `PageCurl` has 2 mandatory arguments: -* **count** - The count of pages. -* **content** - The content lambda to provide the page composable. Receives the page number. +[The compose multiplatform shadows way](https://github.com/oleksandrbalan/pagecurl/issues/23#issuecomment-1767145310) -``` -val pages = listOf("One", "Two", "Three") -PageCurl(count = pages.size) { index -> - Box( - contentAlignment = Alignment.Center, - modifier = Modifier - .background(MaterialTheme.colors.background) - .fillMaxSize() - ) { - Text( - text = pages[index], - style = MaterialTheme.typography.h1, - ) - } -} -``` - -Optionally `state` could be provided to observe and manage PageCurl state. -* **state** - The state of the PageCurl. Use it to programmatically change the current page or observe changes, and to configure shadow, back-page and interactions. -``` -Column { - val scope = rememberCoroutineScope() - val state = rememberPageCurlState() - Button(onClick = { scope.launch { state.next() } }) { - Text(text = "Next") - } - - val pages = listOf("One", "Two", "Three") - PageCurl( - count = pages.size, - state = state, - ) { index -> - Box( - contentAlignment = Alignment.Center, - modifier = Modifier - .background(MaterialTheme.colors.background) - .fillMaxSize() - ) { - Text( - text = pages[index], - style = MaterialTheme.typography.h1, - ) - } - } -} -``` - -Optionally `key` lambda could be provided with stable key for each item. PageCurl with keys for each page will correctly preserve a current position when items are added or removed. -* **key** - The lambda to provide stable key for each item. Useful when adding and removing items before current page. -``` -Column { - var pages by remember { mutableStateOf(listOf("Four", "Five", "Six")) } - Button(onClick = { pages = listOf("One", "Two", "Three") + pages }) { - Text(text = "Prepend new pages") - } - - PageCurl( - count = pages.size, - key = { pages[it].hashCode() }, - ) { index -> - Box( - contentAlignment = Alignment.Center, - modifier = Modifier - .background(MaterialTheme.colors.background) - .fillMaxSize() - ) { - Text( - text = pages[index], - style = MaterialTheme.typography.h1, - ) - } - } -} -``` - -See Demo application and [examples](demo/src/main/kotlin/eu/wewox/pagecurl/screens) for more usage examples. - -https://user-images.githubusercontent.com/20944869/185782671-2861c2ed-c033-4318-bf12-1d8db74fc8b5.mp4 - -https://user-images.githubusercontent.com/20944869/185782668-b52da2b9-be8d-49db-8729-88b6f9a8ee48.mp4 - -https://user-images.githubusercontent.com/20944869/185782663-4bd97a57-1a46-408d-a07b-34c193f01aba.mp4 +[Multiplatform Paging](https://github.com/cashapp/multiplatform-paging) \ No newline at end of file diff --git a/build-logic/convention/build.gradle.kts b/build-logic/convention/build.gradle.kts deleted file mode 100644 index a21a774..0000000 --- a/build-logic/convention/build.gradle.kts +++ /dev/null @@ -1,19 +0,0 @@ -plugins { - `kotlin-dsl` -} - -java { - toolchain { - val version = libs.versions.java.toolchain.get() - languageVersion.set(JavaLanguageVersion.of(version)) - } -} - -gradlePlugin { - plugins { - register("conventionJvmToolchain") { - id = "convention.jvm.toolchain" - implementationClass = "JvmToolchainConventionPlugin" - } - } -} diff --git a/build-logic/convention/src/main/kotlin/JvmToolchainConventionPlugin.kt b/build-logic/convention/src/main/kotlin/JvmToolchainConventionPlugin.kt deleted file mode 100644 index 8ee9599..0000000 --- a/build-logic/convention/src/main/kotlin/JvmToolchainConventionPlugin.kt +++ /dev/null @@ -1,18 +0,0 @@ -import org.gradle.api.Plugin -import org.gradle.api.Project -import org.gradle.api.plugins.JavaPluginExtension -import org.gradle.jvm.toolchain.JavaLanguageVersion -import org.gradle.kotlin.dsl.configure -import utils.libs - -class JvmToolchainConventionPlugin : Plugin { - override fun apply(target: Project) = - with(target) { - extensions.configure { - toolchain { - val version = libs.findVersion("java-toolchain").get().displayName - languageVersion.set(JavaLanguageVersion.of(version)) - } - } - } -} diff --git a/build-logic/convention/src/main/kotlin/utils/ProjectExtensions.kt b/build-logic/convention/src/main/kotlin/utils/ProjectExtensions.kt deleted file mode 100644 index 3b0a623..0000000 --- a/build-logic/convention/src/main/kotlin/utils/ProjectExtensions.kt +++ /dev/null @@ -1,9 +0,0 @@ -package utils - -import org.gradle.api.Project -import org.gradle.api.artifacts.VersionCatalog -import org.gradle.api.artifacts.VersionCatalogsExtension -import org.gradle.kotlin.dsl.getByType - -val Project.libs: VersionCatalog - get() = extensions.getByType().named("libs") diff --git a/build-logic/settings.gradle.kts b/build-logic/settings.gradle.kts deleted file mode 100644 index c97f8ca..0000000 --- a/build-logic/settings.gradle.kts +++ /dev/null @@ -1,18 +0,0 @@ -dependencyResolutionManagement { - repositories { - google() - mavenCentral() - } - versionCatalogs { - create("libs") { - from(files("../gradle/libs.versions.toml")) - } - } -} - -plugins { - id("org.gradle.toolchains.foojay-resolver-convention") version ("0.7.0") -} - -rootProject.name = "build-logic" -include(":convention") diff --git a/build.gradle.kts b/build.gradle.kts index 78f7c3a..19264c6 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -1,23 +1,6 @@ -import com.diffplug.gradle.spotless.SpotlessPlugin -import io.gitlab.arturbosch.detekt.DetektPlugin - plugins { - alias(libs.plugins.android.application) apply false - alias(libs.plugins.android.library) apply false - alias(libs.plugins.kotlin) apply false - alias(libs.plugins.detekt) - alias(libs.plugins.spotless) - alias(libs.plugins.mavenpublish) -} - -configure(subprojects) { - apply() - apply() - - spotless { - kotlin { - target("**/*.kt") - ktlint("0.43.2") - } - } -} + autowire(libs.plugins.kotlin.multiplatform) apply false + autowire(libs.plugins.android.application) apply false + autowire(libs.plugins.android.library) apply false + autowire(libs.plugins.jetbrains.compose) apply false +} \ No newline at end of file diff --git a/config/detekt/detekt.yml b/config/detekt/detekt.yml deleted file mode 100644 index 4dbb501..0000000 --- a/config/detekt/detekt.yml +++ /dev/null @@ -1,684 +0,0 @@ -build: - maxIssues: 0 - excludeCorrectable: false - weights: - # complexity: 2 - # LongParameterList: 1 - # style: 1 - # comments: 1 - -config: - validation: true - warningsAsErrors: false - # when writing own rules with new properties, exclude the property path e.g.: 'my_rule_set,.*>.*>[my_property]' - excludes: '' - -processors: - active: true - exclude: - - 'DetektProgressListener' - # - 'KtFileCountProcessor' - # - 'PackageCountProcessor' - # - 'ClassCountProcessor' - # - 'FunctionCountProcessor' - # - 'PropertyCountProcessor' - # - 'ProjectComplexityProcessor' - # - 'ProjectCognitiveComplexityProcessor' - # - 'ProjectLLOCProcessor' - # - 'ProjectCLOCProcessor' - # - 'ProjectLOCProcessor' - # - 'ProjectSLOCProcessor' - # - 'LicenseHeaderLoaderExtension' - -console-reports: - active: true - exclude: - - 'ProjectStatisticsReport' - - 'ComplexityReport' - - 'NotificationReport' - - 'FindingsReport' - - 'FileBasedFindingsReport' - # - 'LiteFindingsReport' - -output-reports: - active: true - exclude: - # - 'TxtOutputReport' - # - 'XmlOutputReport' - # - 'HtmlOutputReport' - -comments: - active: true - AbsentOrWrongFileLicense: - active: false - licenseTemplateFile: 'license.template' - licenseTemplateIsRegex: false - CommentOverPrivateFunction: - active: false - CommentOverPrivateProperty: - active: false - DeprecatedBlockTag: - active: false - EndOfSentenceFormat: - active: false - endOfSentenceFormat: '([.?!][ \t\n\r\f<])|([.?!:]$)' - OutdatedDocumentation: - active: false - matchTypeParameters: true - matchDeclarationsOrder: true - allowParamOnConstructorProperties: false - UndocumentedPublicClass: - active: true - excludes: ['**/test/**', '**/androidTest/**', '**/commonTest/**', '**/jvmTest/**', '**/jsTest/**', '**/iosTest/**'] - searchInNestedClass: true - searchInInnerClass: true - searchInInnerObject: true - searchInInnerInterface: true - UndocumentedPublicFunction: - active: true - excludes: ['**/test/**', '**/androidTest/**', '**/commonTest/**', '**/jvmTest/**', '**/jsTest/**', '**/iosTest/**'] - UndocumentedPublicProperty: - active: true - excludes: ['**/test/**', '**/androidTest/**', '**/commonTest/**', '**/jvmTest/**', '**/jsTest/**', '**/iosTest/**'] - -complexity: - active: true - ComplexCondition: - active: true - threshold: 4 - ComplexInterface: - active: false - threshold: 10 - includeStaticDeclarations: false - includePrivateDeclarations: false - ComplexMethod: - active: true - threshold: 15 - ignoreSingleWhenExpression: false - ignoreSimpleWhenEntries: false - ignoreNestingFunctions: false - nestingFunctions: - - 'also' - - 'apply' - - 'forEach' - - 'isNotNull' - - 'ifNull' - - 'let' - - 'run' - - 'use' - - 'with' - LabeledExpression: - active: false - ignoredLabels: [] - LargeClass: - active: true - threshold: 600 - LongMethod: - active: true - threshold: 60 - LongParameterList: - active: true - functionThreshold: 10 - constructorThreshold: 7 - ignoreDefaultParameters: false - ignoreDataClasses: true - ignoreAnnotated: [ 'Composable' ] - ignoreAnnotatedParameter: [] - MethodOverloading: - active: false - threshold: 6 - NamedArguments: - active: false - threshold: 3 - ignoreArgumentsMatchingNames: false - NestedBlockDepth: - active: true - threshold: 4 - ReplaceSafeCallChainWithRun: - active: false - StringLiteralDuplication: - active: false - excludes: ['**/test/**', '**/androidTest/**', '**/commonTest/**', '**/jvmTest/**', '**/jsTest/**', '**/iosTest/**'] - threshold: 3 - ignoreAnnotation: true - excludeStringsWithLessThan5Characters: true - ignoreStringsRegex: '$^' - TooManyFunctions: - active: true - excludes: ['**/test/**', '**/androidTest/**', '**/commonTest/**', '**/jvmTest/**', '**/jsTest/**', '**/iosTest/**'] - thresholdInFiles: 11 - thresholdInClasses: 11 - thresholdInInterfaces: 11 - thresholdInObjects: 11 - thresholdInEnums: 11 - ignoreDeprecated: false - ignorePrivate: false - ignoreOverridden: false - -coroutines: - active: true - GlobalCoroutineUsage: - active: false - InjectDispatcher: - active: false - dispatcherNames: - - 'IO' - - 'Default' - - 'Unconfined' - RedundantSuspendModifier: - active: false - SleepInsteadOfDelay: - active: false - SuspendFunWithCoroutineScopeReceiver: - active: false - SuspendFunWithFlowReturnType: - active: false - -empty-blocks: - active: true - EmptyCatchBlock: - active: true - allowedExceptionNameRegex: '_|(ignore|expected).*' - EmptyClassBlock: - active: true - EmptyDefaultConstructor: - active: true - EmptyDoWhileBlock: - active: true - EmptyElseBlock: - active: true - EmptyFinallyBlock: - active: true - EmptyForBlock: - active: true - EmptyFunctionBlock: - active: true - ignoreOverridden: false - EmptyIfBlock: - active: true - EmptyInitBlock: - active: true - EmptyKtFile: - active: true - EmptySecondaryConstructor: - active: true - EmptyTryBlock: - active: true - EmptyWhenBlock: - active: true - EmptyWhileBlock: - active: true - -exceptions: - active: true - ExceptionRaisedInUnexpectedLocation: - active: true - methodNames: - - 'equals' - - 'finalize' - - 'hashCode' - - 'toString' - InstanceOfCheckForException: - active: false - excludes: ['**/test/**', '**/androidTest/**', '**/commonTest/**', '**/jvmTest/**', '**/jsTest/**', '**/iosTest/**'] - NotImplementedDeclaration: - active: false - ObjectExtendsThrowable: - active: false - PrintStackTrace: - active: true - RethrowCaughtException: - active: true - ReturnFromFinally: - active: true - ignoreLabeled: false - SwallowedException: - active: true - ignoredExceptionTypes: - - 'InterruptedException' - - 'MalformedURLException' - - 'NumberFormatException' - - 'ParseException' - allowedExceptionNameRegex: '_|(ignore|expected).*' - ThrowingExceptionFromFinally: - active: true - ThrowingExceptionInMain: - active: false - ThrowingExceptionsWithoutMessageOrCause: - active: true - excludes: ['**/test/**', '**/androidTest/**', '**/commonTest/**', '**/jvmTest/**', '**/jsTest/**', '**/iosTest/**'] - exceptions: - - 'ArrayIndexOutOfBoundsException' - - 'Exception' - - 'IllegalArgumentException' - - 'IllegalMonitorStateException' - - 'IllegalStateException' - - 'IndexOutOfBoundsException' - - 'NullPointerException' - - 'RuntimeException' - - 'Throwable' - ThrowingNewInstanceOfSameException: - active: true - TooGenericExceptionCaught: - active: true - excludes: ['**/test/**', '**/androidTest/**', '**/commonTest/**', '**/jvmTest/**', '**/jsTest/**', '**/iosTest/**'] - exceptionNames: - - 'ArrayIndexOutOfBoundsException' - - 'Error' - - 'Exception' - - 'IllegalMonitorStateException' - - 'IndexOutOfBoundsException' - - 'NullPointerException' - - 'RuntimeException' - - 'Throwable' - allowedExceptionNameRegex: '_|(ignore|expected).*' - TooGenericExceptionThrown: - active: true - exceptionNames: - - 'Error' - - 'Exception' - - 'RuntimeException' - - 'Throwable' - -naming: - active: true - BooleanPropertyNaming: - active: false - allowedPattern: '^(is|has|are)' - ignoreOverridden: true - ClassNaming: - active: true - classPattern: '[A-Z][a-zA-Z0-9]*' - ConstructorParameterNaming: - active: true - parameterPattern: '[a-z][A-Za-z0-9]*' - privateParameterPattern: '[a-z][A-Za-z0-9]*' - excludeClassPattern: '$^' - ignoreOverridden: true - EnumNaming: - active: true - enumEntryPattern: '[A-Z][_a-zA-Z0-9]*' - ForbiddenClassName: - active: false - forbiddenName: [] - FunctionMaxLength: - active: false - maximumFunctionNameLength: 30 - FunctionMinLength: - active: false - minimumFunctionNameLength: 3 - FunctionNaming: - active: true - excludes: ['**/test/**', '**/androidTest/**', '**/commonTest/**', '**/jvmTest/**', '**/jsTest/**', '**/iosTest/**'] - functionPattern: '[a-z][a-zA-Z0-9]*' - excludeClassPattern: '$^' - ignoreOverridden: true - ignoreAnnotated: [ 'Composable' ] - FunctionParameterNaming: - active: true - parameterPattern: '[a-z][A-Za-z0-9]*' - excludeClassPattern: '$^' - ignoreOverridden: true - InvalidPackageDeclaration: - active: false - rootPackage: '' - requireRootInDeclaration: false - LambdaParameterNaming: - active: false - parameterPattern: '[a-z][A-Za-z0-9]*|_' - MatchingDeclarationName: - active: true - mustBeFirst: true - MemberNameEqualsClassName: - active: true - ignoreOverridden: true - NoNameShadowing: - active: false - NonBooleanPropertyPrefixedWithIs: - active: false - ObjectPropertyNaming: - active: true - constantPattern: '[A-Za-z][_A-Za-z0-9]*' - propertyPattern: '[A-Za-z][_A-Za-z0-9]*' - privatePropertyPattern: '(_)?[A-Za-z][_A-Za-z0-9]*' - PackageNaming: - active: true - packagePattern: '[a-z]+(\.[a-z][A-Za-z0-9]*)*' - TopLevelPropertyNaming: - active: true - constantPattern: '[A-Z][A-Za-z0-9]*' - propertyPattern: '[A-Za-z][_A-Za-z0-9]*' - privatePropertyPattern: '_?[A-Za-z][_A-Za-z0-9]*' - VariableMaxLength: - active: false - maximumVariableNameLength: 64 - VariableMinLength: - active: false - minimumVariableNameLength: 1 - VariableNaming: - active: true - variablePattern: '[a-z][A-Za-z0-9]*' - privateVariablePattern: '(_)?[a-z][A-Za-z0-9]*' - excludeClassPattern: '$^' - ignoreOverridden: true - -performance: - active: true - ArrayPrimitive: - active: true - ForEachOnRange: - active: true - excludes: ['**/test/**', '**/androidTest/**', '**/commonTest/**', '**/jvmTest/**', '**/jsTest/**', '**/iosTest/**'] - SpreadOperator: - active: false - excludes: ['**/test/**', '**/androidTest/**', '**/commonTest/**', '**/jvmTest/**', '**/jsTest/**', '**/iosTest/**'] - UnnecessaryTemporaryInstantiation: - active: true - -potential-bugs: - active: true - AvoidReferentialEquality: - active: false - forbiddenTypePatterns: - - 'kotlin.String' - CastToNullableType: - active: false - Deprecation: - active: false - DontDowncastCollectionTypes: - active: false - DoubleMutabilityForCollection: - active: false - mutableTypes: - - 'kotlin.collections.MutableList' - - 'kotlin.collections.MutableMap' - - 'kotlin.collections.MutableSet' - - 'java.util.ArrayList' - - 'java.util.LinkedHashSet' - - 'java.util.HashSet' - - 'java.util.LinkedHashMap' - - 'java.util.HashMap' - DuplicateCaseInWhenExpression: - active: true - ElseCaseInsteadOfExhaustiveWhen: - active: false - EqualsAlwaysReturnsTrueOrFalse: - active: true - EqualsWithHashCodeExist: - active: true - ExitOutsideMain: - active: false - ExplicitGarbageCollectionCall: - active: true - HasPlatformType: - active: false - IgnoredReturnValue: - active: false - restrictToAnnotatedMethods: true - returnValueAnnotations: - - '*.CheckResult' - - '*.CheckReturnValue' - ignoreReturnValueAnnotations: - - '*.CanIgnoreReturnValue' - ignoreFunctionCall: [] - ImplicitDefaultLocale: - active: true - ImplicitUnitReturnType: - active: false - allowExplicitReturnType: true - InvalidRange: - active: true - IteratorHasNextCallsNextMethod: - active: true - IteratorNotThrowingNoSuchElementException: - active: true - LateinitUsage: - active: false - excludes: ['**/test/**', '**/androidTest/**', '**/commonTest/**', '**/jvmTest/**', '**/jsTest/**', '**/iosTest/**'] - ignoreOnClassesPattern: '' - MapGetWithNotNullAssertionOperator: - active: false - MissingPackageDeclaration: - active: false - excludes: ['**/*.kts'] - MissingWhenCase: - active: true - allowElseExpression: true - NullCheckOnMutableProperty: - active: false - NullableToStringCall: - active: false - RedundantElseInWhen: - active: true - UnconditionalJumpStatementInLoop: - active: false - UnnecessaryNotNullOperator: - active: true - UnnecessarySafeCall: - active: true - UnreachableCatchBlock: - active: false - UnreachableCode: - active: true - UnsafeCallOnNullableType: - active: true - excludes: ['**/test/**', '**/androidTest/**', '**/commonTest/**', '**/jvmTest/**', '**/jsTest/**', '**/iosTest/**'] - UnsafeCast: - active: true - UnusedUnaryOperator: - active: false - UselessPostfixExpression: - active: false - WrongEqualsTypeParameter: - active: true - -style: - active: true - CanBeNonNullable: - active: false - ClassOrdering: - active: false - CollapsibleIfStatements: - active: false - DataClassContainsFunctions: - active: false - conversionFunctionPrefix: 'to' - DataClassShouldBeImmutable: - active: false - DestructuringDeclarationWithTooManyEntries: - active: false - maxDestructuringEntries: 3 - EqualsNullCall: - active: true - EqualsOnSignatureLine: - active: false - ExplicitCollectionElementAccessMethod: - active: false - ExplicitItLambdaParameter: - active: false - ExpressionBodySyntax: - active: false - includeLineWrapping: false - ForbiddenComment: - active: true - values: - - 'FIXME:' - - 'STOPSHIP:' - - 'TODO:' - allowedPatterns: '' - customMessage: '' - ForbiddenImport: - active: false - imports: [] - forbiddenPatterns: '' - ForbiddenMethodCall: - active: false - methods: - - 'kotlin.io.print' - - 'kotlin.io.println' - ForbiddenPublicDataClass: - active: true - excludes: ['**'] - ignorePackages: - - '*.internal' - - '*.internal.*' - ForbiddenVoid: - active: false - ignoreOverridden: false - ignoreUsageInGenerics: false - FunctionOnlyReturningConstant: - active: true - ignoreOverridableFunction: true - ignoreActualFunction: true - excludedFunctions: '' - LibraryCodeMustSpecifyReturnType: - active: true - excludes: ['**'] - LibraryEntitiesShouldNotBePublic: - active: true - excludes: ['**'] - LoopWithTooManyJumpStatements: - active: true - maxJumpCount: 1 - MagicNumber: - active: false - excludes: ['**/test/**', '**/androidTest/**', '**/commonTest/**', '**/jvmTest/**', '**/jsTest/**', '**/iosTest/**'] - ignoreNumbers: - - '-1' - - '0' - - '1' - - '2' - ignoreHashCodeFunction: true - ignorePropertyDeclaration: false - ignoreLocalVariableDeclaration: false - ignoreConstantDeclaration: true - ignoreCompanionObjectPropertyDeclaration: true - ignoreAnnotation: false - ignoreNamedArgument: true - ignoreEnums: false - ignoreRanges: false - ignoreExtensionFunctions: true - MandatoryBracesIfStatements: - active: false - MandatoryBracesLoops: - active: false - MaxLineLength: - active: true - maxLineLength: 120 - excludePackageStatements: true - excludeImportStatements: true - excludeCommentStatements: false - MayBeConst: - active: true - ModifierOrder: - active: true - MultilineLambdaItParameter: - active: false - NestedClassesVisibility: - active: true - NewLineAtEndOfFile: - active: true - NoTabs: - active: false - ObjectLiteralToLambda: - active: false - OptionalAbstractKeyword: - active: true - OptionalUnit: - active: false - OptionalWhenBraces: - active: false - PreferToOverPairSyntax: - active: false - ProtectedMemberInFinalClass: - active: true - RedundantExplicitType: - active: false - RedundantHigherOrderMapUsage: - active: false - RedundantVisibilityModifierRule: - active: false - ReturnCount: - active: true - max: 2 - excludedFunctions: 'equals' - excludeLabeled: false - excludeReturnFromLambda: true - excludeGuardClauses: false - SafeCast: - active: true - SerialVersionUIDInSerializableClass: - active: true - SpacingBetweenPackageAndImports: - active: false - ThrowsCount: - active: true - max: 2 - excludeGuardClauses: false - TrailingWhitespace: - active: false - UnderscoresInNumericLiterals: - active: false - acceptableLength: 4 - allowNonStandardGrouping: false - UnnecessaryAbstractClass: - active: true - UnnecessaryAnnotationUseSiteTarget: - active: false - UnnecessaryApply: - active: true - UnnecessaryFilter: - active: false - UnnecessaryInheritance: - active: true - UnnecessaryInnerClass: - active: false - UnnecessaryLet: - active: false - UnnecessaryParentheses: - active: false - UntilInsteadOfRangeTo: - active: false - UnusedImports: - active: false - UnusedPrivateClass: - active: true - UnusedPrivateMember: - active: true - allowedNames: '(_|ignored|expected|serialVersionUID)' - UseAnyOrNoneInsteadOfFind: - active: false - UseArrayLiteralsInAnnotations: - active: false - UseCheckNotNull: - active: false - UseCheckOrError: - active: false - UseDataClass: - active: false - allowVars: false - UseEmptyCounterpart: - active: false - UseIfEmptyOrIfBlank: - active: false - UseIfInsteadOfWhen: - active: false - UseIsNullOrEmpty: - active: false - UseOrEmpty: - active: false - UseRequire: - active: false - UseRequireNotNull: - active: false - UselessCallOnNotNull: - active: true - UtilityClassWithPublicConstructor: - active: true - VarCouldBeVal: - active: true - WildcardImport: - active: true - excludes: ['**/test/**', '**/androidTest/**', '**/commonTest/**', '**/jvmTest/**', '**/jsTest/**', '**/iosTest/**'] - excludeImports: - - 'java.util.*' diff --git a/demo/build.gradle.kts b/demo/build.gradle.kts deleted file mode 100644 index 0fee587..0000000 --- a/demo/build.gradle.kts +++ /dev/null @@ -1,61 +0,0 @@ -plugins { - alias(libs.plugins.android.application) - alias(libs.plugins.kotlin) - id("convention.jvm.toolchain") -} - -android { - namespace = "eu.wewox.pagecurl" - - compileSdk = libs.versions.sdk.compile.get().toInt() - - defaultConfig { - applicationId = "eu.wewox.pagecurl" - - minSdk = libs.versions.sdk.min.get().toInt() - targetSdk = libs.versions.sdk.target.get().toInt() - - versionCode = 1 - versionName = "1.0" - - vectorDrawables { - useSupportLibrary = true - } - } - - buildTypes { - release { - isMinifyEnabled = false - proguardFiles( - getDefaultProguardFile("proguard-android-optimize.txt"), - "proguard-rules.pro" - ) - } - } - buildFeatures { - compose = true - } - composeOptions { - kotlinCompilerExtensionVersion = libs.versions.compose.compiler.get() - } - kotlinOptions { - freeCompilerArgs = freeCompilerArgs + - "-opt-in=androidx.compose.material3.ExperimentalMaterial3Api" - } - packaging { - resources { - excludes += "/META-INF/{AL2.0,LGPL2.1}" - } - } -} - -dependencies { - implementation(project(":pagecurl")) - - implementation(platform(libs.compose.bom)) - implementation(libs.compose.material3) - implementation(libs.compose.ui) - implementation(libs.androidx.activitycompose) - implementation(libs.androidx.pagingruntime) - implementation(libs.androidx.pagingcompose) -} diff --git a/demo/src/main/kotlin/eu/wewox/pagecurl/MainActivity.kt b/demo/src/main/kotlin/eu/wewox/pagecurl/MainActivity.kt deleted file mode 100644 index db56fb0..0000000 --- a/demo/src/main/kotlin/eu/wewox/pagecurl/MainActivity.kt +++ /dev/null @@ -1,63 +0,0 @@ -package eu.wewox.pagecurl - -import android.os.Bundle -import androidx.activity.ComponentActivity -import androidx.activity.compose.BackHandler -import androidx.activity.compose.setContent -import androidx.activity.enableEdgeToEdge -import androidx.compose.animation.Crossfade -import androidx.compose.foundation.layout.safeDrawingPadding -import androidx.compose.material3.MaterialTheme -import androidx.compose.material3.Surface -import androidx.compose.runtime.getValue -import androidx.compose.runtime.mutableStateOf -import androidx.compose.runtime.saveable.rememberSaveable -import androidx.compose.runtime.setValue -import androidx.compose.ui.Modifier -import androidx.core.view.WindowCompat -import eu.wewox.pagecurl.screens.BackPagePageCurlScreen -import eu.wewox.pagecurl.screens.InteractionConfigInPageCurlScreen -import eu.wewox.pagecurl.screens.PagingPageCurlScreen -import eu.wewox.pagecurl.screens.SettingsPageCurlScreen -import eu.wewox.pagecurl.screens.ShadowInPageCurlScreen -import eu.wewox.pagecurl.screens.SimplePageCurlScreen -import eu.wewox.pagecurl.screens.StateInPageCurlScreen -import eu.wewox.pagecurl.ui.theme.PageCurlTheme - -/** - * Main activity for demo application. - * Contains simple "Crossfade" based navigation to various examples. - */ -class MainActivity : ComponentActivity() { - override fun onCreate(savedInstanceState: Bundle?) { - super.onCreate(savedInstanceState) - enableEdgeToEdge() - - WindowCompat.setDecorFitsSystemWindows(window, false) - - setContent { - PageCurlTheme { - var example by rememberSaveable { mutableStateOf(null) } - - BackHandler(enabled = example != null) { - example = null - } - - Surface(color = MaterialTheme.colorScheme.background) { - Crossfade(targetState = example, Modifier.safeDrawingPadding(), label = "Crossfade") { selected -> - when (selected) { - null -> RootScreen(onExampleClick = { example = it }) - Example.SimplePageCurl -> SimplePageCurlScreen() - Example.PagingPageCurl -> PagingPageCurlScreen() - Example.SettingsPageCurl -> SettingsPageCurlScreen() - Example.StateInPageCurl -> StateInPageCurlScreen() - Example.InteractionConfigInPageCurl -> InteractionConfigInPageCurlScreen() - Example.ShadowPageCurl -> ShadowInPageCurlScreen() - Example.BackPagePageCurl -> BackPagePageCurlScreen() - } - } - } - } - } - } -} diff --git a/gradle.properties b/gradle.properties index 754d361..7b94f5d 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,48 +1,21 @@ -# Project-wide Gradle settings. -# IDE (e.g. Android Studio) users: -# Gradle settings configured through the IDE *will override* -# any settings specified in this file. -# For more details on how to configure your build environment visit -# http://www.gradle.org/docs/current/userguide/build_environment.html -# Specifies the JVM arguments used for the daemon process. -# The setting is particularly useful for tweaking memory settings. +# Compiler Configuration org.gradle.jvmargs=-Xmx2048m -Dfile.encoding=UTF-8 -# When configured, Gradle will run in incubating parallel mode. -# This option should only be used with decoupled projects. More details, visit -# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects -# org.gradle.parallel=true -# AndroidX package structure to make it clearer which packages are bundled with the -# Android operating system, and which are packaged with your app"s APK -# https://developer.android.com/topic/libraries/support-library/androidx-rn android.useAndroidX=true -# Kotlin code style for this project: "official" or "obsolete": -kotlin.code.style=official -# Enables namespacing of each library's R class so that its R class includes only the -# resources declared in the library itself and none from the library's dependencies, -# thereby reducing the size of the R class for that library android.nonTransitiveRClass=true - -# Maven setup with https://github.com/vanniktech/gradle-maven-publish-plugin -SONATYPE_HOST=S01 -RELEASE_SIGNING_ENABLED=true - -GROUP=io.github.oleksandrbalan -POM_ARTIFACT_ID=pagecurl -VERSION_NAME=1.4.1 - -POM_NAME=Page Curl -POM_DESCRIPTION=This library allows to create an effect of turning pages, which can be used in book reader applications, custom on-boarding screens or elsewhere. -POM_INCEPTION_YEAR=2022 -POM_URL=https://github.com/oleksandrbalan/pagecurl - -POM_LICENSE_NAME=The Apache Software License, Version 2.0 -POM_LICENSE_URL=https://www.apache.org/licenses/LICENSE-2.0.txt -POM_LICENSE_DIST=repo - -POM_SCM_URL=https://github.com/oleksandrbalan/pagecurl -POM_SCM_CONNECTION=scm:git:git://github.com/oleksandrbalan/pagecurl.git -POM_SCM_DEV_CONNECTION=scm:git:ssh://git@github.com/oleksandrbalan/pagecurl.git - -POM_DEVELOPER_ID=oleksandrbalan -POM_DEVELOPER_NAME=Oleksandr Balan -POM_DEVELOPER_URL=https://github.com/oleksandrbalan +kotlin.code.style=official +kotlin.incremental.useClasspathSnapshot=true +org.jetbrains.compose.experimental.uikit.enabled=true +# Project Configuration +project.name=pagecurl-multiplatform +project.description=Page Curl library for Jetpack Compose Multiplatform. +project.url=https://github.com/fankes/pagecurl-multiplatform +project.groupName=eu.wewox.pagecurl +project.moduleName=pagecurl-multiplatform +project.version="1.4.1" +project.licence.name=Apache License 2.0 +project.licence.url=https://github.com/fankes/pagecurl-multiplatform/blob/master/LICENSE +project.android.compileSdk=34 +project.android.minSdk=21 +project.android.targetSdk=34 +project.samples.androidApp.versionName=universal +project.samples.androidApp.versionCode=1 \ No newline at end of file diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml deleted file mode 100644 index 579ffb2..0000000 --- a/gradle/libs.versions.toml +++ /dev/null @@ -1,34 +0,0 @@ -[versions] -sdk-compile = "34" -sdk-min = "21" -sdk-target = "33" - -compose-bom = "2023.09.00" -compose-compiler = "1.5.3" -activity-compose = "1.8.0-beta01" -paging = "3.2.1" - -plugin-android-gradle = "8.1.1" -plugin-kotlin = "1.9.10" -plugin-detekt = "1.21.0" -plugin-spotless = "6.5.1" -plugin-mavenpublish = "0.25.3" - -java-toolchain = "17" - -[libraries] -compose-bom = { module = "androidx.compose:compose-bom", version.ref = "compose-bom" } -compose-foundation = { module = "androidx.compose.foundation:foundation" } -compose-material3 = { module = "androidx.compose.material3:material3" } -compose-ui = { module = "androidx.compose.ui:ui" } -androidx-activitycompose = { module = "androidx.activity:activity-compose", version.ref = "activity-compose" } -androidx-pagingruntime = { module = "androidx.paging:paging-runtime", version.ref = "paging" } -androidx-pagingcompose = { module = "androidx.paging:paging-compose", version.ref = "paging" } - -[plugins] -android-application = { id = "com.android.application", version.ref = "plugin-android-gradle" } -android-library = { id = "com.android.library", version.ref = "plugin-android-gradle" } -kotlin = { id = "org.jetbrains.kotlin.android", version.ref = "plugin-kotlin" } -detekt = { id = "io.gitlab.arturbosch.detekt", version.ref = "plugin-detekt" } -spotless = { id = "com.diffplug.spotless", version.ref = "plugin-spotless" } -mavenpublish = { id = "com.vanniktech.maven.publish", version.ref = "plugin-mavenpublish" } diff --git a/gradle/sweet-dependency/sweet-dependency-config.yaml b/gradle/sweet-dependency/sweet-dependency-config.yaml new file mode 100644 index 0000000..b020053 --- /dev/null +++ b/gradle/sweet-dependency/sweet-dependency-config.yaml @@ -0,0 +1,65 @@ +preferences: + autowire-on-sync-mode: UPDATE_OPTIONAL_DEPENDENCIES + repositories-mode: FAIL_ON_PROJECT_REPOS + +repositories: + gradle-plugin-portal: + scope: PLUGINS + google: + maven-central: + +plugins: + org.jetbrains.kotlin.multiplatform: + alias: kotlin-multiplatform + version: 1.9.10 + org.jetbrains.compose: + alias: jetbrains-compose + version: 1.5.1 + com.android.application: + alias: android-application + version: 8.1.2 + com.android.library: + alias: android-library + version-ref: android-application + +libraries: + app.cash.paging: + paging-common: + version: 3.3.0-alpha02-0.4.0 + paging-compose-common: + version-ref: ::paging-common + androidx.compose: + compose-bom: + version: 2023.09.02 + androidx.compose.foundation: + foundation: + version: + androidx.compose.ui: + ui: + version: + androidx.compose.material3: + material3: + version: + androidx.activity: + activity: + version: 1.8.0 + activity-compose: + version: 1.7.2 + androidx.core: + core-ktx: + version: 1.10.0 + androidx.appcompat: + appcompat: + version: 1.6.1 + com.google.android.material: + material: + version: 1.8.0 + androidx.test.ext: + junit: + version: 1.1.5 + androidx.test.espresso: + espresso-core: + version: 3.5.1 + junit: + junit: + version: 4.13.2 \ No newline at end of file diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 3e49027..692fc5c 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,5 @@ -#Wed Sep 06 22:11:14 CEST 2023 distributionBase=GRADLE_USER_HOME -distributionPath=wrapper/dists distributionUrl=https\://services.gradle.org/distributions/gradle-8.3-bin.zip -zipStoreBase=GRADLE_USER_HOME +distributionPath=wrapper/dists zipStorePath=wrapper/dists +zipStoreBase=GRADLE_USER_HOME \ No newline at end of file diff --git a/gradlew.bat b/gradlew.bat index ac1b06f..107acd3 100644 --- a/gradlew.bat +++ b/gradlew.bat @@ -1,89 +1,89 @@ -@rem -@rem Copyright 2015 the original author or authors. -@rem -@rem Licensed under the Apache License, Version 2.0 (the "License"); -@rem you may not use this file except in compliance with the License. -@rem You may obtain a copy of the License at -@rem -@rem https://www.apache.org/licenses/LICENSE-2.0 -@rem -@rem Unless required by applicable law or agreed to in writing, software -@rem distributed under the License is distributed on an "AS IS" BASIS, -@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -@rem See the License for the specific language governing permissions and -@rem limitations under the License. -@rem - -@if "%DEBUG%" == "" @echo off -@rem ########################################################################## -@rem -@rem Gradle startup script for Windows -@rem -@rem ########################################################################## - -@rem Set local scope for the variables with windows NT shell -if "%OS%"=="Windows_NT" setlocal - -set DIRNAME=%~dp0 -if "%DIRNAME%" == "" set DIRNAME=. -set APP_BASE_NAME=%~n0 -set APP_HOME=%DIRNAME% - -@rem Resolve any "." and ".." in APP_HOME to make it shorter. -for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi - -@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. -set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" - -@rem Find java.exe -if defined JAVA_HOME goto findJavaFromJavaHome - -set JAVA_EXE=java.exe -%JAVA_EXE% -version >NUL 2>&1 -if "%ERRORLEVEL%" == "0" goto execute - -echo. -echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. -echo. -echo Please set the JAVA_HOME variable in your environment to match the -echo location of your Java installation. - -goto fail - -:findJavaFromJavaHome -set JAVA_HOME=%JAVA_HOME:"=% -set JAVA_EXE=%JAVA_HOME%/bin/java.exe - -if exist "%JAVA_EXE%" goto execute - -echo. -echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% -echo. -echo Please set the JAVA_HOME variable in your environment to match the -echo location of your Java installation. - -goto fail - -:execute -@rem Setup the command line - -set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar - - -@rem Execute Gradle -"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* - -:end -@rem End local scope for the variables with windows NT shell -if "%ERRORLEVEL%"=="0" goto mainEnd - -:fail -rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of -rem the _cmd.exe /c_ return code! -if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 -exit /b 1 - -:mainEnd -if "%OS%"=="Windows_NT" endlocal - -:omega +@rem +@rem Copyright 2015 the original author or authors. +@rem +@rem Licensed under the Apache License, Version 2.0 (the "License"); +@rem you may not use this file except in compliance with the License. +@rem You may obtain a copy of the License at +@rem +@rem https://www.apache.org/licenses/LICENSE-2.0 +@rem +@rem Unless required by applicable law or agreed to in writing, software +@rem distributed under the License is distributed on an "AS IS" BASIS, +@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +@rem See the License for the specific language governing permissions and +@rem limitations under the License. +@rem + +@if "%DEBUG%" == "" @echo off +@rem ########################################################################## +@rem +@rem Gradle startup script for Windows +@rem +@rem ########################################################################## + +@rem Set local scope for the variables with windows NT shell +if "%OS%"=="Windows_NT" setlocal + +set DIRNAME=%~dp0 +if "%DIRNAME%" == "" set DIRNAME=. +set APP_BASE_NAME=%~n0 +set APP_HOME=%DIRNAME% + +@rem Resolve any "." and ".." in APP_HOME to make it shorter. +for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi + +@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" + +@rem Find java.exe +if defined JAVA_HOME goto findJavaFromJavaHome + +set JAVA_EXE=java.exe +%JAVA_EXE% -version >NUL 2>&1 +if "%ERRORLEVEL%" == "0" goto execute + +echo. +echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:findJavaFromJavaHome +set JAVA_HOME=%JAVA_HOME:"=% +set JAVA_EXE=%JAVA_HOME%/bin/java.exe + +if exist "%JAVA_EXE%" goto execute + +echo. +echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:execute +@rem Setup the command line + +set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar + + +@rem Execute Gradle +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* + +:end +@rem End local scope for the variables with windows NT shell +if "%ERRORLEVEL%"=="0" goto mainEnd + +:fail +rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of +rem the _cmd.exe /c_ return code! +if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 +exit /b 1 + +:mainEnd +if "%OS%"=="Windows_NT" endlocal + +:omega diff --git a/pagecurl/build.gradle.kts b/pagecurl/build.gradle.kts index 1a22fd1..d842e04 100644 --- a/pagecurl/build.gradle.kts +++ b/pagecurl/build.gradle.kts @@ -1,32 +1,65 @@ plugins { - alias(libs.plugins.android.library) - alias(libs.plugins.kotlin) - alias(libs.plugins.mavenpublish) - id("convention.jvm.toolchain") + autowire(libs.plugins.kotlin.multiplatform) + autowire(libs.plugins.android.library) + autowire(libs.plugins.jetbrains.compose) +} + +group = property.project.groupName + +kotlin { + androidTarget() + jvm("desktop") + iosX64() + iosArm64() + iosSimulatorArm64() + jvmToolchain(17) + sourceSets { + all { + languageSettings { + optIn("kotlinx.cinterop.ExperimentalForeignApi") + } + } + val commonMain by getting { + dependencies { + implementation(compose.runtime) + implementation(compose.foundation) + implementation(compose.material3) + } + } + val androidMain by getting + val desktopMain by getting { + dependencies { + implementation(compose.desktop.currentOs) + } + } + val iosX64Main by getting + val iosArm64Main by getting + val iosSimulatorArm64Main by getting + val iosMain by creating { + dependsOn(commonMain) + iosX64Main.dependsOn(this) + iosArm64Main.dependsOn(this) + iosSimulatorArm64Main.dependsOn(this) + } + } } android { - namespace = "eu.wewox.pagecurl" + namespace = property.project.groupName + compileSdk = property.project.android.compileSdk - compileSdk = libs.versions.sdk.compile.get().toInt() + sourceSets["main"].manifest.srcFile("src/androidMain/AndroidManifest.xml") defaultConfig { - minSdk = libs.versions.sdk.min.get().toInt() + minSdk = property.project.android.minSdk } - buildFeatures { - compose = true - } - composeOptions { - kotlinCompilerExtensionVersion = libs.versions.compose.compiler.get() - } - kotlinOptions { - freeCompilerArgs = freeCompilerArgs + - "-Xexplicit-api=strict" + compileOptions { + sourceCompatibility = JavaVersion.VERSION_17 + targetCompatibility = JavaVersion.VERSION_17 } } -dependencies { - implementation(platform(libs.compose.bom)) - implementation(libs.compose.foundation) - implementation(libs.compose.ui) -} +java { + sourceCompatibility = JavaVersion.VERSION_17 + targetCompatibility = JavaVersion.VERSION_17 +} \ No newline at end of file diff --git a/pagecurl/src/androidMain/AndroidManifest.xml b/pagecurl/src/androidMain/AndroidManifest.xml new file mode 100644 index 0000000..568741e --- /dev/null +++ b/pagecurl/src/androidMain/AndroidManifest.xml @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/pagecurl/src/androidMain/kotlin/eu/wewox/pagecurl/page/CurlDraw.android.kt b/pagecurl/src/androidMain/kotlin/eu/wewox/pagecurl/page/CurlDraw.android.kt new file mode 100644 index 0000000..9ccc680 --- /dev/null +++ b/pagecurl/src/androidMain/kotlin/eu/wewox/pagecurl/page/CurlDraw.android.kt @@ -0,0 +1,9 @@ +package eu.wewox.pagecurl.page + +import android.graphics.BlurMaskFilter +import androidx.compose.ui.graphics.Paint + +actual fun Paint.setBlurred(value: Float) { + if (value == 0f) return + asFrameworkPaint().maskFilter = BlurMaskFilter(value, BlurMaskFilter.Blur.NORMAL) +} \ No newline at end of file diff --git a/pagecurl/src/androidMain/kotlin/eu/wewox/pagecurl/page/CurlGesture.android.kt b/pagecurl/src/androidMain/kotlin/eu/wewox/pagecurl/page/CurlGesture.android.kt new file mode 100644 index 0000000..332cc68 --- /dev/null +++ b/pagecurl/src/androidMain/kotlin/eu/wewox/pagecurl/page/CurlGesture.android.kt @@ -0,0 +1,3 @@ +package eu.wewox.pagecurl.page + +internal actual fun systemCurrentTimeMillis() = System.currentTimeMillis() \ No newline at end of file diff --git a/pagecurl/src/main/kotlin/eu/wewox/pagecurl/ExperimentalPageCurlApi.kt b/pagecurl/src/commonMain/kotlin/eu/wewox/pagecurl/ExperimentalPageCurlApi.kt similarity index 100% rename from pagecurl/src/main/kotlin/eu/wewox/pagecurl/ExperimentalPageCurlApi.kt rename to pagecurl/src/commonMain/kotlin/eu/wewox/pagecurl/ExperimentalPageCurlApi.kt diff --git a/pagecurl/src/main/kotlin/eu/wewox/pagecurl/config/PageCurlConfig.kt b/pagecurl/src/commonMain/kotlin/eu/wewox/pagecurl/config/PageCurlConfig.kt similarity index 99% rename from pagecurl/src/main/kotlin/eu/wewox/pagecurl/config/PageCurlConfig.kt rename to pagecurl/src/commonMain/kotlin/eu/wewox/pagecurl/config/PageCurlConfig.kt index b4c0d69..875c72d 100644 --- a/pagecurl/src/main/kotlin/eu/wewox/pagecurl/config/PageCurlConfig.kt +++ b/pagecurl/src/commonMain/kotlin/eu/wewox/pagecurl/config/PageCurlConfig.kt @@ -48,7 +48,7 @@ public fun rememberPageCurlConfig( backPageColor: Color = Color.White, backPageContentAlpha: Float = 0.1f, shadowColor: Color = Color.Black, - shadowAlpha: Float = 0.2f, + shadowAlpha: Float = 0.5f, shadowRadius: Dp = 15.dp, shadowOffset: DpOffset = DpOffset((-5).dp, 0.dp), dragForwardEnabled: Boolean = true, diff --git a/pagecurl/src/main/kotlin/eu/wewox/pagecurl/page/CurlDraw.kt b/pagecurl/src/commonMain/kotlin/eu/wewox/pagecurl/page/CurlDraw.kt similarity index 85% rename from pagecurl/src/main/kotlin/eu/wewox/pagecurl/page/CurlDraw.kt rename to pagecurl/src/commonMain/kotlin/eu/wewox/pagecurl/page/CurlDraw.kt index 1d8d040..574ec16 100644 --- a/pagecurl/src/main/kotlin/eu/wewox/pagecurl/page/CurlDraw.kt +++ b/pagecurl/src/commonMain/kotlin/eu/wewox/pagecurl/page/CurlDraw.kt @@ -1,23 +1,22 @@ package eu.wewox.pagecurl.page -import android.graphics.Bitmap -import android.graphics.Canvas -import android.os.Build import androidx.compose.ui.Modifier import androidx.compose.ui.draw.CacheDrawScope import androidx.compose.ui.draw.DrawResult import androidx.compose.ui.draw.drawWithCache import androidx.compose.ui.geometry.Offset import androidx.compose.ui.geometry.toRect +import androidx.compose.ui.graphics.Canvas +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.graphics.ImageBitmap +import androidx.compose.ui.graphics.ImageBitmapConfig import androidx.compose.ui.graphics.Paint import androidx.compose.ui.graphics.Path -import androidx.compose.ui.graphics.asAndroidPath import androidx.compose.ui.graphics.drawscope.ContentDrawScope import androidx.compose.ui.graphics.drawscope.clipPath import androidx.compose.ui.graphics.drawscope.drawIntoCanvas import androidx.compose.ui.graphics.drawscope.rotateRad import androidx.compose.ui.graphics.drawscope.withTransform -import androidx.compose.ui.graphics.nativeCanvas import androidx.compose.ui.graphics.toArgb import androidx.compose.ui.unit.dp import eu.wewox.pagecurl.ExperimentalPageCurlApi @@ -25,8 +24,9 @@ import eu.wewox.pagecurl.config.PageCurlConfig import eu.wewox.pagecurl.utils.Polygon import eu.wewox.pagecurl.utils.lineLineIntersection import eu.wewox.pagecurl.utils.rotate -import java.lang.Float.max +import kotlin.math.PI import kotlin.math.atan2 +import kotlin.math.max @ExperimentalPageCurlApi internal fun Modifier.drawCurl( @@ -157,7 +157,7 @@ private fun CacheDrawScope.prepareCurl( // Calculate the angle in radians between X axis and the curl line, this is used to rotate mirrored content to the // right position of the curled back-page val lineVector = topCurlOffset - bottomCurlOffset - val angle = Math.PI.toFloat() - atan2(lineVector.y, lineVector.x) * 2 + val angle = PI.toFloat() - atan2(lineVector.y, lineVector.x) * 2 // Prepare a lambda to draw the shadow of the back-page val drawShadow = prepareShadow(config, polygon, angle) @@ -197,29 +197,27 @@ private fun CacheDrawScope.prepareShadow( // Prepare shadow parameters val radius = config.shadowRadius.toPx() val shadowColor = config.shadowColor.copy(alpha = config.shadowAlpha).toArgb() - val transparent = config.shadowColor.copy(alpha = 0f).toArgb() + // TODO shadowOffset to be set here val shadowOffset = Offset(-config.shadowOffset.x.toPx(), config.shadowOffset.y.toPx()) - .rotate(2 * Math.PI.toFloat() - angle) + .rotate(2 * PI.toFloat() - angle) // Prepare shadow paint with a shadow layer val paint = Paint().apply { - val frameworkPaint = asFrameworkPaint() - frameworkPaint.color = transparent - frameworkPaint.setShadowLayer( - config.shadowRadius.toPx(), - shadowOffset.x, - shadowOffset.y, - shadowColor - ) + color = Color(shadowColor) + setBlurred(radius) + +// val frameworkPaint = asFrameworkPaint() +// frameworkPaint.color = transparent +// frameworkPaint.setShadowLayer( +// config.shadowRadius.toPx(), +// shadowOffset.x, +// shadowOffset.y, +// shadowColor +// ) } - // Hardware acceleration supports setShadowLayer() only on API 28 and above, thus to support previous API versions // draw a shadow to the bitmap instead - return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) { - prepareShadowApi28(radius, paint, polygon) - } else { - prepareShadowImage(radius, paint, polygon) - } + return prepareShadowImage(radius, paint, polygon) } private fun prepareShadowApi28( @@ -228,12 +226,7 @@ private fun prepareShadowApi28( polygon: Polygon, ): ContentDrawScope.() -> Unit = { drawIntoCanvas { - it.nativeCanvas.drawPath( - polygon - .offset(radius).toPath() - .asAndroidPath(), - paint.asFrameworkPaint() - ) + it.drawPath(polygon.offset(radius).toPath(), paint) } } @@ -243,26 +236,26 @@ private fun CacheDrawScope.prepareShadowImage( polygon: Polygon, ): ContentDrawScope.() -> Unit { // Increase the size a little bit so that shadow is not clipped - val bitmap = Bitmap.createBitmap( + val bitmap = ImageBitmap( (size.width + radius * 4).toInt(), (size.height + radius * 4).toInt(), - Bitmap.Config.ARGB_8888 + ImageBitmapConfig.Argb8888 ) Canvas(bitmap).apply { drawPath( polygon // As bitmap size is increased we should translate the polygon so that shadow remains in center .translate(Offset(2 * radius, 2 * radius)) - .offset(radius).toPath() - .asAndroidPath(), - paint.asFrameworkPaint() + .offset(radius).toPath(), paint ) } return { drawIntoCanvas { // As bitmap size is increased we should shift the drawing so that shadow remains in center - it.nativeCanvas.drawBitmap(bitmap, -2 * radius, -2 * radius, null) + it.drawImage(bitmap, Offset(-2 * radius, -2 * radius), paint) } } } + +internal expect fun Paint.setBlurred(value: Float) \ No newline at end of file diff --git a/pagecurl/src/main/kotlin/eu/wewox/pagecurl/page/CurlGesture.kt b/pagecurl/src/commonMain/kotlin/eu/wewox/pagecurl/page/CurlGesture.kt similarity index 60% rename from pagecurl/src/main/kotlin/eu/wewox/pagecurl/page/CurlGesture.kt rename to pagecurl/src/commonMain/kotlin/eu/wewox/pagecurl/page/CurlGesture.kt index 3fbdeda..fbafa4f 100644 --- a/pagecurl/src/main/kotlin/eu/wewox/pagecurl/page/CurlGesture.kt +++ b/pagecurl/src/commonMain/kotlin/eu/wewox/pagecurl/page/CurlGesture.kt @@ -5,9 +5,9 @@ import androidx.compose.animation.core.AnimationVector4D import androidx.compose.animation.core.VectorConverter import androidx.compose.animation.core.calculateTargetValue import androidx.compose.animation.splineBasedDecay +import androidx.compose.foundation.gestures.awaitEachGesture import androidx.compose.foundation.gestures.awaitFirstDown import androidx.compose.foundation.gestures.drag -import androidx.compose.foundation.gestures.forEachGesture import androidx.compose.ui.Modifier import androidx.compose.ui.geometry.Offset import androidx.compose.ui.geometry.Rect @@ -84,50 +84,50 @@ internal fun Modifier.curlGesture( val velocityTracker = VelocityTracker() val startRect by lazy { targetStart.multiply(size) } val endRect by lazy { targetEnd.multiply(size) } - forEachGesture { - awaitPointerEventScope { - val down = awaitFirstDown(requireUnconsumed = false) - if (!startRect.contains(down.position)) { - return@awaitPointerEventScope - } + awaitEachGesture { + val down = awaitFirstDown(requireUnconsumed = false) + if (!startRect.contains(down.position)) { + return@awaitEachGesture + } - // Change X position to be always on the right side for more convenient gesture tracking - val dragStart = down.position.copy(x = size.width.toFloat()) + // Change X position to be always on the right side for more convenient gesture tracking + val dragStart = down.position.copy(x = size.width.toFloat()) - onStart() + onStart() - var dragCurrent = dragStart - drag(down.id) { change -> - dragCurrent = change.position - velocityTracker.addPosition(System.currentTimeMillis(), dragCurrent) - change.consume() - val vector = (dragStart - dragCurrent).rotate(PI.toFloat() / 2) - onCurl(dragCurrent - vector, dragCurrent + vector) - } + var dragCurrent = dragStart + drag(down.id) { change -> + dragCurrent = change.position + velocityTracker.addPosition(systemCurrentTimeMillis(), dragCurrent) + change.consume() + val vector = (dragStart - dragCurrent).rotate(PI.toFloat() / 2) + onCurl(dragCurrent - vector, dragCurrent + vector) + } - if (dragCurrent == dragStart) { - onCancel() - return@awaitPointerEventScope - } + if (dragCurrent == dragStart) { + onCancel() + return@awaitEachGesture + } - val velocity = velocityTracker.calculateVelocity() - val decay = splineBasedDecay(this) - val target = decay.calculateTargetValue( - Offset.VectorConverter, - dragCurrent, - Offset(velocity.x, velocity.y) - ).let { - Offset( - it.x.coerceIn(0f, size.width.toFloat() - 1), - it.y.coerceIn(0f, size.height.toFloat() - 1) - ) - } + val velocity = velocityTracker.calculateVelocity() + val decay = splineBasedDecay(this) + val target = decay.calculateTargetValue( + Offset.VectorConverter, + dragCurrent, + Offset(velocity.x, velocity.y) + ).let { + Offset( + it.x.coerceIn(0f, size.width.toFloat() - 1), + it.y.coerceIn(0f, size.height.toFloat() - 1) + ) + } - if (endRect.contains(target)) { - onEnd() - } else { - onCancel() - } + if (endRect.contains(target)) { + onEnd() + } else { + onCancel() } } } + +internal expect fun systemCurrentTimeMillis(): Long \ No newline at end of file diff --git a/pagecurl/src/main/kotlin/eu/wewox/pagecurl/page/PageCurl.kt b/pagecurl/src/commonMain/kotlin/eu/wewox/pagecurl/page/PageCurl.kt similarity index 100% rename from pagecurl/src/main/kotlin/eu/wewox/pagecurl/page/PageCurl.kt rename to pagecurl/src/commonMain/kotlin/eu/wewox/pagecurl/page/PageCurl.kt diff --git a/pagecurl/src/main/kotlin/eu/wewox/pagecurl/page/PageCurlState.kt b/pagecurl/src/commonMain/kotlin/eu/wewox/pagecurl/page/PageCurlState.kt similarity index 100% rename from pagecurl/src/main/kotlin/eu/wewox/pagecurl/page/PageCurlState.kt rename to pagecurl/src/commonMain/kotlin/eu/wewox/pagecurl/page/PageCurlState.kt diff --git a/pagecurl/src/commonMain/kotlin/eu/wewox/pagecurl/page/TapGesture.kt b/pagecurl/src/commonMain/kotlin/eu/wewox/pagecurl/page/TapGesture.kt new file mode 100644 index 0000000..4ac537d --- /dev/null +++ b/pagecurl/src/commonMain/kotlin/eu/wewox/pagecurl/page/TapGesture.kt @@ -0,0 +1,51 @@ +package eu.wewox.pagecurl.page + +import androidx.compose.foundation.gestures.awaitEachGesture +import androidx.compose.foundation.gestures.awaitFirstDown +import androidx.compose.foundation.gestures.waitForUpOrCancellation +import androidx.compose.ui.Modifier +import androidx.compose.ui.input.pointer.pointerInput +import eu.wewox.pagecurl.ExperimentalPageCurlApi +import eu.wewox.pagecurl.config.PageCurlConfig +import eu.wewox.pagecurl.utils.multiply +import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.launch + +@ExperimentalPageCurlApi +internal fun Modifier.tapGesture( + config: PageCurlConfig, + scope: CoroutineScope, + onTapForward: suspend () -> Unit, + onTapBackward: suspend () -> Unit, +): Modifier = pointerInput(config) { + awaitEachGesture { + val down = awaitFirstDown().also { it.consume() } + val up = waitForUpOrCancellation() ?: return@awaitEachGesture + + if ((down.position - up.position).getDistance() > viewConfiguration.touchSlop) { + return@awaitEachGesture + } + + if (config.tapCustomEnabled && config.onCustomTap(this, size, up.position)) { + return@awaitEachGesture + } + + if (config.tapForwardEnabled && config.tapForwardInteraction.target.multiply(size).contains(up.position)) { + scope.launch { + onTapForward() + } + return@awaitEachGesture + } + + if (config.tapBackwardEnabled && + config.tapBackwardInteraction.target + .multiply(size) + .contains(up.position) + ) { + scope.launch { + onTapBackward() + } + return@awaitEachGesture + } + } +} \ No newline at end of file diff --git a/pagecurl/src/main/kotlin/eu/wewox/pagecurl/utils/MathUtils.kt b/pagecurl/src/commonMain/kotlin/eu/wewox/pagecurl/utils/MathUtils.kt similarity index 100% rename from pagecurl/src/main/kotlin/eu/wewox/pagecurl/utils/MathUtils.kt rename to pagecurl/src/commonMain/kotlin/eu/wewox/pagecurl/utils/MathUtils.kt diff --git a/pagecurl/src/main/kotlin/eu/wewox/pagecurl/utils/Polygon.kt b/pagecurl/src/commonMain/kotlin/eu/wewox/pagecurl/utils/Polygon.kt similarity index 100% rename from pagecurl/src/main/kotlin/eu/wewox/pagecurl/utils/Polygon.kt rename to pagecurl/src/commonMain/kotlin/eu/wewox/pagecurl/utils/Polygon.kt diff --git a/pagecurl/src/main/kotlin/eu/wewox/pagecurl/utils/RectUtils.kt b/pagecurl/src/commonMain/kotlin/eu/wewox/pagecurl/utils/RectUtils.kt similarity index 100% rename from pagecurl/src/main/kotlin/eu/wewox/pagecurl/utils/RectUtils.kt rename to pagecurl/src/commonMain/kotlin/eu/wewox/pagecurl/utils/RectUtils.kt diff --git a/pagecurl/src/desktopMain/kotlin/eu/wewox/pagecurl/page/CurlDraw.desktop.kt b/pagecurl/src/desktopMain/kotlin/eu/wewox/pagecurl/page/CurlDraw.desktop.kt new file mode 100644 index 0000000..0f6604a --- /dev/null +++ b/pagecurl/src/desktopMain/kotlin/eu/wewox/pagecurl/page/CurlDraw.desktop.kt @@ -0,0 +1,10 @@ +package eu.wewox.pagecurl.page + +import androidx.compose.ui.graphics.Paint +import org.jetbrains.skia.FilterBlurMode +import org.jetbrains.skia.MaskFilter + +actual fun Paint.setBlurred(value: Float) { + if (value == 0f) return + asFrameworkPaint().maskFilter = MaskFilter.makeBlur(FilterBlurMode.NORMAL, value / 2f) +} \ No newline at end of file diff --git a/pagecurl/src/desktopMain/kotlin/eu/wewox/pagecurl/page/CurlGesture.desktop.kt b/pagecurl/src/desktopMain/kotlin/eu/wewox/pagecurl/page/CurlGesture.desktop.kt new file mode 100644 index 0000000..332cc68 --- /dev/null +++ b/pagecurl/src/desktopMain/kotlin/eu/wewox/pagecurl/page/CurlGesture.desktop.kt @@ -0,0 +1,3 @@ +package eu.wewox.pagecurl.page + +internal actual fun systemCurrentTimeMillis() = System.currentTimeMillis() \ No newline at end of file diff --git a/pagecurl/src/iosMain/kotlin/eu/wewox/pagecurl/page/CurlDraw.ios.kt b/pagecurl/src/iosMain/kotlin/eu/wewox/pagecurl/page/CurlDraw.ios.kt new file mode 100644 index 0000000..0f6604a --- /dev/null +++ b/pagecurl/src/iosMain/kotlin/eu/wewox/pagecurl/page/CurlDraw.ios.kt @@ -0,0 +1,10 @@ +package eu.wewox.pagecurl.page + +import androidx.compose.ui.graphics.Paint +import org.jetbrains.skia.FilterBlurMode +import org.jetbrains.skia.MaskFilter + +actual fun Paint.setBlurred(value: Float) { + if (value == 0f) return + asFrameworkPaint().maskFilter = MaskFilter.makeBlur(FilterBlurMode.NORMAL, value / 2f) +} \ No newline at end of file diff --git a/pagecurl/src/iosMain/kotlin/eu/wewox/pagecurl/page/CurlGesture.ios.kt b/pagecurl/src/iosMain/kotlin/eu/wewox/pagecurl/page/CurlGesture.ios.kt new file mode 100644 index 0000000..ae1c9a6 --- /dev/null +++ b/pagecurl/src/iosMain/kotlin/eu/wewox/pagecurl/page/CurlGesture.ios.kt @@ -0,0 +1,13 @@ +package eu.wewox.pagecurl.page + +import kotlinx.cinterop.alloc +import kotlinx.cinterop.memScoped +import kotlinx.cinterop.ptr +import platform.posix.gettimeofday +import platform.posix.timeval + +internal actual fun systemCurrentTimeMillis() = memScoped { + val timeVal = alloc() + gettimeofday(timeVal.ptr, null) + (timeVal.tv_sec * 1000) + (timeVal.tv_usec / 1000) +} \ No newline at end of file diff --git a/pagecurl/src/main/AndroidManifest.xml b/pagecurl/src/main/AndroidManifest.xml deleted file mode 100644 index c191e0f..0000000 --- a/pagecurl/src/main/AndroidManifest.xml +++ /dev/null @@ -1,2 +0,0 @@ - - diff --git a/pagecurl/src/main/kotlin/eu/wewox/pagecurl/page/TapGesture.kt b/pagecurl/src/main/kotlin/eu/wewox/pagecurl/page/TapGesture.kt deleted file mode 100644 index 20dd2ef..0000000 --- a/pagecurl/src/main/kotlin/eu/wewox/pagecurl/page/TapGesture.kt +++ /dev/null @@ -1,53 +0,0 @@ -package eu.wewox.pagecurl.page - -import androidx.compose.foundation.gestures.awaitFirstDown -import androidx.compose.foundation.gestures.forEachGesture -import androidx.compose.foundation.gestures.waitForUpOrCancellation -import androidx.compose.ui.Modifier -import androidx.compose.ui.input.pointer.pointerInput -import eu.wewox.pagecurl.ExperimentalPageCurlApi -import eu.wewox.pagecurl.config.PageCurlConfig -import eu.wewox.pagecurl.utils.multiply -import kotlinx.coroutines.CoroutineScope -import kotlinx.coroutines.launch - -@ExperimentalPageCurlApi -internal fun Modifier.tapGesture( - config: PageCurlConfig, - scope: CoroutineScope, - onTapForward: suspend () -> Unit, - onTapBackward: suspend () -> Unit, -): Modifier = pointerInput(config) { - forEachGesture { - awaitPointerEventScope { - val down = awaitFirstDown().also { it.consume() } - val up = waitForUpOrCancellation() ?: return@awaitPointerEventScope - - if ((down.position - up.position).getDistance() > viewConfiguration.touchSlop) { - return@awaitPointerEventScope - } - - if (config.tapCustomEnabled && config.onCustomTap(this, size, up.position)) { - return@awaitPointerEventScope - } - - if (config.tapForwardEnabled && config.tapForwardInteraction.target.multiply(size).contains(up.position)) { - scope.launch { - onTapForward() - } - return@awaitPointerEventScope - } - - if (config.tapBackwardEnabled && - config.tapBackwardInteraction.target - .multiply(size) - .contains(up.position) - ) { - scope.launch { - onTapBackward() - } - return@awaitPointerEventScope - } - } - } -} diff --git a/build-logic/.gitignore b/samples/.gitignore similarity index 100% rename from build-logic/.gitignore rename to samples/.gitignore diff --git a/build-logic/convention/.gitignore b/samples/androidApp/.gitignore similarity index 100% rename from build-logic/convention/.gitignore rename to samples/androidApp/.gitignore diff --git a/samples/androidApp/build.gradle.kts b/samples/androidApp/build.gradle.kts new file mode 100644 index 0000000..a04d949 --- /dev/null +++ b/samples/androidApp/build.gradle.kts @@ -0,0 +1,45 @@ +plugins { + autowire(libs.plugins.kotlin.multiplatform) + autowire(libs.plugins.android.application) + autowire(libs.plugins.jetbrains.compose) +} + +group = property.project.groupName + +kotlin { + androidTarget() + jvmToolchain(17) + sourceSets { + val androidMain by getting { + dependencies { + implementation(projects.samples.shared) + } + } + } +} + +android { + namespace = property.project.groupName + compileSdk = property.project.android.compileSdk + + sourceSets["main"].manifest.srcFile("src/androidMain/AndroidManifest.xml") + + defaultConfig { + applicationId = property.project.groupName + minSdk = property.project.android.minSdk + targetSdk = property.project.android.targetSdk + versionName = property.project.samples.androidApp.versionName + versionCode = property.project.samples.androidApp.versionCode + testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner" + } + buildTypes { + release { + isMinifyEnabled = false + proguardFiles(getDefaultProguardFile("proguard-android-optimize.txt"), "proguard-rules.pro") + } + } + compileOptions { + sourceCompatibility = JavaVersion.VERSION_17 + targetCompatibility = JavaVersion.VERSION_17 + } +} \ No newline at end of file diff --git a/demo/proguard-rules.pro b/samples/androidApp/proguard-rules.pro similarity index 88% rename from demo/proguard-rules.pro rename to samples/androidApp/proguard-rules.pro index 481bb43..ff59496 100644 --- a/demo/proguard-rules.pro +++ b/samples/androidApp/proguard-rules.pro @@ -1,6 +1,6 @@ # Add project specific ProGuard rules here. # You can control the set of applied configuration files using the -# proguardFiles setting in build.gradle. +# proguardFiles setting in build.gradle.kts. # # For more details, see # http://developer.android.com/guide/developing/tools/proguard.html diff --git a/demo/src/main/AndroidManifest.xml b/samples/androidApp/src/androidMain/AndroidManifest.xml similarity index 95% rename from demo/src/main/AndroidManifest.xml rename to samples/androidApp/src/androidMain/AndroidManifest.xml index b32aa5c..ddd8703 100644 --- a/demo/src/main/AndroidManifest.xml +++ b/samples/androidApp/src/androidMain/AndroidManifest.xml @@ -1,6 +1,5 @@ - + S7j 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 Y{EVIz>XsF;zO!toOO^ + + + + IDEDidComputeMac32BitWarning + + + diff --git a/samples/iosApp/iosApp/Assets.xcassets/AccentColor.colorset/Contents.json b/samples/iosApp/iosApp/Assets.xcassets/AccentColor.colorset/Contents.json new file mode 100644 index 0000000..ee7e3ca --- /dev/null +++ b/samples/iosApp/iosApp/Assets.xcassets/AccentColor.colorset/Contents.json @@ -0,0 +1,11 @@ +{ + "colors" : [ + { + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} \ No newline at end of file diff --git a/samples/iosApp/iosApp/Assets.xcassets/AppIcon.appiconset/Contents.json b/samples/iosApp/iosApp/Assets.xcassets/AppIcon.appiconset/Contents.json new file mode 100644 index 0000000..083f644 --- /dev/null +++ b/samples/iosApp/iosApp/Assets.xcassets/AppIcon.appiconset/Contents.json @@ -0,0 +1,14 @@ +{ + "images" : [ + { + "filename" : "app-icon-512.png", + "idiom" : "universal", + "platform" : "ios", + "size" : "512x512" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/samples/iosApp/iosApp/Assets.xcassets/AppIcon.appiconset/app-icon-512.png b/samples/iosApp/iosApp/Assets.xcassets/AppIcon.appiconset/app-icon-512.png new file mode 100644 index 0000000000000000000000000000000000000000..5365c183b4eb67b67f03090295bb242ba0fb9937 GIT binary patch literal 17077 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 B9U%Y! literal 0 HcmV?d00001 diff --git a/samples/iosApp/iosApp/Assets.xcassets/Contents.json b/samples/iosApp/iosApp/Assets.xcassets/Contents.json new file mode 100644 index 0000000..73c0059 --- /dev/null +++ b/samples/iosApp/iosApp/Assets.xcassets/Contents.json @@ -0,0 +1,6 @@ +{ + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/samples/iosApp/iosApp/ContentView.swift b/samples/iosApp/iosApp/ContentView.swift new file mode 100644 index 0000000..473b05a --- /dev/null +++ b/samples/iosApp/iosApp/ContentView.swift @@ -0,0 +1,19 @@ +import UIKit +import SwiftUI +import shared + +struct ComposeView: UIViewControllerRepresentable { + func makeUIViewController(context: Context) -> UIViewController { + let viewController = Main_iosKt.createUIViewController() + return viewController + } + + func updateUIViewController(_ uiViewController: UIViewController, context: Context) {} +} + +struct ContentView: View { + var body: some View { + ComposeView() + .ignoresSafeArea(.all, edges: .bottom) // Compose has own keyboard handler + } +} diff --git a/samples/iosApp/iosApp/Info.plist b/samples/iosApp/iosApp/Info.plist new file mode 100644 index 0000000..412e378 --- /dev/null +++ b/samples/iosApp/iosApp/Info.plist @@ -0,0 +1,50 @@ + + + + + CFBundleDevelopmentRegion + $(DEVELOPMENT_LANGUAGE) + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + $(PRODUCT_BUNDLE_PACKAGE_TYPE) + CFBundleShortVersionString + 1.0 + CFBundleVersion + 1 + LSRequiresIPhoneOS + + CADisableMinimumFrameDurationOnPhone + + UIApplicationSceneManifest + + UIApplicationSupportsMultipleScenes + + + UILaunchScreen + + UIRequiredDeviceCapabilities + + armv7 + + UISupportedInterfaceOrientations + + UIInterfaceOrientationPortrait + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + UISupportedInterfaceOrientations~ipad + + UIInterfaceOrientationPortrait + UIInterfaceOrientationPortraitUpsideDown + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + + diff --git a/samples/iosApp/iosApp/Preview Content/Preview Assets.xcassets/Contents.json b/samples/iosApp/iosApp/Preview Content/Preview Assets.xcassets/Contents.json new file mode 100644 index 0000000..4aa7c53 --- /dev/null +++ b/samples/iosApp/iosApp/Preview Content/Preview Assets.xcassets/Contents.json @@ -0,0 +1,6 @@ +{ + "info" : { + "author" : "xcode", + "version" : 1 + } +} \ No newline at end of file diff --git a/samples/iosApp/iosApp/iOSApp.swift b/samples/iosApp/iosApp/iOSApp.swift new file mode 100644 index 0000000..b7bf2f4 --- /dev/null +++ b/samples/iosApp/iosApp/iOSApp.swift @@ -0,0 +1,10 @@ +import SwiftUI + +@main +struct iOSApp: App { + var body: some Scene { + WindowGroup { + ContentView() + } + } +} diff --git a/samples/shared/.gitignore b/samples/shared/.gitignore new file mode 100644 index 0000000..42afabf --- /dev/null +++ b/samples/shared/.gitignore @@ -0,0 +1 @@ +/build \ No newline at end of file diff --git a/samples/shared/build.gradle.kts b/samples/shared/build.gradle.kts new file mode 100644 index 0000000..f1ff602 --- /dev/null +++ b/samples/shared/build.gradle.kts @@ -0,0 +1,87 @@ +plugins { + autowire(libs.plugins.kotlin.multiplatform) + autowire(libs.plugins.android.library) + autowire(libs.plugins.jetbrains.compose) +} + +group = property.project.groupName + +kotlin { + androidTarget() + jvm("desktop") + listOf( + iosX64(), + iosArm64(), + iosSimulatorArm64() + ).forEach { iosTarget -> + iosTarget.binaries.framework { + baseName = "shared" + isStatic = true + } + } + jvmToolchain(17) + sourceSets { + all { + languageSettings { + optIn("androidx.compose.material3.ExperimentalMaterial3Api") + optIn("eu.wewox.pagecurl.ExperimentalPageCurlApi") + } + } + val commonMain by getting { + dependencies { + implementation(compose.runtime) + implementation(compose.foundation) + implementation(compose.material3) + implementation(app.cash.paging.paging.common) + implementation(app.cash.paging.paging.compose.common) + implementation(projects.pagecurl) + } + } + val androidMain by getting { + dependencies { + api(compose.foundation) + api(androidx.core.core.ktx) + api(androidx.appcompat.appcompat) + api(androidx.activity.activity) + api(androidx.activity.activity.compose) + } + } + val desktopMain by getting { + dependencies { + api(compose.desktop.currentOs) + api(compose.runtime) + api(compose.foundation) + api(compose.material3) + } + } + val iosX64Main by getting + val iosArm64Main by getting + val iosSimulatorArm64Main by getting + val iosMain by creating { + dependsOn(commonMain) + iosX64Main.dependsOn(this) + iosArm64Main.dependsOn(this) + iosSimulatorArm64Main.dependsOn(this) + } + } +} + +android { + namespace = property.project.groupName + compileSdk = property.project.android.compileSdk + + sourceSets["main"].manifest.srcFile("src/androidMain/AndroidManifest.xml") + + defaultConfig { + minSdk = property.project.android.minSdk + } + compileOptions { + sourceCompatibility = JavaVersion.VERSION_17 + targetCompatibility = JavaVersion.VERSION_17 + } +} + +java { + sourceCompatibility = JavaVersion.VERSION_17 + targetCompatibility = JavaVersion.VERSION_17 +} \ No newline at end of file diff --git a/samples/shared/src/androidMain/kotlin/eu/wewox/pagecurl/App.android.kt b/samples/shared/src/androidMain/kotlin/eu/wewox/pagecurl/App.android.kt new file mode 100644 index 0000000..1145196 --- /dev/null +++ b/samples/shared/src/androidMain/kotlin/eu/wewox/pagecurl/App.android.kt @@ -0,0 +1,8 @@ +package eu.wewox.pagecurl + +import androidx.compose.runtime.Composable + +@Composable +internal actual fun BackablePageScreen(content: @Composable () -> Unit) { + content() +} \ No newline at end of file diff --git a/samples/shared/src/commonMain/kotlin/eu/wewox/pagecurl/App.kt b/samples/shared/src/commonMain/kotlin/eu/wewox/pagecurl/App.kt new file mode 100644 index 0000000..ff9f88e --- /dev/null +++ b/samples/shared/src/commonMain/kotlin/eu/wewox/pagecurl/App.kt @@ -0,0 +1,62 @@ +package eu.wewox.pagecurl + +import androidx.compose.animation.Crossfade +import androidx.compose.material3.MaterialTheme +import androidx.compose.material3.Surface +import androidx.compose.runtime.Composable +import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.saveable.rememberSaveable +import androidx.compose.runtime.setValue +import androidx.compose.ui.Modifier +import eu.wewox.pagecurl.screens.BackPagePageCurlScreen +import eu.wewox.pagecurl.screens.InteractionConfigInPageCurlScreen +import eu.wewox.pagecurl.screens.PagingPageCurlScreen +import eu.wewox.pagecurl.screens.SettingsPageCurlScreen +import eu.wewox.pagecurl.screens.ShadowInPageCurlScreen +import eu.wewox.pagecurl.screens.SimplePageCurlScreen +import eu.wewox.pagecurl.screens.StateInPageCurlScreen +import eu.wewox.pagecurl.ui.theme.PageCurlTheme + +/** + * Main view for demo application. + * Contains simple "Crossfade" based navigation to various examples. + */ +@Composable +fun App(modifier: Modifier = Modifier) { + PageCurlTheme { + var example by rememberSaveable { mutableStateOf(null) } + PageStateHandler.callNavToMain = { example = null } + Surface(color = MaterialTheme.colorScheme.background) { + Crossfade(targetState = example, modifier, label = "Crossfade") { selected -> + when (selected) { + null -> RootScreen(onExampleClick = { PageStateHandler.onLeftMain?.invoke(); example = it }) + Example.SimplePageCurl -> BackablePageScreen { SimplePageCurlScreen() } + Example.PagingPageCurl -> BackablePageScreen { PagingPageCurlScreen() } + Example.SettingsPageCurl -> BackablePageScreen { SettingsPageCurlScreen() } + Example.StateInPageCurl -> BackablePageScreen { StateInPageCurlScreen() } + Example.InteractionConfigInPageCurl -> BackablePageScreen { InteractionConfigInPageCurlScreen() } + Example.ShadowPageCurl -> BackablePageScreen { ShadowInPageCurlScreen() } + Example.BackPagePageCurl -> BackablePageScreen { BackPagePageCurlScreen() } + } + } + } + } +} + +object PageStateHandler { + + internal var onLeftMain: (() -> Unit)? = null + internal var callNavToMain: (() -> Unit)? = null + + fun onLeftMain(onLeftMain: () -> Unit) { + this.onLeftMain = onLeftMain + } + + fun navToMain() { + callNavToMain?.invoke() + } +} + +@Composable +internal expect fun BackablePageScreen(content: @Composable () -> Unit) \ No newline at end of file diff --git a/demo/src/main/kotlin/eu/wewox/pagecurl/Example.kt b/samples/shared/src/commonMain/kotlin/eu/wewox/pagecurl/Example.kt similarity index 100% rename from demo/src/main/kotlin/eu/wewox/pagecurl/Example.kt rename to samples/shared/src/commonMain/kotlin/eu/wewox/pagecurl/Example.kt diff --git a/demo/src/main/kotlin/eu/wewox/pagecurl/HowToPageData.kt b/samples/shared/src/commonMain/kotlin/eu/wewox/pagecurl/HowToPageData.kt similarity index 100% rename from demo/src/main/kotlin/eu/wewox/pagecurl/HowToPageData.kt rename to samples/shared/src/commonMain/kotlin/eu/wewox/pagecurl/HowToPageData.kt diff --git a/demo/src/main/kotlin/eu/wewox/pagecurl/RootScreen.kt b/samples/shared/src/commonMain/kotlin/eu/wewox/pagecurl/RootScreen.kt similarity index 100% rename from demo/src/main/kotlin/eu/wewox/pagecurl/RootScreen.kt rename to samples/shared/src/commonMain/kotlin/eu/wewox/pagecurl/RootScreen.kt diff --git a/demo/src/main/kotlin/eu/wewox/pagecurl/components/HowToPage.kt b/samples/shared/src/commonMain/kotlin/eu/wewox/pagecurl/components/HowToPage.kt similarity index 100% rename from demo/src/main/kotlin/eu/wewox/pagecurl/components/HowToPage.kt rename to samples/shared/src/commonMain/kotlin/eu/wewox/pagecurl/components/HowToPage.kt diff --git a/demo/src/main/kotlin/eu/wewox/pagecurl/components/SettingsPopup.kt b/samples/shared/src/commonMain/kotlin/eu/wewox/pagecurl/components/SettingsPopup.kt similarity index 97% rename from demo/src/main/kotlin/eu/wewox/pagecurl/components/SettingsPopup.kt rename to samples/shared/src/commonMain/kotlin/eu/wewox/pagecurl/components/SettingsPopup.kt index ccba5fe..94fcefb 100644 --- a/demo/src/main/kotlin/eu/wewox/pagecurl/components/SettingsPopup.kt +++ b/samples/shared/src/commonMain/kotlin/eu/wewox/pagecurl/components/SettingsPopup.kt @@ -1,5 +1,3 @@ -@file:OptIn(ExperimentalPageCurlApi::class) - package eu.wewox.pagecurl.components import androidx.compose.foundation.layout.Arrangement @@ -20,7 +18,6 @@ import androidx.compose.ui.Modifier import androidx.compose.ui.unit.dp import androidx.compose.ui.window.Popup import androidx.compose.ui.window.PopupProperties -import eu.wewox.pagecurl.ExperimentalPageCurlApi import eu.wewox.pagecurl.config.PageCurlConfig @Composable diff --git a/demo/src/main/kotlin/eu/wewox/pagecurl/components/TopBar.kt b/samples/shared/src/commonMain/kotlin/eu/wewox/pagecurl/components/TopBar.kt similarity index 100% rename from demo/src/main/kotlin/eu/wewox/pagecurl/components/TopBar.kt rename to samples/shared/src/commonMain/kotlin/eu/wewox/pagecurl/components/TopBar.kt diff --git a/demo/src/main/kotlin/eu/wewox/pagecurl/components/ZoomOutLayout.kt b/samples/shared/src/commonMain/kotlin/eu/wewox/pagecurl/components/ZoomOutLayout.kt similarity index 97% rename from demo/src/main/kotlin/eu/wewox/pagecurl/components/ZoomOutLayout.kt rename to samples/shared/src/commonMain/kotlin/eu/wewox/pagecurl/components/ZoomOutLayout.kt index 58f40a0..2d3b404 100644 --- a/demo/src/main/kotlin/eu/wewox/pagecurl/components/ZoomOutLayout.kt +++ b/samples/shared/src/commonMain/kotlin/eu/wewox/pagecurl/components/ZoomOutLayout.kt @@ -1,5 +1,3 @@ -@file:OptIn(ExperimentalPageCurlApi::class) - package eu.wewox.pagecurl.components import androidx.compose.animation.AnimatedVisibility @@ -18,7 +16,6 @@ import androidx.compose.ui.Modifier import androidx.compose.ui.layout.Layout import androidx.compose.ui.unit.IntSize import androidx.compose.ui.unit.dp -import eu.wewox.pagecurl.ExperimentalPageCurlApi import eu.wewox.pagecurl.config.PageCurlConfig /** diff --git a/demo/src/main/kotlin/eu/wewox/pagecurl/screens/BackPagePageCurlScreen.kt b/samples/shared/src/commonMain/kotlin/eu/wewox/pagecurl/screens/BackPagePageCurlScreen.kt similarity index 98% rename from demo/src/main/kotlin/eu/wewox/pagecurl/screens/BackPagePageCurlScreen.kt rename to samples/shared/src/commonMain/kotlin/eu/wewox/pagecurl/screens/BackPagePageCurlScreen.kt index d951277..0b7cb84 100644 --- a/demo/src/main/kotlin/eu/wewox/pagecurl/screens/BackPagePageCurlScreen.kt +++ b/samples/shared/src/commonMain/kotlin/eu/wewox/pagecurl/screens/BackPagePageCurlScreen.kt @@ -1,4 +1,3 @@ -@file:OptIn(ExperimentalPageCurlApi::class) @file:Suppress("MagicNumber") package eu.wewox.pagecurl.screens @@ -31,7 +30,6 @@ import androidx.compose.ui.graphics.Color import androidx.compose.ui.unit.center import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.toOffset -import eu.wewox.pagecurl.ExperimentalPageCurlApi import eu.wewox.pagecurl.HowToPageData import eu.wewox.pagecurl.components.HowToPage import eu.wewox.pagecurl.components.ZoomOutLayout diff --git a/demo/src/main/kotlin/eu/wewox/pagecurl/screens/InteractionConfigInPageCurl.kt b/samples/shared/src/commonMain/kotlin/eu/wewox/pagecurl/screens/InteractionConfigInPageCurl.kt similarity index 98% rename from demo/src/main/kotlin/eu/wewox/pagecurl/screens/InteractionConfigInPageCurl.kt rename to samples/shared/src/commonMain/kotlin/eu/wewox/pagecurl/screens/InteractionConfigInPageCurl.kt index 791250b..c2b2186 100644 --- a/demo/src/main/kotlin/eu/wewox/pagecurl/screens/InteractionConfigInPageCurl.kt +++ b/samples/shared/src/commonMain/kotlin/eu/wewox/pagecurl/screens/InteractionConfigInPageCurl.kt @@ -1,5 +1,3 @@ -@file:OptIn(ExperimentalPageCurlApi::class) - package eu.wewox.pagecurl.screens import androidx.compose.foundation.layout.Arrangement @@ -26,7 +24,6 @@ import androidx.compose.ui.semantics.Role import androidx.compose.ui.unit.center import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.toOffset -import eu.wewox.pagecurl.ExperimentalPageCurlApi import eu.wewox.pagecurl.HowToPageData import eu.wewox.pagecurl.components.HowToPage import eu.wewox.pagecurl.components.ZoomOutLayout diff --git a/demo/src/main/kotlin/eu/wewox/pagecurl/screens/PagingPageCurlScreen.kt b/samples/shared/src/commonMain/kotlin/eu/wewox/pagecurl/screens/PagingPageCurlScreen.kt similarity index 96% rename from demo/src/main/kotlin/eu/wewox/pagecurl/screens/PagingPageCurlScreen.kt rename to samples/shared/src/commonMain/kotlin/eu/wewox/pagecurl/screens/PagingPageCurlScreen.kt index 0c44745..10b6815 100644 --- a/demo/src/main/kotlin/eu/wewox/pagecurl/screens/PagingPageCurlScreen.kt +++ b/samples/shared/src/commonMain/kotlin/eu/wewox/pagecurl/screens/PagingPageCurlScreen.kt @@ -1,5 +1,3 @@ -@file:OptIn(ExperimentalPageCurlApi::class) - package eu.wewox.pagecurl.screens import androidx.compose.foundation.background @@ -20,8 +18,7 @@ import androidx.paging.PagingConfig import androidx.paging.PagingData import androidx.paging.PagingSource import androidx.paging.PagingState -import androidx.paging.compose.collectAsLazyPagingItems -import eu.wewox.pagecurl.ExperimentalPageCurlApi +import app.cash.paging.compose.collectAsLazyPagingItems import eu.wewox.pagecurl.page.PageCurl import eu.wewox.pagecurl.page.rememberPageCurlState import kotlinx.coroutines.delay diff --git a/demo/src/main/kotlin/eu/wewox/pagecurl/screens/SettingsPageCurlScreen.kt b/samples/shared/src/commonMain/kotlin/eu/wewox/pagecurl/screens/SettingsPageCurlScreen.kt similarity index 95% rename from demo/src/main/kotlin/eu/wewox/pagecurl/screens/SettingsPageCurlScreen.kt rename to samples/shared/src/commonMain/kotlin/eu/wewox/pagecurl/screens/SettingsPageCurlScreen.kt index fa1d6a3..c402f82 100644 --- a/demo/src/main/kotlin/eu/wewox/pagecurl/screens/SettingsPageCurlScreen.kt +++ b/samples/shared/src/commonMain/kotlin/eu/wewox/pagecurl/screens/SettingsPageCurlScreen.kt @@ -1,5 +1,3 @@ -@file:OptIn(ExperimentalPageCurlApi::class) - package eu.wewox.pagecurl.screens import androidx.compose.foundation.layout.Box @@ -14,7 +12,6 @@ import androidx.compose.ui.Modifier import androidx.compose.ui.unit.center import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.toOffset -import eu.wewox.pagecurl.ExperimentalPageCurlApi import eu.wewox.pagecurl.HowToPageData import eu.wewox.pagecurl.components.HowToPage import eu.wewox.pagecurl.components.SettingsPopup diff --git a/demo/src/main/kotlin/eu/wewox/pagecurl/screens/ShadowInPageCurlScreen.kt b/samples/shared/src/commonMain/kotlin/eu/wewox/pagecurl/screens/ShadowInPageCurlScreen.kt similarity index 97% rename from demo/src/main/kotlin/eu/wewox/pagecurl/screens/ShadowInPageCurlScreen.kt rename to samples/shared/src/commonMain/kotlin/eu/wewox/pagecurl/screens/ShadowInPageCurlScreen.kt index cfe7736..e17e8ed 100644 --- a/demo/src/main/kotlin/eu/wewox/pagecurl/screens/ShadowInPageCurlScreen.kt +++ b/samples/shared/src/commonMain/kotlin/eu/wewox/pagecurl/screens/ShadowInPageCurlScreen.kt @@ -1,4 +1,3 @@ -@file:OptIn(ExperimentalPageCurlApi::class) @file:Suppress("MagicNumber") package eu.wewox.pagecurl.screens @@ -20,7 +19,6 @@ import androidx.compose.ui.unit.DpOffset import androidx.compose.ui.unit.center import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.toOffset -import eu.wewox.pagecurl.ExperimentalPageCurlApi import eu.wewox.pagecurl.HowToPageData import eu.wewox.pagecurl.components.HowToPage import eu.wewox.pagecurl.components.ZoomOutLayout diff --git a/demo/src/main/kotlin/eu/wewox/pagecurl/screens/SimplePageCurlScreen.kt b/samples/shared/src/commonMain/kotlin/eu/wewox/pagecurl/screens/SimplePageCurlScreen.kt similarity index 87% rename from demo/src/main/kotlin/eu/wewox/pagecurl/screens/SimplePageCurlScreen.kt rename to samples/shared/src/commonMain/kotlin/eu/wewox/pagecurl/screens/SimplePageCurlScreen.kt index 824fc5b..0932db0 100644 --- a/demo/src/main/kotlin/eu/wewox/pagecurl/screens/SimplePageCurlScreen.kt +++ b/samples/shared/src/commonMain/kotlin/eu/wewox/pagecurl/screens/SimplePageCurlScreen.kt @@ -1,5 +1,3 @@ -@file:OptIn(ExperimentalPageCurlApi::class) - package eu.wewox.pagecurl.screens import androidx.compose.foundation.layout.Box @@ -7,7 +5,6 @@ import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.runtime.Composable import androidx.compose.runtime.remember import androidx.compose.ui.Modifier -import eu.wewox.pagecurl.ExperimentalPageCurlApi import eu.wewox.pagecurl.HowToPageData import eu.wewox.pagecurl.components.HowToPage import eu.wewox.pagecurl.page.PageCurl diff --git a/demo/src/main/kotlin/eu/wewox/pagecurl/screens/StateInPageCurlScreen.kt b/samples/shared/src/commonMain/kotlin/eu/wewox/pagecurl/screens/StateInPageCurlScreen.kt similarity index 97% rename from demo/src/main/kotlin/eu/wewox/pagecurl/screens/StateInPageCurlScreen.kt rename to samples/shared/src/commonMain/kotlin/eu/wewox/pagecurl/screens/StateInPageCurlScreen.kt index 375827b..143d575 100644 --- a/demo/src/main/kotlin/eu/wewox/pagecurl/screens/StateInPageCurlScreen.kt +++ b/samples/shared/src/commonMain/kotlin/eu/wewox/pagecurl/screens/StateInPageCurlScreen.kt @@ -1,5 +1,3 @@ -@file:OptIn(ExperimentalPageCurlApi::class) - package eu.wewox.pagecurl.screens import androidx.compose.foundation.horizontalScroll @@ -23,7 +21,6 @@ import androidx.compose.ui.Modifier import androidx.compose.ui.unit.center import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.toOffset -import eu.wewox.pagecurl.ExperimentalPageCurlApi import eu.wewox.pagecurl.HowToPageData import eu.wewox.pagecurl.components.HowToPage import eu.wewox.pagecurl.components.ZoomOutLayout diff --git a/demo/src/main/kotlin/eu/wewox/pagecurl/ui/Spacing.kt b/samples/shared/src/commonMain/kotlin/eu/wewox/pagecurl/ui/Spacing.kt similarity index 100% rename from demo/src/main/kotlin/eu/wewox/pagecurl/ui/Spacing.kt rename to samples/shared/src/commonMain/kotlin/eu/wewox/pagecurl/ui/Spacing.kt diff --git a/demo/src/main/kotlin/eu/wewox/pagecurl/ui/theme/Color.kt b/samples/shared/src/commonMain/kotlin/eu/wewox/pagecurl/ui/theme/Color.kt similarity index 100% rename from demo/src/main/kotlin/eu/wewox/pagecurl/ui/theme/Color.kt rename to samples/shared/src/commonMain/kotlin/eu/wewox/pagecurl/ui/theme/Color.kt diff --git a/demo/src/main/kotlin/eu/wewox/pagecurl/ui/theme/Theme.kt b/samples/shared/src/commonMain/kotlin/eu/wewox/pagecurl/ui/theme/Theme.kt similarity index 100% rename from demo/src/main/kotlin/eu/wewox/pagecurl/ui/theme/Theme.kt rename to samples/shared/src/commonMain/kotlin/eu/wewox/pagecurl/ui/theme/Theme.kt diff --git a/samples/shared/src/desktopMain/kotlin/eu/wewox/pagecurl/App.desktop.kt b/samples/shared/src/desktopMain/kotlin/eu/wewox/pagecurl/App.desktop.kt new file mode 100644 index 0000000..d0231aa --- /dev/null +++ b/samples/shared/src/desktopMain/kotlin/eu/wewox/pagecurl/App.desktop.kt @@ -0,0 +1,13 @@ +package eu.wewox.pagecurl + +import androidx.compose.foundation.layout.Box +import androidx.compose.runtime.Composable +import eu.wewox.pagecurl.components.TopBar + +@Composable +internal actual fun BackablePageScreen(content: @Composable () -> Unit) { + Box { + content() + TopBar(title = "", onBackClick = { PageStateHandler.navToMain() }) + } +} \ No newline at end of file diff --git a/samples/shared/src/iosMain/kotlin/Main.ios.kt b/samples/shared/src/iosMain/kotlin/Main.ios.kt new file mode 100644 index 0000000..9aaf6a8 --- /dev/null +++ b/samples/shared/src/iosMain/kotlin/Main.ios.kt @@ -0,0 +1,6 @@ +@file:Suppress("unused") + +import androidx.compose.ui.window.ComposeUIViewController +import eu.wewox.pagecurl.App + +fun createUIViewController() = ComposeUIViewController { App() } \ No newline at end of file diff --git a/samples/shared/src/iosMain/kotlin/eu/wewox/pagecurl/App.ios.kt b/samples/shared/src/iosMain/kotlin/eu/wewox/pagecurl/App.ios.kt new file mode 100644 index 0000000..d0231aa --- /dev/null +++ b/samples/shared/src/iosMain/kotlin/eu/wewox/pagecurl/App.ios.kt @@ -0,0 +1,13 @@ +package eu.wewox.pagecurl + +import androidx.compose.foundation.layout.Box +import androidx.compose.runtime.Composable +import eu.wewox.pagecurl.components.TopBar + +@Composable +internal actual fun BackablePageScreen(content: @Composable () -> Unit) { + Box { + content() + TopBar(title = "", onBackClick = { PageStateHandler.navToMain() }) + } +} \ No newline at end of file diff --git a/settings.gradle.kts b/settings.gradle.kts index dc66895..753a76c 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -1,23 +1,19 @@ +enableFeaturePreview("TYPESAFE_PROJECT_ACCESSORS") pluginManagement { - includeBuild("build-logic") repositories { - google() - mavenCentral() gradlePluginPortal() - } -} - -plugins { - id("org.gradle.toolchains.foojay-resolver-convention") version ("0.7.0") -} - -dependencyResolutionManagement { - repositories { google() mavenCentral() } } - -rootProject.name = "PageCurl" -include(":demo") -include(":pagecurl") +plugins { + id("com.highcapable.sweetdependency") version "1.0.2" + id("com.highcapable.sweetproperty") version "1.0.3" +} +sweetProperty { + global { sourcesCode { isEnable = false } } + rootProject { all { isEnable = false } } +} +rootProject.name = "pagecurl-multiplatform" +include(":samples:androidApp", ":samples:desktopApp", ":samples:shared") +include(":pagecurl") \ No newline at end of file