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

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

package io.nacular.doodle.theme.basic.range

import io.nacular.doodle.controls.range.CircularSlider
import io.nacular.doodle.controls.theme.range.AbstractCircularSliderBehavior
import io.nacular.doodle.drawing.Canvas
import io.nacular.doodle.drawing.Color.Companion.Blue
import io.nacular.doodle.drawing.Color.Companion.Lightgray
import io.nacular.doodle.drawing.Paint
import io.nacular.doodle.drawing.paint
import io.nacular.doodle.focus.FocusManager
import io.nacular.doodle.geometry.Circle
import io.nacular.doodle.geometry.Point
import io.nacular.doodle.geometry.ring
import io.nacular.doodle.geometry.ringSection
import io.nacular.doodle.theme.PaintMapper
import io.nacular.doodle.theme.basic.defaultDisabledPaintMapper
import io.nacular.measured.units.Angle.Companion.cos
import io.nacular.measured.units.Angle.Companion.degrees
import io.nacular.measured.units.Angle.Companion.sin
import io.nacular.measured.units.times

public class BasicCircularSliderBehavior(
        private val barFill  :  (CircularSlider) -> Paint,
        private val knobFill :  (CircularSlider) -> Paint,
        private val rangeFill: ((CircularSlider) -> Paint)? = null,
        private val thickness: Double = 20.0,
        focusManager: FocusManager? = null
): AbstractCircularSliderBehavior(focusManager) where T: Comparable {
    public constructor(
            barFill     : Paint         = Lightgray.paint,
            knobFill    : Paint         = Blue.paint,
            rangeFill   : Paint?        = null,
            thickness   : Double        = 20.0,
            focusManager: FocusManager? = null): this(barFill = { barFill }, knobFill = { knobFill }, rangeFill = rangeFill?.let { f -> { f } }, thickness, focusManager)

    public var disabledPaintMapper: PaintMapper = defaultDisabledPaintMapper

    override fun render(view: CircularSlider, canvas: Canvas) {
        val center      = Point(view.width / 2, view.height / 2)
        val outerRadius = minOf(view.width,     view.height) / 2
        val innerRadius = maxOf(0.0, outerRadius - thickness)
        val handleAngle = handleAngle(view)

        canvas.path(ring(center, innerRadius, outerRadius), adjust(view, barFill(view)))

        rangeFill?.let {
            canvas.path(ringSection(
                center      = center,
                innerRadius = innerRadius,
                outerRadius = outerRadius,
                start       = startAngle - if (startAngle > handleAngle) 360 * degrees else 0 * degrees,
                end         = handleAngle,
                endCap      = { _, point ->
                    arcTo(point, 1.0, 1.0, largeArch = true, sweep = true)
                }
            ), adjust(view, it(view)))
        }

        val radiusToHandleCenter = (innerRadius + outerRadius) / 2
        val handleCenter         = center + Point(radiusToHandleCenter * cos(handleAngle), radiusToHandleCenter * sin(handleAngle))

        canvas.circle(Circle(handleCenter, (outerRadius - innerRadius) / 2), adjust(view, knobFill(view)))
    }

    private fun adjust(view: CircularSlider, fill: Paint) = if (view.enabled) fill else disabledPaintMapper(fill)
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy