Olivier Patry
03/06/2023, 7:55 PMMenu
content, state & action (of the WindowScope
) for different "screens"?
Currently, I have a single desktop specific MyApp
class which is responsible to
• provide main()
• create application {}
• create main Window
composable
• delegate main window content to a MyAppContent
composable
The MyAppContent
then handles the navigation logic between "screens" (using #decompose library (but whatever?))
Depending on the navigation state machine, a proper FooScreen
composable is chosen to display screen content.
Each of these "screen" have its own FooViewModel
to drive logic and UI binding.
Now, back to the menu topic.
AFAIK, the menu must be managed within the WindowScope
and thus currently in my main top level MyApp
.
For general purpose menu items like preferences, it's fine but several items are contextual to the screen being displayed.
I need to
• decide if an item must be displayed or not
• decide if the item is enabled or disabled
• provide a business logic callback to call when item is clicked (most likely to a FooViewModel
entity)
I'm not sure what would work well in this setup, ideally isolating desktop specific stuff like that outside main screens meant to be reusable at least on Android and maybe more later.
If "duplicating" some boilerplate of "screens" would be needed to combine desktop feature and reusing code in other platforms, it's fine though.Dima Avdeev
03/06/2023, 9:00 PMOlivier Patry
03/06/2023, 9:11 PMFooViewModel
state, right?
Doing that would spread menu logic into reusable screen but it's not necessarily a problem, it wouldn't be coupled to desktop specific stuff if I use my own "menu item data model", only useless elsewhere (or reused another way).
So basically I would have something like
MyApp {
val menuState = remember { mutableStateOf(MyMenuDataModel()) }
Window {
// interpret menuState/MyMenuDataModel as Menu and Item tree
Menu {
Item() {}
}
MyAppContent(menuState)
}
}
@Composable
fun MyAppContent(menuState: MutableState<MyMenuDataModel>) {
// depending on state machine, choose right screen composable
FooScreen(menuState)
}
@Composable
fun FooScreen(menuState: MutableState<MyMenuDataModel>) {
val viewModel = ...
val canDoSomething = viewModel.canDoSomething.collectAsState()
menuState.update(MyMenuDataModel.FooScreen(..., canDoSomething, ...))
...
}
Is this something like that you were suggesting?Dima Avdeev
03/06/2023, 9:13 PMdata class AppState(val screen: Screen)
sealed interface Screen {
object Notes: Screen
object Edit: Screen
}
val menuItems = listOf(Item("AlwaysMenuItem")) + when(state.screen) {
is Notes -> listOf(Item("Add note"))
is Edit -> listOf(Item("Save"), Item("Remove"))
}
Olivier Patry
03/06/2023, 9:28 PMDima Avdeev
03/06/2023, 9:28 PMOlivier Patry
03/06/2023, 9:30 PMCompositionLocalProvider
-like thingsDima Avdeev
03/07/2023, 12:08 PM