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

commonMain.io.nacular.doodle.theme.basic.BasicTheme.kt Maven / Gradle / Ivy

The newest version!
@file:Suppress("unused")

package io.nacular.doodle.theme.basic

import io.nacular.doodle.controls.DynamicListModel
import io.nacular.doodle.controls.ItemVisualizer
import io.nacular.doodle.controls.MutableListModel
import io.nacular.doodle.controls.ProgressBar
import io.nacular.doodle.controls.ProgressIndicator
import io.nacular.doodle.controls.buttons.Button
import io.nacular.doodle.controls.buttons.CheckBox
import io.nacular.doodle.controls.buttons.RadioButton
import io.nacular.doodle.controls.buttons.Switch
import io.nacular.doodle.controls.date.DaysOfTheWeekPanel
import io.nacular.doodle.controls.date.MonthPanel
import io.nacular.doodle.controls.dropdown.MutableSelectBox
import io.nacular.doodle.controls.dropdown.SelectBox
import io.nacular.doodle.controls.list.HorizontalDynamicList
import io.nacular.doodle.controls.list.HorizontalList
import io.nacular.doodle.controls.list.HorizontalMutableList
import io.nacular.doodle.controls.list.List
import io.nacular.doodle.controls.list.MutableList
import io.nacular.doodle.controls.list.VerticalDynamicList
import io.nacular.doodle.controls.list.VerticalList
import io.nacular.doodle.controls.list.VerticalMutableList
import io.nacular.doodle.controls.panels.GridPanel
import io.nacular.doodle.controls.panels.SplitPanel
import io.nacular.doodle.controls.panels.TabbedPanel
import io.nacular.doodle.controls.popupmenu.Menu
import io.nacular.doodle.controls.range.CircularRangeSlider
import io.nacular.doodle.controls.range.CircularSlider
import io.nacular.doodle.controls.range.RangeSlider
import io.nacular.doodle.controls.range.Slider
import io.nacular.doodle.controls.spinner.MutableSpinButton
import io.nacular.doodle.controls.spinner.MutableSpinButtonModel
import io.nacular.doodle.controls.spinner.SpinButton
import io.nacular.doodle.controls.spinner.SpinButtonModel
import io.nacular.doodle.controls.table.MutableTable
import io.nacular.doodle.controls.table.Table
import io.nacular.doodle.controls.table.TreeTable
import io.nacular.doodle.controls.text.Label
import io.nacular.doodle.controls.theme.CommonLabelBehavior
import io.nacular.doodle.controls.tree.MutableTree
import io.nacular.doodle.controls.tree.Tree
import io.nacular.doodle.controls.tree.TreeModel
import io.nacular.doodle.controls.treecolumns.TreeColumns
import io.nacular.doodle.core.Behavior
import io.nacular.doodle.drawing.Canvas
import io.nacular.doodle.drawing.Color
import io.nacular.doodle.drawing.Color.Companion.Black
import io.nacular.doodle.drawing.Color.Companion.Blue
import io.nacular.doodle.drawing.Color.Companion.White
import io.nacular.doodle.drawing.ColorPaint
import io.nacular.doodle.drawing.GradientPaint
import io.nacular.doodle.drawing.ImagePaint
import io.nacular.doodle.drawing.LinearGradientPaint
import io.nacular.doodle.drawing.Paint
import io.nacular.doodle.drawing.PatternPaint
import io.nacular.doodle.drawing.RadialGradientPaint
import io.nacular.doodle.drawing.Stroke
import io.nacular.doodle.drawing.darker
import io.nacular.doodle.drawing.grayScale
import io.nacular.doodle.drawing.lighter
import io.nacular.doodle.drawing.paint
import io.nacular.doodle.geometry.Path
import io.nacular.doodle.geometry.SegmentBuilder
import io.nacular.doodle.geometry.Size
import io.nacular.doodle.theme.Modules
import io.nacular.doodle.theme.Modules.Companion.ThemeModule
import io.nacular.doodle.theme.Modules.Companion.bindBehavior
import io.nacular.doodle.theme.PaintMapper
import io.nacular.doodle.theme.PathProgressIndicatorBehavior
import io.nacular.doodle.theme.PathProgressIndicatorBehavior.Direction
import io.nacular.doodle.theme.Scene
import io.nacular.doodle.theme.adhoc.DynamicTheme
import io.nacular.doodle.theme.basic.BasicMenuBehavior.Config
import io.nacular.doodle.theme.basic.date.BasicDaysOfTheWeekPanelBehavior
import io.nacular.doodle.theme.basic.date.BasicMonthPanelBehavior
import io.nacular.doodle.theme.basic.dropdown.BasicMutableSelectBoxBehavior
import io.nacular.doodle.theme.basic.dropdown.BasicSelectBoxBehavior
import io.nacular.doodle.theme.basic.list.basicHorizontalListBehavior
import io.nacular.doodle.theme.basic.list.basicHorizontalMutableListBehavior
import io.nacular.doodle.theme.basic.list.basicVerticalListBehavior
import io.nacular.doodle.theme.basic.list.basicVerticalMutableListBehavior
import io.nacular.doodle.theme.basic.range.BasicCircularRangeSliderBehavior
import io.nacular.doodle.theme.basic.range.BasicCircularSliderBehavior
import io.nacular.doodle.theme.basic.range.BasicRangeSliderBehavior
import io.nacular.doodle.theme.basic.range.BasicSliderBehavior
import io.nacular.doodle.theme.basic.range.TickPresentation
import io.nacular.doodle.theme.basic.spinner.BasicMutableSpinButtonBehavior
import io.nacular.doodle.theme.basic.spinner.BasicSpinButtonBehavior
import io.nacular.doodle.theme.basic.tabbedpanel.BasicTabProducer
import io.nacular.doodle.theme.basic.tabbedpanel.BasicTabbedPanelBehavior
import io.nacular.doodle.theme.basic.tabbedpanel.SimpleTabContainer
import io.nacular.doodle.theme.basic.tabbedpanel.TabContainer
import io.nacular.doodle.theme.basic.tabbedpanel.TabProducer
import io.nacular.doodle.theme.basic.table.BasicMutableTableBehavior
import io.nacular.doodle.theme.basic.table.BasicTableBehavior
import io.nacular.doodle.theme.basic.table.BasicTreeTableBehavior
import io.nacular.doodle.theme.basic.tree.BasicMutableTreeBehavior
import io.nacular.doodle.theme.basic.tree.BasicTreeBehavior
import io.nacular.doodle.theme.basic.treecolumns.BasicTreeColumnsBehavior
import io.nacular.doodle.theme.basic.treecolumns.SimpleTreeColumnRowIcon
import io.nacular.doodle.theme.basic.treecolumns.TreeColumnRowIcon
import io.nacular.doodle.utils.RotationDirection
import io.nacular.doodle.utils.RotationDirection.Clockwise
import io.nacular.measured.units.Angle
import io.nacular.measured.units.Angle.Companion.degrees
import io.nacular.measured.units.Measure
import io.nacular.measured.units.times
import kotlinx.datetime.DayOfWeek
import org.kodein.di.DI
import org.kodein.di.DI.Module
import org.kodein.di.DirectDI
import org.kodein.di.bind
import org.kodein.di.bindings.NoArgBindingDI
import org.kodein.di.erasedSet
import org.kodein.di.instance
import org.kodein.di.instanceOrNull
import org.kodein.di.provider
import org.kodein.di.singleton

