@@ -26,29 +26,35 @@ import com.android.aaptcompiler.extractPathData
2626import com.blankj.utilcode.util.KeyboardUtils
2727import com.itsaky.androidide.actions.ActionData
2828import com.itsaky.androidide.actions.EditorRelatedAction
29- import com.itsaky.androidide.actions.file.CloseFileAction
3029import com.itsaky.androidide.actions.markInvisible
31- import com.itsaky.androidide.activities.editor.EditorActivityKt
3230import com.itsaky.androidide.activities.editor.EditorHandlerActivity
31+ import com.itsaky.androidide.compose.preview.ComposePreviewActivity
3332import com.itsaky.androidide.editor.ui.IDEEditor
3433import com.itsaky.androidide.idetooltips.TooltipTag
3534import com.itsaky.androidide.resources.R
36- import com.itsaky.androidide.uidesigner.UIDesignerActivity
3735import org.appdevforall.codeonthego.layouteditor.activities.EditorActivity
3836import org.appdevforall.codeonthego.layouteditor.utils.Constants
37+ import org.slf4j.LoggerFactory
3938import java.io.File
4039
41-
42-
4340/* * @author Akash Yadav */
4441class PreviewLayoutAction (context : Context , override val order : Int ) : EditorRelatedAction() {
4542
4643 override val id: String = ID
4744 override fun retrieveTooltipTag (isReadOnlyContext : Boolean ): String = TooltipTag .EDITOR_TOOLBAR_PREVIEW_LAYOUT
4845 override var requiresUIThread: Boolean = false
4946
50- companion object {
47+ private var previewType: PreviewType = PreviewType .NONE
48+
49+ private enum class PreviewType {
50+ NONE ,
51+ XML_LAYOUT ,
52+ COMPOSE
53+ }
54+
55+ companion object {
5156 const val ID = " ide.editor.previewLayout"
57+ private val LOG = LoggerFactory .getLogger(PreviewLayoutAction ::class .java)
5258 }
5359
5460 init {
@@ -59,6 +65,8 @@ class PreviewLayoutAction(context: Context, override val order: Int) : EditorRel
5965 override fun prepare (data : ActionData ) {
6066 super .prepare(data)
6167
68+ previewType = PreviewType .NONE
69+
6270 val viewModel = data.requireActivity().editorViewModel
6371 if (viewModel.isInitializing) {
6472 visible = true
@@ -71,24 +79,47 @@ class PreviewLayoutAction(context: Context, override val order: Int) : EditorRel
7179 }
7280
7381 val editor = data.requireEditor()
74- val file = editor.file!!
75-
76- val isXml = file.name.endsWith(" .xml" )
77-
78- if (! isXml) {
82+ val file = editor.file ? : run {
83+ LOG .warn(" Editor file is null" )
7984 markInvisible()
8085 return
8186 }
8287
83- val type = try {
84- extractPathData(file).type
85- } catch (err: Throwable ) {
86- markInvisible()
87- return
88+ when {
89+ file.name.endsWith(" .xml" ) -> {
90+ val type = try {
91+ extractPathData(file).type
92+ } catch (err: Throwable ) {
93+ markInvisible()
94+ return
95+ }
96+
97+ if (type == LAYOUT ) {
98+ previewType = PreviewType .XML_LAYOUT
99+ visible = true
100+ enabled = true
101+ } else {
102+ markInvisible()
103+ }
104+ }
105+ file.name.endsWith(" .kt" ) -> {
106+ val content = editor.text.toString()
107+ val hasCompose = content.contains(" @Composable" ) ||
108+ content.contains(" androidx.compose" ) ||
109+ content.contains(" @Preview" )
110+
111+ if (hasCompose) {
112+ previewType = PreviewType .COMPOSE
113+ visible = true
114+ enabled = true
115+ } else {
116+ markInvisible()
117+ }
118+ }
119+ else -> {
120+ markInvisible()
121+ }
88122 }
89-
90- visible = type == LAYOUT
91- enabled = visible
92123 }
93124
94125 override fun getShowAsActionFlags (data : ActionData ): Int {
@@ -108,23 +139,30 @@ class PreviewLayoutAction(context: Context, override val order: Int) : EditorRel
108139
109140 override fun postExec (data : ActionData , result : Any ) {
110141 val activity = data.requireActivity()
111- activity.previewLayout(data.requireEditor().file!! )
112- }
142+ val editor = data.requireEditor()
143+ val file = editor.file ? : run {
144+ LOG .warn(" Editor file is null in postExec" )
145+ return
146+ }
113147
114- private fun EditorHandlerActivity.previewLayout (file : File ) {
115- // //close any open xml files first
116- // val openEditors = editorViewModel.getOpenedFileCount()
117- // for(index in 1..openEditors) {
118- // closeFile(index-1) //zero based
119- // }
120- // invalidateOptionsMenu()
148+ when (previewType) {
149+ PreviewType .XML_LAYOUT -> activity.previewXmlLayout(file)
150+ PreviewType .COMPOSE -> activity.showComposePreviewSheet(file, editor.text.toString())
151+ PreviewType .NONE -> {}
152+ }
153+ }
121154
155+ private fun EditorHandlerActivity.previewXmlLayout (file : File ) {
122156 val intent = Intent (this , EditorActivity ::class .java)
123157 intent.putExtra(Constants .EXTRA_KEY_FILE_PATH , file.absolutePath.substringBefore(" layout" ))
124158 intent.putExtra(Constants .EXTRA_KEY_LAYOUT_FILE_NAME , file.name.substringBefore(" ." ))
125159 uiDesignerResultLauncher?.launch(intent)
126160 }
127161
162+ private fun EditorHandlerActivity.showComposePreviewSheet (file : File , sourceCode : String ) {
163+ ComposePreviewActivity .start(this , sourceCode, file.absolutePath)
164+ }
165+
128166 private fun ActionData.requireEditor (): IDEEditor {
129167 return this .getEditor() ? : throw IllegalArgumentException (
130168 " An editor instance is required but none was provided" )
0 commit comments