All Downloads are FREE. Search and download functionalities are using the official Maven repository.

commonMain.io.nacular.doodle.theme.Modules.kt Maven / Gradle / Ivy

package io.nacular.doodle.theme

import io.nacular.doodle.core.View
import io.nacular.doodle.theme.Modules.BehaviorResult.Matched
import io.nacular.doodle.theme.Modules.BehaviorResult.NotMatched
import io.nacular.doodle.theme.adhoc.DynamicTheme
import org.kodein.di.DI.Builder
import org.kodein.di.DI.Module
import org.kodein.di.addInBindSet
import org.kodein.di.bind
import org.kodein.di.bindSet
import org.kodein.di.bindings.NoArgBindingDI
import org.kodein.di.erasedSet
import org.kodein.di.instance
import org.kodein.di.singleton
import kotlin.reflect.KClass

/**
 * Created by Nicholas Eddy on 4/15/20.
 */
public class Modules private constructor() {
    public enum class BehaviorResult { Matched, NotMatched }

    public interface BehaviorResolver {
        public val theme: KClass? get() = null

        public operator fun invoke(view: View): BehaviorResult
    }

    public companion object {
        /**
         * Provides access to [ThemeManager], so it can be injected.
         */
        public val ThemeModule: Module = Module(allowSilentOverride = true, name = "Theme") {
            bind        () with singleton { instance() }
            bind() with singleton { ThemeManagerImpl(instance()) }
        }

        /**
         * Provides access to [DynamicTheme], so it can be injected.
         */
        public val DynamicThemeModule: Module = Module(name = "DynamicThemeModule") {
            importOnce(ThemeModule, allowOverride = true)

            bindSet()

            bind() with singleton { object: DynamicTheme(Instance(erasedSet())) {} }
            bind       () with singleton { instance() }
        }

        public inline fun  Builder.bindBehavior(theme: KClass? = null, crossinline block: NoArgBindingDI<*>.(T) -> Unit): Unit = bindConditionalBehavior(theme) {
            block(this, it)
            Matched
        }

        // TODO: Can this be renamed to bindBehavior in 1.4?
        public inline fun  Builder.bindConditionalBehavior(theme: KClass? = null, crossinline block: NoArgBindingDI<*>.(T) -> BehaviorResult) {
            importOnce(DynamicThemeModule, allowOverride = true)

            // FIXME: changing to inBindSet { add {} } causes crash on desktop
            addInBindSet { singleton {
                object: BehaviorResolver {
                    override val theme = theme

                    override fun invoke(view: View) = when (view) {
                        is T -> block(this@singleton, view)
                        else -> NotMatched
                    }
                }
            } }
        }
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy