package aluminum import "io" import "image" import "git.tebibyte.media/tomo/tomo" import "git.tebibyte.media/tomo/tomo/theme" import "git.tebibyte.media/tomo/tomo/canvas" type iconIndex interface { ~int | ~string } type iconEntry[T iconIndex] struct { position image.Point index T } func i[T iconIndex] (x, y int, index T) iconEntry[T] { return iconEntry[T] { position: image.Pt(x, y), index: index, } } type iconSet[T iconIndex] struct { icons map[theme.IconSize] map[T] canvas.Texture } func (this *iconSet[T]) Get (index T,size theme.IconSize) canvas.Texture { return this.icons[size][index] } func (this *iconSet[T]) Init ( small, medium, large io.Reader, rows, columns int, icons ...iconEntry[T], ) { this.icons = make(map[theme.IconSize] map[T] canvas.Texture) this.initFor(theme.IconSizeSmall, small, rows, columns, icons...) this.initFor(theme.IconSizeMedium, medium, rows, columns, icons...) this.initFor(theme.IconSizeLarge, large, rows, columns, icons...) } func (this *iconSet[T]) initFor ( size theme.IconSize, file io.Reader, rows, columns int, icons ...iconEntry[T], ) { if file == nil { return } atlasImage, _, err := image.Decode(file) if err != nil { panic(err) } atlas := tomo.NewTexture(atlasImage) cellW := atlasImage.Bounds().Dx() / columns cellH := atlasImage.Bounds().Dy() / rows cellSize := image.Rect(0, 0, cellW, cellH) this.icons[size] = make(map[T] canvas.Texture) for _, icon := range icons { offset := image.Pt ( icon.position.X * cellW, icon.position.Y * cellH) this.icons[size][icon.index] = atlas.Clip(cellSize.Add(offset)) } }