<commit_before>package ui

import (
	"image"
	"image/color"
	"image/draw"
	"log"
)

// Button ...
type Button struct {
	component
	icon *image.RGBA
	text *Text
}

// NewButton ...
func NewButton(width, height int) *Button {
	btn := &Button{}
	btn.Width = width
	btn.Height = height
	btn.text = NewText(8, color.White)
	return btn
}

// SetIcon a image to show on button, instead of text
func (btn *Button) SetIcon(img *image.RGBA) {
	btn.icon = img
	btn.isClean = false
}

// SetText ...
func (btn *Button) SetText(s string) {
	btn.text.SetText(s)
}

// Draw redraws internal buffer
func (btn *Button) Draw(mx, my int) *image.RGBA {
	if btn.isClean {
		return btn.Image
	}

	rect := image.Rect(0, 0, btn.Width, btn.Height)
	if btn.Image == nil {
		btn.Image = image.NewRGBA(rect)
	} else {
		draw.Draw(btn.Image, rect, &image.Uniform{color.Transparent}, image.ZP, draw.Src)
	}

	// draw outline
	DrawRect(btn.Image, &rect, color.White)

	btn.drawIcon()

	// XXX draw text
	txt := btn.text.Draw(mx, my)

	// XXX center text
	b := txt.Bounds()
	x0 := 2
	y0 := 1
	x1 := x0 + b.Max.X
	y1 := y0 + b.Max.Y
	textRect := image.Rect(x0, y0, x1, y1)
	draw.Draw(btn.Image, textRect, txt, image.ZP, draw.Over)
	btn.isClean = true
	return btn.Image
}

func (btn *Button) drawIcon() {
	if btn.icon == nil {
		return
	}
	allB := btn.Image.Bounds()
	btnB := btn.icon.Bounds()
	if allB.Max.X > btn.Width || allB.Max.Y > btn.Height {
		log.Println("button.drawImage: image is bigger than container button")
	}

	// centered
	x0 := (allB.Size().X / 2) - (btnB.Size().X / 2)
	y0 := (allB.Size().Y / 2) - (btnB.Size().Y / 2)
	x1 := x0 + btnB.Max.X<commit_msg>render: work on improving viewport render speed<commit_after>package ui

import (
	"image"
	"image/color"
	"image/draw"
	"log"
)

// Button ...
type Button struct {
	component
	icon *image.RGBA
	text *Text
}

// NewButton ...
func NewButton(width, height int) *Button {
	btn := &Button{}
	btn.Width = width
	btn.Height = height
	btn.text = NewText(8, color.White)
	return btn
}

// SetIcon a image to show on button, instead of text
func (btn *Button) SetIcon(img *image.RGBA) {
	btn.icon = img
	btn.isClean = false
}

// SetText ...
func (btn *Button) SetText(s string) {
	btn.text.SetText(s)
}

// Draw redraws internal buffer
func (btn *Button) Draw(mx, my int) *image.RGBA {
	if btn.isClean {
		return btn.Image
	}

	rect := image.Rect(0, 0, btn.Width, btn.Height)
	if btn.Image == nil {
		btn.Image = image.NewRGBA(rect)
	} else {
		draw.Draw(btn.Image, rect, &image.Uniform{color.Transparent}, image.ZP, draw.Src)
	}

	// draw outline
	DrawRect(btn.Image, &rect, color.White)

	btn.drawIcon()

	txt := btn.text.Draw(mx, my)

	// XXX center text ?
	b := txt.Bounds()
	x0 := 2
	y0 := 1
	x1 := x0 + b.Max.X
	y1 := y0 + b.Max.Y
	textRect := image.Rect(x0, y0, x1, y1)
	draw.Draw(btn.Image, textRect, txt, image.ZP, draw.Over)
	btn.isClean = true
	return btn.Image
}

func (btn *Button) drawIcon() {
	if btn.icon == nil {
		return
	}
	allB := btn.Image.Bounds()
	btnB := btn.icon.Bounds()
	if allB.Max.X > btn.Width || allB.Max.Y > btn.Height {
		log.Println("button.drawImage: image is bigger than container button")
	}

	// centered
	x0 := (allB.Size().X / 2) - (btnB.Size().X / 2)
	y0 := (allB.Size().Y / 2) - (btnB.Size().Y / 2)
	x1 := x0 + btnB.Max.X
{'fraction_non_alphanumeric': 0.17122040072859745, 'fraction_numerical': 0.013964784456587736, 'mean_word_length': 3.042944785276074, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 7, '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': '4453654', 'n_tokens_mistral': 1374, 'n_tokens_neox': 1337, 'n_words': 340}