Skip to content

Commit

Permalink
refactor: new sample app
Browse files Browse the repository at this point in the history
  • Loading branch information
adrielcafe committed Apr 20, 2022
1 parent 5587060 commit 50e6763
Show file tree
Hide file tree
Showing 10 changed files with 4,386 additions and 179 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,8 @@ import androidx.compose.ui.unit.Dp
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import cafe.adriel.bonsai.core.node.Node
import cafe.adriel.bonsai.core.tree.extension.ExpandableTree
import cafe.adriel.bonsai.core.tree.Tree
import cafe.adriel.bonsai.core.tree.extension.ExpandableTree
import cafe.adriel.bonsai.core.tree.extension.SelectableTree

public typealias OnNodeClick<T> = ((Node<T>) -> Unit)?
Expand Down
6 changes: 4 additions & 2 deletions gradle/libs.versions.toml
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,9 @@ okio = "3.0.0"
serialization = "1.3.2"

compose = "1.1.1"
composeActivity = "1.4.0"
composeMultiplatform = "1.1.1"
composeActivity = "1.4.0"
composeVoyager = "1.0.0-beta16"

[libraries]
plugin-android = { module = "com.android.tools.build:gradle", version.ref = "plugin-android" }
Expand All @@ -24,10 +25,11 @@ plugin-compose-multiplatform = { module = "org.jetbrains.compose:compose-gradle-
okio = { module = "com.squareup.okio:okio", version.ref = "okio" }
serialization = { module = "org.jetbrains.kotlinx:kotlinx-serialization-json", version.ref = "serialization" }

compose-activity = { module = "androidx.activity:activity-compose", version.ref = "composeActivity" }
compose-runtime = { module = "androidx.compose.runtime:runtime", version.ref = "compose" }
compose-material = { module = "androidx.compose.material:material", version.ref = "compose" }
compose-material-icons = { module = "androidx.compose.material:material-icons-extended", version.ref = "compose" }
compose-activity = { module = "androidx.activity:activity-compose", version.ref = "composeActivity" }
compose-voyager = { module = "cafe.adriel.voyager:voyager-navigator", version.ref = "composeVoyager" }

[bundles]
plugins = ["plugin-android", "plugin-ktlint", "plugin-detekt", "plugin-maven", "plugin-kotlin", "plugin-serialization", "plugin-compose-multiplatform"]
3 changes: 2 additions & 1 deletion sample/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,8 @@ dependencies {
implementation(projects.bonsaiFileSystem)
implementation(projects.bonsaiJson)

implementation libs.compose.activity
implementation libs.compose.material
implementation libs.compose.material.icons
implementation libs.compose.activity
implementation libs.compose.voyager
}
55 changes: 55 additions & 0 deletions sample/src/main/java/cafe/adriel/bonsai/sample/HomeScreen.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
package cafe.adriel.bonsai.sample

import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.material.Button
import androidx.compose.material.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import cafe.adriel.bonsai.sample.tree.DslTreeScreen
import cafe.adriel.bonsai.sample.tree.FileSystemTreeScreen
import cafe.adriel.bonsai.sample.tree.JsonTreeScreen
import cafe.adriel.voyager.core.screen.Screen
import cafe.adriel.voyager.navigator.LocalNavigator
import cafe.adriel.voyager.navigator.currentOrThrow

object HomeScreen : Screen {

@Composable
override fun Content() {
Column(
verticalArrangement = Arrangement.Center,
horizontalAlignment = Alignment.CenterHorizontally,
modifier = Modifier.fillMaxSize()
) {
SampleButton(
text = "DSL Tree",
screen = DslTreeScreen
)
SampleButton(
text = "File System Tree",
screen = FileSystemTreeScreen
)
SampleButton(
text = "JSON Tree",
screen = JsonTreeScreen
)
}
}

@Composable
private fun SampleButton(
text: String,
screen: Screen
) {
val navigator = LocalNavigator.currentOrThrow

Button(
onClick = { navigator push screen }
) {
Text(text)
}
}
}
177 changes: 2 additions & 175 deletions sample/src/main/java/cafe/adriel/bonsai/sample/SampleActivity.kt
Original file line number Diff line number Diff line change
@@ -1,192 +1,19 @@
package cafe.adriel.bonsai.sample

import android.os.Build
import android.os.Bundle
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.lazy.LazyRow
import androidx.compose.material.Button
import androidx.compose.material.MaterialTheme
import androidx.compose.material.Text
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.outlined.Adb
import androidx.compose.material.icons.outlined.Android
import androidx.compose.material.icons.outlined.Description
import androidx.compose.material.icons.outlined.Folder
import androidx.compose.material.icons.outlined.FolderOpen
import androidx.compose.material.icons.outlined.Image
import androidx.compose.material.icons.outlined.InsertDriveFile
import androidx.compose.material.icons.outlined.LocalCafe
import androidx.compose.material.icons.outlined.Memory
import androidx.compose.material.icons.outlined.Mic
import androidx.compose.material.icons.outlined.Videocam
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.vector.ImageVector
import androidx.compose.ui.graphics.vector.rememberVectorPainter
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.unit.dp
import cafe.adriel.bonsai.core.Bonsai
import cafe.adriel.bonsai.core.node.BranchNode
import cafe.adriel.bonsai.core.node.Node
import cafe.adriel.bonsai.core.tree.Tree
import cafe.adriel.bonsai.core.tree.rememberTree
import cafe.adriel.bonsai.filesystem.FileSystemBonsaiStyle
import cafe.adriel.bonsai.filesystem.fileSystemNodes
import okio.Path
import cafe.adriel.voyager.navigator.Navigator

class SampleActivity : ComponentActivity() {

private val rootDirectory by lazy {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) dataDir
else codeCacheDir
}

private val Tree<Path>.firstBranchNodeAtLevel1: Node<Path>
get() = nodes
.filterIsInstance<BranchNode<Path>>()
.first { it.children.isNotEmpty() }
.children
.filterIsInstance<BranchNode<Path>>()
.first { it.children.isNotEmpty() }

override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContent {
MaterialTheme {
val tree = rememberTree<Path>(
nodes = fileSystemNodes(
rootPath = rootDirectory,
selfInclude = true
)
)

Column(
verticalArrangement = Arrangement.Bottom,
modifier = Modifier.fillMaxSize()
) {
Bonsai(
tree = tree,
style = FileSystemBonsaiStyle().copy(
nodeCollapsedIcon = { node ->
getIcon(
path = node.content,
default = if (node is BranchNode) Icons.Outlined.Folder
else Icons.Outlined.InsertDriveFile
)
},
nodeExpandedIcon = { node ->
getIcon(path = node.content, default = Icons.Outlined.FolderOpen)
}
),
modifier = Modifier
.weight(1f)
.padding(bottom = 4.dp)
)
TreeController(
tree = tree
)
}
Navigator(HomeScreen)
}
}
}

