Icons and styles use xyz.holanet.Nasin config
This commit is contained in:
		
							parent
							
								
									a69c726482
								
							
						
					
					
						commit
						f512deb96e
					
				@ -144,15 +144,43 @@ func RunApplication (application Application) {
 | 
			
		||||
	}
 | 
			
		||||
	flag.Parse()
 | 
			
		||||
 | 
			
		||||
	// open config
 | 
			
		||||
	globalConfig, err := ApplicationConfig(GlobalApplicationDescription())
 | 
			
		||||
	if err != nil { log.Fatalln("nasin: could not open config:", err) }
 | 
			
		||||
	defer globalConfig.Close()
 | 
			
		||||
	styleConfigKey   := "Style"
 | 
			
		||||
	iconSetConfigKey := "IconSet"
 | 
			
		||||
 | 
			
		||||
	// registry
 | 
			
		||||
	// TODO: rebuild registry around the config
 | 
			
		||||
	reg := new(registrar.Registrar)
 | 
			
		||||
	backend, err := reg.SetBackend()
 | 
			
		||||
	if err != nil { log.Fatalln("nasin: could not register backend:", err) }
 | 
			
		||||
	err = reg.SetTheme()
 | 
			
		||||
	if err != nil { log.Fatalln("nasin: could not set theme:", err) }
 | 
			
		||||
	err = reg.SetIconSet()
 | 
			
		||||
	if err != nil { log.Fatalln("nasin: could not set icon set:", err) }
 | 
			
		||||
	err = reg.SetFaceSet()
 | 
			
		||||
	if err != nil { log.Fatalln("nasin: could not set face set:", err) }
 | 
			
		||||
	updateStyle := func () {
 | 
			
		||||
		value, err := globalConfig.GetString(styleConfigKey, "")
 | 
			
		||||
		if err != nil { log.Fatalln("nasin: could not set theme:", err) }
 | 
			
		||||
		err = reg.SetStyle(value)
 | 
			
		||||
		if err != nil { log.Fatalln("nasin: could not set theme:", err) }
 | 
			
		||||
	}
 | 
			
		||||
	updateIconSet := func () {
 | 
			
		||||
		value, err := globalConfig.GetString(iconSetConfigKey, "")
 | 
			
		||||
		if err != nil { log.Fatalln("nasin: could not set icon set:", err) }
 | 
			
		||||
		err = reg.SetIconSet(value)
 | 
			
		||||
		if err != nil { log.Fatalln("nasin: could not set icon set:", err) }
 | 
			
		||||
	}
 | 
			
		||||
	updateStyle()
 | 
			
		||||
	updateIconSet()
 | 
			
		||||
 | 
			
		||||
	globalConfig.OnChange(func (key string) {
 | 
			
		||||
		switch key {
 | 
			
		||||
		case styleConfigKey:   updateStyle()
 | 
			
		||||
		case iconSetConfigKey: updateIconSet()
 | 
			
		||||
		}
 | 
			
		||||
	})
 | 
			
		||||
 | 
			
		||||
	// init application
 | 
			
		||||
	err = application.Init()
 | 
			
		||||
	if err != nil { log.Fatalln("nasin: could not run application:", err) }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -6,9 +6,10 @@ import _ "embed"
 | 
			
		||||
import _ "image/png"
 | 
			
		||||
import "git.tebibyte.media/tomo/tomo"
 | 
			
		||||
import "git.tebibyte.media/tomo/tomo/data"
 | 
			
		||||
import "git.tebibyte.media/tomo/nasin/internal/util"
 | 
			
		||||
import "git.tebibyte.media/tomo/tomo/event"
 | 
			
		||||
import "git.tebibyte.media/tomo/tomo/canvas"
 | 
			
		||||
import "git.tebibyte.media/tomo/backend/style"
 | 
			
		||||
import "git.tebibyte.media/tomo/nasin/internal/util"
 | 
			
		||||
 | 
			
		||||
//go:embed assets/icons-small.png
 | 
			
		||||
var atlasSmallBytes []byte
 | 
			
		||||
