Browse Source

Move experimental/examples to examples (#2976)

* Move experimental/examples to examples

* Change version to 1.4.0-rc01
pull/2977/head
Nikita Lipsky 2 years ago committed by GitHub
parent
commit
a8003a0f5d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 0
      examples/chat/.gitignore
  2. 0
      examples/chat/.run/desktopApp.run.xml
  3. 0
      examples/chat/.run/jsApp.run.xml
  4. 0
      examples/chat/README.md
  5. 0
      examples/chat/androidApp/build.gradle.kts
  6. 0
      examples/chat/androidApp/src/androidMain/AndroidManifest.xml
  7. 0
      examples/chat/androidApp/src/androidMain/kotlin/MainActivity.kt
  8. 0
      examples/chat/androidApp/src/androidMain/res/values/strings.xml
  9. 0
      examples/chat/build.gradle.kts
  10. 0
      examples/chat/desktopApp/build.gradle.kts
  11. 0
      examples/chat/desktopApp/src/jvmMain/kotlin/Main.kt
  12. 2
      examples/chat/gradle.properties
  13. 0
      examples/chat/gradle/wrapper/gradle-wrapper.jar
  14. 0
      examples/chat/gradle/wrapper/gradle-wrapper.properties
  15. 0
      examples/chat/gradlew
  16. 0
      examples/chat/iosApp/Configuration/Config.xcconfig
  17. 0
      examples/chat/iosApp/Podfile
  18. 0
      examples/chat/iosApp/iosApp.xcodeproj/project.pbxproj
  19. 0
      examples/chat/iosApp/iosApp/ComposeInsideSwiftUIScreen.swift
  20. 0
      examples/chat/iosApp/iosApp/ComposeViewControllerToSwiftUI.swift
  21. 0
      examples/chat/iosApp/iosApp/GradientTemplate.swift
  22. 0
      examples/chat/iosApp/iosApp/Info.plist
  23. 0
      examples/chat/iosApp/iosApp/KotlinToSwiftHelper.swift
  24. 0
      examples/chat/iosApp/iosApp/YetAnotherSwiftUIScreen.swift
  25. 0
      examples/chat/iosApp/iosApp/iosApp.swift
  26. 0
      examples/chat/jsApp/build.gradle.kts
  27. 0
      examples/chat/jsApp/src/jsMain/kotlin/main.js.kt
  28. 0
      examples/chat/jsApp/src/jsMain/resources/index.html
  29. 0
      examples/chat/jsApp/src/jsMain/resources/styles.css
  30. 0
      examples/chat/run-configurations.png
  31. 0
      examples/chat/settings.gradle.kts
  32. 0
      examples/chat/shared/build.gradle.kts
  33. 0
      examples/chat/shared/src/androidMain/AndroidManifest.xml
  34. 0
      examples/chat/shared/src/androidMain/kotlin/currentTime.android.kt
  35. 0
      examples/chat/shared/src/androidMain/kotlin/main.android.kt
  36. 0
      examples/chat/shared/src/commonMain/kotlin/ChatApp.kt
  37. 0
      examples/chat/shared/src/commonMain/kotlin/Colors.kt
  38. 0
      examples/chat/shared/src/commonMain/kotlin/Data.kt
  39. 0
      examples/chat/shared/src/commonMain/kotlin/Messages.kt
  40. 0
      examples/chat/shared/src/commonMain/kotlin/Reducer.kt
  41. 0
      examples/chat/shared/src/commonMain/kotlin/SendMessage.kt
  42. 0
      examples/chat/shared/src/commonMain/kotlin/Store.kt
  43. 0
      examples/chat/shared/src/commonMain/kotlin/currentTime.common.kt
  44. 0
      examples/chat/shared/src/desktopMain/kotlin/currentTime.desktop.kt
  45. 0
      examples/chat/shared/src/desktopMain/kotlin/main.desktop.kt
  46. 0
      examples/chat/shared/src/iosMain/kotlin/currentTime.ios.kt
  47. 0
      examples/chat/shared/src/iosMain/kotlin/main.ios.kt
  48. 0
      examples/chat/shared/src/jsMain/kotlin/currentTime.js.kt
  49. 0
      examples/chat/shared/src/jsMain/kotlin/main.js.kt
  50. 0
      examples/chat/shared/src/macosMain/kotlin/currentTime.macos.kt
  51. 0
      examples/chat/shared/src/macosMain/kotlin/main.macos.kt
  52. 12
      examples/codeviewer/.gitignore
  53. 21
      examples/codeviewer/.run/desktop.run.xml
  54. 0
      examples/codeviewer/.run/desktopApp.run.xml
  55. 26
      examples/codeviewer/README.md
  56. 26
      examples/codeviewer/android/build.gradle.kts
  57. 32
      examples/codeviewer/android/src/main/java/org/jetbrains/codeviewer/MainActivity.kt
  58. 0
      examples/codeviewer/androidApp/build.gradle.kts
  59. 0
      examples/codeviewer/androidApp/src/androidMain/AndroidManifest.xml
  60. 0
      examples/codeviewer/androidApp/src/androidMain/assets/data/EditorView.kt
  61. 0
      examples/codeviewer/androidApp/src/androidMain/kotlin/org/jetbrains/codeviewer/MainActivity.kt
  62. 0
      examples/codeviewer/androidApp/src/androidMain/res/drawable/ic_launcher_foreground.xml
  63. 0
      examples/codeviewer/androidApp/src/androidMain/res/mipmap-anydpi-v26/ic_launcher.xml
  64. 0
      examples/codeviewer/androidApp/src/androidMain/res/mipmap-anydpi-v26/ic_launcher_round.xml
  65. 0
      examples/codeviewer/androidApp/src/androidMain/res/values/ic_launcher_background.xml
  66. 0
      examples/codeviewer/androidApp/src/androidMain/res/values/strings.xml
  67. 50
      examples/codeviewer/common/build.gradle.kts
  68. 9
      examples/codeviewer/common/src/commonMain/kotlin/org/jetbrains/codeviewer/platform/Resources.kt
  69. 19
      examples/codeviewer/common/src/commonMain/kotlin/org/jetbrains/codeviewer/platform/Scrollbar.kt
  70. 107
      examples/codeviewer/common/src/commonMain/kotlin/org/jetbrains/codeviewer/ui/CodeViewerView.kt
  71. 35
      examples/codeviewer/common/src/commonMain/kotlin/org/jetbrains/codeviewer/ui/MainView.kt
  72. 64
      examples/codeviewer/common/src/commonMain/kotlin/org/jetbrains/codeviewer/ui/common/Fonts.kt
  73. 35
      examples/codeviewer/common/src/commonMain/kotlin/org/jetbrains/codeviewer/ui/editor/EditorEmptyView.kt
  74. 78
      examples/codeviewer/common/src/commonMain/kotlin/org/jetbrains/codeviewer/ui/editor/EditorTabsView.kt
  75. 186
      examples/codeviewer/common/src/commonMain/kotlin/org/jetbrains/codeviewer/ui/editor/EditorView.kt
  76. 125
      examples/codeviewer/common/src/commonMain/kotlin/org/jetbrains/codeviewer/ui/filetree/FileTreeView.kt
  77. 47
      examples/codeviewer/common/src/commonMain/kotlin/org/jetbrains/codeviewer/ui/statusbar/StatusBar.kt
  78. 27
      examples/codeviewer/common/src/commonMain/kotlin/org/jetbrains/codeviewer/util/Loadable.kt
  79. 95
      examples/codeviewer/common/src/commonMain/kotlin/org/jetbrains/codeviewer/util/VerticalSplittable.kt
  80. 10
      examples/codeviewer/common/src/desktopMain/kotlin/org/jetbrains/codeviewer/platform/Mouse.kt
  81. 177
      examples/codeviewer/common/src/jvmMain/kotlin/org/jetbrains/codeviewer/platform/JvmFile.kt
  82. 41
      examples/codeviewer/desktop/build.gradle.kts
  83. 17
      examples/codeviewer/desktop/src/jvmMain/kotlin/org/jetbrains/codeviewer/main.kt
  84. 0
      examples/codeviewer/desktopApp/build.gradle.kts
  85. 0
      examples/codeviewer/desktopApp/src/jvmMain/kotlin/org/jetbrains/codeviewer/main.kt
  86. 0
      examples/codeviewer/desktopApp/src/jvmMain/resources/ic_launcher.png
  87. 36
      examples/codeviewer/gradle.properties
  88. BIN
      examples/codeviewer/gradle/wrapper/gradle-wrapper.jar
  89. 263
      examples/codeviewer/gradlew
  90. 37
      examples/codeviewer/gradlew.bat
  91. 0
      examples/codeviewer/iosApp/Configuration/Config.xcconfig
  92. 0
      examples/codeviewer/iosApp/Podfile
  93. 0
      examples/codeviewer/iosApp/iosApp.xcodeproj/project.pbxproj
  94. 0
      examples/codeviewer/iosApp/iosApp/Assets.xcassets/AccentColor.colorset/Contents.json
  95. 0
      examples/codeviewer/iosApp/iosApp/Assets.xcassets/AppIcon.appiconset/Contents.json
  96. 0
      examples/codeviewer/iosApp/iosApp/Assets.xcassets/Contents.json
  97. 0
      examples/codeviewer/iosApp/iosApp/ContentView.swift
  98. 0
      examples/codeviewer/iosApp/iosApp/Info.plist
  99. 0
      examples/codeviewer/iosApp/iosApp/Preview Content/Preview Assets.xcassets/Contents.json
  100. 0
      examples/codeviewer/iosApp/iosApp/iOSApp.swift
  101. Some files were not shown because too many files have changed in this diff Show More

0
experimental/examples/chat-mpp/.gitignore → examples/chat/.gitignore vendored

0
experimental/examples/chat-mpp/.run/desktopApp.run.xml → examples/chat/.run/desktopApp.run.xml

0
experimental/examples/chat-mpp/.run/jsApp.run.xml → examples/chat/.run/jsApp.run.xml

0
experimental/examples/chat-mpp/README.md → examples/chat/README.md

0
experimental/examples/chat-mpp/androidApp/build.gradle.kts → examples/chat/androidApp/build.gradle.kts

0
experimental/examples/chat-mpp/androidApp/src/androidMain/AndroidManifest.xml → examples/chat/androidApp/src/androidMain/AndroidManifest.xml

0
experimental/examples/chat-mpp/androidApp/src/androidMain/kotlin/MainActivity.kt → examples/chat/androidApp/src/androidMain/kotlin/MainActivity.kt

0
experimental/examples/chat-mpp/androidApp/src/androidMain/res/values/strings.xml → examples/chat/androidApp/src/androidMain/res/values/strings.xml

0
experimental/examples/chat-mpp/build.gradle.kts → examples/chat/build.gradle.kts

0
experimental/examples/chat-mpp/desktopApp/build.gradle.kts → examples/chat/desktopApp/build.gradle.kts

0
experimental/examples/chat-mpp/desktopApp/src/jvmMain/kotlin/Main.kt → examples/chat/desktopApp/src/jvmMain/kotlin/Main.kt

2
experimental/examples/chat-mpp/gradle.properties → examples/chat/gradle.properties

@ -13,4 +13,4 @@ kotlin.mpp.androidSourceSetLayoutVersion=2
kotlin.native.binary.memoryModel=experimental kotlin.native.binary.memoryModel=experimental
kotlin.version=1.8.0 kotlin.version=1.8.0
agp.version=7.1.3 agp.version=7.1.3
compose.version=1.4.0-alpha01-dev1004 compose.version=1.4.0-rc01

0
experimental/examples/chat-mpp/gradle/wrapper/gradle-wrapper.jar → examples/chat/gradle/wrapper/gradle-wrapper.jar vendored

0
experimental/examples/chat-mpp/gradle/wrapper/gradle-wrapper.properties → examples/chat/gradle/wrapper/gradle-wrapper.properties vendored

0
experimental/examples/chat-mpp/gradlew → examples/chat/gradlew vendored

0
experimental/examples/chat-mpp/iosApp/Configuration/Config.xcconfig → examples/chat/iosApp/Configuration/Config.xcconfig

0
experimental/examples/chat-mpp/iosApp/Podfile → examples/chat/iosApp/Podfile

0
experimental/examples/chat-mpp/iosApp/iosApp.xcodeproj/project.pbxproj → examples/chat/iosApp/iosApp.xcodeproj/project.pbxproj

0
experimental/examples/chat-mpp/iosApp/iosApp/ComposeInsideSwiftUIScreen.swift → examples/chat/iosApp/iosApp/ComposeInsideSwiftUIScreen.swift

0
experimental/examples/chat-mpp/iosApp/iosApp/ComposeViewControllerToSwiftUI.swift → examples/chat/iosApp/iosApp/ComposeViewControllerToSwiftUI.swift

0
experimental/examples/chat-mpp/iosApp/iosApp/GradientTemplate.swift → examples/chat/iosApp/iosApp/GradientTemplate.swift

0
experimental/examples/chat-mpp/iosApp/iosApp/Info.plist → examples/chat/iosApp/iosApp/Info.plist

0
experimental/examples/chat-mpp/iosApp/iosApp/KotlinToSwiftHelper.swift → examples/chat/iosApp/iosApp/KotlinToSwiftHelper.swift

0
experimental/examples/chat-mpp/iosApp/iosApp/YetAnotherSwiftUIScreen.swift → examples/chat/iosApp/iosApp/YetAnotherSwiftUIScreen.swift

0
experimental/examples/chat-mpp/iosApp/iosApp/iosApp.swift → examples/chat/iosApp/iosApp/iosApp.swift

0
experimental/examples/chat-mpp/jsApp/build.gradle.kts → examples/chat/jsApp/build.gradle.kts

0
experimental/examples/chat-mpp/jsApp/src/jsMain/kotlin/main.js.kt → examples/chat/jsApp/src/jsMain/kotlin/main.js.kt

0
experimental/examples/chat-mpp/jsApp/src/jsMain/resources/index.html → examples/chat/jsApp/src/jsMain/resources/index.html

0
experimental/examples/chat-mpp/jsApp/src/jsMain/resources/styles.css → examples/chat/jsApp/src/jsMain/resources/styles.css

0
experimental/examples/chat-mpp/run-configurations.png → examples/chat/run-configurations.png

Before

Width:  |  Height:  |  Size: 21 KiB

After

Width:  |  Height:  |  Size: 21 KiB

0
experimental/examples/chat-mpp/settings.gradle.kts → examples/chat/settings.gradle.kts

0
experimental/examples/chat-mpp/shared/build.gradle.kts → examples/chat/shared/build.gradle.kts

0
experimental/examples/chat-mpp/shared/src/androidMain/AndroidManifest.xml → examples/chat/shared/src/androidMain/AndroidManifest.xml

0
experimental/examples/chat-mpp/shared/src/androidMain/kotlin/currentTime.android.kt → examples/chat/shared/src/androidMain/kotlin/currentTime.android.kt

0
experimental/examples/chat-mpp/shared/src/androidMain/kotlin/main.android.kt → examples/chat/shared/src/androidMain/kotlin/main.android.kt

0
experimental/examples/chat-mpp/shared/src/commonMain/kotlin/ChatApp.kt → examples/chat/shared/src/commonMain/kotlin/ChatApp.kt

0
experimental/examples/chat-mpp/shared/src/commonMain/kotlin/Colors.kt → examples/chat/shared/src/commonMain/kotlin/Colors.kt

0
experimental/examples/chat-mpp/shared/src/commonMain/kotlin/Data.kt → examples/chat/shared/src/commonMain/kotlin/Data.kt

0
experimental/examples/chat-mpp/shared/src/commonMain/kotlin/Messages.kt → examples/chat/shared/src/commonMain/kotlin/Messages.kt

0
experimental/examples/chat-mpp/shared/src/commonMain/kotlin/Reducer.kt → examples/chat/shared/src/commonMain/kotlin/Reducer.kt

0
experimental/examples/chat-mpp/shared/src/commonMain/kotlin/SendMessage.kt → examples/chat/shared/src/commonMain/kotlin/SendMessage.kt

0
experimental/examples/chat-mpp/shared/src/commonMain/kotlin/Store.kt → examples/chat/shared/src/commonMain/kotlin/Store.kt

0
experimental/examples/chat-mpp/shared/src/commonMain/kotlin/currentTime.common.kt → examples/chat/shared/src/commonMain/kotlin/currentTime.common.kt

0
experimental/examples/chat-mpp/shared/src/desktopMain/kotlin/currentTime.desktop.kt → examples/chat/shared/src/desktopMain/kotlin/currentTime.desktop.kt

0
experimental/examples/chat-mpp/shared/src/desktopMain/kotlin/main.desktop.kt → examples/chat/shared/src/desktopMain/kotlin/main.desktop.kt

0
experimental/examples/chat-mpp/shared/src/iosMain/kotlin/currentTime.ios.kt → examples/chat/shared/src/iosMain/kotlin/currentTime.ios.kt

0
experimental/examples/chat-mpp/shared/src/iosMain/kotlin/main.ios.kt → examples/chat/shared/src/iosMain/kotlin/main.ios.kt

0
experimental/examples/chat-mpp/shared/src/jsMain/kotlin/currentTime.js.kt → examples/chat/shared/src/jsMain/kotlin/currentTime.js.kt

0
experimental/examples/chat-mpp/shared/src/jsMain/kotlin/main.js.kt → examples/chat/shared/src/jsMain/kotlin/main.js.kt

0
experimental/examples/chat-mpp/shared/src/macosMain/kotlin/currentTime.macos.kt → examples/chat/shared/src/macosMain/kotlin/currentTime.macos.kt

0
experimental/examples/chat-mpp/shared/src/macosMain/kotlin/main.macos.kt → examples/chat/shared/src/macosMain/kotlin/main.macos.kt

12
examples/codeviewer/.gitignore vendored

@ -2,14 +2,14 @@
.gradle .gradle
/local.properties /local.properties
/.idea /.idea
/.idea/caches
/.idea/libraries
/.idea/modules.xml
/.idea/workspace.xml
/.idea/navEditor.xml
/.idea/assetWizardSettings.xml
.DS_Store .DS_Store
build/ build/
/captures /captures
.externalNativeBuild .externalNativeBuild
.cxx .cxx
iosApp/Podfile.lock
iosApp/Pods/*
iosApp/iosApp.xcworkspace/*
iosApp/iosApp.xcodeproj/*
!iosApp/iosApp.xcodeproj/project.pbxproj
shared/shared.podspec

21
examples/codeviewer/.run/desktop.run.xml

@ -1,21 +0,0 @@
<component name="ProjectRunConfigurationManager">
<configuration default="false" name="desktop" type="GradleRunConfiguration" factoryName="Gradle">
<ExternalSystemSettings>
<option name="executionName" />
<option name="externalProjectPath" value="$PROJECT_DIR$/desktop" />
<option name="externalSystemIdString" value="GRADLE" />
<option name="scriptParameters" value="" />
<option name="taskDescriptions">
<list />
</option>
<option name="taskNames">
<list>
<option value="run" />
</list>
</option>
<option name="vmOptions" value="" />
</ExternalSystemSettings>
<GradleScriptDebugEnabled>true</GradleScriptDebugEnabled>
<method v="2" />
</configuration>
</component>

0
experimental/examples/codeviewer/.run/desktopApp.run.xml → examples/codeviewer/.run/desktopApp.run.xml

26
examples/codeviewer/README.md

@ -1,10 +1,21 @@
MPP Code Viewer example for desktop/android written in Multiplatform Compose library. # Code Viewer
MPP Code Viewer example for desktop/android/iOS written in Multiplatform Compose library.
### Running desktop application ## How to run
* To run, launch command: `./gradlew :desktop:run` Choose a run configuration for an appropriate target in IDE and run it.
* Or choose **desktop** configuration in IDE and run it.
![desktop-run-configuration.png](screenshots/desktop-run-configuration.png) ![run-configurations.png](run-configurations.png)
To run on iOS device, please correct `TEAM_ID` value in `iosApp/Configuration/Config.xcconfig` with your Apple Team ID.
Alternatively, you may setup signing within XCode opening `iosApp/iosApp.xcworkspace` and then
using "Signing & Capabilities" tab of `Codeviewer` target.
Then choose **iosApp** configuration in IDE and run it.
## Run on desktop via Gradle
`./gradlew desktopApp:run`
### Building native desktop distribution ### Building native desktop distribution
``` ```
@ -12,9 +23,4 @@ MPP Code Viewer example for desktop/android written in Multiplatform Compose lib
# outputs are written to desktop/build/compose/binaries # outputs are written to desktop/build/compose/binaries
``` ```
### Installing Android application on device/emulator
```
./gradlew installDebug
```
![Desktop](screenshots/codeviewer.png) ![Desktop](screenshots/codeviewer.png)

26
examples/codeviewer/android/build.gradle.kts

@ -1,26 +0,0 @@
plugins {
id("com.android.application")
kotlin("android")
id("org.jetbrains.compose")
}
android {
compileSdk = 33
defaultConfig {
minSdk = 26
targetSdk = 33
versionCode = 1
versionName = "1.0"
}
compileOptions {
sourceCompatibility = JavaVersion.VERSION_11
targetCompatibility = JavaVersion.VERSION_11
}
}
dependencies {
implementation(project(":common"))
implementation("androidx.activity:activity-compose:1.5.0")
}

32
examples/codeviewer/android/src/main/java/org/jetbrains/codeviewer/MainActivity.kt

@ -1,32 +0,0 @@
package org.jetbrains.codeviewer
import android.os.Bundle
import androidx.activity.compose.setContent
import androidx.appcompat.app.AppCompatActivity
import org.jetbrains.codeviewer.platform._HomeFolder
import org.jetbrains.codeviewer.ui.MainView
import java.io.File
import java.io.FileOutputStream
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
copyAssets()
_HomeFolder = filesDir
setContent {
MainView()
}
}
private fun copyAssets() {
for (filename in assets.list("data")!!) {
assets.open("data/$filename").use { assetStream ->
val file = File(filesDir, filename)
FileOutputStream(file).use { fileStream ->
assetStream.copyTo(fileStream)
}
}
}
}
}

0
experimental/examples/codeviewer/androidApp/build.gradle.kts → examples/codeviewer/androidApp/build.gradle.kts

0
examples/codeviewer/android/src/main/AndroidManifest.xml → examples/codeviewer/androidApp/src/androidMain/AndroidManifest.xml

0
examples/codeviewer/android/src/main/assets/data/EditorView.kt → examples/codeviewer/androidApp/src/androidMain/assets/data/EditorView.kt

0
experimental/examples/codeviewer/androidApp/src/androidMain/kotlin/org/jetbrains/codeviewer/MainActivity.kt → examples/codeviewer/androidApp/src/androidMain/kotlin/org/jetbrains/codeviewer/MainActivity.kt

0
examples/codeviewer/android/src/main/res/drawable/ic_launcher_foreground.xml → examples/codeviewer/androidApp/src/androidMain/res/drawable/ic_launcher_foreground.xml

0
examples/codeviewer/android/src/main/res/mipmap-anydpi-v26/ic_launcher.xml → examples/codeviewer/androidApp/src/androidMain/res/mipmap-anydpi-v26/ic_launcher.xml

0
examples/codeviewer/android/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml → examples/codeviewer/androidApp/src/androidMain/res/mipmap-anydpi-v26/ic_launcher_round.xml

0
examples/codeviewer/android/src/main/res/values/ic_launcher_background.xml → examples/codeviewer/androidApp/src/androidMain/res/values/ic_launcher_background.xml

0
examples/codeviewer/android/src/main/res/values/strings.xml → examples/codeviewer/androidApp/src/androidMain/res/values/strings.xml

50
examples/codeviewer/common/build.gradle.kts

@ -1,50 +0,0 @@
plugins {
id("com.android.library")
kotlin("multiplatform")
id("org.jetbrains.compose")
}
kotlin {
android()
jvm("desktop")
sourceSets {
named("commonMain") {
dependencies {
api(compose.runtime)
api(compose.foundation)
api(compose.material)
api(compose.materialIconsExtended)
}
}
named("androidMain") {
kotlin.srcDirs("src/jvmMain/kotlin")
dependencies {
api("androidx.appcompat:appcompat:1.5.1")
api("androidx.core:core-ktx:1.8.0")
}
}
named("desktopMain") {
kotlin.srcDirs("src/jvmMain/kotlin")
dependencies {
api(compose.desktop.common)
}
}
}
}
android {
compileSdk = 33
defaultConfig {
minSdk = 26
targetSdk = 33
}
sourceSets {
named("main") {
manifest.srcFile("src/androidMain/AndroidManifest.xml")
res.srcDirs("src/androidMain/res", "src/commonMain/resources")
}
}
}

9
examples/codeviewer/common/src/commonMain/kotlin/org/jetbrains/codeviewer/platform/Resources.kt

@ -1,9 +0,0 @@
package org.jetbrains.codeviewer.platform
import androidx.compose.runtime.Composable
import androidx.compose.ui.text.font.Font
import androidx.compose.ui.text.font.FontStyle
import androidx.compose.ui.text.font.FontWeight
@Composable
expect fun font(name: String, res: String, weight: FontWeight, style: FontStyle): Font

19
examples/codeviewer/common/src/commonMain/kotlin/org/jetbrains/codeviewer/platform/Scrollbar.kt

@ -1,19 +0,0 @@
package org.jetbrains.codeviewer.platform
import androidx.compose.foundation.ScrollState
import androidx.compose.foundation.lazy.LazyListState
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.unit.Dp
@Composable
expect fun VerticalScrollbar(
modifier: Modifier,
scrollState: ScrollState
)
@Composable
expect fun VerticalScrollbar(
modifier: Modifier,
scrollState: LazyListState
)

107
examples/codeviewer/common/src/commonMain/kotlin/org/jetbrains/codeviewer/ui/CodeViewerView.kt

@ -1,107 +0,0 @@
package org.jetbrains.codeviewer.ui
import androidx.compose.animation.core.Spring.StiffnessLow
import androidx.compose.animation.core.SpringSpec
import androidx.compose.animation.core.animateDpAsState
import androidx.compose.animation.core.animateFloatAsState
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.*
import androidx.compose.material.Icon
import androidx.compose.material.LocalContentColor
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.ArrowBack
import androidx.compose.material.icons.filled.ArrowForward
import androidx.compose.runtime.*
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.graphicsLayer
import androidx.compose.ui.unit.dp
import org.jetbrains.codeviewer.ui.editor.EditorEmptyView
import org.jetbrains.codeviewer.ui.editor.EditorTabsView
import org.jetbrains.codeviewer.ui.editor.EditorView
import org.jetbrains.codeviewer.ui.filetree.FileTreeView
import org.jetbrains.codeviewer.ui.filetree.FileTreeViewTabView
import org.jetbrains.codeviewer.ui.statusbar.StatusBar
import org.jetbrains.codeviewer.util.SplitterState
import org.jetbrains.codeviewer.util.VerticalSplittable
@Composable
fun CodeViewerView(model: CodeViewer) {
val panelState = remember { PanelState() }
val animatedSize = if (panelState.splitter.isResizing) {
if (panelState.isExpanded) panelState.expandedSize else panelState.collapsedSize
} else {
animateDpAsState(
if (panelState.isExpanded) panelState.expandedSize else panelState.collapsedSize,
SpringSpec(stiffness = StiffnessLow)
).value
}
VerticalSplittable(
Modifier.fillMaxSize(),
panelState.splitter,
onResize = {
panelState.expandedSize =
(panelState.expandedSize + it).coerceAtLeast(panelState.expandedSizeMin)
}
) {
ResizablePanel(Modifier.width(animatedSize).fillMaxHeight(), panelState) {
Column {
FileTreeViewTabView()
FileTreeView(model.fileTree)
}
}
Box {
if (model.editors.active != null) {
Column(Modifier.fillMaxSize()) {
EditorTabsView(model.editors)
Box(Modifier.weight(1f)) {
EditorView(model.editors.active!!, model.settings)
}
StatusBar(model.settings)
}
} else {
EditorEmptyView()
}
}
}
}
private class PanelState {
val collapsedSize = 24.dp
var expandedSize by mutableStateOf(300.dp)
val expandedSizeMin = 90.dp
var isExpanded by mutableStateOf(true)
val splitter = SplitterState()
}
@Composable
private fun ResizablePanel(
modifier: Modifier,
state: PanelState,
content: @Composable () -> Unit,
) {
val alpha by animateFloatAsState(if (state.isExpanded) 1f else 0f, SpringSpec(stiffness = StiffnessLow))
Box(modifier) {
Box(Modifier.fillMaxSize().graphicsLayer(alpha = alpha)) {
content()
}
Icon(
if (state.isExpanded) Icons.Default.ArrowBack else Icons.Default.ArrowForward,
contentDescription = if (state.isExpanded) "Collapse" else "Expand",
tint = LocalContentColor.current,
modifier = Modifier
.padding(top = 4.dp)
.width(24.dp)
.clickable {
state.isExpanded = !state.isExpanded
}
.padding(4.dp)
.align(Alignment.TopEnd)
)
}
}

35
examples/codeviewer/common/src/commonMain/kotlin/org/jetbrains/codeviewer/ui/MainView.kt

@ -1,35 +0,0 @@
package org.jetbrains.codeviewer.ui
import androidx.compose.foundation.text.selection.DisableSelection
import androidx.compose.material.MaterialTheme
import androidx.compose.material.Surface
import androidx.compose.runtime.Composable
import androidx.compose.runtime.remember
import org.jetbrains.codeviewer.platform.HomeFolder
import org.jetbrains.codeviewer.ui.common.AppTheme
import org.jetbrains.codeviewer.ui.common.Settings
import org.jetbrains.codeviewer.ui.editor.Editors
import org.jetbrains.codeviewer.ui.filetree.FileTree
@Composable
fun MainView() {
val codeViewer = remember {
val editors = Editors()
CodeViewer(
editors = editors,
fileTree = FileTree(HomeFolder, editors),
settings = Settings()
)
}
DisableSelection {
MaterialTheme(
colors = AppTheme.colors.material
) {
Surface {
CodeViewerView(codeViewer)
}
}
}
}

64
examples/codeviewer/common/src/commonMain/kotlin/org/jetbrains/codeviewer/ui/common/Fonts.kt

@ -1,64 +0,0 @@
package org.jetbrains.codeviewer.ui.common
import androidx.compose.runtime.Composable
import androidx.compose.ui.text.font.FontFamily
import androidx.compose.ui.text.font.FontStyle
import androidx.compose.ui.text.font.FontWeight
import org.jetbrains.codeviewer.platform.font
object Fonts {
@Composable
fun jetbrainsMono() = FontFamily(
font(
"JetBrains Mono",
"jetbrainsmono_regular",
FontWeight.Normal,
FontStyle.Normal
),
font(
"JetBrains Mono",
"jetbrainsmono_italic",
FontWeight.Normal,
FontStyle.Italic
),
font(
"JetBrains Mono",
"jetbrainsmono_bold",
FontWeight.Bold,
FontStyle.Normal
),
font(
"JetBrains Mono",
"jetbrainsmono_bold_italic",
FontWeight.Bold,
FontStyle.Italic
),
font(
"JetBrains Mono",
"jetbrainsmono_extrabold",
FontWeight.ExtraBold,
FontStyle.Normal
),
font(
"JetBrains Mono",
"jetbrainsmono_extrabold_italic",
FontWeight.ExtraBold,
FontStyle.Italic
),
font(
"JetBrains Mono",
"jetbrainsmono_medium",
FontWeight.Medium,
FontStyle.Normal
),
font(
"JetBrains Mono",
"jetbrainsmono_medium_italic",
FontWeight.Medium,
FontStyle.Italic
)
)
}

35
examples/codeviewer/common/src/commonMain/kotlin/org/jetbrains/codeviewer/ui/editor/EditorEmptyView.kt

@ -1,35 +0,0 @@
package org.jetbrains.codeviewer.ui.editor
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.padding
import androidx.compose.material.Icon
import androidx.compose.material.LocalContentColor
import androidx.compose.material.Text
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.Code
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
@Composable
fun EditorEmptyView() = Box(Modifier.fillMaxSize()) {
Column(Modifier.align(Alignment.Center)) {
Icon(
Icons.Default.Code,
contentDescription = null,
tint = LocalContentColor.current.copy(alpha = 0.60f),
modifier = Modifier.align(Alignment.CenterHorizontally)
)
Text(
"To view file open it from the file tree",
color = LocalContentColor.current.copy(alpha = 0.60f),
fontSize = 20.sp,
modifier = Modifier.align(Alignment.CenterHorizontally).padding(16.dp)
)
}
}

78
examples/codeviewer/common/src/commonMain/kotlin/org/jetbrains/codeviewer/ui/editor/EditorTabsView.kt

@ -1,78 +0,0 @@
package org.jetbrains.codeviewer.ui.editor
import androidx.compose.foundation.clickable
import androidx.compose.foundation.horizontalScroll
import androidx.compose.foundation.interaction.MutableInteractionSource
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.rememberScrollState
import androidx.compose.material.Icon
import androidx.compose.material.LocalContentColor
import androidx.compose.material.Surface
import androidx.compose.material.Text
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.Close
import androidx.compose.runtime.Composable
import androidx.compose.runtime.remember
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import org.jetbrains.codeviewer.ui.common.AppTheme
@Composable
fun EditorTabsView(model: Editors) = Row(Modifier.horizontalScroll(rememberScrollState())) {
for (editor in model.editors) {
EditorTabView(editor)
}
}
@Composable
fun EditorTabView(model: Editor) = Surface(
color = if (model.isActive) {
AppTheme.colors.backgroundDark
} else {
Color.Transparent
}
) {
Row(
Modifier
.clickable(remember(::MutableInteractionSource), indication = null) {
model.activate()
}
.padding(4.dp),
verticalAlignment = Alignment.CenterVertically
) {
Text(
model.fileName,
color = LocalContentColor.current,
fontSize = 12.sp,
modifier = Modifier.padding(horizontal = 4.dp)
)
val close = model.close
if (close != null) {
Icon(
Icons.Default.Close,
tint = LocalContentColor.current,
contentDescription = "Close",
modifier = Modifier
.size(24.dp)
.padding(4.dp)
.clickable {
close()
}
)
} else {
Box(
modifier = Modifier
.size(24.dp, 24.dp)
.padding(4.dp)
)
}
}
}

186
examples/codeviewer/common/src/commonMain/kotlin/org/jetbrains/codeviewer/ui/editor/EditorView.kt

@ -1,186 +0,0 @@
package org.jetbrains.codeviewer.ui.editor
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.*
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.rememberLazyListState
import androidx.compose.foundation.text.selection.DisableSelection
import androidx.compose.foundation.text.selection.SelectionContainer
import androidx.compose.material.CircularProgressIndicator
import androidx.compose.material.LocalContentColor
import androidx.compose.material.Surface
import androidx.compose.material.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.key
import androidx.compose.runtime.remember
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.alpha
import androidx.compose.ui.platform.LocalDensity
import androidx.compose.ui.text.AnnotatedString
import androidx.compose.ui.text.SpanStyle
import androidx.compose.ui.text.buildAnnotatedString
import androidx.compose.ui.text.withStyle
import androidx.compose.ui.unit.dp
import org.jetbrains.codeviewer.platform.VerticalScrollbar
import org.jetbrains.codeviewer.ui.common.AppTheme
import org.jetbrains.codeviewer.ui.common.Fonts
import org.jetbrains.codeviewer.ui.common.Settings
import org.jetbrains.codeviewer.util.loadableScoped
import org.jetbrains.codeviewer.util.withoutWidthConstraints
import kotlin.text.Regex.Companion.fromLiteral
@Composable
fun EditorView(model: Editor, settings: Settings) = key(model) {
with (LocalDensity.current) {
SelectionContainer {
Surface(
Modifier.fillMaxSize(),
color = AppTheme.colors.backgroundDark,
) {
val lines by loadableScoped(model.lines)
if (lines != null) {
Box {
Lines(lines!!, settings)
Box(
Modifier
.offset(
x = settings.fontSize.toDp() * 0.5f * settings.maxLineSymbols
)
.width(1.dp)
.fillMaxHeight()
.background(AppTheme.colors.backgroundLight)
)
}
} else {
CircularProgressIndicator(
modifier = Modifier
.size(36.dp)
.padding(4.dp)
)
}
}
}
}
}
@Composable
private fun Lines(lines: Editor.Lines, settings: Settings) = with(LocalDensity.current) {
val maxNum = remember(lines.lineNumberDigitCount) {
(1..lines.lineNumberDigitCount).joinToString(separator = "") { "9" }
}
Box(Modifier.fillMaxSize()) {
val scrollState = rememberLazyListState()
LazyColumn(
modifier = Modifier.fillMaxSize(),
state = scrollState
) {
items(lines.size) { index ->
Box(Modifier.height(settings.fontSize.toDp() * 1.6f)) {
Line(Modifier.align(Alignment.CenterStart), maxNum, lines[index], settings)
}
}
}
VerticalScrollbar(
Modifier.align(Alignment.CenterEnd),
scrollState
)
}
}
// Поддержка русского языка
// دعم اللغة العربية
// 中文支持
@Composable
private fun Line(modifier: Modifier, maxNum: String, line: Editor.Line, settings: Settings) {
Row(modifier = modifier) {
DisableSelection {
Box {
LineNumber(maxNum, Modifier.alpha(0f), settings)
LineNumber(line.number.toString(), Modifier.align(Alignment.CenterEnd), settings)
}
}
LineContent(
line.content,
modifier = Modifier
.weight(1f)
.withoutWidthConstraints()
.padding(start = 28.dp, end = 12.dp),
settings = settings
)
}
}
@Composable
private fun LineNumber(number: String, modifier: Modifier, settings: Settings) = Text(
text = number,
fontSize = settings.fontSize,
fontFamily = Fonts.jetbrainsMono(),
color = LocalContentColor.current.copy(alpha = 0.30f),
modifier = modifier.padding(start = 12.dp)
)
@Composable
private fun LineContent(content: Editor.Content, modifier: Modifier, settings: Settings) = Text(
text = if (content.isCode) {
codeString(content.value.value)
} else {
buildAnnotatedString {
withStyle(AppTheme.code.simple) {
append(content.value.value)
}
}
},
fontSize = settings.fontSize,
fontFamily = Fonts.jetbrainsMono(),
maxLines = 1,
modifier = modifier,
softWrap = false
)
private fun codeString(str: String) = buildAnnotatedString {
withStyle(AppTheme.code.simple) {
val strFormatted = str.replace("\t", " ")
append(strFormatted)
addStyle(AppTheme.code.punctuation, strFormatted, ":")
addStyle(AppTheme.code.punctuation, strFormatted, "=")
addStyle(AppTheme.code.punctuation, strFormatted, "\"")
addStyle(AppTheme.code.punctuation, strFormatted, "[")
addStyle(AppTheme.code.punctuation, strFormatted, "]")
addStyle(AppTheme.code.punctuation, strFormatted, "{")
addStyle(AppTheme.code.punctuation, strFormatted, "}")
addStyle(AppTheme.code.punctuation, strFormatted, "(")
addStyle(AppTheme.code.punctuation, strFormatted, ")")
addStyle(AppTheme.code.punctuation, strFormatted, ",")
addStyle(AppTheme.code.keyword, strFormatted, "fun ")
addStyle(AppTheme.code.keyword, strFormatted, "val ")
addStyle(AppTheme.code.keyword, strFormatted, "var ")
addStyle(AppTheme.code.keyword, strFormatted, "private ")
addStyle(AppTheme.code.keyword, strFormatted, "internal ")
addStyle(AppTheme.code.keyword, strFormatted, "for ")
addStyle(AppTheme.code.keyword, strFormatted, "expect ")
addStyle(AppTheme.code.keyword, strFormatted, "actual ")
addStyle(AppTheme.code.keyword, strFormatted, "import ")
addStyle(AppTheme.code.keyword, strFormatted, "package ")
addStyle(AppTheme.code.value, strFormatted, "true")
addStyle(AppTheme.code.value, strFormatted, "false")
addStyle(AppTheme.code.value, strFormatted, Regex("[0-9]+"))
addStyle(AppTheme.code.annotation, strFormatted, Regex("^@[a-zA-Z_]*"))
addStyle(AppTheme.code.comment, strFormatted, Regex("^\\s*//.*"))
}
}
private fun AnnotatedString.Builder.addStyle(style: SpanStyle, text: String, regexp: String) {
addStyle(style, text, fromLiteral(regexp))
}
private fun AnnotatedString.Builder.addStyle(style: SpanStyle, text: String, regexp: Regex) {
for (result in regexp.findAll(text)) {
addStyle(style, result.range.first, result.range.last + 1)
}
}

