<commit_before>package ui

import (
	"fmt"
	"image"
	"image/color"
	"image/draw"
	"log"
	"time"

	"github.com/ninjasphere/go-gestic"
	"github.com/ninjasphere/sphere-go-led-controller/fonts/O4b03b"
)

type ColorPane struct {
	image  *image.RGBA
	color  func() color.Color
	draw   func()
	bounds func() image.Rectangle
}

func NewColorPane(in color.Color) *ColorPane {
	pane := &ColorPane{
		color: func() color.Color {
			return in
		},
		image: image.NewRGBA(image.Rect(0, 0, width, height)),
	}
	pane.draw = func() {
		draw.Draw(pane.image, pane.bounds(), &image.Uniform{pane.color()}, image.ZP, draw.Src)
	}
	pane.bounds = func() image.Rectangle {
		return pane.image.Bounds()
	}
	return pane
}

func NewFadingColorPane(in color.Color, d time.Duration) *ColorPane {

	pane := NewColorPane(in)
	start := time.Now()
	pane.color = func() color.Color {
		n := time.Now().Sub(start)
		ratio := 1.0
		if n < d {
			ratio = float64(n) / float64(d)
		}
		r, g, b, a := in.RGBA()
		return color.RGBA{
			R: uint8(uint16((1.0-ratio)*float64(r)) >> 8),
			G: uint8(uint16((1.0-ratio)*float64(g)) >> 8),
			B: uint8(uint16((1.0-ratio)*float64(b)) >> 8),
			A: uint8(a),
		}
	}
	return pane
}
	}
}

func (p *ColorPane) Gesture(gesture *gestic.GestureData) {

}

func (p *ColorPane) Render() (*image.RGBA, error) {
	p.draw()
	return p.image, nil
}

func (p *ColorPane) IsDirty() bool {
	return false
}<commit_msg>An implementation of a color pane that shrinks as it fades.<commit_after>package ui

import (
	"fmt"
	"image"
	"image/color"
	"image/draw"
	"log"
	"time"

	"github.com/ninjasphere/go-gestic"
	"github.com/ninjasphere/sphere-go-led-controller/fonts/O4b03b"
)

type ColorPane struct {
	image  *image.RGBA
	color  func() color.Color
	draw   func()
	bounds func() image.Rectangle
}

func NewColorPane(in color.Color) *ColorPane {
	pane := &ColorPane{
		color: func() color.Color {
			return in
		},
		image: image.NewRGBA(image.Rect(0, 0, width, height)),
	}
	pane.draw = func() {
		draw.Draw(pane.image, pane.bounds(), &image.Uniform{pane.color()}, image.ZP, draw.Src)
	}
	pane.bounds = func() image.Rectangle {
		return pane.image.Bounds()
	}
	return pane
}

func NewFadingColorPane(in color.Color, d time.Duration) *ColorPane {

	pane := NewColorPane(in)
	start := time.Now()
	pane.color = func() color.Color {
		n := time.Now().Sub(start)
		ratio := 1.0
		if n < d {
			ratio = float64(n) / float64(d)
		}
		r, g, b, a := in.RGBA()
		return color.RGBA{
			R: uint8(uint16((1.0-ratio)*float64(r)) >> 8),
			G: uint8(uint16((1.0-ratio)*float64(g)) >> 8),
			B: uint8(uint16((1.0-ratio)*float64(b)) >> 8),
			A: uint8(a),
		}
	}
	return pane
}

// creates a pane that fades and shrinks towards the center as time progresses
func NewFadingShrinkingColorPane(in color.Color, d time.Duration) *ColorPane {

	pane := NewFadingColorPane(in, d)
	basicDraw := pane.draw
	start := time.Now()
	black := color.RGBA{
		R: 0,
		G: 0,
		B: 0,
		A: 0,
	}

	pane.bounds = func() image.Rectangle {
		n := time.Now().Sub(start)
		dim := 0
		if d > n && d > 0 {
			dim = int(float64(d-n) * 8.0 / float64(d))
		}
		rect := image.Rectangle{
			Min: image.Point{
				X: 8 - dim,
				Y: 8 - dim,
			},
			Max: image.Point{
				X: 8 + dim,
				Y: 8 + dim,
			},
		}
		return rect
	}

	pane.draw = func() {
		draw.Draw(pane.image, pane.image.Bounds(), &image.Uniform{black}, image.ZP, draw.Src)
		basicDraw()
	}

	return pane
}

func (p *ColorPane) Gesture(gesture *gestic.GestureData) {

}

func (p *ColorPane) Render() (*image.RGBA, error) {
	p.draw()
	return p.image, nil
}

func (p *ColorPane) IsDirty() bool {
	return false
}
{'fraction_non_alphanumeric': 0.17374410213710798, 'fraction_numerical': 0.024424091035248403, 'mean_word_length': 3.395121951219512, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 17, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6136400', 'n_tokens_mistral': 1642, 'n_tokens_neox': 1490, 'n_words': 330}