Skip to main content

Desktop

Coming from Form Controls, let's look at the handful of things that only make sense once your app is actually running as a native Desktop window.

Multi-window apps​

Back on Displays, you saw that a multi-window app gives each window its own Display. This is the API that actually manages those windows: WindowGroup. Inject it to get going — it hands you the app's main window, plus everything you need to create more.

package display import io.nacular.doodle.application.Application import io.nacular.doodle.core.WindowGroup import io.nacular.doodle.core.view import io.nacular.doodle.geometry.Size import io.nacular.doodle.layout.constraints.constrain import io.nacular.doodle.layout.constraints.fill //sampleStart class MyCoolApp(windows: WindowGroup): Application { init { // main window's display, same as if Display were injected windows.main.apply { title = "Main Window" // manipulate main window's display display += view {} } // create a new window windows { title = "A New Window!" size = Size(500) enabled = false resizable = false triesToAlwaysBeOnTop = true // manipulate the new window's display display += view {} display.layout = constrain(display.first(), fill) closed += { // handle window close } } } override fun shutdown() {} } //sampleEnd
tip

No need to inject Display separately if you're already injecting WindowGroup — the injected Display is exactly equivalent to WindowGroup.main.display.

Native window menus​

Apps can give a window a genuine native menu — the kind that lives in the OS's own window chrome, not drawn by Doodle itself. The API will look familiar: it's built the same way as the in-app Menu control you've already met, just installed onto a Window instead of the Display. These menus are just as interactive as their in-app counterparts too — they fire the same kind of events when the user interacts with them.

package display import io.nacular.doodle.controls.popupmenu.MenuBehavior.ItemInfo import io.nacular.doodle.core.Icon import io.nacular.doodle.core.Window fun example(window: Window, icon1: Icon<ItemInfo>, icon2: Icon<ItemInfo>) { //sampleStart window.menuBar { menu("Menu 1") { action("Do action 2", icon1) { /*..*/ } menu("Sub menu") { action("Do action sub", icon = icon2) { /*..*/ } separator() prompt("Some Prompt sub") { /*..*/ } } separator() prompt("Some Prompt") { /*..*/ } } menu("Menu 2") { // ... } } //sampleEnd }

Native context menus​

Context/popup menus work the same way — genuinely native, and built with an API that mirrors the menu bar above almost exactly:

package display import io.nacular.doodle.controls.popupmenu.MenuBehavior.ItemInfo import io.nacular.doodle.core.Icon import io.nacular.doodle.core.Window import io.nacular.doodle.geometry.Point fun contextMenu(window: Window, icon1: Icon<ItemInfo>, icon2: Icon<ItemInfo>) { //sampleStart window.popupMenu(at = Point()) { action("Do action 2", icon1) { /*..*/ } menu("Sub menu") { action("Do action sub", icon = icon2) { /*..*/ } separator() prompt("Some Prompt sub") { /*..*/ } } separator() prompt("Some Prompt") { /*..*/ } } //sampleEnd }

Recap​

  • WindowGroup manages multiple windows — inject it instead of Display once your app needs more than one, and you get Display access for free through WindowGroup.main.display.
  • Native window menus and native context menus both use an API that closely mirrors the in-app Menu control, just installed on a Window rather than the Display.

Next: on to Web for what's unique to running in the browser.