125
examples/codeviewer/common/src/commonMain/kotlin/org/jetbrains/codeviewer/ui/filetree/FileTreeView.kt

@ -1,125 +0,0 @@
package org.jetbrains.codeviewer.ui.filetree
import androidx.compose.foundation.clickable
import androidx.compose.foundation.hoverable
import androidx.compose.foundation.interaction.MutableInteractionSource
import androidx.compose.foundation.interaction.collectIsHoveredAsState
import androidx.compose.foundation.layout.*
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.rememberLazyListState
import androidx.compose.material.Icon
import androidx.compose.material.LocalContentColor
import androidx.compose.material.Surface
import androidx.compose.material.Text
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.*
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clipToBounds
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.platform.LocalDensity
import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.unit.Dp
import androidx.compose.ui.unit.TextUnit
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import org.jetbrains.codeviewer.platform.VerticalScrollbar
import org.jetbrains.codeviewer.util.withoutWidthConstraints
@Composable
fun FileTreeViewTabView() = Surface {
Row(
Modifier.padding(8.dp),
verticalAlignment = Alignment.CenterVertically
) {
Text(
"Files",
color = LocalContentColor.current.copy(alpha = 0.60f),
fontSize = 12.sp,
modifier = Modifier.padding(horizontal = 4.dp)
)
}
}
@Composable
fun FileTreeView(model: FileTree) = Surface(
modifier = Modifier.fillMaxSize()
) {
with(LocalDensity.current) {
Box {
val scrollState = rememberLazyListState()
LazyColumn(
modifier = Modifier.fillMaxSize().withoutWidthConstraints(),
state = scrollState
) {
items(model.items.size) {
FileTreeItemView(14.sp, 14.sp.toDp() * 1.5f, model.items[it])
}
}
VerticalScrollbar(
Modifier.align(Alignment.CenterEnd),
scrollState
)
}
}
}
@Composable
private fun FileTreeItemView(fontSize: TextUnit, height: Dp, model: FileTree.Item) = Row(
modifier = Modifier
.wrapContentHeight()
.clickable { model.open() }
.padding(start = 24.dp * model.level)
.height(height)
.fillMaxWidth()
) {
val interactionSource = remember { MutableInteractionSource() }
val active by interactionSource.collectIsHoveredAsState()
FileItemIcon(Modifier.align(Alignment.CenterVertically), model)
Text(
text = model.name,
color = if (active) LocalContentColor.current.copy(alpha = 0.60f) else LocalContentColor.current,
modifier = Modifier
.align(Alignment.CenterVertically)
.clipToBounds()
.hoverable(interactionSource),
softWrap = true,
fontSize = fontSize,
overflow = TextOverflow.Ellipsis,
maxLines = 1
)
}
@Composable
private fun FileItemIcon(modifier: Modifier, model: FileTree.Item) = Box(modifier.size(24.dp).padding(4.dp)) {
when (val type = model.type) {
is FileTree.ItemType.Folder -> when {
!type.canExpand -> Unit
type.isExpanded -> Icon(
Icons.Default.KeyboardArrowDown, contentDescription = null, tint = LocalContentColor.current
)
else -> Icon(
Icons.Default.KeyboardArrowRight, contentDescription = null, tint = LocalContentColor.current
)
}
is FileTree.ItemType.File -> when (type.ext) {
"kt" -> Icon(Icons.Default.Code, contentDescription = null, tint = Color(0xFF3E86A0))
"xml" -> Icon(Icons.Default.Code, contentDescription = null, tint = Color(0xFFC19C5F))
"txt" -> Icon(Icons.Default.Description, contentDescription = null, tint = Color(0xFF87939A))
"md" -> Icon(Icons.Default.Description, contentDescription = null, tint = Color(0xFF87939A))
"gitignore" -> Icon(Icons.Default.BrokenImage, contentDescription = null, tint = Color(0xFF87939A))
"gradle" -> Icon(Icons.Default.Build, contentDescription = null, tint = Color(0xFF87939A))
"kts" -> Icon(Icons.Default.Build, contentDescription = null, tint = Color(0xFF3E86A0))
"properties" -> Icon(Icons.Default.Settings, contentDescription = null, tint = Color(0xFF62B543))
"bat" -> Icon(Icons.Default.Launch, contentDescription = null, tint = Color(0xFF87939A))
else -> Icon(Icons.Default.TextSnippet, contentDescription = null, tint = Color(0xFF87939A))
}
}
}

