I have a question about @Composable requirements a...
# compose-desktop
x
I have a question about @Composable requirements and compilation. Following an example from @Igor Demin I tried to setup mutable states before the
Window()
call. However it is not allowed due the following error:
Copy code
(24, 5): Functions which invoke @Composable functions must be marked with the @Composable annotation

(25, 56): @Composable invocations can only happen from the context of a @Composable function

(32, 35): @Composable invocations can only happen from the context of a @Composable function

(33, 16): @Composable invocations can only happen from the context of a @Composable function
This is the snippet:
Copy code
fun main() {
    val characterState: SnapshotStateList<Character> = remember {
        mutableStateListOf(
            CharacterTemplate.DEFAULT_CHARACTER,
            CharacterTemplate.DEFAULT_CHARACTER,
            CharacterTemplate.DEFAULT_CHARACTER
        )
    }
    val window = AppWindowAmbient.current!!.window
    val file = remember { mutableStateOf(File("")) }

    Window(
        title = "CK3 Mod Workbench",
        menuBar = MenuBar(
            Menu("File", MenuItem("Exit", onClick = { AppManager.exit() })),
            Menu(
                "Characters",
                MenuItem("Import characters", onClick = { }),
                MenuItem("Dynasties", onClick = {})
            ),
        )
    ) {
        MaterialTheme(
            colors = workbenchLightColors(),
            shapes = workBenchShapes()
        ) {
            CharacterModuleView()
        }
    }
}
i
We don't need to call
remember
outside Composable functions (i.e. outside Window). Because Composable can be called multiple times,
remember
helps us to execute code only once. So just use
mutableStateListOf/mutableStateOf
without
remember
.
x
oh... ok need to write that down 😄
couldn't it be a warning instead of a compiling error then?
meh nah the error is fine I guess
i
if we make it a warning everyone will just ignore it 😄
x
haha ye I would to be fair 😛
val window = AppWindowAmbient.current!!.window
however this part still has issues. I have to say here that I have 0 experience in desktop application stuff. Maybe I just can't see the obvious
I understand there is no window created yet since
Window
comes after it
But using it in
MenuItem("Import characters", onClick = { }),
doesn't work either - is it Window is no
@composable
? If yes - is it sufficient (and good practise) to wrap the logic into a
@Composable
?
i
Copy code
AppWindowAmbient.current
is also a Composable function. So we need to call it inside Window { }
x
Ok I think the whole Menu Item stuff is not working with the Composable Concepts right?
See I'd like to have this logic wenn clicking on a MenuItem:
Copy code
val fileDialog = FileDialog(window)
    fileDialog.mode = FileDialog.LOAD
    fileDialog.isVisible = true
    file.value = File(fileDialog.directory + fileDialog.file)
Just want to open a file there
Since FileDialog needs a Window I am kind of stuck here
i
If you need to access window inside onClick then we can write our own initialization:
Copy code
import androidx.compose.desktop.AppWindow
import <http://androidx.compose.ui.window.Menu|androidx.compose.ui.window.Menu>
import androidx.compose.ui.window.MenuBar
import androidx.compose.ui.window.MenuItem
import java.awt.FileDialog
import javax.swing.SwingUtilities.invokeLater

fun main() = invokeLater {
    lateinit var window: AppWindow

    window = AppWindow(
        menuBar = MenuBar(
            Menu(
                "Characters",
                MenuItem("Import characters", onClick = {
                    val fileDialog = FileDialog(window.window)
                }),
            ),
        )
    )

    window.show {
        // Composable content
    }
}
x
Ah yes finally thanks a heap @Igor Demin!
👍 1