Skip to content

Commit

Permalink
Copy codeviewer from examples to experimental/examples as is (#2508)
Browse files Browse the repository at this point in the history
  • Loading branch information
pjBooms authored Nov 28, 2022
1 parent a052086 commit 0d6271c
Show file tree
Hide file tree
Showing 66 changed files with 2,152 additions and 0 deletions.
15 changes: 15 additions & 0 deletions experimental/examples/codeviewer/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +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/
/captures
.externalNativeBuild
.cxx
21 changes: 21 additions & 0 deletions experimental/examples/codeviewer/.run/desktop.run.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
<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>
20 changes: 20 additions & 0 deletions experimental/examples/codeviewer/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
MPP Code Viewer example for desktop/android written in Multiplatform Compose library.

### Running desktop application

* To run, launch command: `./gradlew :desktop:run`
* Or choose **desktop** configuration in IDE and run it.
![desktop-run-configuration.png](screenshots/desktop-run-configuration.png)

### Building native desktop distribution
```
./gradlew :desktop:packageDistributionForCurrentOS
# outputs are written to desktop/build/compose/binaries
```

### Installing Android application on device/emulator
```
./gradlew installDebug
```

![Desktop](screenshots/codeviewer.png)
26 changes: 26 additions & 0 deletions experimental/examples/codeviewer/android/build.gradle.kts
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
plugins {
id("com.android.application")
kotlin("android")
id("org.jetbrains.compose")
}

android {
compileSdk = 32

defaultConfig {
minSdk = 26
targetSdk = 32
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")
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="org.jetbrains.codeviewer">

<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/Theme.AppCompat.Light.NoActionBar">
<activity
android:exported="true"
android:name="MainActivity"
>
<intent-filter>
<action android:name="android.intent.action.MAIN" />

<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>

</manifest>
Original file line number Diff line number Diff line change
@@ -0,0 +1,183 @@
/**
* This file is an example (we can open it in android application)
*/

package org.jetbrains.codeviewer.ui.editor

import androidx.compose.foundation.background
import androidx.compose.foundation.layout.*
import androidx.compose.foundation.text.selection.DisableSelection
import androidx.compose.material.AmbientContentColor
import androidx.compose.material.CircularProgressIndicator
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.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.alpha
import androidx.compose.ui.platform.LocalDensity
import androidx.compose.ui.text.*
import androidx.compose.ui.unit.dp
import org.jetbrains.codeviewer.platform.SelectionContainer
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(DensityAmbient.current) {
val maxNumber = remember(lines.lineNumberDigitCount) {
(1..lines.lineNumberDigitCount).joinToString(separator = "") { "9" }
}

Box(Modifier.fillMaxSize()) {
val scrollState = rememberLazyListState()
val lineHeight = settings.fontSize.toDp() * 1.6f

LazyColumnFor(
lines.size,
modifier = Modifier.fillMaxSize(),
state = scrollState,
itemContent = { index ->
val line: Editor.Line? by loadable { lines.get(index) }
Box(Modifier.height(lineHeight)) {
if (line != null) {
Line(Modifier.align(Alignment.CenterStart), maxNumber, line!!, settings)
}
}
}
)

VerticalScrollbar(
Modifier.align(Alignment.CenterEnd),
scrollState,
lines.size,
lineHeight
)
}
}

// Поддержка русского языка
// دعم اللغة العربية
// 中文支持
@Composable
private fun Line(modifier: Modifier, maxNumber: String, line: Editor.Line, settings: Settings) {
Row(modifier = modifier) {
DisableSelection {
Box {
LineNumber(maxNumber, 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 = AmbientContentColor.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 {
AnnotatedString(content.value.value)
},
fontSize = settings.fontSize,
fontFamily = Fonts.jetbrainsMono(),
modifier = modifier,
softWrap = false
)

private fun codeString(str: String) = buildAnnotatedString {
withStyle(AppTheme.code.simple) {
append(str.replace("\t", " "))
addStyle(AppTheme.code.punctuation, ":")
addStyle(AppTheme.code.punctuation, "=")
addStyle(AppTheme.code.punctuation, "\"")
addStyle(AppTheme.code.punctuation, "[")
addStyle(AppTheme.code.punctuation, "]")
addStyle(AppTheme.code.punctuation, "{")
addStyle(AppTheme.code.punctuation, "}")
addStyle(AppTheme.code.punctuation, "(")
addStyle(AppTheme.code.punctuation, ")")
addStyle(AppTheme.code.punctuation, ",")
addStyle(AppTheme.code.keyword, "fun ")
addStyle(AppTheme.code.keyword, "val ")
addStyle(AppTheme.code.keyword, "var ")
addStyle(AppTheme.code.keyword, "private ")
addStyle(AppTheme.code.keyword, "internal ")
addStyle(AppTheme.code.keyword, "for ")
addStyle(AppTheme.code.keyword, "expect ")
addStyle(AppTheme.code.keyword, "actual ")
addStyle(AppTheme.code.keyword, "import ")
addStyle(AppTheme.code.keyword, "package ")
addStyle(AppTheme.code.value, "true")
addStyle(AppTheme.code.value, "false")
addStyle(AppTheme.code.value, Regex("[0-9]*"))
addStyle(AppTheme.code.annotation, Regex("^@[a-zA-Z_]*"))
addStyle(AppTheme.code.comment, Regex("^\\s*//.*"))
}
}

private fun AnnotatedString.Builder.addStyle(style: SpanStyle, regexp: String) {
addStyle(style, fromLiteral(regexp))
}

private fun AnnotatedString.Builder.addStyle(style: SpanStyle, regexp: Regex) {
for (result in regexp.findAll(toString())) {
addStyle(style, result.range.first, result.range.last + 1)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
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)
}
}
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="108dp"
android:height="108dp"
android:viewportWidth="108"
android:viewportHeight="108"
android:tint="#FFFFFF">
<group android:scaleX="2.61"
android:scaleY="2.61"
android:translateX="22.68"
android:translateY="22.68">
<path
android:fillColor="@android:color/white"
android:pathData="M9.4,16.6L4.8,12l4.6,-4.6L8,6l-6,6 6,6 1.4,-1.4zM14.6,16.6l4.6,-4.6 -4.6,-4.6L16,6l6,6 -6,6 -1.4,-1.4z"/>
</group>
</vector>
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
<background android:drawable="@color/ic_launcher_background"/>
<foreground android:drawable="@drawable/ic_launcher_foreground"/>
</adaptive-icon>
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
<background android:drawable="@color/ic_launcher_background"/>
<foreground android:drawable="@drawable/ic_launcher_foreground"/>
</adaptive-icon>
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<color name="ic_launcher_background">#3C3F41</color>
</resources>
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
<resources>
<string name="app_name">Code Viewer</string>
</resources>
18 changes: 18 additions & 0 deletions experimental/examples/codeviewer/build.gradle.kts
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
plugins {
// this is necessary to avoid the plugins to be loaded multiple times
// in each subproject's classloader
kotlin("jvm") apply false
kotlin("multiplatform") apply false
kotlin("android") apply false
id("com.android.application") apply false
id("com.android.library") apply false
id("org.jetbrains.compose") apply false
}

subprojects {
repositories {
google()
mavenCentral()
maven("https://maven.pkg.jetbrains.space/public/p/compose/dev")
}
}
Loading

0 comments on commit 0d6271c

Please sign in to comment.