47
examples/codeviewer/common/src/commonMain/kotlin/org/jetbrains/codeviewer/ui/statusbar/StatusBar.kt

@ -1,47 +0,0 @@
package org.jetbrains.codeviewer.ui.statusbar
import androidx.compose.foundation.layout.*
import androidx.compose.material.LocalContentColor
import androidx.compose.material.Slider
import androidx.compose.material.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.CompositionLocalProvider
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalDensity
import androidx.compose.ui.unit.*
import org.jetbrains.codeviewer.ui.common.Settings
private val MinFontSize = 6.sp
private val MaxFontSize = 40.sp
@Composable
fun StatusBar(settings: Settings) = Box(
Modifier
.height(32.dp)
.fillMaxWidth()
.padding(4.dp)
) {
Row(Modifier.fillMaxHeight().align(Alignment.CenterEnd)) {
Text(
text = "Text size",
modifier = Modifier.align(Alignment.CenterVertically),
color = LocalContentColor.current.copy(alpha = 0.60f),
fontSize = 12.sp
)
Spacer(Modifier.width(8.dp))
CompositionLocalProvider(LocalDensity provides LocalDensity.current.scale(0.5f)) {
Slider(
(settings.fontSize - MinFontSize) / (MaxFontSize - MinFontSize),
onValueChange = { settings.fontSize = lerp(MinFontSize, MaxFontSize, it) },
modifier = Modifier.width(240.dp).align(Alignment.CenterVertically)
)
}
}
}
private fun Density.scale(scale: Float) = Density(density * scale, fontScale * scale)
private operator fun TextUnit.minus(other: TextUnit) = (value - other.value).sp
private operator fun TextUnit.div(other: TextUnit) = value / other.value

