benruehl / adonis-ui

Lightweight UI toolkit for WPF applications offering classic but enhanced windows visuals
https://benruehl.github.io/adonis-ui/
MIT License
1.71k stars 143 forks source link

Script to Tweak Dark Theme Color #90

Closed alexhelms closed 4 years ago

alexhelms commented 4 years ago

Is your feature request related to a problem? Please describe. The dark color theme was too "purple" for my taste and I wanted to change it.

Describe the solution you'd like A script to help shift the hue of the theme's colors.

I really am enjoying using adonis UI and I like the dark theme but I felt the color was slightly too purple and I was looking for more blue.

I wrote a small python script to extract the hex color strings from a resource dictionary, convert them to RGB and rotate them in HSV color space so the hue can be changed. Then convert them back to RGB, hex strings, and replace them in the resource dictionary. Then I just imported this new resource dictionary in App.xaml after adonis like the documentation says.

This worked out great and accomplished what I wanted. I thought I could share this here since others may want to do something similar. Perhaps include this in the project as some kind of helper script? Either way, I just wanted an issue to exist so if somebody was searching for this problem, I can offer one potential solution.

Thank you for your hard work on adonis, it is a great looking UI pack!

import re
from math import sqrt,cos,sin,radians

def clamp(v):
    if v < 0:
        return 0
    if v > 255:
        return 255
    return int(v + 0.5)

class RGBRotate(object):
    def __init__(self):
        self.matrix = [[1,0,0],[0,1,0],[0,0,1]]

    def set_hue_rotation(self, degrees):
        cosA = cos(radians(degrees))
        sinA = sin(radians(degrees))
        self.matrix[0][0] = cosA + (1.0 - cosA) / 3.0
        self.matrix[0][1] = 1./3. * (1.0 - cosA) - sqrt(1./3.) * sinA
        self.matrix[0][2] = 1./3. * (1.0 - cosA) + sqrt(1./3.) * sinA
        self.matrix[1][0] = 1./3. * (1.0 - cosA) + sqrt(1./3.) * sinA
        self.matrix[1][1] = cosA + 1./3.*(1.0 - cosA)
        self.matrix[1][2] = 1./3. * (1.0 - cosA) - sqrt(1./3.) * sinA
        self.matrix[2][0] = 1./3. * (1.0 - cosA) - sqrt(1./3.) * sinA
        self.matrix[2][1] = 1./3. * (1.0 - cosA) + sqrt(1./3.) * sinA
        self.matrix[2][2] = cosA + 1./3. * (1.0 - cosA)

    def apply(self, r, g, b):
        rx = r * self.matrix[0][0] + g * self.matrix[0][1] + b * self.matrix[0][2]
        gx = r * self.matrix[1][0] + g * self.matrix[1][1] + b * self.matrix[1][2]
        bx = r * self.matrix[2][0] + g * self.matrix[2][1] + b * self.matrix[2][2]
        return clamp(rx), clamp(gx), clamp(bx)

if __name__ == "__main__":

    # xaml resource dictionary containing hex color strings
    filename = 'colors.xaml'

    with open(filename, 'r') as f:
        text = f.read()
        rotate = RGBRotate()

        # rotate by this many degrees
        rotate.set_hue_rotation(-17)

        # find all hex color strings
        m = re.findall(r'#(?:[a-fA-F0-9]{3}|[a-fA-F0-9]{6})\b', text)

        for item in m:

            # convert to rgb
            r = (int(item[1:], 16) & 0xFF0000) >> 16
            g = (int(item[1:], 16) & 0x00FF00) >> 8
            b = (int(item[1:], 16) & 0x0000FF)

            # rotate in hsv and convert back to rgb
            r, g, b = rotate.apply(r, g, b)

            # replace original with rotated color, original position matters!
            text = text.replace(item, f'#{r:02x}{g:02x}{b:02x}')

        with open(filename + '.out', 'w') as fout:
            fout.write(text)
benruehl commented 4 years ago

Wow that's really cool. I added a link to this issue to the docs so that it does not get lost. Thank you for the contribution!