It is currently March 28th, 2024, 10:03 pm

Complementary color

Tips and Tricks from the Rainmeter Community
DollarD
Posts: 16
Joined: March 2nd, 2013, 5:56 pm

Re: Complementary color

Post by DollarD »

Well, I used a different method to dynamically generate complementary colors for my skin. Maybe this could be of use to someone...

Essentially, it creates a fade in to the desktop from the Windows 10 accent color as a background, and generates the complementary and contrasting colors for use by other meters for text etc. Useful if you have changing backgrounds and the windows accent is set to change with it.

I have a .inc file to save the calculated colors etc. so the other meters can simply load from there.

D10Variables.inc :

Code: Select all

[Variables]
FontSize=12
FontName="Segoe UI"
ColorBG=86AFC5
ColorMain=005489
ColorCplA=062C93
ColorCplB=99001E
ColorShade=002944
ColorTint=44B6FF
The base color control skin then uses the SysColor plugin to detect when the accent color changes, and fetches it from the registry via the RunCommand plugin as the Registry measure doesn't read binary registry entries. A regex then splits it into RGB and feeds it to the lua script.

D10Control.ini :

Code: Select all

[Rainmeter]
Update=1000
MiddleMouseDownAction=[!UpdateMeasure "MeasureColorizerRandom"][!CommandMeasure MeasurePaletteRegistry Run][!UpdateMeasure "MeasureColorScript"]
....................................................................................................................................................

[Variables]
@Include="#CURRENTPATH#D10Variables.inc"
IncFile="#CURRENTPATH#D10Variables.inc"

FromAlpha=FF
MidRAlpha=AF
MidLAlpha=9F
ToAlpha=00
........................................................................................................................................................

[MeasureColorizerRandom]
Measure=Calc
Formula=Random
UpdateRandom=1
LowBound=0
HighBound=100
UpdateDivider=-1

[MeasureColorTrigger]
Measure=String
OnUpdateAction=[!UpdateMeasure "MeasureColorizerRandom"][!SetOption "MeasureSysColor" "UpdateDivider" "1"][!UpdateMeasure "MeasureSysColor"]
DynamicVariables=1
UpdateDivider=-1

[MeasureSysColor]
Measure=Plugin
Plugin=Plugin\SysColor.dll
ColorType=WIN8 
Hex=1
DisplayType=RGB
OnChangeAction=[!CommandMeasure MeasurePaletteRegistry Run]
DynamicVariables=1
UpdateDivider=-1

[MeasurePaletteRegistry]
Measure=Plugin
Plugin=Plugin\RunCommand.dll
Parameter=C:\Windows\System32\reg.exe query HKCU\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\Accent /v AccentPalette
OutputType=ANSI
FinishAction=[!UpdateMeasure "MeasureSplitPaletteBG"]
DynamicVariables=1
UpdateDivider=-1

[MeasureSplitPaletteBG]
Measure=String
String=[MeasurePaletteRegistry]
DynamicVariables=1
RegExpSubstitute=1
Substitute="(?siU).*REG_BINARY\s*([[:xdigit:]]{2})([[:xdigit:]]{2})([[:xdigit:]]{2})([[:xdigit:]]{2})([[:xdigit:]]{2})([[:xdigit:]]{2})([[:xdigit:]]{2})([[:xdigit:]]{2})([[:xdigit:]]{2})([[:xdigit:]]{2})([[:xdigit:]]{2})([[:xdigit:]]{2})([[:xdigit:]]{2})([[:xdigit:]]{2})([[:xdigit:]]{2})([[:xdigit:]]{2})([[:xdigit:]]{2})([[:xdigit:]]{2})([[:xdigit:]]{2})([[:xdigit:]]{2})([[:xdigit:]]{2})([[:xdigit:]]{2})([[:xdigit:]]{2})([[:xdigit:]]{2})([[:xdigit:]]{2})([[:xdigit:]]{2})([[:xdigit:]]{2})([[:xdigit:]]{2})([[:xdigit:]]{2})([[:xdigit:]]{2})([[:xdigit:]]{2})([[:xdigit:]]{2}).*":"\21\22\23"
; Select a palette entry from
; "\1\2\3\4 \5\6\7\8 \9\10\11\12 \13\14\15\16 \17\18\19\20 \21\22\23\24 \25\26\27\28 \29\30\31\32"
OnChangeAction=[!UpdateMeasure "MeasureColorScript"]
UpdateDivider=-1

[MeasureColorScript]
Measure=Script
ScriptFile=D10Color.lua
OnUpdateAction=[!SetOption "MeasureSysColor" "UpdateDivider" "-1"][!ActivateConfig "DDWin10\UpdRegistry"][!Redraw *] 
UpdateDivider=-1

