Skip to content

Commit b101569

Browse files
committed
feat(Filetree): Update filetree
1 parent 97ac419 commit b101569

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

56 files changed

+142
-2559
lines changed

app/build.gradle.kts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -122,7 +122,6 @@ dependencies {
122122
// projects
123123
implementation(projects.appStrings)
124124

125-
implementation(projects.feature.treeview)
126125
implementation(projects.feature.editor)
127126
implementation(projects.feature.compiler)
128127

app/src/main/java/org/robok/engine/ui/screens/editor/EditorScreen.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,12 +55,12 @@ import androidx.compose.ui.res.stringResource
5555
import androidx.compose.ui.unit.dp
5656
import androidx.compose.ui.viewinterop.AndroidView
5757
import dev.trindadedev.scrolleffect.cupertino.CupertinoColumnScroll
58+
import java.io.File
5859
import kotlinx.coroutines.launch
5960
import org.koin.androidx.compose.koinViewModel
6061
import org.robok.engine.Strings
6162
import org.robok.engine.feature.compiler.android.logger.LoggerViewModel
6263
import org.robok.engine.feature.editor.RobokCodeEditor
63-
import org.robok.engine.io.File
6464
import org.robok.engine.manage.project.ProjectManager
6565
import org.robok.engine.state.KeyboardState
6666
import org.robok.engine.state.keyboardAsState

app/src/main/java/org/robok/engine/ui/screens/editor/components/drawer/EditorFilesDrawer.kt

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -17,18 +17,17 @@ package org.robok.engine.ui.screens.editor.components.drawer
1717
*/
1818

1919
import androidx.compose.runtime.Composable
20-
import org.robok.engine.io.File
20+
import java.io.File
2121
import org.robok.engine.ui.screens.editor.components.drawer.filetree.FileTreeDrawer
2222
import org.robok.engine.ui.screens.editor.viewmodel.EditorViewModel
2323

2424
@Composable
2525
fun EditorFilesDrawer(editorViewModel: EditorViewModel) {
2626
FileTreeDrawer(
27-
path = editorViewModel.projectManager.projectPath.absolutePath,
28-
onClick = { node ->
29-
val file = File(node.value.getAbsolutePath())
30-
if (file.isDirectory()) {} else {
31-
editorViewModel.openFile(file)
27+
path = editorViewModel.projectManager.projectPath,
28+
onNodeClick = { node ->
29+
if (node.abs.isDirectory()) {} else {
30+
editorViewModel.openFile(node.abs)
3231
}
3332
},
3433
)

app/src/main/java/org/robok/engine/ui/screens/editor/components/drawer/filetree/FileTree.kt

Lines changed: 113 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -16,61 +16,126 @@ package org.robok.engine.ui.screens.editor.components.drawer.filetree
1616
* limitations under the License.
1717
*/
1818

19-
import android.content.Context
20-
import androidx.compose.foundation.*
21-
import androidx.compose.foundation.layout.*
22-
import androidx.compose.material3.*
23-
import androidx.compose.runtime.*
24-
import androidx.compose.ui.*
25-
import androidx.compose.ui.platform.LocalContext
26-
import androidx.compose.ui.res.*
27-
import androidx.compose.ui.unit.*
28-
import androidx.compose.ui.viewinterop.AndroidView
19+
import androidx.compose.animation.core.animateFloatAsState
20+
import androidx.compose.animation.core.tween
21+
import androidx.compose.foundation.clickable
22+
import androidx.compose.foundation.layout.Column
23+
import androidx.compose.foundation.layout.Spacer
24+
import androidx.compose.foundation.layout.Row
25+
import androidx.compose.foundation.layout.fillMaxWidth
26+
import androidx.compose.foundation.layout.padding
27+
import androidx.compose.foundation.layout.width
28+
import androidx.compose.material.icons.Icons
29+
import androidx.compose.material.icons.filled.ChevronRight
30+
import androidx.compose.material.icons.filled.ExpandMore
31+
import androidx.compose.material.icons.filled.InsertDriveFile
32+
import androidx.compose.material.icons.filled.Folder
33+
import androidx.compose.material3.Icon
34+
import androidx.compose.material3.Text
35+
import androidx.compose.runtime.Composable
36+
import androidx.compose.runtime.MutableState
37+
import androidx.compose.runtime.mutableStateOf
38+
import androidx.compose.runtime.getValue
39+
import androidx.compose.runtime.remember
40+
import androidx.compose.ui.Alignment
41+
import androidx.compose.ui.Modifier
42+
import androidx.compose.ui.draw.rotate
43+
import androidx.compose.ui.unit.dp
2944
import java.io.File
30-
import org.robok.engine.feature.treeview.interfaces.FileClickListener
31-
import org.robok.engine.feature.treeview.interfaces.FileObject
32-
import org.robok.engine.feature.treeview.model.Node
33-
import org.robok.engine.feature.treeview.provider.DefaultFileIconProvider
34-
import org.robok.engine.feature.treeview.provider.FileWrapper
35-
import org.robok.engine.feature.treeview.widget.FileTree as FileTreeView
45+
import org.robok.engine.ui.core.components.animation.ExpandAndShrink
46+
47+
data class FileNode(
48+
val name: String,
49+
val isDirectory: Boolean,
50+
val abs: File,
51+
val children: List<FileNode> = emptyList(),
52+
val isExpanded: MutableState<Boolean> = mutableStateOf(false)
53+
)
54+
55+
fun buildFileTree(file: File): FileNode {
56+
return if (file.isDirectory) {
57+
val children = file.listFiles()?.sortedBy {
58+
it.name
59+
}?.map {
60+
buildFileTree(it)
61+
} ?: emptyList()
62+
FileNode(
63+
name = file.name,
64+
isDirectory = true,
65+
abs = file,
66+
children = children)
67+
} else {
68+
FileNode(
69+
name = file.name,
70+
isDirectory = false,
71+
abs = file
72+
)
73+
}
74+
}
3675

3776
@Composable
3877
fun FileTree(
39-
path: String,
40-
onClick: (Node<FileObject>) -> Unit,
41-
modifier: Modifier = Modifier,
42-
state: FileTreeState,
78+
path: File,
79+
onNodeClick: (FileNode) -> Unit = {}
4380
) {
44-
val context = LocalContext.current
45-
val fileTreeFactory = remember {
46-
setFileTreeFactory(context = context, path = path, onClick = onClick, state = state)
47-
}
48-
AndroidView(factory = { fileTreeFactory }, modifier = modifier)
81+
val rootNode = remember(path) { buildFileTree(path) }
82+
83+
FileTree(
84+
nodes = listOf(rootNode),
85+
onNodeClick = onNodeClick
86+
)
4987
}
5088

51-
private fun setFileTreeFactory(
52-
context: Context,
53-
path: String,
54-
onClick: (Node<FileObject>) -> Unit,
55-
state: FileTreeState,
56-
): FileTreeView {
57-
val fileObject = FileWrapper(File(path))
58-
val fileTree =
59-
FileTreeView(context).apply {
60-
loadFiles(fileObject)
61-
setOnFileClickListener(
62-
object : FileClickListener {
63-
override fun onClick(node: Node<FileObject>) {
64-
onClick(node)
89+
@Composable
90+
fun FileTree(
91+
nodes: List<FileNode>,
92+
level: Int = 0,
93+
onNodeClick: (FileNode) -> Unit = {}
94+
) {
95+
Column {
96+
nodes.forEach { node ->
97+
Row(
98+
modifier = Modifier
99+
.fillMaxWidth()
100+
.clickable {
101+
if (node.isDirectory) {
102+
node.isExpanded.value = !node.isExpanded.value
103+
}
104+
onNodeClick(node)
65105
}
106+
.padding(
107+
start = (level * 16).dp,
108+
top = 4.dp,
109+
bottom = 4.dp
110+
),
111+
verticalAlignment = Alignment.CenterVertically
112+
) {
113+
if (node.isDirectory) {
114+
val rotation by animateFloatAsState(
115+
targetValue = if (node.isExpanded.value) 0f else -180f,
116+
animationSpec = tween(500)
117+
)
118+
Icon(
119+
imageVector = if (node.isExpanded.value) Icons.Filled.ExpandMore else Icons.Filled.ChevronRight,
120+
contentDescription = null,
121+
modifier = Modifier.rotate(rotation)
122+
)
123+
} else {
124+
Spacer(modifier = Modifier.width(24.dp))
66125
}
67-
)
68-
setIconProvider(DefaultFileIconProvider(context))
126+
Icon(
127+
imageVector = if (node.isDirectory) Icons.Filled.Folder else Icons.Filled.InsertDriveFile,
128+
contentDescription = null
129+
)
130+
Text(text = node.name)
131+
}
132+
ExpandAndShrink(node.isDirectory && node.isExpanded.value) {
133+
FileTree(
134+
nodes = node.children,
135+
level = level + 1,
136+
onNodeClick = onNodeClick
137+
)
138+
}
69139
}
70-
state.fileTreeView = fileTree
71-
return fileTree
72-
}
73-
74-
data class FileTreeState(var fileTreeView: FileTreeView? = null)
75-
76-
@Composable fun rememberFileTreeState() = remember { FileTreeState() }
140+
}
141+
}

app/src/main/java/org/robok/engine/ui/screens/editor/components/drawer/filetree/FileTreeDrawer.kt

Lines changed: 18 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -16,21 +16,24 @@ package org.robok.engine.ui.screens.editor.components.drawer.filetree
1616
* limitations under the License.
1717
*/
1818

19-
import androidx.compose.foundation.*
20-
import androidx.compose.foundation.layout.*
21-
import androidx.compose.material3.*
22-
import androidx.compose.runtime.*
23-
import androidx.compose.ui.*
24-
import androidx.compose.ui.res.*
25-
import androidx.compose.ui.unit.*
19+
import androidx.compose.foundation.layout.Column
20+
import androidx.compose.foundation.layout.padding
21+
import androidx.compose.material3.MaterialTheme
22+
import androidx.compose.material3.Text
23+
import androidx.compose.runtime.Composable
24+
import androidx.compose.ui.Modifier
25+
import androidx.compose.ui.unit.dp
26+
import androidx.compose.ui.unit.sp
27+
import androidx.compose.ui.res.stringResource
28+
import java.io.File
2629
import org.robok.engine.Strings
27-
import org.robok.engine.feature.treeview.interfaces.FileObject
28-
import org.robok.engine.feature.treeview.model.Node
2930
import org.robok.engine.ui.theme.Typography
3031

3132
@Composable
32-
fun FileTreeDrawer(path: String, onClick: (Node<FileObject>) -> Unit) {
33-
val fileTreeState = rememberFileTreeState()
33+
fun FileTreeDrawer(
34+
path: File,
35+
onNodeClick: (FileNode) -> Unit
36+
) {
3437
Column {
3538
Text(
3639
text = stringResource(id = Strings.common_word_files),
@@ -39,6 +42,9 @@ fun FileTreeDrawer(path: String, onClick: (Node<FileObject>) -> Unit) {
3942
color = MaterialTheme.colorScheme.onSurface,
4043
modifier = Modifier.padding(start = 16.dp, top = 8.dp, bottom = 8.dp),
4144
)
42-
FileTree(path = path, onClick = onClick, state = fileTreeState)
45+
FileTree(
46+
path = path,
47+
onNodeClick = onNodeClick,
48+
)
4349
}
4450
}

app/src/main/java/org/robok/engine/ui/screens/editor/components/tab/EditorFileTabLayout.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,7 @@ fun EditorFileTabLayout(modifier: Modifier = Modifier, editorViewModel: EditorVi
9595
}
9696
},
9797
text = {
98-
Text(text = if (openedFile.isModified()) "*${openedFile.name}" else openedFile.name)
98+
Text(text = openedFile.name)
9999
},
100100
)
101101
}

app/src/main/java/org/robok/engine/ui/screens/editor/event/EditorEvent.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ package org.robok.engine.ui.screens.editor.event
1616
* limitations under the License.
1717
*/
1818

19-
import org.robok.engine.io.File
19+
import java.io.File
2020

2121
sealed interface EditorEvent {
2222
data class SelectFile(val index: Int) : EditorEvent

app/src/main/java/org/robok/engine/ui/screens/editor/state/BuildState.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ package org.robok.engine.ui.screens.editor.state
1616
* limitations under the License.
1717
*/
1818

19-
import org.robok.engine.io.File
19+
import java.io.File
2020

2121
sealed class BuildState {
2222
object NotStarted : BuildState()

app/src/main/java/org/robok/engine/ui/screens/editor/state/EditorUIState.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,9 +16,9 @@ package org.robok.engine.ui.screens.editor.state
1616
* limitations under the License.
1717
*/
1818

19+
import java.io.File
1920
import org.robok.engine.feature.compiler.android.logger.Log
2021
import org.robok.engine.feature.editor.RobokCodeEditor
21-
import org.robok.engine.io.File
2222
import org.robok.engine.ui.screens.editor.EditorNavigateActions
2323

2424
data class EditorUIState(

app/src/main/java/org/robok/engine/ui/screens/editor/viewmodel/EditorViewModel.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,12 +21,12 @@ import androidx.compose.runtime.getValue
2121
import androidx.compose.runtime.mutableStateOf
2222
import androidx.compose.runtime.setValue
2323
import androidx.lifecycle.ViewModel
24+
import java.io.File
2425
import org.robok.engine.core.utils.FileUtil
2526
import org.robok.engine.feature.compiler.android.OnCompileResult
2627
import org.robok.engine.feature.compiler.android.logger.Log as CompilerLog
2728
import org.robok.engine.feature.compiler.android.logger.LoggerViewModel
2829
import org.robok.engine.feature.editor.RobokCodeEditor
29-
import org.robok.engine.io.File
3030
import org.robok.engine.manage.project.ProjectManager
3131
import org.robok.engine.ui.screens.editor.EditorNavigateActions
3232
import org.robok.engine.ui.screens.editor.event.EditorEvent

0 commit comments

Comments
 (0)