27
examples/codeviewer/common/src/commonMain/kotlin/org/jetbrains/codeviewer/util/Loadable.kt

@ -1,27 +0,0 @@
package org.jetbrains.codeviewer.util
import androidx.compose.runtime.*
import kotlinx.coroutines.CancellationException
import kotlinx.coroutines.CoroutineScope
@Composable
fun <T : Any> loadable(load: () -> T): MutableState<T?> {
return loadableScoped { load() }
}
private val loadingKey = Any()
@Composable
fun <T : Any> loadableScoped(load: CoroutineScope.() -> T): MutableState<T?> {
val state: MutableState<T?> = remember { mutableStateOf(null) }
LaunchedEffect(loadingKey) {
try {
state.value = load()
} catch (e: CancellationException) {
// ignore
} catch (e: Exception) {
e.printStackTrace()
}
}
return state
}

95
examples/codeviewer/common/src/commonMain/kotlin/org/jetbrains/codeviewer/util/VerticalSplittable.kt

@ -1,95 +0,0 @@
package org.jetbrains.codeviewer.util
import androidx.compose.foundation.background
import androidx.compose.foundation.gestures.Orientation
import androidx.compose.foundation.gestures.draggable
import androidx.compose.foundation.gestures.rememberDraggableState
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.fillMaxHeight
import androidx.compose.foundation.layout.width
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.setValue
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.layout.Layout
import androidx.compose.ui.platform.LocalDensity
import androidx.compose.ui.unit.Constraints
import androidx.compose.ui.unit.Dp
import androidx.compose.ui.unit.dp
import org.jetbrains.codeviewer.platform.cursorForHorizontalResize
import org.jetbrains.codeviewer.ui.common.AppTheme
@Composable
fun VerticalSplittable(
modifier: Modifier,
splitterState: SplitterState,
onResize: (delta: Dp) -> Unit,
children: @Composable () -> Unit
) = Layout({
children()
VerticalSplitter(splitterState, onResize)
}, modifier, measurePolicy = { measurables, constraints ->
require(measurables.size == 3)
val firstPlaceable = measurables[0].measure(constraints.copy(minWidth = 0))
val secondWidth = constraints.maxWidth - firstPlaceable.width
val secondPlaceable = measurables[1].measure(
Constraints(
minWidth = secondWidth,
maxWidth = secondWidth,
minHeight = constraints.maxHeight,
maxHeight = constraints.maxHeight
)
)
val splitterPlaceable = measurables[2].measure(constraints)
layout(constraints.maxWidth, constraints.maxHeight) {
firstPlaceable.place(0, 0)
secondPlaceable.place(firstPlaceable.width, 0)
splitterPlaceable.place(firstPlaceable.width, 0)
}
})
class SplitterState {
var isResizing by mutableStateOf(false)
var isResizeEnabled by mutableStateOf(true)
}
@Composable
fun VerticalSplitter(
splitterState: SplitterState,
onResize: (delta: Dp) -> Unit,
color: Color = AppTheme.colors.backgroundDark
) = Box {
val density = LocalDensity.current
Box(
Modifier
.width(8.dp)
.fillMaxHeight()
.run {
if (splitterState.isResizeEnabled) {
this.draggable(
state = rememberDraggableState {
with(density) {
onResize(it.toDp())
}
},
orientation = Orientation.Horizontal,
startDragImmediately = true,
onDragStarted = { splitterState.isResizing = true },
onDragStopped = { splitterState.isResizing = false }
).cursorForHorizontalResize()
} else {
this
}
}
)
Box(
Modifier
.width(1.dp)
.fillMaxHeight()
.background(color)
)
}

