hnnggg icons

This commit is contained in:
Sasha Koshka 2023-09-04 02:35:01 -04:00
parent 1b489485da
commit d597f79a16
7 changed files with 126 additions and 41 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 912 B

Binary file not shown.

BIN
assets/mime-medium.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

2
go.mod
View File

@ -3,6 +3,6 @@ module git.tebibyte.media/tomo/aluminum
go 1.20 go 1.20
require ( require (
git.tebibyte.media/tomo/tomo v0.26.1 git.tebibyte.media/tomo/tomo v0.27.0
golang.org/x/image v0.11.0 golang.org/x/image v0.11.0
) )

4
go.sum
View File

@ -1,5 +1,5 @@
git.tebibyte.media/tomo/tomo v0.26.1 h1:V5ciRuixMYb79aAawgquFEfJ1icyEmMKBKFPWwi94NE= git.tebibyte.media/tomo/tomo v0.27.0 h1:gCwxQe0qm1hZLfHkMI3OccNMC/lB1cfs4BbaMz/bXug=
git.tebibyte.media/tomo/tomo v0.26.1/go.mod h1:C9EzepS9wjkTJjnZaPBh22YvVPyA4hbBAJVU20Rdmps= git.tebibyte.media/tomo/tomo v0.27.0/go.mod h1:C9EzepS9wjkTJjnZaPBh22YvVPyA4hbBAJVU20Rdmps=
github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=

View File

@ -1,56 +1,66 @@
package aluminum package aluminum
import "fmt" import "io"
import "io/fs"
import "image" import "image"
import _ "image/png"
import "git.tebibyte.media/tomo/tomo" import "git.tebibyte.media/tomo/tomo"
import "git.tebibyte.media/tomo/tomo/data"
import "git.tebibyte.media/tomo/tomo/theme" import "git.tebibyte.media/tomo/tomo/theme"
import "git.tebibyte.media/tomo/tomo/canvas" import "git.tebibyte.media/tomo/tomo/canvas"
type iconSet struct { type iconIndex interface {
fs fs.FS ~int | ~string
icons map[theme.IconSize] map[string] canvas.Texture
} }
func (this *iconSet) get (size theme.IconSize, name string) canvas.Texture { type iconEntry[T iconIndex] struct {
texture := this.icons[size][name] position image.Point
if texture != nil { index T
return texture }
} else {
texture = nil
defer func () { this.icons[size][name] = texture } ()
file, err := this.fs.Open(fmt.Sprint(size, "/", name, ".png")) func i[T iconIndex] (x, y int, index T) iconEntry[T] {
if err != nil { return texture } return iconEntry[T] {
defer file.Close() position: image.Pt(x, y),
image, _, err := image.Decode(file) index: index,
if err != nil { return texture }
texture = tomo.NewTexture(image)
return texture
} }
} }
func (this *iconSet) Icon (id theme.Icon, size theme.IconSize) canvas.Texture { type iconSet[T iconIndex] struct {
return this.get(size, fmt.Sprint("actions/", id)) icons map[theme.IconSize] map[T] canvas.Texture
} }
func (this *iconSet) MimeIcon (mime data.Mime, size theme.IconSize) canvas.Texture { func (this *iconSet[T]) Get (index T,size theme.IconSize) canvas.Texture {
texture := this.get(size, fmt.Sprint("mime/", mime)) return this.icons[size][index]
if texture != nil {
return texture
} else {
return this.get(size, fmt.Sprint("mime-generic/", mime.Type))
}
} }
func (this *iconSet) ApplicationIcon (id theme.ApplicationIcon, size theme.IconSize) canvas.Texture { func (this *iconSet[T]) Init (
texture := this.get(size, fmt.Sprint("app/", id.Name)) small, medium, large io.Reader,
if texture != nil { rows, columns int,
return texture icons ...iconEntry[T],
} else { ) {
return this.get(size, fmt.Sprint("app-generic/", id.Role)) 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))
} }
} }

