Copy + paste color palettes into your program

I saw that Edwin just added ctrl+v support for orx-panel to paste colors and I thought… wow, it would be cool to copy color palettes from any website and just paste them into my program, so I wrote this PoC:

import org.openrndr.KeyModifier
import org.openrndr.application
import org.openrndr.color.ColorRGBa
import org.openrndr.color.rgb
import org.openrndr.extra.shapes.grid

fun main() = application {
    program {
        val palette = mutableListOf(ColorRGBa.PINK)
        extend {
            if(palette.isNotEmpty()) {
                drawer.bounds.grid(palette.size, 1, 20.0, 20.0).flatten().forEachIndexed { i, rect ->
                    drawer.fill = palette[i]
                    drawer.rectangle(rect)
                }
            }
        }
        keyboard.keyDown.listen { ev ->
            if (KeyModifier.CTRL in ev.modifiers || KeyModifier.SUPER in ev.modifiers) {
                if (ev.name == "v") {
                    clipboard.contents?.let { pasted ->
                        val regex = """[#x]([0-9a-fA-F]{6})([^0-9a-fA-F]|$)""".toRegex()
                        val colors = regex.findAll(pasted).filter {
                            it.groupValues.size == 3
                        }.map {
                            it.groupValues[1]
                        }.distinct().map {
                            rgb(it)
                        }.toList()
                        palette.clear()
                        palette.addAll(colors)
                    }
                    ev.cancelPropagation()
                }
            }
        }
    }
}

So I can select some text in a website, press ctrl+c…
image

Then click on the window of the program above and press ctrl+v…
image

In the past I used to copy the colors one by one into the source code and then run the program, but this is much more convenient! :slight_smile:

The regular expression will try to parse the colors and ignore anything else, so copying a string like

I like #F5E6CA and also #FB9300 combined with 0xF54748 and 0x343F56

would also work :slight_smile:

2 Likes

As an Extension, to make it more reusable:

import org.openrndr.Extension
import org.openrndr.KeyModifier
import org.openrndr.Program
import org.openrndr.color.ColorRGBa
import org.openrndr.color.rgb

/**
 * OPENRNDR extension to enable
 * CTRL+V to paste a color palette copied from any website.
 * The extension searches in the clipboard for colors
 * formatted as #123456 or 0x123456.
 */

class PastePalette : Extension {
    override var enabled: Boolean = true

    val colors = mutableListOf<ColorRGBa>()

    var size = 0
        get() = colors.size

    fun isEmpty() = colors.isEmpty()
    fun isNotEmpty() = colors.isNotEmpty()

    override fun setup(program: Program) {
        println("Listening to CTRL+V")
        program.keyboard.keyDown.listen { ev ->
            if (KeyModifier.CTRL in ev.modifiers && ev.name == "v") {
                program.clipboard.contents?.let { pasted ->
                    val regex = """[#x]([0-9a-fA-F]{6})([^0-9a-fA-F]|$)""".toRegex()
                    val colors = regex.findAll(pasted).filter {
                        it.groupValues.size == 3
                    }.map {
                        it.groupValues[1]
                    }.distinct().map {
                        rgb(it)
                    }.toList()
                    this.colors.clear()
                    this.colors.addAll(colors)
                }
                ev.cancelPropagation()
            }
        }
    }
}

Then it can be used like this:

import PastePalette
import org.openrndr.application
import org.openrndr.extra.shapes.grid

fun main() = application {
    program {
        val palette = PastePalette()
        extend(palette)
        extend {
            if(palette.isNotEmpty()) {
                drawer.bounds.grid(palette.size, 1, 20.0, 20.0).flatten().forEachIndexed { i, rect ->
                    drawer.fill = palette.colors[i]
                    drawer.rectangle(rect)
                }
            }
        }
    }
}