10
examples/codeviewer/common/src/desktopMain/kotlin/org/jetbrains/codeviewer/platform/Mouse.kt

@ -1,10 +0,0 @@
package org.jetbrains.codeviewer.platform
import androidx.compose.ui.ExperimentalComposeUiApi
import androidx.compose.ui.Modifier
import androidx.compose.ui.input.pointer.PointerIcon
import androidx.compose.ui.input.pointer.pointerHoverIcon
import java.awt.Cursor
actual fun Modifier.cursorForHorizontalResize(): Modifier =
this.pointerHoverIcon(PointerIcon(Cursor(Cursor.E_RESIZE_CURSOR)))

177
examples/codeviewer/common/src/jvmMain/kotlin/org/jetbrains/codeviewer/platform/JvmFile.kt

@ -1,177 +0,0 @@
package org.jetbrains.codeviewer.platform
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.setValue
import kotlinx.coroutines.*
import org.jetbrains.codeviewer.util.TextLines
import java.io.FileInputStream
import java.io.FilenameFilter
import java.io.IOException
import java.io.RandomAccessFile
import java.nio.ByteBuffer
import java.nio.channels.FileChannel
import java.nio.charset.StandardCharsets
fun java.io.File.toProjectFile(): File = object : File {
override val name: String
get() = this@toProjectFile.name
override val isDirectory: Boolean
get() = this@toProjectFile.isDirectory
override val children: List<File>
get() = this@toProjectFile
.listFiles(FilenameFilter { _, name -> !name.startsWith(".")})
.orEmpty()
.map { it.toProjectFile() }
private val numberOfFiles
get() = listFiles()?.size ?: 0
override val hasChildren: Boolean
get() = isDirectory && numberOfFiles > 0
override fun readLines(scope: CoroutineScope): TextLines {
var byteBufferSize: Int
val byteBuffer = RandomAccessFile(this@toProjectFile, "r").use { file ->
byteBufferSize = file.length().toInt()
file.channel.map(FileChannel.MapMode.READ_ONLY, 0, file.length())
}
val lineStartPositions = IntList()
var size by mutableStateOf(0)
// In case of big files, update number of lines periodically
val refreshJob = scope.launch {
delay(100)
size = lineStartPositions.size
while (isActive) {
delay(1000)
size = lineStartPositions.size
}
}
// Find indexes where lines starts in background
scope.launch(Dispatchers.IO) {
readLinePositions(lineStartPositions)
refreshJob.cancel()
size = lineStartPositions.size
}
return object : TextLines {
override val size get() = size
override fun get(index: Int): String {
val position = lineRange(index)
val slice = byteBuffer.slice(position.first, position.last - position.first)
return StandardCharsets.UTF_8.decode(slice).toString()
}
private fun lineRange(index: Int): IntRange {
val startPosition = lineStartPositions[index]
val nextLineIndex = index + 1
var endPosition = if (nextLineIndex < size) lineStartPositions[nextLineIndex] else byteBufferSize
// Remove line endings from the range
while (endPosition > startPosition) {
val lastSymbol = byteBuffer[endPosition - 1]
when (lastSymbol.toInt().toChar()) {
'\n', '\r' -> endPosition--
else -> break
}
}
return startPosition..endPosition
}
}
}
}
// Backport slice from JDK 13
private fun ByteBuffer.slice(index: Int, length: Int): ByteBuffer {
position(index)
return slice().limit(length)
}
private fun java.io.File.readLinePositions(starts: IntList) {
require(length() <= Int.MAX_VALUE) {
"Files with size over ${Int.MAX_VALUE} aren't supported"
}
val averageLineLength = 200
starts.clear(length().toInt() / averageLineLength)
try {
for (i in readLinePositions()) {
starts.add(i)
}
} catch (e: IOException) {
e.printStackTrace()
starts.clear(1)
starts.add(0)
}
starts.compact()
}
private fun java.io.File.readLinePositions() = sequence {
require(length() <= Int.MAX_VALUE) {
"Files with size over ${Int.MAX_VALUE} aren't supported"
}
readBuffer {
yield(position())
while (hasRemaining()) {
val byte = get()
if (byte.isChar('\n')) {
yield(position())
}
}
}
}
private inline fun java.io.File.readBuffer(block: ByteBuffer.() -> Unit) {
FileInputStream(this).use { stream ->
stream.channel.use { channel ->
channel.map(FileChannel.MapMode.READ_ONLY, 0, channel.size()).block()
}
}
}
private fun Byte.isChar(char: Char) = toInt().toChar() == char
/**
* Compact version of List<Int> (without unboxing Int and using IntArray under the hood)
*/
private class IntList(initialCapacity: Int = 16) {
@Volatile
private var array = IntArray(initialCapacity)
@Volatile
var size: Int = 0
private set
fun clear(capacity: Int) {
array = IntArray(capacity)
size = 0
}
fun add(value: Int) {
if (size == array.size) {
doubleCapacity()
}
array[size++] = value
}
operator fun get(index: Int) = array[index]
private fun doubleCapacity() {
val newArray = IntArray(array.size * 2 + 1)
System.arraycopy(array, 0, newArray, 0, size)
array = newArray
}
fun compact() {
array = array.copyOfRange(0, size)
}
}