View File

@ -1,12 +1,22 @@
package aluminum package aluminum
import "bytes"
import "image" import "image"
import _ "embed"
import _ "image/png"
import "image/color" import "image/color"
import "git.tebibyte.media/tomo/tomo" import "git.tebibyte.media/tomo/tomo"
import "golang.org/x/image/font/basicfont" import "golang.org/x/image/font/basicfont"
import "git.tebibyte.media/tomo/tomo/data"
import "git.tebibyte.media/tomo/tomo/theme" import "git.tebibyte.media/tomo/tomo/theme"
import "git.tebibyte.media/tomo/tomo/input" import "git.tebibyte.media/tomo/tomo/input"
import "git.tebibyte.media/tomo/tomo/event" import "git.tebibyte.media/tomo/tomo/event"
import "git.tebibyte.media/tomo/tomo/canvas"
//go:embed assets/mime-generic-medium.png
var genericMimeIconsMedium []byte
//go:embed assets/mime-medium.png
var mimeIconsMedium []byte
func hex (color uint32) (c color.RGBA) { func hex (color uint32) (c color.RGBA) {
c.A = uint8(color) c.A = uint8(color)
@ -45,7 +55,12 @@ var gutterColor = hex(0xbfc6d1FF)
var gutterColorHovered = hex(0xc5cbd6FF) var gutterColorHovered = hex(0xc5cbd6FF)
type Theme struct { type Theme struct {
iconSet unpackedIcons bool
icons iconSet[theme.Icon]
mimeIcons iconSet[string]
genericMimeIcons iconSet[string]
appIcons iconSet[string]
genericAppIcons iconSet[tomo.ApplicationRole]
} }
func (this *Theme) RGBA (id theme.Color) (r, g, b, a uint32) { func (this *Theme) RGBA (id theme.Color) (r, g, b, a uint32) {
@ -215,7 +230,67 @@ func (this *Theme) Apply (object tomo.Object, role theme.Role) event.Cookie {
} }
box.SetBorder(border...) box.SetBorder(border...)
box.SetColor(buttonColor) box.SetColor(buttonColor)
case "Icon":
switch role.Variant {
case "small": box.SetMinimumSize(image.Pt(16, 16))
case "medium": box.SetMinimumSize(image.Pt(32, 32))
case "large": box.SetMinimumSize(image.Pt(48, 48))
}
} }
return event.MultiCookie() return event.MultiCookie()
} }
func (this *Theme) Icon (id theme.Icon, size theme.IconSize) canvas.Texture {
this.ensureIcons()
return this.icons.Get(id, size)
}
func (this *Theme) MimeIcon (mime data.Mime, size theme.IconSize) canvas.Texture {
this.ensureIcons()
texture := this.mimeIcons.Get(mime.String(), size)
if texture != nil {
return texture
} else {
return this.genericMimeIcons.Get(mime.Type, size)
}
}
func (this *Theme) ApplicationIcon (id theme.ApplicationIcon, size theme.IconSize) canvas.Texture {
this.ensureIcons()
texture := this.appIcons.Get(id.Name, size)
if texture != nil {
return texture
} else {
return this.genericAppIcons.Get(id.Role, size)
}
}
func (this *Theme) ensureIcons () {
if this.unpackedIcons { return }
this.unpackedIcons = true
// this.icons.Init () // TODO
this.mimeIcons.Init (
nil, // TODO
bytes.NewReader(mimeIconsMedium),
nil, // TODO
32, 12,
// TODO
)
this.genericMimeIcons.Init (
nil, // TODO
bytes.NewReader(genericMimeIconsMedium),
nil, // TODO
1, 5,
i(0, 0, "text"),
i(1, 0, "image"),
i(2, 0, "audio"),
i(3, 0, "video"),
i(4, 0, "application"),
)
// this.appIcons.Init () // TODO
// this.genericAppIcons.Init () // TODO
}