@ -35,7 +36,7 @@ const (
 | 
			
		||||
	iconXOfficeSpreadsheet     = tomo.Icon("x-office-spreadsheet")
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
func generateSource (data []byte, width int) map[tomo.Icon] canvas.Texture {
 | 
			
		||||
func generateSource (data []byte, width int) (canvas.TextureCloser, map[tomo.Icon] canvas.Texture) {
 | 
			
		||||
	atlasImage, _, err := image.Decode(bytes.NewReader(data))
 | 
			
		||||
	if err != nil { panic(err) }
 | 
			
		||||
	atlasTexture := tomo.NewTexture(atlasImage)
 | 
			
		||||
@ -448,23 +449,26 @@ func generateSource (data []byte, width int) map[tomo.Icon] canvas.Texture {
 | 
			
		||||
	col(tomo.IconWeatherSnow)
 | 
			
		||||
	col(tomo.IconWeatherStorm)
 | 
			
		||||
	
 | 
			
		||||
	return source
 | 
			
		||||
	return atlasTexture, source
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type iconSet struct {
 | 
			
		||||
	atlasSmall canvas.TextureCloser
 | 
			
		||||
	atlasLarge canvas.TextureCloser
 | 
			
		||||
	texturesSmall map[tomo.Icon] canvas.Texture
 | 
			
		||||
	texturesLarge map[tomo.Icon] canvas.Texture
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// New creates a new fallback icon set.
 | 
			
		||||
func New () style.IconSet {
 | 
			
		||||
	return new(iconSet)
 | 
			
		||||
func New () (style.IconSet, event.Cookie) {
 | 
			
		||||
	iconSet := new(iconSet)
 | 
			
		||||
	return iconSet, iconSet
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (this *iconSet) ensure () {
 | 
			
		||||
	if this.texturesSmall != nil { return }
 | 
			
		||||
	this.texturesSmall = generateSource(atlasSmallBytes, 16)
 | 
			
		||||
	this.texturesLarge = generateSource(atlasLargeBytes, 32)
 | 
			
		||||
	this.atlasSmall, this.texturesSmall = generateSource(atlasSmallBytes, 16)
 | 
			
		||||
	this.atlasLarge, this.texturesLarge = generateSource(atlasLargeBytes, 32)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (this *iconSet) selectSource (size tomo.IconSize) map[tomo.Icon] canvas.Texture {
 | 
			
		||||
@ -500,3 +504,12 @@ func (this *iconSet) MimeIcon (mime data.Mime, size tomo.IconSize) canvas.Textur
 | 
			
		||||
		return source[tomo.Icon(iconApplicationXGeneric)]
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (this *iconSet) Close () {
 | 
			
		||||
	if this.atlasSmall != nil {
 | 
			
		||||
		this.atlasSmall.Close()
 | 
			
		||||
	}
 | 
			
		||||
	if this.atlasLarge != nil {
 | 
			
		||||
		this.atlasLarge.Close()
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -9,6 +9,7 @@ import "strings"
 | 
			
		||||
import _ "image/png"
 | 
			
		||||
import "git.tebibyte.media/tomo/tomo"
 | 
			
		||||
import "git.tebibyte.media/tomo/tomo/data"
 | 
			
		||||
import "git.tebibyte.media/tomo/tomo/event"
 | 
			
		||||
import "git.tebibyte.media/tomo/tomo/canvas"
 | 
			
		||||
import "git.tebibyte.media/tomo/backend/style"
 | 
			
		||||
import "git.tebibyte.media/tomo/nasin/internal/util"
 | 
			
		||||
@ -17,27 +18,27 @@ import xdgIconTheme "git.tebibyte.media/tomo/xdg/icon-theme"
 | 
			
		||||
type iconTheme struct {
 | 
			
		||||
	xdg xdgIconTheme.Theme
 | 
			
		||||
	fallback       style.IconSet
 | 
			
		||||
	texturesSmall  map[tomo.Icon] canvas.Texture
 | 
			
		||||
	texturesMedium map[tomo.Icon] canvas.Texture
 | 
			
		||||
	texturesLarge  map[tomo.Icon] canvas.Texture
 | 
			
		||||
	texturesSmall  map[tomo.Icon] canvas.TextureCloser
 | 
			
		||||
	texturesMedium map[tomo.Icon] canvas.TextureCloser
 | 
			
		||||
	texturesLarge  map[tomo.Icon] canvas.TextureCloser
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func FindThemeWarn (name string, fallback style.IconSet, path ...string) (style.IconSet, error) {
 | 
			
		||||
func FindThemeWarn (name string, fallback style.IconSet, path ...string) (style.IconSet, event.Cookie, error) {
 | 
			
		||||
	this := &iconTheme {
 | 
			
		||||
		fallback:       fallback,
 | 
			
		||||
		texturesLarge:  make(map[tomo.Icon] canvas.Texture),
 | 
			
		||||
		texturesMedium: make(map[tomo.Icon] canvas.Texture),
 | 
			
		||||
		texturesSmall:  make(map[tomo.Icon] canvas.Texture),
 | 
			
		||||
		texturesLarge:  make(map[tomo.Icon] canvas.TextureCloser),
 | 
			
		||||
		texturesMedium: make(map[tomo.Icon] canvas.TextureCloser),
 | 
			
		||||
		texturesSmall:  make(map[tomo.Icon] canvas.TextureCloser),
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	xdg, err := xdgIconTheme.FindThemeWarn(name, path...)
 | 
			
		||||
	if err != nil { return nil, err }
 | 
			
		||||
	if err != nil { return nil, nil, err }
 | 
			
		||||
	this.xdg = xdg
 | 
			
		||||
	
 | 
			
		||||
	return this, nil
 | 
			
		||||
	return this, this, nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (this *iconTheme) selectSource (size tomo.IconSize) map[tomo.Icon] canvas.Texture {
 | 
			
		||||
func (this *iconTheme) selectSource (size tomo.IconSize) map[tomo.Icon] canvas.TextureCloser {
 | 
			
		||||
	switch size {
 | 
			
		||||
	case tomo.IconSizeMedium: return this.texturesMedium
 | 
			
		||||
	case tomo.IconSizeLarge:  return this.texturesLarge
 | 
			
		||||
@ -45,7 +46,7 @@ func (this *iconTheme) selectSource (size tomo.IconSize) map[tomo.Icon] canvas.T
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (this *iconTheme) xdgIcon (name string, size tomo.IconSize) (canvas.Texture, bool) {
 | 
			
		||||
func (this *iconTheme) xdgIcon (name string, size tomo.IconSize) (canvas.TextureCloser, bool) {
 | 
			
		||||
	// TODO use scaling factor instead of 1
 | 
			
		||||
	// find icon file
 | 
			
		||||
	icon, err := this.xdg.FindIcon(name, iconSizePixels(size), 1, xdgIconTheme.PNG)
 | 
			
		||||
@ -100,7 +101,20 @@ func (this *iconTheme) MimeIcon (mime data.Mime, size tomo.IconSize) canvas.Text
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (this *iconTheme) icon (icon tomo.Icon, size tomo.IconSize) canvas.Texture {
 | 
			
		||||
func (this *iconTheme) Close () {
 | 
			
		||||
	closeAllIn := func (mp map[tomo.Icon] canvas.TextureCloser) {
 | 
			
		||||
		for _, texture := range mp {
 | 
			
		||||
			if texture != nil {
 | 
			
		||||
				texture.Close()
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	closeAllIn(this.texturesSmall)
 | 
			
		||||
	closeAllIn(this.texturesMedium)
 | 
			
		||||
	closeAllIn(this.texturesLarge)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (this *iconTheme) icon (icon tomo.Icon, size tomo.IconSize) canvas.TextureCloser {
 | 
			
		||||
	if texture, ok := this.xdgIcon(XdgIconName(icon), size); ok {
 | 
			
		||||
		return texture
 | 
			
		||||
	}
 | 
			
		||||
@ -110,7 +124,7 @@ func (this *iconTheme) icon (icon tomo.Icon, size tomo.IconSize) canvas.Texture
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (this *iconTheme) mimeIcon (mime data.Mime, size tomo.IconSize) canvas.Texture {
 | 
			
		||||
func (this *iconTheme) mimeIcon (mime data.Mime, size tomo.IconSize) canvas.TextureCloser {
 | 
			
		||||
	if texture, ok := this.xdgIcon(xdgFormatMime(mime), size); ok {
 | 
			
		||||
		return texture
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
@ -1,10 +1,10 @@
 | 
			
		||||
//go:build unix && (!darwin)
 | 
			
		||||
package registrar
 | 
			
		||||
 | 
			
		||||
import "os"
 | 
			
		||||
import "log"
 | 
			
		||||
import "git.tebibyte.media/tomo/tomo"
 | 
			
		||||
import "git.tebibyte.media/tomo/backend/x"
 | 
			
		||||
import "git.tebibyte.media/tomo/tomo/event"
 | 
			
		||||
import "git.tebibyte.media/sashakoshka/goparse"
 | 
			
		||||
import "git.tebibyte.media/tomo/nasin/internal/icons/xdg"
 | 
			
		||||
import "git.tebibyte.media/tomo/nasin/internal/styles/tss"
 | 
			
		||||
@ -14,6 +14,8 @@ import "git.tebibyte.media/tomo/nasin/internal/faces/fallback"
 | 
			
		||||
 | 
			
		||||
type Registrar struct {
 | 
			
		||||
	backend *x.Backend
 | 
			
		||||
	iconSetCookie event.Cookie
 | 
			
		||||
	styleCookie   event.Cookie
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (this *Registrar) SetBackend () (tomo.Backend, error) {
 | 
			
		||||
@ -24,38 +26,50 @@ func (this *Registrar) SetBackend () (tomo.Backend, error) {
 | 
			
		||||
	return backend, nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (this *Registrar) SetTheme () error {
 | 
			
		||||
	styleSheetName := os.Getenv("TOMO_STYLE_SHEET")
 | 
			
		||||
	if styleSheetName != "" {
 | 
			
		||||
		styl, _, err := tss.LoadFile(styleSheetName)
 | 
			
		||||
func (this *Registrar) SetStyle (name string) error {
 | 
			
		||||
	if this.styleCookie != nil {
 | 
			
		||||
		this.styleCookie.Close()
 | 
			
		||||
		this.styleCookie = nil
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if name != "" {
 | 
			
		||||
		styl, cookie, err := tss.LoadFile(name)
 | 
			
		||||
		if err == nil {
 | 
			
		||||
			this.backend.SetStyle(styl)
 | 
			
		||||
			this.styleCookie = cookie
 | 
			
		||||
			return nil
 | 
			
		||||
		} else {
 | 
			
		||||
			log.Printf (
 | 
			
		||||
				"nasin: could not load style sheet '%s'\n%v",
 | 
			
		||||
				styleSheetName, parse.Format(err))
 | 
			
		||||
				name, parse.Format(err))
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	styl, _ := fallbackStyle.New()
 | 
			
		||||
	styl, cookie := fallbackStyle.New()
 | 
			
		||||
	this.styleCookie = cookie
 | 
			
		||||
	this.backend.SetStyle(styl)
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (this *Registrar) SetIconSet () error {
 | 
			
		||||
	iconSet := fallbackIcons.New()
 | 
			
		||||
	iconSetName := os.Getenv("TOMO_XDG_ICON_THEME")
 | 
			
		||||
	if iconSetName != "" {
 | 
			
		||||
		xdgIconSet, err := xdgIcons.FindThemeWarn(iconSetName, iconSet)
 | 
			
		||||
func (this *Registrar) SetIconSet (name string) error {
 | 
			
		||||
	if this.iconSetCookie != nil {
 | 
			
		||||
		this.iconSetCookie.Close()
 | 
			
		||||
		this.iconSetCookie = nil
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	iconSet, cookie := fallbackIcons.New()
 | 
			
		||||
	if name != "" {
 | 
			
		||||
		xdgIconSet, xdgCookie, err := xdgIcons.FindThemeWarn(name, iconSet)
 | 
			
		||||
		cookie = event.MultiCookie(cookie, xdgCookie)
 | 
			
		||||
		if err == nil {
 | 
			
		||||
			iconSet = xdgIconSet
 | 
			
		||||
		} else {
 | 
			
		||||
			log.Printf("nasin: could not load icon theme '%s': %v", iconSetName, err)
 | 
			
		||||
			log.Printf("nasin: could not load icon theme '%s': %v", name, err)
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	this.backend.SetIconSet(iconSet)
 | 
			
		||||
	this.iconSetCookie = cookie
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user