41
examples/codeviewer/desktop/build.gradle.kts

@ -1,41 +0,0 @@
import org.jetbrains.compose.desktop.application.dsl.TargetFormat
plugins {
kotlin("multiplatform") // kotlin("jvm") doesn't work well in IDEA/AndroidStudio (https://github.com/JetBrains/compose-jb/issues/22)
id("org.jetbrains.compose")
}
kotlin {
jvm {}
sourceSets {
named("jvmMain") {
dependencies {
implementation(compose.desktop.currentOs)
implementation(project(":common"))
}
}
}
}
compose.desktop {
application {
mainClass = "org.jetbrains.codeviewer.MainKt"
nativeDistributions {
targetFormats(TargetFormat.Dmg, TargetFormat.Msi, TargetFormat.Deb)
packageName = "ComposeCodeViewer"
packageVersion = "1.0.0"
windows {
menu = true
// see https://wixtoolset.org/documentation/manual/v3/howtos/general/generate_guids.html
upgradeUuid = "AF792DA6-2EA3-495A-95E5-C3C6CBCB9948"
}
macOS {
// Use -Pcompose.desktop.mac.sign=true to sign and notarize.
bundleID = "com.jetbrains.compose.codeviewer"
}
}
}
}

17
examples/codeviewer/desktop/src/jvmMain/kotlin/org/jetbrains/codeviewer/main.kt