@Composable
private fun TreeController(
tree: Tree<Path>
) {
Column {
TreeManagerTitle("Expand")
LazyRow {
item {
TreeManagerButton(
text = "Root",
onClick = { tree.expandRoot() }
)
TreeManagerButton(
text = "Node",
onClick = { tree.expandNode(tree.firstBranchNodeAtLevel1) }
)
TreeManagerButton(
text = "Level 2",
onClick = { tree.expandUntil(2) }
)
}
}
TreeManagerTitle("Collapse")
LazyRow {
item {
TreeManagerButton(
text = "Root",
onClick = { tree.collapseRoot() }
)
TreeManagerButton(
text = "Node",
onClick = { tree.collapseNode(tree.firstBranchNodeAtLevel1) }
)
TreeManagerButton(
text = "Level 2",
onClick = { tree.collapseFrom(2) }
)
}
}
TreeManagerTitle("Select")
LazyRow {
item {
TreeManagerButton(
text = "Toggle",
onClick = { tree.toggleSelection(tree.nodes.first()) }
)
TreeManagerButton(
text = "Clear",
onClick = { tree.clearSelection() }
)
}
}
}
}

@Composable
private fun TreeManagerTitle(
text: String
) {
Text(
text = text,
fontWeight = FontWeight.SemiBold,
modifier = Modifier.padding(horizontal = 4.dp)
)
}

@Composable
private fun TreeManagerButton(
text: String,
onClick: () -> Unit
) {
Button(
onClick = onClick,
modifier = Modifier.padding(horizontal = 4.dp)
) {
Text(text = text)
}
}

@Composable
private fun getIcon(path: Path, default: ImageVector) =
rememberVectorPainter(
when (path.toFile().extension) {
"apk" -> Icons.Outlined.Android
"jar" -> Icons.Outlined.LocalCafe
"studio" -> Icons.Outlined.Adb
"so" -> Icons.Outlined.Memory
"xml" -> Icons.Outlined.Description
"png", "webp", "jpg" -> Icons.Outlined.Image
"mp4", "webm", "gif" -> Icons.Outlined.Videocam
"wav", "mp3", "ogg" -> Icons.Outlined.Mic
else -> default
}
)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
package cafe.adriel.bonsai.sample.tree

import androidx.compose.material.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.unit.dp
import cafe.adriel.bonsai.core.Bonsai
import cafe.adriel.bonsai.core.BonsaiStyle
import cafe.adriel.bonsai.core.node.Branch
import cafe.adriel.bonsai.core.node.Leaf
import cafe.adriel.bonsai.core.tree.Tree

object DslTreeScreen : TreeScreen<String> {

override val title = "DSL Tree"

@Composable
override fun buildTree(): Tree<String> =
Tree {
Branch("Animalia") {
Branch("Chordata") {
Branch("Mammalia") {
Branch("Carnivora") {
Branch("Canidae") {
Branch("Canis") {
Leaf("Wolf", customIcon = { LeafIcon("\uD83D\uDC3A") })
Leaf("Dog", customIcon = { LeafIcon("\uD83D\uDC36") })
}
}
Branch("Felidae") {
Branch("Felis") {
Leaf("Cat", customIcon = { LeafIcon("\uD83D\uDC31") })
}
Branch("Panthera") {
Leaf("Lion", customIcon = { LeafIcon("\uD83E\uDD81") })
}
}
}
}
}
}
Branch("Plantae") {
Branch("Solanales") {
Branch("Convolvulaceae") {
Branch("Ipomoea") {
Leaf("Sweet Potato", customIcon = { LeafIcon("\uD83C\uDF60") })
}
}
Branch("Solanaceae") {
Leaf("Potato", customIcon = { LeafIcon("\uD83E\uDD54") })
Leaf("Tomato", customIcon = { LeafIcon("\uD83C\uDF45") })
}
}
}
}

@Composable
override fun BonsaiContent(
tree: Tree<String>,
modifier: Modifier
) {
Bonsai(
tree = tree,
style = BonsaiStyle(
nodeNameStartPadding = 4.dp
),
modifier = modifier
)
}

@Composable
private fun LeafIcon(emoji: String) {
Text(emoji)
}
}
Loading

0 comments on commit 50e6763

Please sign in to comment.