Browse Source
* Move experimental/examples to examples * Change version to 1.4.0-rc01pull/2977/head
Nikita Lipsky
2 years ago
committed by
GitHub
938 changed files with 1484 additions and 13809 deletions
Before Width: | Height: | Size: 21 KiB After Width: | Height: | Size: 21 KiB |
@ -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> |
@ -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") |
||||
} |
@ -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) |
||||
} |
||||
} |
||||
} |
||||
} |
||||
} |
@ -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") |
||||
} |
||||
} |
||||
} |
@ -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 |
@ -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 |
||||
) |
@ -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) |
||||
) |
||||
} |
||||
} |
@ -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) |
||||
} |
||||
} |
||||
} |
||||
} |
@ -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 |
||||
) |
||||
) |
||||
} |
@ -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) |
||||
) |
||||
} |
||||
} |
@ -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) |
||||
) |
||||
} |
||||
} |
||||
} |
@ -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) |
||||
} |
||||
} |
@ -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)) |
||||
} |
||||
} |
||||
} |
@ -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 |
@ -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 |
||||
} |
@ -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) |
||||
) |
||||
} |
@ -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))) |
@ -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) |
||||
} |
||||
} |
@ -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" |
||||
} |
||||
} |
||||
} |
||||
} |
@ -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() |
||||
} |
Before Width: | Height: | Size: 9.1 KiB After Width: | Height: | Size: 9.1 KiB |
@ -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.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 |
||||
compose.version=1.3.1 |
||||
compose.version=1.4.0-rc01 |
||||
|
Binary file not shown.
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in new issue