110 lines
3.3 KiB
Go
110 lines
3.3 KiB
Go
package theme
|
|
|
|
import "fmt"
|
|
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"
|
|
|
|
// Role describes the role of an object.
|
|
type Role struct {
|
|
// Package is an optional namespace field. If specified, it should be
|
|
// the package name or module name the object is from.
|
|
Package string
|
|
|
|
// Object specifies what type of object it is. For example:
|
|
// - TextInput
|
|
// - Table
|
|
// - Label
|
|
// - Dial
|
|
// This should correspond directly to the type name of the object.
|
|
Object string
|
|
|
|
// Variant is an optional field to be used when an object has one or
|
|
// more soft variants under one type. For example, an object "Slider"
|
|
// may have variations "horizontal" and "vertical".
|
|
Variant string
|
|
}
|
|
|
|
// String satisfies the fmt.Stringer interface.
|
|
// It follows the format of:
|
|
// Package.Object[Variant]
|
|
func (r Role) String () string {
|
|
return fmt.Sprintf("%s.%s[%s]", r.Package, r.Object, r.Variant)
|
|
}
|
|
|
|
// R is shorthand for creating a Role structure.
|
|
func R (pack, object, variant string) Role {
|
|
return Role { Package: pack, Object: object, Variant: variant }
|
|
}
|
|
|
|
// Color represents a color ID.
|
|
type Color int; const (
|
|
ColorBackground Color = iota
|
|
ColorForeground
|
|
ColorRaised
|
|
ColorSunken
|
|
ColorAccent
|
|
)
|
|
|
|
// String satisfies the fmt.Stringer interface.
|
|
func (c Color) String () string {
|
|
switch c {
|
|
case ColorBackground: return "background"
|
|
case ColorForeground: return "foreground"
|
|
case ColorRaised: return "raised"
|
|
case ColorSunken: return "sunken"
|
|
case ColorAccent: return "accent"
|
|
default: return "unknown"
|
|
}
|
|
}
|
|
|
|
// RGBA satisfies the color.Color interface.
|
|
func (id Color) RGBA () (r, g, b, a uint32) {
|
|
if current == nil { return }
|
|
return current.RGBA(id)
|
|
}
|
|
|
|
// Theme can apply a visual style to different objects.
|
|
type Theme interface {
|
|
// A word on textures:
|
|
//
|
|
// Because textures can be linked to some resource that is outside of
|
|
// the control of Go's garbage collector, methods of Theme must not
|
|
// allocate new copies of a texture each time they are called. It is
|
|
// fine to lazily load textures and save them for later use, but the
|
|
// same texture must never be allocated multiple times as this could
|
|
// cause a memory leak.
|
|
//
|
|
// As such, textures returned by these methods must be protected.
|
|
|
|
// Apply applies the theme to the given object, according to the given
|
|
// role. This may register event listeners with the given object;
|
|
// closing the returned cookie must remove them.
|
|
Apply (tomo.Object, Role) event.Cookie
|
|
|
|
// RGBA returns the RGBA values of the corresponding color ID.
|
|
RGBA (Color) (r, g, b, a uint32)
|
|
|
|
// Icon returns a texture of the corresponding icon ID.
|
|
Icon (Icon, IconSize) canvas.Texture
|
|
|
|
// MimeIcon returns an icon corresponding to a MIME type.
|
|
MimeIcon (data.Mime, IconSize) canvas.Texture
|
|
}
|
|
|
|
var current Theme
|
|
|
|
// SetTheme sets the theme.
|
|
func SetTheme (theme Theme) {
|
|
current = theme
|
|
}
|
|
|
|
// Apply applies the current theme to the given object, according to the given
|
|
// role. This may register event listeners with the given object; closing the
|
|
// returned cookie will remove them.
|
|
func Apply (object tomo.Object, role Role) event.Cookie {
|
|
if current == nil { return event.NoCookie { } }
|
|
return current.Apply(object, role)
|
|
}
|