61 lines
1.3 KiB
Go
61 lines
1.3 KiB
Go
package system
|
|
|
|
import "git.tebibyte.media/tomo/tomo"
|
|
import "git.tebibyte.media/tomo/backend/style"
|
|
|
|
type styleApplicator struct {
|
|
style *style.Style
|
|
role tomo.Role
|
|
rules []style.Rule
|
|
currentSet style.AttrSet
|
|
}
|
|
|
|
func (this *styleApplicator) apply (box anyBox) {
|
|
if box.Role() != this.role {
|
|
this.role = box.Role()
|
|
// the role has changed, so re-cache the list of rules
|
|
this.rules = nil
|
|
for _, rule := range this.style.Rules {
|
|
role := box.Role()
|
|
// blank fields match anything
|
|
if rule.Role.Package == "" { role.Package = "" }
|
|
if rule.Role.Object == "" { role.Object = "" }
|
|
if rule.Role == role {
|
|
this.rules = append(this.rules, rule)
|
|
}
|
|
}
|
|
}
|
|
|
|
// compile list of attributes by searching through the cached ruleset
|
|
attrs := make(style.AttrSet)
|
|
for _, rule := range this.rules {
|
|
satisifed := true
|
|
for _, tag := range rule.Tags {
|
|
if !box.Tag(tag) {
|
|
satisifed = false
|
|
break
|
|
}
|
|
}
|
|
|
|
if satisifed {
|
|
attrs.MergeOver(rule.Set)
|
|
}
|
|
}
|
|
|
|
// reset an attribute if it is no longer specified
|
|
if this.currentSet != nil {
|
|
for kind := range this.currentSet {
|
|
_, exists := attrs[kind]
|
|
if !exists {
|
|
box.unsetAttr(kind, false)
|
|
}
|
|
}
|
|
}
|
|
|
|
// apply that list of attributes
|
|
this.currentSet = attrs
|
|
for _, attr := range attrs {
|
|
box.setAttr(attr, false)
|
|
}
|
|
}
|