MahApps / MahApps.Metro

A framework that allows developers to cobble together a better UI for their own WPF applications with minimal effort.
https://mahapps.com
MIT License
9.32k stars 2.45k forks source link

Accent colors in cyan accent are lightened with the alpha channel #2805

Closed manne closed 7 years ago

manne commented 7 years ago

What steps will reproduce this issue?

  1. Use the cyan accent
  2. put an image to the window
  3. add a control with the background of AccentColor3 over the image image

Expected outcome

The control has got the wanted color (lightened cyan) without seeing the image. image

Question

Is there a reason to lighten the accent colors with the alpha channel? The same behavior can be achieved with these values

<ResourceDictionary>
    <Color x:Key="HighlightColor">#FF1377A7</Color>

    <Color x:Key="AccentBaseColor">#FF1BA1E2</Color>
    <!--80%-->
    <Color x:Key="AccentColor">#49B4E8</Color>
    <!--60%-->
    <Color x:Key="AccentColor2">#76C7EE</Color>
    <!--40%-->
    <Color x:Key="AccentColor3">#A4D9F3</Color>
    <!--20%-->
    <Color x:Key="AccentColor4">#D1ECF9</Color>
</ResourceDictionary>

--

Environment

[Update] added another MahApps.Metro version

amkuchta commented 7 years ago

This has a detrimental effect on my proposed updates to TabControlHelper.IsUnderlined (see #2895). You can see the border through the underline box:

cyantransparent

I agree that this needs to be fixed. I bungled a recent PR (added commits that should have gone into a separate pull), so I want to wait for it to get approved, but I will look at tackling this next.

punker76 commented 7 years ago

@manne how do you get these values? and what's with the other accent colors?

manne commented 7 years ago

@punker76 I used the RGB/Hexadecimal Tint Calculator Entered the values

End got the result 3. Verified that the returned color is the "same" color as in the xaml.

Repeated the previous steps with the remaining accent colors.

image

punker76 commented 7 years ago

@manne thx :-D I found this too, this works maybe fine for the light theme, but for the dark theme with a dark background the colors are now different, cause the alpha channel is gone. I think I will not do this change for all colors. If someone (like you) need non alpha channel accent colors then you can create your own accent resource dictionary.

timunie commented 5 years ago

Hello guys, Hello @punker76 , Hello @batzen

I recently had to parse a xlsx file and there were AccentColors from the M$ Office Themes. They just give the base color and a tint value... After some research I found a quite good working solution to make a color lighter or darker (Based on the value form -1 to +1).

Thinking further, this could also be used to calculate the AccentColor Values (lighter accents for the LightTheme and darker accents for the DarkTheme).

We may use this to create custom accents (see #3515 )

So just in case someone is interested in I will leave the helper class below. The code is taken from here: http://ciintelligence.blogspot.com/2012/02/converting-excel-theme-color-and-tint.html

    /// <summary>
    /// This struct represent a Color in HSL (Hue, Saturation, Luminance)
    /// 
    /// Idea taken from here: <see cref="http://ciintelligence.blogspot.com/2012/02/converting-excel-theme-color-and-tint.html"/>
    /// </summary>
    public struct HSLColor
    {

        public double A { get; set; }
        public double H { get; set; }
        public double L { get; set; }
        public double S { get; set; }

        /// <summary>
        /// Creates a new HSL Color
        /// </summary>
        /// <param name="RGBColor">Any System.Windows.Media.Color</param>
        public HSLColor (Color RGBColor)
        {
            // Init Parameters
            A = 0;
            H = 0;
            L = 0;
            S = 0;

            double r = (double)RGBColor.R / 255d;
            double g = (double)RGBColor.G / 255d;
            double b = (double)RGBColor.B / 255d;
            double a = (double)RGBColor.A / 255d;

            double min = Math.Min(r, Math.Min(g, b));
            double max = Math.Max(r, Math.Max(g, b));

            double delta = max - min;

            if (max == min)
            {
                H = 0;
                S = 0;
                L = max;
            }
            else
            {
                L = (min + max) / 2;
                if (L < 0.5)
                {
                    S = delta / (max + min);
                }
                else
                {
                    S = delta / (2.0 - max - min);
                }

                if (r == max) H = (g - b) / delta;
                if (g == max) H = 2.0 + (b - r) / delta;
                if (b == max) H = 4.0 + (r - g) / delta;
                H *= 60;

                if (H < 0) H += 360;

                A = a;
            }
        }

        /// <summary>
        /// Creates a new HSL Color
        /// </summary>
        /// <param name="A">Alpha Channel [0;1]</param>
        /// <param name="H">Hue Channel [0;1]</param>
        /// <param name="S">Saturation Channel [0;1]</param>
        /// <param name="L">Luminance Channel [0;1]</param>
        public HSLColor (double A, double H, double S, double L)
        {
            this.A = A;
            this.H = H;
            this.S = S;
            this.L = L;
        }

        /// <summary>
        /// Gets the ARGB-Color for this HSL-Color
        /// </summary>
        /// <returns>System.Windows.Media.Color</returns>
        public Color ToColor()
        {
            Color rgbColor;

            if (S == 0)
            {
                rgbColor = Color.FromArgb((byte)(A * 255), (byte)(L * 255), (byte)(L * 255), (byte)(L * 255));
            }
            else
            {
                double t1;

                if (L < 0.5)
                {
                    t1 = L * (1.0 + S);
                }

                else
                {
                    t1 = L + S - (L * S);
                }

                double t2 = 2.0 * L - t1;
                double h = H / 360d;
                double tR = h + (1.0 / 3.0);
                double r = getColorComponent(t1, t2, tR);
                double tG = h;
                double g = getColorComponent(t1, t2, tG);
                double tB = h - (1.0 / 3.0);
                double b = getColorComponent(t1, t2, tB);
                rgbColor = Color.FromArgb((byte)(A * 255), (byte)(r * 255), (byte)(g * 255), (byte)(b * 255));
            }

            return rgbColor;
        }

        private double getColorComponent(double t1, double t2, double t3)
        {
            if (t3 < 0) t3 += 1.0;
            if (t3 > 1) t3 -= 1.0;

            double color;

            if (6.0 * t3 < 1)
            {
                color = t2 + (t1 - t2) * 6.0 * t3;
            }
            else if (2.0 * t3 < 1)
            {
                color = t1;
            }
            else if (3.0 * t3 < 2)
            {
                color = t2 + (t1 - t2) * ((2.0 / 3.0) - t3) * 6.0;
            }
            else
            {
                color = t2;
            }

            return color;
        }

        /// <summary>
        /// Gets a Lighter / Darker Color based on a tint value. If  <paramref name="Tint"/> is ![CDATA[<]]>0 then the returned Color is darker, otherwise it will be lighter
        /// </summary>
        /// <param name="Tint">Tint Value in the Range [-1;1]</param>
        /// <returns>a new System.Windows.Media.Color which is lighter or darker</returns>
        public Color GetTintedColor (double Tint)
        {

            double lum = L * 255;

            if (Tint < 0)
            {
                lum = lum * (1.0 + Tint);
            }
            else
            {
                lum = lum * (1.0 - Tint) + (255 - 255 * (1.0 - Tint));
            }

            return new HSLColor(A, H, S, lum/255d).ToColor();
        }

    }

Happy coding Tim