@ -1,17 +0,0 @@
package org.jetbrains.codeviewer
import androidx.compose.ui.graphics.painter.BitmapPainter
import androidx.compose.ui.res.loadImageBitmap
import androidx.compose.ui.res.useResource
import androidx.compose.ui.unit.dp
import androidx.compose.ui.window.WindowState
import androidx.compose.ui.window.singleWindowApplication
import org.jetbrains.codeviewer.ui.MainView
fun main() = singleWindowApplication(
title = "Code Viewer",
state = WindowState(width = 1280.dp, height = 768.dp),
icon = BitmapPainter(useResource("ic_launcher.png", ::loadImageBitmap)),
) {
MainView()
}

0
experimental/examples/codeviewer/desktopApp/build.gradle.kts → examples/codeviewer/desktopApp/build.gradle.kts

0
experimental/examples/codeviewer/desktopApp/src/jvmMain/kotlin/org/jetbrains/codeviewer/main.kt → examples/codeviewer/desktopApp/src/jvmMain/kotlin/org/jetbrains/codeviewer/main.kt

0
examples/codeviewer/desktop/src/jvmMain/resources/ic_launcher.png → examples/codeviewer/desktopApp/src/jvmMain/resources/ic_launcher.png

Before

Width:  |  Height:  |  Size: 9.1 KiB

After

Width:  |  Height:  |  Size: 9.1 KiB

36
examples/codeviewer/gradle.properties

@ -1,24 +1,16 @@
# 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.
org.gradle.jvmargs=-Xmx2048m
# 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
# Automatically convert third-party libraries to use AndroidX
android.enableJetifier=true
# Kotlin code style for this project: "official" or "obsolete":
kotlin.code.style=official kotlin.code.style=official
kotlin.version=1.8.10 xcodeproj=./iosApp
kotlin.native.cocoapods.generate.wrapper=true
android.useAndroidX=true
org.gradle.jvmargs=-Xmx3g
org.jetbrains.compose.experimental.jscanvas.enabled=true
org.jetbrains.compose.experimental.macos.enabled=true
org.jetbrains.compose.experimental.uikit.enabled=true
kotlin.native.cacheKind=none
kotlin.native.useEmbeddableCompilerJar=true
kotlin.mpp.androidSourceSetLayoutVersion=2
# Enable kotlin/native experimental memory model
kotlin.native.binary.memoryModel=experimental
kotlin.version=1.8.0
agp.version=7.1.3 agp.version=7.1.3
compose.version=1.3.1 compose.version=1.4.0-rc01

BIN
examples/codeviewer/gradle/wrapper/gradle-wrapper.jar vendored

Binary file not shown.

263
examples/codeviewer/gradlew vendored

@ -1,7 +1,7 @@
#!/usr/bin/env sh #!/bin/sh
# #
# Copyright 2015 the original author or authors. # Copyright © 2015-2021 the original authors.
# #
# Licensed under the Apache License, Version 2.0 (the "License"); # Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License. # you may not use this file except in compliance with the License.
@ -17,78 +17,113 @@
# #
############################################################################## ##############################################################################
## #
## Gradle start up script for UN*X # Gradle start up script for POSIX generated by Gradle.
## #
# Important for running:
#
# (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is
# noncompliant, but you have some other compliant shell such as ksh or
# bash, then to run this script, type that shell name before the whole
# command line, like:
#
# ksh Gradle
#
# Busybox and similar reduced shells will NOT work, because this script
# requires all of these POSIX shell features:
# * functions;
# * expansions «$var», «${var}», «${var:-default}», «${var+SET}»,
# «${var#prefix}», «${var%suffix}», and «$( cmd )»;
# * compound commands having a testable exit status, especially «case»;
# * various built-in commands including «command», «set», and «ulimit».
#
# Important for patching:
#
# (2) This script targets any POSIX shell, so it avoids extensions provided
# by Bash, Ksh, etc; in particular arrays are avoided.
#
# The "traditional" practice of packing multiple parameters into a
# space-separated string is a well documented source of bugs and security
# problems, so this is (mostly) avoided, by progressively accumulating
# options in "$@", and eventually passing that to Java.
#
# Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS,
# and GRADLE_OPTS) rely on word-splitting, this is performed explicitly;
# see the in-line comments for details.
#
# There are tweaks for specific operating systems such as AIX, CygWin,
# Darwin, MinGW, and NonStop.
#
# (3) This script is generated from the Groovy template
# https://github.com/gradle/gradle/blob/master/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt
# within the Gradle project.
#
# You can find Gradle at https://github.com/gradle/gradle/.
#
############################################################################## ##############################################################################
# Attempt to set APP_HOME # Attempt to set APP_HOME
# Resolve links: $0 may be a link # Resolve links: $0 may be a link
PRG="$0" app_path=$0
# Need this for relative symlinks.
while [ -h "$PRG" ] ; do # Need this for daisy-chained symlinks.
ls=`ls -ld "$PRG"` while
link=`expr "$ls" : '.*-> \(.*\)$'` APP_HOME=${app_path%"${app_path##*/}"} # leaves a trailing /; empty if no leading path
if expr "$link" : '/.*' > /dev/null; then [ -h "$app_path" ]
PRG="$link" do
else ls=$( ls -ld "$app_path" )
PRG=`dirname "$PRG"`"/$link" link=${ls#*' -> '}
fi case $link in #(
/*) app_path=$link ;; #(
*) app_path=$APP_HOME$link ;;
esac
done done
SAVED="`pwd`"
cd "`dirname \"$PRG\"`/" >/dev/null APP_HOME=$( cd "${APP_HOME:-./}" && pwd -P ) || exit
APP_HOME="`pwd -P`"
cd "$SAVED" >/dev/null
APP_NAME="Gradle" APP_NAME="Gradle"
APP_BASE_NAME=`basename "$0"` APP_BASE_NAME=${0##*/}
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
# Use the maximum available, or set MAX_FD != -1 to use that value. # Use the maximum available, or set MAX_FD != -1 to use that value.
MAX_FD="maximum" MAX_FD=maximum
warn () { warn () {
echo "$*" echo "$*"
} } >&2
die () { die () {
echo echo
echo "$*" echo "$*"
echo echo
exit 1 exit 1
} } >&2
# OS specific support (must be 'true' or 'false'). # OS specific support (must be 'true' or 'false').
cygwin=false cygwin=false
msys=false msys=false
darwin=false darwin=false
nonstop=false nonstop=false
case "`uname`" in case "$( uname )" in #(
CYGWIN* ) CYGWIN* ) cygwin=true ;; #(
cygwin=true Darwin* ) darwin=true ;; #(
;; MSYS* | MINGW* ) msys=true ;; #(
Darwin* ) NONSTOP* ) nonstop=true ;;
darwin=true
;;
MINGW* )
msys=true
;;
NONSTOP* )
nonstop=true
;;
esac esac
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
# Determine the Java command to use to start the JVM. # Determine the Java command to use to start the JVM.
if [ -n "$JAVA_HOME" ] ; then if [ -n "$JAVA_HOME" ] ; then
if [ -x "$JAVA_HOME/jre/sh/java" ] ; then if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
# IBM's JDK on AIX uses strange locations for the executables # IBM's JDK on AIX uses strange locations for the executables
JAVACMD="$JAVA_HOME/jre/sh/java" JAVACMD=$JAVA_HOME/jre/sh/java
else else
JAVACMD="$JAVA_HOME/bin/java" JAVACMD=$JAVA_HOME/bin/java
fi fi
if [ ! -x "$JAVACMD" ] ; then if [ ! -x "$JAVACMD" ] ; then
die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
@ -97,7 +132,7 @@ Please set the JAVA_HOME variable in your environment to match the
location of your Java installation." location of your Java installation."
fi fi
else else
JAVACMD="java" JAVACMD=java
which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
Please set the JAVA_HOME variable in your environment to match the Please set the JAVA_HOME variable in your environment to match the
@ -105,79 +140,101 @@ location of your Java installation."
fi fi
# Increase the maximum file descriptors if we can. # Increase the maximum file descriptors if we can.
if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then
MAX_FD_LIMIT=`ulimit -H -n` case $MAX_FD in #(
if [ $? -eq 0 ] ; then max*)
if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then MAX_FD=$( ulimit -H -n ) ||
MAX_FD="$MAX_FD_LIMIT" warn "Could not query maximum file descriptor limit"
fi esac
ulimit -n $MAX_FD case $MAX_FD in #(
if [ $? -ne 0 ] ; then '' | soft) :;; #(
warn "Could not set maximum file descriptor limit: $MAX_FD" *)
fi ulimit -n "$MAX_FD" ||
else warn "Could not set maximum file descriptor limit to $MAX_FD"
warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" esac
fi
fi fi
# For Darwin, add options to specify how the application appears in the dock # Collect all arguments for the java command, stacking in reverse order:
if $darwin; then # * args from the command line
GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" # * the main class name
fi # * -classpath
# * -D...appname settings
# * --module-path (only if needed)
# * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables.
# For Cygwin or MSYS, switch paths to Windows format before running java # For Cygwin or MSYS, switch paths to Windows format before running java
if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then if "$cygwin" || "$msys" ; then
APP_HOME=`cygpath --path --mixed "$APP_HOME"` APP_HOME=$( cygpath --path --mixed "$APP_HOME" )
CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" )
JAVACMD=`cygpath --unix "$JAVACMD"`
# We build the pattern for arguments to be converted via cygpath
ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
SEP=""
for dir in $ROOTDIRSRAW ; do
ROOTDIRS="$ROOTDIRS$SEP$dir"
SEP="|"
done
OURCYGPATTERN="(^($ROOTDIRS))"
# Add a user-defined pattern to the cygpath arguments
if [ "$GRADLE_CYGPATTERN" != "" ] ; then
OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
fi
# Now convert the arguments - kludge to limit ourselves to /bin/sh
i=0
for arg in "$@" ; do
CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition JAVACMD=$( cygpath --unix "$JAVACMD" )
eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
else # Now convert the arguments - kludge to limit ourselves to /bin/sh
eval `echo args$i`="\"$arg\"" for arg do
if
case $arg in #(
-*) false ;; # don't mess with options #(
/?*) t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath
[ -e "$t" ] ;; #(
*) false ;;
esac
then
arg=$( cygpath --path --ignore --mixed "$arg" )
fi fi
i=`expr $i + 1` # Roll the args list around exactly as many times as the number of
# args, so each arg winds up back in the position where it started, but
# possibly modified.
#
# NB: a `for` loop captures its iteration list before it begins, so
# changing the positional parameters here affects neither the number of
# iterations, nor the values presented in `arg`.
shift # remove old arg
set -- "$@" "$arg" # push replacement arg
done done
case $i in
0) set -- ;;
1) set -- "$args0" ;;
2) set -- "$args0" "$args1" ;;
3) set -- "$args0" "$args1" "$args2" ;;
4) set -- "$args0" "$args1" "$args2" "$args3" ;;
5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
esac
fi fi
# Escape application args # Collect all arguments for the java command;
save () { # * $DEFAULT_JVM_OPTS, $JAVA_OPTS, and $GRADLE_OPTS can contain fragments of
for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done # shell script including quotes and variable substitutions, so put them in
echo " " # double quotes to make sure that they get re-expanded; and
} # * put everything else in single quotes, so that it's not re-expanded.
APP_ARGS=`save "$@"`
set -- \
"-Dorg.gradle.appname=$APP_BASE_NAME" \
-classpath "$CLASSPATH" \
org.gradle.wrapper.GradleWrapperMain \
"$@"
# Stop when "xargs" is not available.
if ! command -v xargs >/dev/null 2>&1
then
die "xargs is not available"
fi
# Use "xargs" to parse quoted args.
#
# With -n1 it outputs one arg per line, with the quotes and backslashes removed.
#
# In Bash we could simply go:
#
# readarray ARGS < <( xargs -n1 <<<"$var" ) &&
# set -- "${ARGS[@]}" "$@"
#
# but POSIX shell has neither arrays nor command substitution, so instead we
# post-process each arg (as a line of input to sed) to backslash-escape any
# character that might be a shell metacharacter, then use eval to reverse
# that process (while maintaining the separation between arguments), and wrap
# the whole thing up as a single "set" statement.
#
# This will of course break if any of these variables contains a newline or
# an unmatched quote.
#
# Collect all arguments for the java command, following the shell quoting and substitution rules eval "set -- $(
eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS" printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" |
xargs -n1 |
sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' |
tr '\n' ' '
)" '"$@"'
exec "$JAVACMD" "$@" exec "$JAVACMD" "$@"