private typealias BTheme                 = BasicTheme
private typealias ListModel           = io.nacular.doodle.controls.ListModel
private typealias MutableTreeModel    = io.nacular.doodle.controls.tree.MutableTreeModel
private typealias TabContainerFactory = DirectDI.(TabbedPanel, TabProducer) -> TabContainer

@Suppress("UNCHECKED_CAST")
public open class BasicTheme(private val configProvider: ConfigProvider, behaviors: Iterable): DynamicTheme(behaviors.filter { it.theme == BTheme::class }) {
    override fun install(scene: Scene) {
        configProvider.config = config

        super.install(scene)
    }

    public open val config: BasicThemeConfig = object: BasicThemeConfig {}

    override fun toString(): String = this::class.simpleName ?: ""

    public interface BasicThemeConfig {
        public val borderColor           : Color  get() = Color(0x888888u)
        public val oddItemColor          : Color  get() = foregroundColor.inverted
        public val evenItemColor         : Color  get() = lightBackgroundColor
        public val selectionColor        : Color  get() = Color(0x0063e1u)
        public val foregroundColor       : Color  get() = Black
        public val backgroundColor       : Color  get() = Color(0xccccccu)
        public val darkBackgroundColor   : Color  get() = Color(0xaaaaaau)
        public val lightBackgroundColor  : Color  get() = Color(0xf3f4f5u)
        public val defaultBackgroundColor: Color  get() = backgroundColor
        public val cornerRadius          : Double get() = 6.0
        public val checkBoxCornerRadius  : Double get() = 4.0
        public val hoverColorMapper      : ColorMapper get() = { it.darker(0.1f) }
        public val disabledColorMapper   : ColorMapper get() = { it.lighter()    }
        public val disabledPaintMapper   : PaintMapper get() = defaultDisabledPaintMapper
    }

