Doodle <https://github.com/nacular/doodle/releases...
# doodle
n
Doodle 0.10.0 is now available Hosting arbitrary HTML elements You can now embed any HTML element into your app as a View. This means Doodle apps can now host React and other web components and interop with a much larger part of the Web ecosystem out of the box!
Copy code
import io.nacular.doodle.HtmlElementViewFactory
import io.nacular.doodle.application.Application
import io.nacular.doodle.core.Display
import org.w3c.dom.HTMLElement

class MyApp(
    display        : Display,
    htmlElementView: HtmlElementViewFactory,
    someElement    : HTMLElement,
): Application {

    init {
        display += htmlElementView(element = someElement)
    }

    override fun shutdown() {}
}
Copy code
application(modules = listOf(Modules.HtmlElementViewModule)) {
    MyApp(display = instance(), viewFactory = instance(), element = element)
}
WASM JS Support Doodle now supports the
wasmJS
build target. This means apps can also target WASM for the browser. The APIs/features for this new target are identical as those for the
js
target; which means code can be shared between apps targeting both. The only difference is that the
application
launchers need to be called from separate source sets (i.e.
jsMain
vs
wasmJsMain
). Multi-window Support (Desktop) Apps for Desktop can now create/manage multiple windows using a new
WindowGroup
instance. This instance can be injected into an app just like the
Display
. It then provides APIs for getting the
main
window and creating new ones. Single window apps continue to work as they did before. That is, an app that injects the
Display
will receive the
main
window display and can manipulate it as before. But apps that want to manage their window(s) will need to inject this new type.
Copy code
class MyCoolApp(windows: WindowGroup /*, mainWindowDisplay: Display*/): Application {
    init {
        // main window's display, same as if 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() {}
}
Native Window Menus (Desktop) Apps can now set up native menus for their windows. This looks a lot like working with the existing menu APIs, but it results in changes to the OS window decoration. These menus are just as interactive as the in-app ones as well, meaning they trigger events when the user interacts with them.
Copy code
window.menuBar {
    menu("Menu 1") {
        action("Do action 2", pathIcon) { /*..*/ }
        menu("Sub menu") {
            action("Do action sub", icon = simpleIcon) { /*..*/ }
            separator()
            prompt("Some Prompt sub") { /*..*/ }
        }
        separator()
        prompt("Some Prompt") { /*..*/ }
    }
  
    menu("Menu 2") {
      // ...
    }
}
Native Window Context Menus (Desktop) Apps can now set up native context/popup menus for their windows. The API is very similar to native menus.
Copy code
window.popupMenu(at = somePoint) {
    action("Do action 2", pathIcon) { /*..*/ }
    menu("Sub menu") {
        action("Do action sub", icon = simpleIcon) { /*..*/ }
        separator()
        prompt("Some Prompt sub") { /*..*/ }
    }
    separator()
    prompt("Some Prompt") { /*..*/ }
}
Key events behave more like Pointer events Key events now "sink" and "bubble" like pointer events. This means ancestor Views can intercept (and veto) them before they are delivered to their target (the focused View). They also bubble up to ancestors after being delivered to the target if they are not consumed. The notifications for the first phase happen via a new
View.keyFilter
property, while the bubbling phase is notified via the existing
View.keyChanged
property.
.wasm 3
🔥 4