Skip to content

Commit

Permalink
Make color pickers working again.
Browse files Browse the repository at this point in the history
  • Loading branch information
sknull committed Jan 10, 2024
1 parent 555282b commit e4e765c
Show file tree
Hide file tree
Showing 9 changed files with 172 additions and 41 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -83,12 +83,14 @@ class HybridScene() : Fadeable<HybridScene> {
initializeFromFadeables()
}

fun fadeableMap(): Map<String, Fadeable<*>> = fadeables.toMap()

fun fadeables(): List<Fadeable<*>> = fadeables.values.toList()

fun getFadeable(id: String): Fadeable<*>? = fadeables[id]

fun putFadeable(id: String, fadeable: Fadeable<*>) {
fadeables[id] = fadeable
fadeables[id] = fadeable.clone()
initializeFromFadeables()
}

Expand Down Expand Up @@ -239,8 +241,12 @@ class HybridScene() : Fadeable<HybridScene> {
coroutineScope {
// call shelly interface which is pretty slow with native fading (RGBW shelly devices can fade on their own)
// but api calls cost around 100 millis
other.fadeables().filterIsInstance<ShellyColor>().forEach {
launch { it.write(preferences, true, fadeDuration) }
other.fadeableMap().filter { it.value is ShellyColor }.forEach {
val otherFadeable = it.value as ShellyColor
val fadeable = fadeables[otherFadeable.getId()]
if (fadeable != null && otherFadeable.getRgbColor() != fadeable.getRgbColor()) {
launch { (otherFadeable as ShellyColor).write(preferences, true, fadeDuration) }
}
}
}

Expand Down Expand Up @@ -274,7 +280,7 @@ class HybridScene() : Fadeable<HybridScene> {
// first collect all frame data for the dmx frame to avoid lots of costly write operations to a serial interface
otherParameterSets.forEach { (id, otherParameterSet) ->
val parameterSet = parameterSets[id]
if (parameterSet != null) {
if (parameterSet != null && otherParameterSet.getRgbColor() != parameterSet.getRgbColor()) {
val faded = parameterSet.fade(otherParameterSet, factor)
preferences.setDmxData(
baseChannel = faded.baseChannel,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ class ConfigHolder {
val klanglichtDirectory: File = File(SystemUtils.getUserHome(), ".klanglicht")

var currentScene: HybridScene? = null
val colorStore: MutableMap<String, String> = mutableMapOf()

@PostConstruct
fun initialize() {
Expand Down Expand Up @@ -54,4 +55,12 @@ class ConfigHolder {
fun updateScene(nextScene: HybridScene) {
currentScene?.update(nextScene)
}

fun putColor(id: String, hexColor: String) {
colorStore[id] = hexColor
}

fun getColor(id: String): String? {
return colorStore[id]
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -22,15 +22,28 @@ class HybridStageRestController {
@RequestParam(value = "gains", required = false, defaultValue = "") gains: String,
@RequestParam(value = "transition", required = false) transitionDuration: Long?,
@RequestParam(value = "turnOn", required = false, defaultValue = "true") turnOn: Boolean,
@RequestParam(value = "store", required = false, defaultValue = "true") store: Boolean
@RequestParam(value = "store", required = false, defaultValue = "true") store: Boolean,
@RequestParam(value = "storeName", required = false) storeName: String?
) {
hybridStageHandler?.hexColor(
ids = ids,
hexColors = hexColors,
gains = gains,
transitionDuration = transitionDuration,
turnOn = turnOn,
store = store
store = store,
storeName = storeName
)
}

@GetMapping("putColor")
fun putColor(
@RequestParam(value = "id") id: String,
@RequestParam(value = "hexColor") hexColor: String
) {
hybridStageHandler?.putColor(
id = id,
hexColor = hexColor
)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -25,25 +25,43 @@ class HybridStageHandler {
* @param transitionDuration The fade duration in milli seconds.
* @param turnOn Determines if the device should be turned on.
* @param store Determines if the colors should be saved in the ConfigHolder.
* @param storeName An additional name to strore values.
*/
fun hexColor(
ids: String,
hexColors: String,
gains: String,
transitionDuration: Long?,
turnOn: Boolean,
store: Boolean = true
store: Boolean = true,
storeName: String?
) {
val currentScene = configHolder?.currentScene?.clone()
val nextScene = HybridScene(ids, hexColors, gains, turnOn.toString(), preferences = configHolder?.preferences)
val nextScene = configHolder?.currentScene?.clone()?.let { n ->
HybridScene(ids, hexColors, gains, turnOn.toString(), preferences = configHolder.preferences).fadeableMap().forEach {
n.putFadeable(it.key, it.value)
}
n
}
if (store) {
configHolder?.updateScene(nextScene)
configHolder?.updateScene(nextScene!!)
if (storeName != null) {
configHolder?.putColor(storeName, hexColors)
}
}
log.info("nextScene : $nextScene")
log.info("nextScene: $nextScene")

currentScene?.fade(nextScene, transitionDuration?:configHolder?.preferences?.fadeDurationDefault?:1000, configHolder?.preferences!!)
currentScene?.fade(nextScene!!, transitionDuration?:configHolder?.preferences?.fadeDurationDefault?:1000, configHolder?.preferences!!)
}

fun putColor(
id: String,
hexColor: String,
) {
configHolder?.putColor(id, hexColor)
}


fun restoreColors(
ids: String,
transitionDuration: Long?
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ class LMScenes(

override fun toHtml(configHolder: ConfigHolder): String {
val sb = StringBuilder()
sb.append("<div class=\"title\" onclick=\"toggleFullScreen();\" alt=\"Toggle Fullscreen\" title=\"Toggle Fullscreen\">")
sb.append("<div class=\"title\" onclick=\"toggleFullScreen();\" title=\"Toggle Fullscreen\">")
.append(name)
.append("</div>\n")
sb.append("<div class=\"center-category\">\n")
Expand All @@ -61,6 +61,16 @@ class LMScenes(
groupScenes
)
}
sb.append(" <div class=\"group\">\n")
renderLabel(sb, "All")
sb.append(ColorWheel("All").toHtml(configHolder))
sb.append(" </div><!-- group -->\n")

sb.append(" <div class=\"group\">\n")
renderLabel(sb, "All Odd Even")
sb.append(ColorWheel("All").toHtml(configHolder, true))
sb.append(" </div><!-- group -->\n")

sb.append("</div><!-- scenes -->\n\n")
return sb.toString()
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -169,7 +169,7 @@ class LMZones(

override fun toHtml(configHolder: ConfigHolder): String {
val sb = StringBuilder()
sb.append("<div class=\"title\" onclick=\"toggleFullScreen();\" alt=\"Toggle Fullscreen\" title=\"Toggle Fullscreen\">")
sb.append("<div class=\"title\" onclick=\"toggleFullScreen();\" title=\"Toggle Fullscreen\">")
.append(name)
.append("</div>\n")
sb.append("<div class=\"category\">\n")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,27 +13,93 @@ class ColorWheel(
private val log: Logger = LoggerFactory.getLogger(javaClass)

override fun toHtml(configHolder: ConfigHolder): String {
return toHtml(configHolder, false)
}

fun toHtml(configHolder: ConfigHolder, oddEven: Boolean): String {
val wheelId = id!!.replace(" ", "")
val lastColorState = configHolder.getFadeable(id)
val hexColor = lastColorState?.getRgbColor()?.web()?:"#000000"
log.debug("Got color '${RGBColor(hexColor).ansiColor()}' for id '$id'")
return "\t<div class=\"colorwheel-wrapper\">\n" +
"\t\t<div class=\"colorwheel-title\"><span class=\"label\">COLORPICKER - " + id + "</span></div>\n" +
"\t\t<div class=\"colorwheel-panel\">\n" +
"\t\t\t<div class=\"color-wheel\" id=\"colorwheel-" + wheelId + "\"></div>\n" +
"\t\t</div>\n" +
"\t\t<script type=\"application/javascript\">\n" +
"\t\t\tvar colorWheel" + wheelId + " = new iro.ColorPicker(\"#colorwheel-" + wheelId + "\", {\n" +
"\t\t\t\twheelLightness: false,\n" +
"\t\t\t\tcolor: \"" + hexColor + "\"\n" +
"\t\t\t});\n" +
"\n" +
"\t\t\tcolorWheel" + wheelId + ".on('color:change', function(color, changes){\n" +
"\t\t\t\tvar colorOdd = colorWheel" + wheelId + ".color.hexString.substring(1);\n" +
"\t\t\t\tvar colorEven = \"000000\";\n" +
"\t\t\t\tColors" + wheelId + " = colorOdd, colorEven;\n" +
"\t\t\t});\n" +
"\t\t</script>\n" +
"\t\t</div>"

val sb = StringBuilder()

if (oddEven) {
sb.append("\t<div class=\"colorwheel-wrapper-oddeven\">\n")
renderColorWheelPanel(sb, wheelId, true)
renderColorWheelPanel(sb, wheelId, false)

renderScript(sb, wheelId, true, configHolder)
sb.append("\t\t</div><!-- colorwheel-wrapper-oddeven -->\n")
} else {
sb.append("\t<div class=\"colorwheel-wrapper\">\n")
renderColorWheelPanel(sb, wheelId, null)

renderScript(sb, wheelId, false, configHolder)
sb.append("\t\t</div><!-- colorwheel-wrapper -->\n")
}


return sb.toString()
}

private fun renderColorWheelPanel(sb: StringBuilder, wheelId: String, odd: Boolean?) {
sb.append("\t\t<div class=\"colorwheel-panel\">\n")
if (odd != null) {
sb.append("\t\t<div class=\"colorwheel-title\"><span class=\"label\">COLORPICKER - $id - ${if (odd) "Odd" else "Even"}</span></div>\n")
sb.append("\t\t\t<div class=\"color-wheel\" id=\"colorwheel-${wheelId}${if (odd) "Odd" else "Even"}\"></div>\n")
} else {
sb.append("\t\t<div class=\"colorwheel-title\"><span class=\"label\">COLORPICKER - $id</span></div>\n")
sb.append("\t\t\t<div class=\"color-wheel\" id=\"colorwheel-${wheelId}\"></div>\n")
}
sb.append("\t\t</div><!-- colorwheel-panel -->\n")
}

private fun renderScript(sb: StringBuilder, wheelId: String, oddEven: Boolean, configHolder: ConfigHolder) {
if (oddEven) {
sb.append("\t\t<script type=\"application/javascript\">\n")

val hexColorOdd = configHolder.getColor("${wheelId}Odd")?:"000000"
sb.append("\t\t\tvar colorWheel${wheelId}Odd = new iro.ColorPicker(\"#colorwheel-${wheelId}Odd\", {\n")
sb.append("\t\t\t\twheelLightness: false,\n")
sb.append("\t\t\t\tcolor: \"${hexColorOdd}\"\n")
sb.append("\t\t\t});\n\n")

val hexColorEven = configHolder.getColor("${wheelId}Even")?:"000000"
sb.append("\t\t\tvar colorWheel${wheelId}Even = new iro.ColorPicker(\"#colorwheel-${wheelId}Even\", {\n")
sb.append("\t\t\t\twheelLightness: false,\n")
sb.append("\t\t\t\tcolor: \"${hexColorEven}\"\n")
sb.append("\t\t\t});\n\n")

sb.append("\t\t\tcolorWheel${wheelId}Odd.on('color:change', function(color, changes){\n")
sb.append("\t\t\t\tvar colorOdd = colorWheel${wheelId}Odd.color.hexString.substring(1);\n")
sb.append("\t\t\t\tvar colorEven = colorWheel${wheelId}Even.color.hexString.substring(1);\n")
sb.append("\t\t\t\tsetColors${wheelId}OddEven(colorOdd, colorEven);\n")
sb.append("\t\t\t});\n\n")

sb.append("\t\t\tcolorWheel${wheelId}Even.on('color:change', function(color, changes){\n")
sb.append("\t\t\t\tvar colorOdd = colorWheel${wheelId}Odd.color.hexString.substring(1);\n")
sb.append("\t\t\t\tvar colorEven = colorWheel${wheelId}Even.color.hexString.substring(1);\n")
sb.append("\t\t\t\tsetColors${wheelId}OddEven(colorOdd, colorEven);\n")
sb.append("\t\t\t});\n\n")

sb.append("\t\t</script>\n")
} else {
val hexColor = configHolder.getFadeable(wheelId)
?.getRgbColor()?.web()
?:configHolder.getColor(wheelId)
?:"000000"
sb.append("\t\t<script type=\"application/javascript\">\n")

sb.append("\t\t\tvar colorWheel${wheelId} = new iro.ColorPicker(\"#colorwheel-${wheelId}\", {\n")
sb.append("\t\t\t\twheelLightness: false,\n")
sb.append("\t\t\t\tcolor: \"${hexColor}\"\n")
sb.append("\t\t\t});\n\n")

sb.append("\t\t\tcolorWheel${wheelId}.on('color:change', function(color, changes){\n")
sb.append("\t\t\t\tvar colorOdd = colorWheel${wheelId}.color.hexString.substring(1);\n")
sb.append("\t\t\t\tvar colorEven = \"000000\";\n")
sb.append("\t\t\t\tsetColors${wheelId}(colorOdd, colorEven);\n")
sb.append("\t\t\t});\n")

sb.append("\t\t</script>\n")
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ class ShellyRestController {
@RequestParam(value = "scene", required = false, defaultValue = "0") sceneId: Int,
@RequestParam(value = "index", required = false, defaultValue = "0") index: Int
) {
shellyHandler?.control(sceneId, index)
shellyHandler?.control(sceneId = sceneId, index = index)
}

@GetMapping("power")
Expand All @@ -41,7 +41,7 @@ class ShellyRestController {
@RequestParam(value = "turnOn", required = false, defaultValue = "true") turnOn: Boolean,
@RequestParam(value = "transition", required = false) transitionDuration: Long?
) {
shellyHandler?.power(ids, turnOn, transitionDuration)
shellyHandler?.power(ids = ids, turnOn = turnOn, transitionDuration = transitionDuration)
}

@GetMapping("hexColor")
Expand All @@ -51,17 +51,26 @@ class ShellyRestController {
@RequestParam(value = "gains", required = false, defaultValue = "") gains: String,
@RequestParam(value = "transition", required = false) transitionDuration: Long?,
@RequestParam(value = "turnOn", required = false, defaultValue = "true") turnOn: Boolean,
@RequestParam(value = "store", required = false, defaultValue = "true") store: Boolean
@RequestParam(value = "store", required = false, defaultValue = "true") store: Boolean,
@RequestParam(value = "storeName", required = false) storeName: String?
) {
hybridStageHandler?.hexColor(ids, hexColors, gains, transitionDuration, turnOn, store)
hybridStageHandler?.hexColor(
ids = ids,
hexColors = hexColors,
gains = gains,
transitionDuration = transitionDuration,
turnOn = turnOn,
store = store,
storeName = storeName
)
}

@GetMapping("restore")
fun restoreColors(
@RequestParam(value = "ids", required = false, defaultValue = "") ids: String,
@RequestParam(value = "transition", required = false) transitionDuration: Long?
) {
hybridStageHandler?.restoreColors(ids, transitionDuration)
hybridStageHandler?.restoreColors(ids = ids, transitionDuration = transitionDuration)
}

@GetMapping("gain")
Expand All @@ -70,6 +79,6 @@ class ShellyRestController {
@RequestParam(value = "gain", required = false, defaultValue = "") gain: Int,
@RequestParam(value = "transition", required = false) transitionDuration: Long?
) {
hybridStageHandler?.gain(ids, gain, transitionDuration)
hybridStageHandler?.gain(ids = ids, gain = gain, transitionDuration = transitionDuration)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ class ShellyStatus : HtmlRenderable {

fun toHtml(shellyHandler: ShellyHandler): String {
val sb = StringBuilder()
sb.append("<div class=\"title\" onclick=\"toggleFullScreen();\" alt=\"Toggle Fullscreen\" title=\"Toggle Fullscreen\">")
sb.append("<div class=\"title\" onclick=\"toggleFullScreen();\" title=\"Toggle Fullscreen\">")
.append("Current Power Values")
.append("</div>\n")
sb.append("<div class=\"category\">\n")
Expand Down

0 comments on commit e4e765c

Please sign in to comment.