~eliasnaur/gio

e383e6d6be3205f0a9cedacf24ec37d3df506880 — Egon Elbre 10 months ago 9cc90d9
widget/material: better disabled color calculation

Use desaturation in combination with alpha multiplication.

Signed-off-by: Egon Elbre <egonelbre@gmail.com>
M internal/f32color/rgba.go => internal/f32color/rgba.go +33 -0
@@ 35,6 35,14 @@ func (col RGBA) SRGB() color.NRGBA {
	}
}

// Luminance calculates the relative luminance of a linear RGBA color.
// Normalized to 0 for black and 1 for white.
//
// See https://www.w3.org/TR/WCAG20/#relativeluminancedef for more details
func (col RGBA) Luminance() float32 {
	return 0.2126*col.R + 0.7152*col.G + 0.0722*col.B
}

// Opaque returns the color without alpha component.
func (col RGBA) Opaque() RGBA {
	col.A = 1.0


@@ 115,3 123,28 @@ func MulAlpha(c color.NRGBA, alpha uint8) color.NRGBA {
	c.A = uint8(uint32(c.A) * uint32(alpha) / 0xFF)
	return c
}

// Disabled blends color towards the luminance and multiplies alpha.
// Blending towards luminance will desaturate the color.
// Multiplying alpha blends the color together more with the background.
func Disabled(c color.NRGBA) (d color.NRGBA) {
	const r = 80 // blend ratio
	lum := approxLuminance(c)
	return color.NRGBA{
		R: byte((int(c.R)*r + int(lum)*(256-r)) / 256),
		G: byte((int(c.G)*r + int(lum)*(256-r)) / 256),
		B: byte((int(c.B)*r + int(lum)*(256-r)) / 256),
		A: byte(int(c.A) * (128 + 32) / 256),
	}
}

// approxLuminance is a fast approximate version of RGBA.Luminance.
func approxLuminance(c color.NRGBA) byte {
	const (
		r = 13933 // 0.2126 * 256 * 256
		g = 46871 // 0.7152 * 256 * 256
		b = 4732  // 0.0722 * 256 * 256
		t = r + g + b
	)
	return byte((r*int(c.R) + g*int(c.G) + b*int(c.B)) / t)
}

M widget/material/button.go => widget/material/button.go +2 -2
@@ 129,7 129,7 @@ func (b ButtonLayoutStyle) Layout(gtx layout.Context, w layout.Widget) layout.Di
			}}, rr).Add(gtx.Ops)
			background := b.Background
			if gtx.Queue == nil {
				background = f32color.MulAlpha(b.Background, 150)
				background = f32color.Disabled(b.Background)
			}
			paint.Fill(gtx.Ops, background)
			for _, c := range b.Button.History() {


@@ 156,7 156,7 @@ func (b IconButtonStyle) Layout(gtx layout.Context) layout.Dimensions {
			}, rr).Add(gtx.Ops)
			background := b.Background
			if gtx.Queue == nil {
				background = f32color.MulAlpha(b.Background, 150)
				background = f32color.Disabled(b.Background)
			}
			paint.Fill(gtx.Ops, background)
			for _, c := range b.Button.History() {

M widget/material/checkable.go => widget/material/checkable.go +1 -1
@@ 43,7 43,7 @@ func (c *checkable) layout(gtx layout.Context, checked bool) layout.Dimensions {
					size := gtx.Px(c.Size)
					icon.Color = c.IconColor
					if gtx.Queue == nil {
						icon.Color = f32color.MulAlpha(icon.Color, 150)
						icon.Color = f32color.Disabled(icon.Color)
					}
					icon.Layout(gtx, unit.Px(float32(size)))
					return layout.Dimensions{

M widget/material/editor.go => widget/material/editor.go +1 -1
@@ 61,7 61,7 @@ func (e EditorStyle) Layout(gtx layout.Context) layout.Dimensions {
	if e.Editor.Len() > 0 {
		textColor := e.Color
		if disabled {
			textColor = f32color.MulAlpha(textColor, 150)
			textColor = f32color.Disabled(textColor)
		}
		paint.ColorOp{Color: textColor}.Add(gtx.Ops)
		e.Editor.PaintText(gtx)

M widget/material/progressbar.go => widget/material/progressbar.go +1 -1
@@ 55,7 55,7 @@ func (p ProgressBarStyle) Layout(gtx layout.Context) layout.Dimensions {
			fillWidth := progressBarWidth * clamp1(p.Progress)
			fillColor := p.Color
			if gtx.Queue == nil {
				fillColor = f32color.MulAlpha(fillColor, 200)
				fillColor = f32color.Disabled(fillColor)
			}
			return shader(fillWidth, fillColor)
		}),

M widget/material/slider.go => widget/material/slider.go +1 -1
@@ 68,7 68,7 @@ func (s SliderStyle) Layout(gtx layout.Context) layout.Dimensions {

	color := s.Color
	if gtx.Queue == nil {
		color = f32color.MulAlpha(color, 150)
		color = f32color.Disabled(color)
	}

	// Draw track before thumb.

M widget/material/switch.go => widget/material/switch.go +1 -1
@@ 55,7 55,7 @@ func (s SwitchStyle) Layout(gtx layout.Context) layout.Dimensions {
		col = s.Color.Enabled
	}
	if gtx.Queue == nil {
		col = f32color.MulAlpha(col, 150)
		col = f32color.Disabled(col)
	}
	trackColor := s.Color.Track
	op.Offset(f32.Point{Y: trackOff}).Add(gtx.Ops)