.................................................................................................................................................................

[BackgroundRRight]
Meter=Image
SolidColor=#ColorBG##FromAlpha#
SolidColor2=#ColorBG##MidRAlpha#
GradientAngle=180
X=(#SCREENAREAWIDTH#-200)
Y=0
W=(200 - 62)
H=(#SCREENAREAHEIGHT#-250)
DynamicVariables=1

[BackgroundRMid]
Meter=Image
SolidColor=#ColorBG##MidRAlpha#
SolidColor2=#ColorBG##MidLAlpha#
GradientAngle=180
X=(#SCREENAREAWIDTH#-375)
Y=0
W=175
H=(#WORKAREAHEIGHT#-250)
DynamicVariables=1

[BackgroundRLeft]
Meter=Image
SolidColor=#ColorBG##MidLAlpha#
SolidColor2=#ColorBG##ToAlpha#
GradientAngle=180
X=(#SCREENAREAWIDTH#-450)
Y=0
W=75
H=(#SCREENAREAHEIGHT#-250)
DynamicVariables=1

[BackgroundRightTop]
Meter=Image
SolidColor=#ColorBG##FromAlpha#
SolidColor2=#ColorBG##MidRAlpha#
GradientAngle=180
X=(#SCREENAREAWIDTH#-200)
Y=(#SCREENAREAHEIGHT#-250)
W=(200 - 62)
H=75
ImageAlpha=127
DynamicVariables=1
BevelType=

[BackgroundTopRight]
Meter=Image
SolidColor=#ColorBG##ToAlpha#
SolidColor2=#ColorBG##MidLAlpha#
GradientAngle=90
X=(#SCREENAREAWIDTH#-200)
Y=(#SCREENAREAHEIGHT#-250)
W=(200 - 62)
H=75
ImageAlpha=127
DynamicVariables=1

[BackgroundRightMid]
Meter=Image
SolidColor=#ColorBG##FromAlpha#
SolidColor2=#ColorBG##MidRAlpha#
GradientAngle=180
X=(#SCREENAREAWIDTH#-200)
Y=(#SCREENAREAHEIGHT#-175)
W=(200 - 62)
H=100
DynamicVariables=1
ImageAlpha=127
BevelType=

[BackgroundMidRight]
Meter=Image
SolidColor=#ColorBG##MidLAlpha#
SolidColor2=#ColorBG##MidRAlpha#
GradientAngle=90
X=(#SCREENAREAWIDTH#-200)
Y=(#SCREENAREAHEIGHT#-175)
W=(200 - 62)
H=100
ImageAlpha=127
DynamicVariables=1

[BackgroundBigCurveLeftTop]
Meter=Image
SolidColor=#ColorBG##MidLAlpha#
SolidColor2=#ColorBG##ToAlpha#
GradientAngle=180
X=(#SCREENAREAWIDTH#-450)
Y=(#SCREENAREAHEIGHT#-250)
W=75
H=75
DynamicVariables=1
ImageAlpha=127
;BevelType=1

[BackgroundBigCurveTopLeft]
Meter=Image
SolidColor=#ColorBG##ToAlpha#
SolidColor2=#ColorBG##MidLAlpha#
GradientAngle=90
X=(#SCREENAREAWIDTH#-450)
Y=(#SCREENAREAHEIGHT#-250)
W=75
H=75
ImageAlpha=127
DynamicVariables=1

[BackgroundBigCurveLeftMid]
Meter=Image
SolidColor=#ColorBG##MidLAlpha#
SolidColor2=#ColorBG##ToAlpha#
GradientAngle=180
X=(#SCREENAREAWIDTH#-450)
Y=(#SCREENAREAHEIGHT#-175)
W=75
H=100
ImageAlpha=127
DynamicVariables=1
;BevelType=1

[BackgroundBigCurveMidLeft]
Meter=Image
SolidColor=#ColorBG##MidLAlpha#
SolidColor2=#ColorBG##MidRAlpha#
GradientAngle=90
X=(#SCREENAREAWIDTH#-450)
Y=(#SCREENAREAHEIGHT#-175)
W=75
H=100
ImageAlpha=127
DynamicVariables=1

[BackgroundBigCurveTopMid]
Meter=Image
SolidColor=#ColorBG##ToAlpha#
SolidColor2=#ColorBG##MidLAlpha#
GradientAngle=90
X=(#SCREENAREAWIDTH#-375)
Y=(#SCREENAREAHEIGHT#-250)
W=175
H=75
DynamicVariables=1
ImageAlpha=127
;BevelType=1

[BackgroundBigCurveMidTop]
Meter=Image
SolidColor=#ColorBG##MidRAlpha#
SolidColor2=#ColorBG##MidLAlpha#
GradientAngle=180
X=(#SCREENAREAWIDTH#-375)
Y=(#SCREENAREAHEIGHT#-250)
W=175
H=75
DynamicVariables=1
ImageAlpha=127
;BevelType=1

[BackgroundCornerMidR]
Meter=Image
SolidColor=#ColorBG##MidRAlpha#
SolidColor2=#ColorBG##MidLAlpha#
GradientAngle=180
X=(#SCREENAREAWIDTH#-375)
Y=(#SCREENAREAHEIGHT#-175)
W=175
H=100
ImageAlpha=127
DynamicVariables=1
;BevelType=1

[BackgroundCornerMidB]
Meter=Image
SolidColor=#ColorBG##MidLAlpha#
SolidColor2=#ColorBG##MidRAlpha#
GradientAngle=90
X=(#SCREENAREAWIDTH#-375)
Y=(#SCREENAREAHEIGHT#-175)
W=175
H=100
ImageAlpha=127
DynamicVariables=1
;BevelType=1

[BackgroundBTop]
Meter=Image
SolidColor=#ColorBG##ToAlpha#
SolidColor2=#ColorBG##MidLAlpha#
GradientAngle=90
X=0
Y=(#SCREENAREAHEIGHT#-250)
W=(#SCREENAREAWIDTH#-450)
H=75
DynamicVariables=1

[BackgroundBMid]
Meter=Image
SolidColor=#ColorBG##MidLAlpha#
SolidColor2=#ColorBG##MidRAlpha#
GradientAngle=90
X=0
Y=(#SCREENAREAHEIGHT#-175)
W=(#SCREENAREAWIDTH#-450)
H=100
DynamicVariables=1

[BackgroundBBottom]
Meter=Image
SolidColor=#ColorBG##MidRAlpha#
SolidColor2=#ColorBG##FromAlpha#
GradientAngle=90
X=0
Y=(#SCREENAREAHEIGHT#-75)
W=(#SCREENAREAWIDTH#-450)
H=75
DynamicVariables=1

[BackgroundLeftBottom]
Meter=Image
SolidColor=#ColorBG##MidLAlpha#
SolidColor2=#ColorBG##ToAlpha#
GradientAngle=180
X=(#SCREENAREAWIDTH#-450)
Y=(#SCREENAREAHEIGHT#-75)
W=75
H=75
ImageAlpha=127
DynamicVariables=1

[BackgroundBottomLeft]
Meter=Image
SolidColor=#ColorBG##MidRAlpha#
SolidColor2=#ColorBG##FromAlpha#
GradientAngle=90
X=(#SCREENAREAWIDTH#-450)
Y=(#SCREENAREAHEIGHT#-75)
W=75
H=75
DynamicVariables=1
ImageAlpha=127

[BackgroundMidBottom]
Meter=Image
SolidColor=#ColorBG##MidRAlpha#
SolidColor2=#ColorBG##MidLAlpha#
GradientAngle=180
X=(#SCREENAREAWIDTH#-375)
Y=(#SCREENAREAHEIGHT#-75)
W=175
H=75
ImageAlpha=127
DynamicVariables=1


[BackgroundBottomMid]
Meter=Image
SolidColor=#ColorBG##MidRAlpha#
SolidColor2=#ColorBG##FromAlpha#
GradientAngle=90
X=(#SCREENAREAWIDTH#-375)
Y=(#SCREENAREAHEIGHT#-75)
W=175
H=75
DynamicVariables=1
ImageAlpha=127

[BackgroundCornerRightBottom]
Meter=Image
SolidColor=#ColorBG##FromAlpha#
SolidColor2=#ColorBG##MidRAlpha#
GradientAngle=180
X=(#SCREENAREAWIDTH#-200)
Y=(#SCREENAREAHEIGHT#-75)
W=(200 - 62)
H=75
DynamicVariables=1
ImageAlpha=127

[BackgroundCornerBottomRight]
Meter=Image
SolidColor=#ColorBG##MidRAlpha#
SolidColor2=#ColorBG##FromAlpha#
GradientAngle=90
X=(#SCREENAREAWIDTH#-200)
Y=(#SCREENAREAHEIGHT#-75)
W=(200 - 62)
H=75
DynamicVariables=1
ImageAlpha=127

...................................................................................................................................................
The lua script grabs the color as measured by SysColor and extracted from the registry, and outputs:

ColorBG - Background Color as per registry
ColorMain - A contrasting color to the background, via HSL color transformation and varying the hue by 15 degrees
ColorCplA - A complement of the accent color, via adjusting the HSL hue by +-30 to 60 degrees
ColorCplB - A complement of the accent color, via adjusting the HSL hue by +-135 to 165 degrees
ColorShade - A darker version of the contrating color, adjusted via Luminance in HSL
ColorTint - A lighter version of the contrating color, adjusted via Luminance in HSL

It also measures the background brightness via a HCY transformation, and brightens or darkens these colors so they can contrast properly.

Color functions included:
HexToRGB(HexString)
RGBToHex(R, G, B)
RGBToHSV(R, G, B)
HSVToRGB(H, S, V)
RGBToHSL(R, G, B)
HSLToRGB(H, S, L)
RGBToHCY(R, G, B)
HCYToRGB(H, C, Y)

D10Color.lua :

Code: Select all

function Initialize()
	
	-- Constants
	ColorGranularity = math.pow(10, 2)
	
end

function Update()
	local Config = " * "
	
	-- Rainmeter Data
	ColorMain = tostring(SKIN:GetVariable('ColorMain', '262524'))
	WinBG = SKIN:GetMeasure('MeasureSplitPaletteBG'):GetStringValue()
	WinAcc = SKIN:GetMeasure('MeasureSysColor'):GetStringValue()
	RandomHue = SKIN:GetMeasure('MeasureColorizerRandom'):GetValue()
	
	if WinBG == '' then return end
	
	-- Reticulating Splines
	
	ColorBG = string.sub(WinBG, 1,6)
	ColorMain = ContrastColor(ColorBG) .. ""
	ColorMainAcc = VaryColor(WinAcc)
	ColorMainAlt = ColorCpl(ColorMain)
	
	-- print("Before: " .. ColorBrightness(ColorBG) .. " " ..ColorBrightness(ColorMain) .. " " .. ColorBrightness(ColorMainAcc) .. " " .. ColorBrightness(ColorMainAlt))

	if ColorBrightness(ColorBG) < ColorBrightness(ColorMain   ) then
		ColorMain 	 = BrightColor(ColorMain, 	(0.375 - math.abs(ColorBrightness(ColorMain   ) - ColorBrightness(ColorBG))) / (1 - ColorBrightness(ColorMain   )))
		else                                        
		ColorMain 	 = DarkColor(ColorMain,     (0.375 - math.abs(ColorBrightness(ColorMain   ) - ColorBrightness(ColorBG))) / ColorBrightness(ColorMain   ))	
	end
	
	if ColorBrightness(ColorBG) < ColorBrightness(ColorMainAcc) then
		ColorMainAcc = BrightColor(ColorMainAcc,(0.375 - math.abs(ColorBrightness(ColorMainAcc) - ColorBrightness(ColorBG))) / (1 - ColorBrightness(ColorMainAcc)))
		else                                        
		ColorMainAcc = DarkColor(ColorMainAcc,  (0.375 - math.abs(ColorBrightness(ColorMainAcc) - ColorBrightness(ColorBG))) / ColorBrightness(ColorMainAcc))	
	end
	
	if ColorBrightness(ColorBG) < ColorBrightness(ColorMainAlt) then
		ColorMainAlt = BrightColor(ColorMainAlt,(0.375 - math.abs(ColorBrightness(ColorMainAlt) - ColorBrightness(ColorBG))) / (1 - ColorBrightness(ColorMainAlt)))
		else                                        
		ColorMainAlt = DarkColor(ColorMainAlt,  (0.375 - math.abs(ColorBrightness(ColorMainAlt) - ColorBrightness(ColorBG))) / ColorBrightness(ColorMainAlt))		
	end
	
	-- print("After: " .. ColorBrightness(ColorBG) .. " " ..ColorBrightness(ColorMain) .. " " .. ColorBrightness(ColorMainAcc) .. " " .. ColorBrightness(ColorMainAlt))
	
	ColorMainShd = ShadeColor(ColorMain, 0.5)
	ColorMainTnT = TintColor(ColorMain, 0.5)
	
	-- Save Data
	SKIN:Bang('!WriteKeyValue Variables ColorBG      "' .. string.upper(ColorBG)        .. '" ' .. SKIN:ReplaceVariables(' #IncFile# '))
	SKIN:Bang('!WriteKeyValue Variables ColorMain    "' .. string.upper(ColorMain)      .. '" ' .. SKIN:ReplaceVariables(' #IncFile# '))
	SKIN:Bang('!WriteKeyValue Variables ColorCplA    "' .. string.upper(ColorMainAcc)   .. '" ' .. SKIN:ReplaceVariables(' #IncFile# '))
	SKIN:Bang('!WriteKeyValue Variables ColorCplB    "' .. string.upper(ColorMainAlt)   .. '" ' .. SKIN:ReplaceVariables(' #IncFile# '))
	SKIN:Bang('!WriteKeyValue Variables ColorShade   "' .. string.upper(ColorMainShd)   .. '" ' .. SKIN:ReplaceVariables(' #IncFile# '))
	SKIN:Bang('!WriteKeyValue Variables ColorTint    "' .. string.upper(ColorMainTnT)   .. '" ' .. SKIN:ReplaceVariables(' #IncFile# '))
	
	SKIN:Bang('!SetVariable ColorBG      "' .. string.upper(ColorBG)       .. '" ' .. Config)
	SKIN:Bang('!SetVariable ColorMain    "' .. string.upper(ColorMain)     .. '" ' .. Config)
	SKIN:Bang('!SetVariable ColorCplA    "' .. string.upper(ColorMainAcc)  .. '" ' .. Config)
	SKIN:Bang('!SetVariable ColorCplB    "' .. string.upper(ColorMainAlt)  .. '" ' .. Config)
	SKIN:Bang('!SetVariable ColorShade   "' .. string.upper(ColorMainShd)  .. '" ' .. Config)
	SKIN:Bang('!SetVariable ColorTint    "' .. string.upper(ColorMainTnT)  .. '" ' .. Config)
	
	return
end

function ColorBrightness(ColorInputString)
	
	-- Hex to RGB
	local R, G, B = HexToRGB(ColorInputString)

	local H, C, Y = RGBToHCY(R, G, B)
	
	-- print("RGB: " .. R .. " " .. G .. " " .. B .. " " .. Brightness)
	
	return Y
	
end

function ContrastColor(ColorInputString)
	
	-- Hex to RGB
	local R, G, B = HexToRGB(ColorInputString)
	-- RGB to HSL
	local H, S, L = RGBToHSL(R, G, B)
	-- Contrast Calc
	
	--print("preHSL: " .. H .. " " .. S .. " " .. L)
	if H == 0 then H = RandomHue * 3.6
		else
		H = (360 + (H - 15 + (RandomHue * 3 / 10))) % 360
	end
	S = 1 - (S * 0.4)
	L = 0.75 - (L * 0.5)
	
	--print("postHSL: " .. H .. " " .. S .. " " .. L)
	
	-- HSL to RGB
	R, G, B = HSLToRGB(H, S, L)
	-- And back
	local HexColor = RGBToHex(R, G, B)
	
	return HexColor
	
end

function VaryColor(ColorInputString)
	
	-- Hex to RGB
	local R, G, B = HexToRGB(ColorInputString)
	-- RGB to HSL
	local H, S, L = RGBToHSL(R, G, B)
	-- Contrast Calc
	
	local AltHue = 50 - RandomHue
	local OffHue = math.max( AltHue / math.abs(AltHue), 0)
	
	AltHue = math.abs(AltHue)
	
	--print("preHSL: " .. H .. " " .. S .. " " .. L)
	if H == 0 then H = RandomHue * 3.6
		else
		H = ((H - 45 + (AltHue * 3 / 5)) + 60 * OffHue ) % 360
	end
	S = 1 - (S * 0.4)
	L = 0.75 - (L * 0.5)
	
	--print("postHSL: " .. H .. " " .. S .. " " .. L)
	
	-- HSL to RGB
	R, G, B = HSLToRGB(H, S, L)
	-- And back
	local HexColor = RGBToHex(R, G, B)
	
	return HexColor
	
end

function ColorCpl(ColorInputString)
	
	-- Hex to RGB
	local R, G, B = HexToRGB(ColorInputString)
	-- RGB to HSL
	local H, S, L = RGBToHSL(R, G, B)
	-- Contrast Calc
	
	-- print("preHSL: " .. H .. " " .. S .. " " .. L)
	
	local AltHue = 50 - RandomHue
	
	if AltHue > 0 then H = (360 + H + (135 + (AltHue * 30 / 50))) % 360
		elseif AltHue < 0 then H = (360 + H + (225 + (AltHue * 30 / 50))) % 360
		else H = (180 + (H - 15 + (RandomHue * 3 / 10))) % 360
	end
	S = S 
	L = L 
	
	-- print("postHSL: " .. H .. " " .. S .. " " .. L)
	
	-- HSL to RGB
	R, G, B = HSLToRGB(H, S, L)
	-- And back
	local HexColor = RGBToHex(R, G, B)
	
	return HexColor
	
end

function ShadeColor(ColorInputString, Factor)
	
	-- Hex to RGB
	local R, G, B = HexToRGB(ColorInputString)
	-- RGB to HSL
	local H, S, L = RGBToHSL(R, G, B)
	-- Contrast Calc
	
	--print("preHSL: " .. H .. " " .. S .. " " .. L)
	
	H = H
	S = S 
	L = L - (L * Factor)
	
	--print("postHSL: " .. H .. " " .. S .. " " .. L)
	
	-- HSL to RGB
	R, G, B = HSLToRGB(H, S, L)
	-- And back
	local HexColor = RGBToHex(R, G, B)
	
	return HexColor
	
end

function TintColor(ColorInputString, Factor)
	
	-- Hex to RGB
	local R, G, B = HexToRGB(ColorInputString)
	-- RGB to HSL
	local H, S, L = RGBToHSL(R, G, B)
	-- Contrast Calc
	
	--print("preHSL: " .. H .. " " .. S .. " " .. L)
	
	H = H
	S = S 
	L = L + ((1 - L) * Factor)
	
	--print("postHSL: " .. H .. " " .. S .. " " .. L)
	
	-- HSL to RGB
	R, G, B = HSLToRGB(H, S, L)
	-- And back
	local HexColor = RGBToHex(R, G, B)
	
	return HexColor
	
end

function BrightColor(ColorInputString, Factor)
	
	-- Hex to RGB
	local R, G, B = HexToRGB(ColorInputString)
	-- RGB to HSL
	local H, C, Y = RGBToHCY(R, G, B)
	-- Contrast Calc
	
	-- print("BpreHCY: " .. H .. " " .. C .. " " .. Y)

	Y = Y + ((1 - Y) * math.min(math.max(Factor,0),1))
	
	-- print("BpostHCY: " .. H .. " " .. C .. " " .. Y .. " " .. math.min(math.max(Factor,0),1))
	
	-- HSL to RGB
	R, G, B = HCYToRGB(H, C, Y)
	-- And back
	local HexColor = RGBToHex(R, G, B)
	
	return HexColor
	
end

function DarkColor(ColorInputString, Factor)
	
	-- Hex to RGB
	local R, G, B = HexToRGB(ColorInputString)
	-- RGB to HSL
	local H, C, Y = RGBToHCY(R, G, B)
	-- Contrast Calc
	
	-- print("DpreHCY: " .. H .. " " .. C .. " " .. Y)

	Y = Y - (Y * math.min(math.max(Factor,0),1))
	
	-- print("DpostHCY: " .. H .. " " .. C .. " " .. Y .. " " .. math.min(math.max(Factor,0),1))
	
	-- HSL to RGB
	R, G, B = HCYToRGB(H, C, Y)
	-- And back
	local HexColor = RGBToHex(R, G, B)
	
	return HexColor
	
end

function HexToRGB(HexString)
	
	local R = tonumber( "0x" .. string.sub(HexString, 1,2) ) / 255
	local G = tonumber( "0x" .. string.sub(HexString, 3,4) ) / 255
	local B = tonumber( "0x" .. string.sub(HexString, 5,6) ) / 255
	
	return R, G, B
	
end

function RGBToHex(R, G, B)
	
	local R = math.max(math.min(math.floor(R * 255), 255), 0)
	local G = math.max(math.min(math.floor(G * 255), 255), 0)
	local B = math.max(math.min(math.floor(B * 255), 255), 0)
	
	local HexR = string.format("%02X", R) .. ""
	local HexG = string.format("%02X", G) .. ""
	local HexB = string.format("%02X", B) .. ""
	
	return HexR .. HexG .. HexB
	
end

function RGBToHSV(R, G, B)
	
	local H, S, V, Delta	
	local MAX = math.max(R, G, B)
	local MIN = math.min(R, G, B)
	
	V = MAX
	Delta = MAX - MIN
	
	if MAX ~= 0 then S = Delta / MAX
		else     S = 0
	end
	
	if Delta == 0 then
		H = 0
		else
		if     MAX == R then H = ((G - B) / Delta) % 6
			elseif MAX == G then H = 2 + (B - R) / Delta
			else 		     H = 4 + (R - G) / Delta
		end		
	end
	
	H = H * 60
	
	if H < 0 then H = H + 360 end
	
	-- Granularity
	
	H = math.floor( H * (ColorGranularity)       ) / (ColorGranularity)
	S = math.floor( S * (ColorGranularity) * 100 ) / (ColorGranularity * 100)
	V = math.floor( V * (ColorGranularity) * 100 ) / (ColorGranularity * 100)
	
	return H, S, V
end

function HSVToRGB(H, S, V)
	
	local R, G, B
	
	local C = V * S
	local X = C * (1 - math.abs(((H / 60) % 2) - 1))
	local m = V - C
	
	local Hi = math.floor(H / 60)
	
	if Hi == 0 then     R, G, B = C, X, 0
		elseif Hi == 1 then R, G, B = X, C, 0
		elseif Hi == 2 then R, G, B = 0, C, X
		elseif Hi == 3 then R, G, B = 0, X, C
		elseif Hi == 4 then R, G, B = X, 0, C
		elseif Hi == 5 then R, G, B = C, 0, X
	end
	
	R, G, B = R + m, G + m, B + m
	
	-- Granularity
	
	R = math.floor( R * (ColorGranularity) * 100 ) / (ColorGranularity * 100)
	G = math.floor( G * (ColorGranularity) * 100 ) / (ColorGranularity * 100)
	B = math.floor( B * (ColorGranularity) * 100 ) / (ColorGranularity * 100)
	
	return R, G, B
	
end

function RGBToHSL(R, G, B)
	
	local H, S, L, Delta	
	local MAX = math.max(R, G, B)
	local MIN = math.min(R, G, B)
	
	Delta = MAX - MIN
	
	L = (MAX + MIN) / 2
	
	if Delta == 0 then
		H, S = 0, 0
		else
		S = Delta / (1 - math.abs((L * 2) - 1))
		if     MAX == R then H = ((G - B) / Delta) % 6
			elseif MAX == G then H = 2 + (B - R) / Delta
			else 		     H = 4 + (R - G) / Delta
		end		
	end
	
	H = H * 60
	
	if H < 0 then H = H + 360 end
	
	-- Granularity
	
	H = math.floor( H * (ColorGranularity)       ) / (ColorGranularity)
	S = math.floor( S * (ColorGranularity) * 100 ) / (ColorGranularity * 100)
	L = math.floor( L * (ColorGranularity) * 100 ) / (ColorGranularity * 100)
	
	-- print("HSL: " .. H .. " " .. S .. " " .. L)
	
	return H, S, L
	
end

function HSLToRGB(H, S, L)
	
	local R, G, B
	
	local C = (1 - math.abs((L * 2) - 1)) * S
	local X = C * (1 - math.abs(((H / 60) % 2) - 1))
	local m = L - C / 2
	
	local Hi = math.floor(H / 60)
	
	if Hi == 0 then     R, G, B = C, X, 0
		elseif Hi == 1 then R, G, B = X, C, 0
		elseif Hi == 2 then R, G, B = 0, C, X
		elseif Hi == 3 then R, G, B = 0, X, C
		elseif Hi == 4 then R, G, B = X, 0, C
		elseif Hi == 5 then R, G, B = C, 0, X
	end
	
	R, G, B = R + m, G + m, B + m
	
	-- Granularity
	
	R = math.floor( R * (ColorGranularity) * 100 ) / (ColorGranularity * 100)
	G = math.floor( G * (ColorGranularity) * 100 ) / (ColorGranularity * 100)
	B = math.floor( B * (ColorGranularity) * 100 ) / (ColorGranularity * 100)
	
	return R, G, B
	
end

function RGBToHCY(R, G, B)
	
	local H, C, Y, Delta	
	local MAX = math.max(R, G, B)
	local MIN = math.min(R, G, B)

	local Pr = 0.299
	local Pg = 0.587
	local Pb = 0.114
	
	Y = math.sqrt(R*R*Pr + G*G*Pg + B*B*Pb)
	
	Delta = MAX - MIN
	C = Delta
	
	if Delta == 0 then
		H, C = 0, 0
		else
		if     MAX == R then H = ((G - B) / Delta) % 6
			elseif MAX == G then H = 2 + (B - R) / Delta
			else 		     H = 4 + (R - G) / Delta
		end		
	end
	
	H = H * 60
	
	if H < 0 then H = H + 360 end
	
	-- Granularity
	
	H = math.floor( H * (ColorGranularity)       ) / (ColorGranularity)
	C = math.floor( C * (ColorGranularity) * 100 ) / (ColorGranularity * 100)
	Y = math.floor( Y * (ColorGranularity) * 100 ) / (ColorGranularity * 100)
	
	return H, C, Y
	
end

function HCYToRGB(H, C, Y)
	
	local R, G, B
	
	local X = C * (1 - math.abs(((H / 60) % 2) - 1))
	
	local Pr = 0.299
	local Pg = 0.587
	local Pb = 0.114
	
	local Hi = math.floor(H / 60)
	
	if 		   Hi == 0 then R, G, B = C, X, 0
		elseif Hi == 1 then R, G, B = X, C, 0
		elseif Hi == 2 then R, G, B = 0, C, X
		elseif Hi == 3 then R, G, B = 0, X, C
		elseif Hi == 4 then R, G, B = X, 0, C
		elseif Hi == 5 then R, G, B = C, 0, X
	end
	
	local m = Y - math.sqrt(R*R*Pr + G*G*Pg + B*B*Pb)
	
	-- m = m - (m - (m * Y))
	
	-- print("PreRGB: " .. R .. " " .. G .. " " .. B .. " " .. Y .. " " .. m)
	
	R, G, B = R + m, G + m, B + m
	
	-- Granularity
	
	R = math.floor( R * (ColorGranularity) * 100 ) / (ColorGranularity * 100)
	G = math.floor( G * (ColorGranularity) * 100 ) / (ColorGranularity * 100)
	B = math.floor( B * (ColorGranularity) * 100 ) / (ColorGranularity * 100)
	
	return R, G, B
	
end
I also write back a color to the registry afterwards as the inactive window color.

UpdRegistry\UpdRegistry.ini :

Code: Select all

[Rainmeter]
Update=1000

....................................................................................................................................................

[Variables]
@Include="#CURRENTPATH#..\D10Variables.inc"

........................................................................................................................................................


[MeasureAccColor]
Measure=String
String=#ColorBG#
DynamicVariables=1
RegExpSubstitute=1
Substitute="(?siU)([[:xdigit:]]{2})([[:xdigit:]]{2})([[:xdigit:]]{2})":"C:\Windows\System32\reg.exe add HKCU\SOFTWARE\Microsoft\Windows\DWM /v AccentColorInactive /t REG_DWORD /d 0x00\3\2\1 /f"
OnUpdateAction=[!SetOption "MeasureAccColor" "UpdateDivider" "-1"][!CommandMeasure MeasureUpdateAccColor Run]
UpdateDivider=1

[MeasureUpdateAccColor]
Measure=Plugin
Plugin=Plugin\RunCommand.dll
Parameter=[MeasureAccColor]
OutputFile=c:\Root\RCDebug.txt
FinishAction=[!DeactivateConfig "DDWin10\UpdRegistry"]
;OutputType=ANSI
DynamicVariables=1
UpdateDivider=-1

[MeterDummy]
Meter=STRING
Text=""
Which allows me to inter alia place readable meters on that background such as this, using the calculated colors.

Time\Time.ini :

Code: Select all

[Rainmeter]
Update=1000
AccurateText=1
....................................................................................................................................................

[Variables]
@Include="#CURRENTPATH#..\D10Variables.inc"
XPos=0
YPos=0
WSize=300
HSize=200
.......................................................................................................................................................................

[MeasureDate]
Measure=Time
Format=%A, %#d %B, %Y
UpdateDivider=15

[Measure24HrTime]
Measure=Time
Format=%H:%M
UpdateDivider=15

[MeasureUptime]
Measure=Uptime
Format="%4!i! Days #CRLF# %3!i! Hours"
UpdateDivider=15

.......................................................................................................................................................................

[MeterTimeText]
Meter=STRING
MeasureName=Measure24HrTime
Text=%1
FontFace=#FontName#
FontColor=#ColorCplB#
FontSize=(#FontSize#+16)
;StringEffect=Shadow
;FontEffectColor=#ColorCplA#
StringStyle=Bold
AntiAlias=1
DynamicVariables=1
StringAlign=CenterBottom
X=(#XPos# + #WSize# / 2)
Y=(#YPos# + #HSize# / 1.25)


[MeterDateText]
Meter=STRING
MeasureName=MeasureDate
Text=%1
FontFace=#FontName#
FontColor=#ColorMain#
FontSize=(#FontSize#+2)
StringStyle=Bold
FontEffectColor=#ColorShade#
AntiAlias=1
DynamicVariables=1
StringAlign=CenterBottom
X=(#XPos# + #WSize# / 2)
Y=(#YPos# + #HSize# / 1.1)

[MeterUptimeText]
Meter=STRING
MeasureName=MeasureUptime
Text=%1
FontFace=#FontName#
FontColor=#ColorCplA#
FontSize=(#FontSize#+4)
AntiAlias=1
DynamicVariables=1
StringAlign=CenterCenter
X=(#XPos# + #WSize# / 2)
Y=(#YPos# + #HSize# / 3)
Hopefully this can be useful to someone besides me.

See attached screenshot for how its used in a full skin.
You do not have the required permissions to view the files attached to this post.