    public interface ConfigProvider {
        public var config: BasicThemeConfig
    }

    private class ConfigProviderImpl: ConfigProvider {
        override var config = object: BasicThemeConfig {}
    }

    @Suppress("MemberVisibilityCanBePrivate")
    public companion object {
        private val Config = Module(name = "BasicThemeConfig") {
            bind  () with singleton { ConfigProviderImpl()              }
            bind() with provider  { instance().config }
        }

        public fun basicThemeModule(name: String, init: DI.Builder.() -> Unit): Module = Module(name = name) {
            importOnce(Config, allowOverride = true)

            init()
        }

        public val BasicTheme: Module = basicThemeModule(name = "BasicTheme") {
            importOnce(ThemeModule, allowOverride = true)

            bind() with singleton { BasicTheme(instance(), Instance(erasedSet())) }
        }

        public fun basicListBehavior(
            itemHeight           : Double? = null,
            evenItemColor        : Color?  = null,
            oddItemColor         : Color?  = null,
            selectionColor       : Color?  = null,
            selectionBlurredColor: Color?  = null
        ): Module = basicThemeModule(name = "BasicListBehavior") {
            bindBehavior>>(BTheme::class) {
                it.behavior = instance().run {
                    basicVerticalListBehavior(
                        focusManager          = instanceOrNull(),
                        evenItemColor         = evenItemColor         ?: this.evenItemColor,
                        oddItemColor          = oddItemColor          ?: this.oddItemColor,
                        selectionColor        = selectionColor        ?: this.selectionColor,
                        selectionBlurredColor = selectionBlurredColor ?: this.selectionColor.grayScale().lighter(),
                        itemHeight            = itemHeight            ?: 20.0,
                        numColumns            = when (it) {
                            is VerticalList        -> it.numColumns
                            is VerticalDynamicList -> it.numColumns
                            is VerticalMutableList -> it.numColumns
                            else                   -> 1
                        }
                    )
                }
            }
        }

        public fun basicHorizontalListBehavior(
            itemWidth            : Double? = null,
            evenItemColor        : Color?  = null,
            oddItemColor         : Color?  = null,
            selectionColor       : Color?  = null,
            selectionBlurredColor: Color?  = null
        ): Module = basicThemeModule(name = "BasicHorizontalListBehavior") {
            val a: NoArgBindingDI<*>.(List) -> Unit = {
                it.behavior = instance().run {
                    basicHorizontalListBehavior(
                        focusManager          = instanceOrNull(),
                        evenItemColor         = evenItemColor         ?: this.evenItemColor,
                        oddItemColor          = oddItemColor          ?: this.oddItemColor,
                        selectionColor        = selectionColor        ?: this.selectionColor,
                        selectionBlurredColor = selectionBlurredColor ?: this.selectionColor.grayScale().lighter(),
                        itemWidth             = itemWidth             ?: 20.0,
                        numRows               = when (it) {
                            is HorizontalList        -> it.numRows
                            is HorizontalDynamicList -> it.numRows
                            is HorizontalMutableList -> it.numRows
                            else                     -> 1
                        }
                    )
                }
            }

            bindBehavior>>(BTheme::class, a)
            bindBehavior>>(BTheme::class, a)
            bindBehavior>>(BTheme::class, a)
        }

        public fun basicMutableListBehavior(
            itemHeight           : Double? = null,
            evenItemColor        : Color?  = null,
            oddItemColor         : Color?  = null,
            selectionColor       : Color?  = null,
            selectionBlurredColor: Color?  = null
        ): Module = basicThemeModule(name = "BasicMutableListBehavior") {
            bindBehavior>>(BTheme::class) {
                it.behavior = instance().run {
                    basicVerticalMutableListBehavior(
                        focusManager          = instanceOrNull(),
                        evenItemColor         = evenItemColor         ?: this.evenItemColor,
                        oddItemColor          = oddItemColor          ?: this.oddItemColor,
                        selectionColor        = selectionColor        ?: this.selectionColor,
                        selectionBlurredColor = selectionBlurredColor ?: this.selectionColor.grayScale().lighter(),
                        itemHeight            = itemHeight            ?: 20.0,
                        numColumns            = if (it is VerticalMutableList) it.numColumns else 1
                ) }
            }
        }

        public fun basicHorizontalMutableListBehavior(
            itemWidth            : Double? = null,
            evenItemColor        : Color?  = null,
            oddItemColor         : Color?  = null,
            selectionColor       : Color?  = null,
            selectionBlurredColor: Color?  = null
        ): Module = basicThemeModule(name = "BasicHorizontalMutableListBehavior") {
            bindBehavior>>(BTheme::class) {
                it.behavior = instance().run {
                    basicHorizontalMutableListBehavior(
                        focusManager          = instanceOrNull(),
                        evenItemColor         = evenItemColor         ?: this.evenItemColor,
                        oddItemColor          = oddItemColor          ?: this.oddItemColor,
                        selectionColor        = selectionColor        ?: this.selectionColor,
                        selectionBlurredColor = selectionBlurredColor ?: this.selectionColor.grayScale().lighter(),
                        itemWidth             = itemWidth             ?: 20.0,
                        numRows               = it.numRows
                    )
                }
            }
        }

        public fun basicTreeBehavior(
                rowHeight            : Double?              = null,
                evenRowColor         : Color?               = null,
                oddRowColor          : Color?               = null,
                selectionColor       : Color?               = null,
                selectionBlurredColor: Color?               = null,
                iconFactory          : (() -> TreeRowIcon)? = null): Module = basicThemeModule(name = "BasicTreeBehavior") {
            bindBehavior>>(BTheme::class) {
                it.behavior = instance().run {
                    BasicTreeBehavior(
                            focusManager          = instanceOrNull(),
                            rowHeight             = rowHeight             ?: 20.0,
                            evenRowColor          = evenRowColor          ?: this.evenItemColor,
                            oddRowColor           = oddRowColor           ?: this.oddItemColor,
                            selectionColor        = selectionColor        ?: this.selectionColor,
                            selectionBlurredColor = selectionBlurredColor ?: this.selectionColor.grayScale().lighter(),
                            iconFactory           = iconFactory           ?: { SimpleTreeRowIcon(foregroundColor, foregroundColor.inverted) }
                    )
                }
            }
        }

        public fun basicMutableTreeBehavior(
                rowHeight            : Double?              = null,
                evenRowColor         : Color?               = null,
                oddRowColor          : Color?               = null,
                selectionColor       : Color?               = null,
                selectionBlurredColor: Color?               = null,
                iconFactory          : (() -> TreeRowIcon)? = null): Module = basicThemeModule(name = "BasicMutableTreeBehavior") {
            bindBehavior>>(BTheme::class) {
                it.behavior = instance().run {
                    BasicMutableTreeBehavior(
                            focusManager          = instanceOrNull(),
                            rowHeight             = rowHeight             ?: 20.0,
                            evenRowColor          = evenRowColor          ?: this.evenItemColor,
                            oddRowColor           = oddRowColor           ?: this.oddItemColor,
                            selectionColor        = selectionColor        ?: this.selectionColor,
                            selectionBlurredColor = selectionBlurredColor ?: this.selectionColor.grayScale().lighter(),
                            iconFactory           = iconFactory           ?: { SimpleTreeRowIcon(foregroundColor, foregroundColor.inverted) }
                ) }
            }
        }

        public fun basicTreeTableBehavior(
            rowHeight            : Double?              = null,
            evenRowColor         : Color?               = null,
            oddRowColor          : Color?               = null,
            selectionColor       : Color?               = null,
            selectionBlurredColor: Color?               = null,
            iconFactory          : (() -> TreeRowIcon)? = null
        ): Module = basicThemeModule(name = "BasicTreeTableBehavior") {
            bindBehavior>>(BTheme::class) {
                it.behavior = instance().run {
                    BasicTreeTableBehavior(
                        focusManager          = instanceOrNull(),
                        rowHeight             = rowHeight             ?: 20.0,
                        evenRowColor          = evenRowColor          ?: this.evenItemColor,
                        oddRowColor           = oddRowColor           ?: this.oddItemColor,
                        selectionColor        = selectionColor        ?: this.selectionColor,
                        selectionBlurredColor = selectionBlurredColor ?: this.selectionColor.grayScale().lighter(),
                        iconFactory           = iconFactory           ?: { SimpleTreeRowIcon(foregroundColor, foregroundColor.inverted) }
                    ) }
            }
        }

        public fun basicLabelBehavior(foregroundColor: Color? = null): Module = basicThemeModule(name = "BasicLabelBehavior") {
            bindBehavior




© 2015 - 2024 Weber Informatics LLC | Privacy Policy