37
examples/codeviewer/gradlew.bat vendored

@ -14,7 +14,7 @@
@rem limitations under the License. @rem limitations under the License.
@rem @rem
@if "%DEBUG%" == "" @echo off @if "%DEBUG%"=="" @echo off
@rem ########################################################################## @rem ##########################################################################
@rem @rem
@rem Gradle startup script for Windows @rem Gradle startup script for Windows
@ -25,10 +25,13 @@
if "%OS%"=="Windows_NT" setlocal if "%OS%"=="Windows_NT" setlocal
set DIRNAME=%~dp0 set DIRNAME=%~dp0
if "%DIRNAME%" == "" set DIRNAME=. if "%DIRNAME%"=="" set DIRNAME=.
set APP_BASE_NAME=%~n0 set APP_BASE_NAME=%~n0
set APP_HOME=%DIRNAME% 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. @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" set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
@ -37,7 +40,7 @@ if defined JAVA_HOME goto findJavaFromJavaHome
set JAVA_EXE=java.exe set JAVA_EXE=java.exe
%JAVA_EXE% -version >NUL 2>&1 %JAVA_EXE% -version >NUL 2>&1
if "%ERRORLEVEL%" == "0" goto init if %ERRORLEVEL% equ 0 goto execute
echo. echo.
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
@ -51,7 +54,7 @@ goto fail
set JAVA_HOME=%JAVA_HOME:"=% set JAVA_HOME=%JAVA_HOME:"=%
set JAVA_EXE=%JAVA_HOME%/bin/java.exe set JAVA_EXE=%JAVA_HOME%/bin/java.exe
if exist "%JAVA_EXE%" goto init if exist "%JAVA_EXE%" goto execute
echo. echo.
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
@ -61,38 +64,26 @@ echo location of your Java installation.
goto fail goto fail
:init
@rem Get command-line arguments, handling Windows variants
if not "%OS%" == "Windows_NT" goto win9xME_args
:win9xME_args
@rem Slurp the command line arguments.
set CMD_LINE_ARGS=
set _SKIP=2
:win9xME_args_slurp
if "x%~1" == "x" goto execute
set CMD_LINE_ARGS=%*
:execute :execute
@rem Setup the command line @rem Setup the command line
set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
@rem Execute Gradle @rem Execute Gradle
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %*
:end :end
@rem End local scope for the variables with windows NT shell @rem End local scope for the variables with windows NT shell
if "%ERRORLEVEL%"=="0" goto mainEnd if %ERRORLEVEL% equ 0 goto mainEnd
:fail :fail
rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
rem the _cmd.exe /c_ return code! rem the _cmd.exe /c_ return code!
if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 set EXIT_CODE=%ERRORLEVEL%
exit /b 1 if %EXIT_CODE% equ 0 set EXIT_CODE=1
if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE%
exit /b %EXIT_CODE%
:mainEnd :mainEnd
if "%OS%"=="Windows_NT" endlocal if "%OS%"=="Windows_NT" endlocal

0
experimental/examples/codeviewer/iosApp/Configuration/Config.xcconfig → examples/codeviewer/iosApp/Configuration/Config.xcconfig

0
experimental/examples/codeviewer/iosApp/Podfile → examples/codeviewer/iosApp/Podfile

0
experimental/examples/codeviewer/iosApp/iosApp.xcodeproj/project.pbxproj → examples/codeviewer/iosApp/iosApp.xcodeproj/project.pbxproj

0
experimental/examples/codeviewer/iosApp/iosApp/Assets.xcassets/AccentColor.colorset/Contents.json → examples/codeviewer/iosApp/iosApp/Assets.xcassets/AccentColor.colorset/Contents.json

0
experimental/examples/codeviewer/iosApp/iosApp/Assets.xcassets/AppIcon.appiconset/Contents.json → examples/codeviewer/iosApp/iosApp/Assets.xcassets/AppIcon.appiconset/Contents.json

0
experimental/examples/codeviewer/iosApp/iosApp/Assets.xcassets/Contents.json → examples/codeviewer/iosApp/iosApp/Assets.xcassets/Contents.json

0
experimental/examples/codeviewer/iosApp/iosApp/ContentView.swift → examples/codeviewer/iosApp/iosApp/ContentView.swift

0
experimental/examples/codeviewer/iosApp/iosApp/Info.plist → examples/codeviewer/iosApp/iosApp/Info.plist

0
experimental/examples/codeviewer/iosApp/iosApp/Preview Content/Preview Assets.xcassets/Contents.json → examples/codeviewer/iosApp/iosApp/Preview Content/Preview Assets.xcassets/Contents.json

0
experimental/examples/codeviewer/iosApp/iosApp/iOSApp.swift → examples/codeviewer/iosApp/iosApp/iOSApp.swift

Some files were not shown because too many files have changed in this diff Show More

Loading…
Cancel
Save