restructure-config #8
@ -1,5 +1,6 @@
|
||||
package config
|
||||
|
||||
// Config can return global configuration parameters.
|
||||
type Config interface {
|
||||
// Padding returns the amount of internal padding elements should have.
|
||||
// An element's inner content (such as text) should be inset by this
|
||||
|
@ -1,48 +0,0 @@
|
||||
package theme
|
||||
|
||||
import "git.tebibyte.media/sashakoshka/tomo/artist"
|
||||
|
||||
var buttonPattern = artist.NewMultiBordered (
|
||||
artist.Stroke { Weight: 1, Pattern: strokePattern },
|
||||
artist.Stroke {
|
||||
Weight: 1,
|
||||
Pattern: artist.Beveled {
|
||||
artist.NewUniform(hex(0xCCD5D2FF)),
|
||||
artist.NewUniform(hex(0x4B5B59FF)),
|
||||
},
|
||||
},
|
||||
artist.Stroke { Pattern: artist.NewUniform(hex(0x8D9894FF)) })
|
||||
var selectedButtonPattern = artist.NewMultiBordered (
|
||||
artist.Stroke { Weight: 1, Pattern: strokePattern },
|
||||
artist.Stroke {
|
||||
Weight: 1,
|
||||
Pattern: artist.Beveled {
|
||||
artist.NewUniform(hex(0xCCD5D2FF)),
|
||||
artist.NewUniform(hex(0x4B5B59FF)),
|
||||
},
|
||||
},
|
||||
artist.Stroke { Weight: 1, Pattern: accentPattern },
|
||||
artist.Stroke { Pattern: artist.NewUniform(hex(0x8D9894FF)) })
|
||||
var pressedButtonPattern = artist.NewMultiBordered (
|
||||
artist.Stroke { Weight: 1, Pattern: strokePattern },
|
||||
artist.Stroke {
|
||||
Weight: 1,
|
||||
Pattern: artist.Beveled {
|
||||
artist.NewUniform(hex(0x4B5B59FF)),
|
||||
artist.NewUniform(hex(0x8D9894FF)),
|
||||
},
|
||||
},
|
||||
artist.Stroke { Pattern: artist.NewUniform(hex(0x8D9894FF)) })
|
||||
var pressedSelectedButtonPattern = artist.NewMultiBordered (
|
||||
artist.Stroke { Weight: 1, Pattern: strokePattern },
|
||||
artist.Stroke {
|
||||
Weight: 1,
|
||||
Pattern: artist.Beveled {
|
||||
artist.NewUniform(hex(0x4B5B59FF)),
|
||||
artist.NewUniform(hex(0x8D9894FF)),
|
||||
},
|
||||
},
|
||||
artist.Stroke { Pattern: artist.NewUniform(hex(0x8D9894FF)) })
|
||||
var disabledButtonPattern = artist.NewMultiBordered (
|
||||
artist.Stroke { Weight: 1, Pattern: weakForegroundPattern },
|
||||
artist.Stroke { Pattern: backgroundPattern })
|
167
theme/default.go
Normal file
167
theme/default.go
Normal file
@ -0,0 +1,167 @@
|
||||
package theme
|
||||
|
||||
import "image"
|
||||
import "golang.org/x/image/font"
|
||||
import "git.tebibyte.media/sashakoshka/tomo/artist"
|
||||
import "git.tebibyte.media/sashakoshka/tomo/defaultfont"
|
||||
|
||||
// Default is the default theme.
|
||||
type Default struct { }
|
||||
|
||||
// FontFace returns the default font face.
|
||||
func (Default) FontFace (style FontStyle, size FontSize, c Case) font.Face {
|
||||
switch style {
|
||||
case FontStyleBold:
|
||||
return defaultfont.FaceBold
|
||||
case FontStyleItalic:
|
||||
return defaultfont.FaceItalic
|
||||
case FontStyleBoldItalic:
|
||||
return defaultfont.FaceBoldItalic
|
||||
default:
|
||||
return defaultfont.FaceRegular
|
||||
}
|
||||
}
|
||||
|
||||
// Icon returns an icon from the default set corresponding to the given name.
|
||||
func (Default) Icon (string, Case) artist.Pattern {
|
||||
// TODO
|
||||
return uhex(0)
|
||||
}
|
||||
|
||||
// Pattern returns a pattern from the default theme corresponding to the given
|
||||
// pattern ID.
|
||||
func (Default) Pattern (
|
||||
pattern Pattern,
|
||||
c Case,
|
||||
state PatternState,
|
||||
) artist.Pattern {
|
||||
switch pattern {
|
||||
case PatternAccent:
|
||||
return accentPattern
|
||||
case PatternBackground:
|
||||
return backgroundPattern
|
||||
case PatternForeground:
|
||||
if state.Disabled {
|
||||
return weakForegroundPattern
|
||||
} else {
|
||||
return foregroundPattern
|
||||
}
|
||||
case PatternDead:
|
||||
return deadPattern
|
||||
case PatternRaised:
|
||||
if c == C("basic", "listEntry") {
|
||||
if state.Focused {
|
||||
if state.On {
|
||||
return focusedOnListEntryPattern
|
||||
} else {
|
||||
return focusedListEntryPattern
|
||||
}
|
||||
} else {
|
||||
if state.On {
|
||||
return onListEntryPattern
|
||||
} else {
|
||||
return listEntryPattern
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if state.Focused {
|
||||
return selectedRaisedPattern
|
||||
} else {
|
||||
return raisedPattern
|
||||
}
|
||||
}
|
||||
case PatternSunken:
|
||||
if c == C("basic", "list") {
|
||||
if state.Focused {
|
||||
return focusedListPattern
|
||||
} else {
|
||||
return listPattern
|
||||
}
|
||||
} else {
|
||||
return sunkenPattern
|
||||
}
|
||||
case PatternPinboard:
|
||||
return texturedSunkenPattern
|
||||
case PatternButton:
|
||||
if state.Disabled {
|
||||
return disabledButtonPattern
|
||||
} else {
|
||||
if state.Pressed {
|
||||
if state.Focused {
|
||||
return pressedSelectedButtonPattern
|
||||
} else {
|
||||
return pressedButtonPattern
|
||||
}
|
||||
} else {
|
||||
if state.Focused {
|
||||
return selectedButtonPattern
|
||||
} else {
|
||||
return buttonPattern
|
||||
}
|
||||
}
|
||||
}
|
||||
case PatternInput:
|
||||
if state.Disabled {
|
||||
return disabledInputPattern
|
||||
} else {
|
||||
if state.Focused {
|
||||
return selectedInputPattern
|
||||
} else {
|
||||
return inputPattern
|
||||
}
|
||||
}
|
||||
case PatternGutter:
|
||||
if state.Disabled {
|
||||
return disabledScrollGutterPattern
|
||||
} else {
|
||||
return scrollGutterPattern
|
||||
}
|
||||
case PatternHandle:
|
||||
if state.Disabled {
|
||||
return disabledScrollBarPattern
|
||||
} else {
|
||||
if state.Focused {
|
||||
if state.Pressed {
|
||||
return pressedSelectedScrollBarPattern
|
||||
} else {
|
||||
return selectedScrollBarPattern
|
||||
}
|
||||
} else {
|
||||
if state.Pressed {
|
||||
return pressedScrollBarPattern
|
||||
} else {
|
||||
return scrollBarPattern
|
||||
}
|
||||
}
|
||||
}
|
||||
default:
|
||||
return uhex(0)
|
||||
}
|
||||
}
|
||||
|
||||
// Inset returns the default inset value for the given pattern.
|
||||
func (Default) Inset (pattern Pattern, c Case) Inset {
|
||||
switch pattern {
|
||||
case PatternRaised:
|
||||
if c == C("basic", "listEntry") {
|
||||
return Inset { 2, 1, 2, 1 }
|
||||
} else {
|
||||
return Inset { 1, 1, 1, 1 }
|
||||
}
|
||||
case PatternSunken:
|
||||
if c == C("basic", "list") {
|
||||
return Inset { 4, 6, 4, 6 }
|
||||
} else {
|
||||
return Inset { 1, 1, 1, 1 }
|
||||
}
|
||||
|
||||
case PatternInput, PatternButton, PatternHandle, PatternPinboard:
|
||||
return Inset { 1, 1, 1, 1}
|
||||
default: return Inset { }
|
||||
}
|
||||
}
|
||||
|
||||
// Sink returns the default sink vector for the given pattern.
|
||||
func (Default) Sink (pattern Pattern, c Case) image.Point {
|
||||
return image.Point { 1, 1 }
|
||||
}
|
237
theme/defaultpatterns.go
Normal file
237
theme/defaultpatterns.go
Normal file
@ -0,0 +1,237 @@
|
||||
package theme
|
||||
|
||||
import "image/color"
|
||||
import "git.tebibyte.media/sashakoshka/tomo/artist"
|
||||
|
||||
var accentPattern = artist.NewUniform(hex(0x408090FF))
|
||||
var backgroundPattern = artist.NewUniform(color.Gray16 { 0xAAAA })
|
||||
var foregroundPattern = artist.NewUniform(color.Gray16 { 0x0000 })
|
||||
var weakForegroundPattern = artist.NewUniform(color.Gray16 { 0x4444 })
|
||||
var strokePattern = artist.NewUniform(color.Gray16 { 0x0000 })
|
||||
|
||||
var sunkenPattern = artist.NewMultiBordered (
|
||||
artist.Stroke { Weight: 1, Pattern: strokePattern },
|
||||
artist.Stroke {
|
||||
Weight: 1,
|
||||
Pattern: artist.Beveled {
|
||||
artist.NewUniform(hex(0x3b534eFF)),
|
||||
artist.NewUniform(hex(0x97a09cFF)),
|
||||
},
|
||||
},
|
||||
artist.Stroke { Pattern: artist.NewUniform(hex(0x97a09cFF)) })
|
||||
|
||||
var texturedSunkenPattern = artist.NewMultiBordered (
|
||||
artist.Stroke { Weight: 1, Pattern: strokePattern },
|
||||
artist.Stroke {
|
||||
Weight: 1,
|
||||
Pattern: artist.Beveled {
|
||||
artist.NewUniform(hex(0x3b534eFF)),
|
||||
artist.NewUniform(hex(0x97a09cFF)),
|
||||
},
|
||||
},
|
||||
// artist.Stroke { Pattern: artist.Striped {
|
||||
// First: artist.Stroke {
|
||||
// Weight: 2,
|
||||
// Pattern: artist.NewUniform(hex(0x97a09cFF)),
|
||||
// },
|
||||
// Second: artist.Stroke {
|
||||
// Weight: 1,
|
||||
// Pattern: artist.NewUniform(hex(0x6e8079FF)),
|
||||
// },
|
||||
// }})
|
||||
|
||||
artist.Stroke { Pattern: artist.Noisy {
|
||||
Low: artist.NewUniform(hex(0x97a09cFF)),
|
||||
High: artist.NewUniform(hex(0x6e8079FF)),
|
||||
}})
|
||||
|
||||
var raisedPattern = artist.NewMultiBordered (
|
||||
artist.Stroke { Weight: 1, Pattern: strokePattern },
|
||||
artist.Stroke {
|
||||
Weight: 1,
|
||||
Pattern: artist.Beveled {
|
||||
artist.NewUniform(hex(0xDBDBDBFF)),
|
||||
artist.NewUniform(hex(0x383C3AFF)),
|
||||
},
|
||||
},
|
||||
artist.Stroke { Pattern: artist.NewUniform(hex(0xAAAAAAFF)) })
|
||||
|
||||
var selectedRaisedPattern = artist.NewMultiBordered (
|
||||
artist.Stroke { Weight: 1, Pattern: strokePattern },
|
||||
artist.Stroke {
|
||||
Weight: 1,
|
||||
Pattern: artist.Beveled {
|
||||
artist.NewUniform(hex(0xDBDBDBFF)),
|
||||
artist.NewUniform(hex(0x383C3AFF)),
|
||||
},
|
||||
},
|
||||
artist.Stroke { Weight: 1, Pattern: accentPattern },
|
||||
artist.Stroke { Pattern: artist.NewUniform(hex(0xAAAAAAFF)) })
|
||||
|
||||
var deadPattern = artist.NewMultiBordered (
|
||||
artist.Stroke { Weight: 1, Pattern: strokePattern },
|
||||
artist.Stroke { Pattern: artist.NewUniform(hex(0x97a09cFF)) })
|
||||
|
||||
var buttonPattern = artist.NewMultiBordered (
|
||||
artist.Stroke { Weight: 1, Pattern: strokePattern },
|
||||
artist.Stroke {
|
||||
Weight: 1,
|
||||
Pattern: artist.Beveled {
|
||||
artist.NewUniform(hex(0xCCD5D2FF)),
|
||||
artist.NewUniform(hex(0x4B5B59FF)),
|
||||
},
|
||||
},
|
||||
artist.Stroke { Pattern: artist.NewUniform(hex(0x8D9894FF)) })
|
||||
var selectedButtonPattern = artist.NewMultiBordered (
|
||||
artist.Stroke { Weight: 1, Pattern: strokePattern },
|
||||
artist.Stroke {
|
||||
Weight: 1,
|
||||
Pattern: artist.Beveled {
|
||||
artist.NewUniform(hex(0xCCD5D2FF)),
|
||||
artist.NewUniform(hex(0x4B5B59FF)),
|
||||
},
|
||||
},
|
||||
artist.Stroke { Weight: 1, Pattern: accentPattern },
|
||||
artist.Stroke { Pattern: artist.NewUniform(hex(0x8D9894FF)) })
|
||||
|
||||
var pressedButtonPattern = artist.NewMultiBordered (
|
||||
artist.Stroke { Weight: 1, Pattern: strokePattern },
|
||||
artist.Stroke {
|
||||
Weight: 1,
|
||||
Pattern: artist.Beveled {
|
||||
artist.NewUniform(hex(0x4B5B59FF)),
|
||||
artist.NewUniform(hex(0x8D9894FF)),
|
||||
},
|
||||
},
|
||||
artist.Stroke { Pattern: artist.NewUniform(hex(0x8D9894FF)) })
|
||||
var pressedSelectedButtonPattern = artist.NewMultiBordered (
|
||||
artist.Stroke { Weight: 1, Pattern: strokePattern },
|
||||
artist.Stroke {
|
||||
Weight: 1,
|
||||
Pattern: artist.Beveled {
|
||||
artist.NewUniform(hex(0x4B5B59FF)),
|
||||
artist.NewUniform(hex(0x8D9894FF)),
|
||||
},
|
||||
},
|
||||
artist.Stroke { Pattern: artist.NewUniform(hex(0x8D9894FF)) })
|
||||
var disabledButtonPattern = artist.NewMultiBordered (
|
||||
artist.Stroke { Weight: 1, Pattern: weakForegroundPattern },
|
||||
artist.Stroke { Pattern: backgroundPattern })
|
||||
|
||||
var inputPattern = artist.NewMultiBordered (
|
||||
artist.Stroke { Weight: 1, Pattern: strokePattern },
|
||||
artist.Stroke {
|
||||
Weight: 1,
|
||||
Pattern: artist.Beveled {
|
||||
artist.NewUniform(hex(0x89925AFF)),
|
||||
artist.NewUniform(hex(0xD2CB9AFF)),
|
||||
},
|
||||
},
|
||||
artist.Stroke { Pattern: artist.NewUniform(hex(0xD2CB9AFF)) })
|
||||
var selectedInputPattern = artist.NewMultiBordered (
|
||||
artist.Stroke { Weight: 1, Pattern: strokePattern },
|
||||
artist.Stroke { Weight: 1, Pattern: accentPattern },
|
||||
artist.Stroke { Pattern: artist.NewUniform(hex(0xD2CB9AFF)) })
|
||||
var disabledInputPattern = artist.NewMultiBordered (
|
||||
artist.Stroke { Weight: 1, Pattern: weakForegroundPattern },
|
||||
artist.Stroke { Pattern: backgroundPattern })
|
||||
|
||||
var listPattern = artist.NewMultiBordered (
|
||||
artist.Stroke { Weight: 1, Pattern: strokePattern },
|
||||
artist.Stroke {
|
||||
Weight: 1,
|
||||
Pattern: artist.Beveled {
|
||||
uhex(0x383C3AFF),
|
||||
uhex(0x999C99FF),
|
||||
},
|
||||
},
|
||||
artist.Stroke { Pattern: uhex(0x999C99FF) })
|
||||
|
||||
var focusedListPattern = artist.NewMultiBordered (
|
||||
artist.Stroke { Weight: 1, Pattern: strokePattern },
|
||||
artist.Stroke { Weight: 1, Pattern: accentPattern },
|
||||
artist.Stroke { Pattern: uhex(0x999C99FF) })
|
||||
|
||||
var listEntryPattern = artist.Padded {
|
||||
Stroke: uhex(0x383C3AFF),
|
||||
Fill: uhex(0x999C99FF),
|
||||
Sides: []int { 0, 0, 0, 1 },
|
||||
}
|
||||
|
||||
var onListEntryPattern = artist.Padded {
|
||||
Stroke: uhex(0x383C3AFF),
|
||||
Fill: uhex(0x6e8079FF),
|
||||
Sides: []int { 0, 0, 0, 1 },
|
||||
}
|
||||
|
||||
var focusedListEntryPattern = artist.Padded {
|
||||
Stroke: accentPattern,
|
||||
Fill: uhex(0x999C99FF),
|
||||
Sides: []int { 0, 1, 0, 1 },
|
||||
}
|
||||
|
||||
var focusedOnListEntryPattern = artist.Padded {
|
||||
Stroke: accentPattern,
|
||||
Fill: uhex(0x6e8079FF),
|
||||
Sides: []int { 0, 1, 0, 1 },
|
||||
}
|
||||
|
||||
var scrollGutterPattern = artist.NewMultiBordered (
|
||||
artist.Stroke { Weight: 1, Pattern: strokePattern },
|
||||
artist.Stroke {
|
||||
Weight: 1,
|
||||
Pattern: artist.Beveled {
|
||||
artist.NewUniform(hex(0x3b534eFF)),
|
||||
artist.NewUniform(hex(0x6e8079FF)),
|
||||
},
|
||||
},
|
||||
artist.Stroke { Pattern: artist.NewUniform(hex(0x6e8079FF)) })
|
||||
var disabledScrollGutterPattern = artist.NewMultiBordered (
|
||||
artist.Stroke { Weight: 1, Pattern: weakForegroundPattern },
|
||||
artist.Stroke { Pattern: backgroundPattern })
|
||||
var scrollBarPattern = artist.NewMultiBordered (
|
||||
artist.Stroke { Weight: 1, Pattern: strokePattern },
|
||||
artist.Stroke {
|
||||
Weight: 1,
|
||||
Pattern: artist.Beveled {
|
||||
artist.NewUniform(hex(0xCCD5D2FF)),
|
||||
artist.NewUniform(hex(0x4B5B59FF)),
|
||||
},
|
||||
},
|
||||
artist.Stroke { Pattern: artist.NewUniform(hex(0x8D9894FF)) })
|
||||
var selectedScrollBarPattern = artist.NewMultiBordered (
|
||||
artist.Stroke { Weight: 1, Pattern: strokePattern },
|
||||
artist.Stroke {
|
||||
Weight: 1,
|
||||
Pattern: artist.Beveled {
|
||||
artist.NewUniform(hex(0xCCD5D2FF)),
|
||||
artist.NewUniform(hex(0x4B5B59FF)),
|
||||
},
|
||||
},
|
||||
artist.Stroke { Weight: 1, Pattern: accentPattern },
|
||||
artist.Stroke { Pattern: artist.NewUniform(hex(0x8D9894FF)) })
|
||||
var pressedScrollBarPattern = artist.NewMultiBordered (
|
||||
artist.Stroke { Weight: 1, Pattern: strokePattern },
|
||||
artist.Stroke {
|
||||
Weight: 1,
|
||||
Pattern: artist.Beveled {
|
||||
artist.NewUniform(hex(0xCCD5D2FF)),
|
||||
artist.NewUniform(hex(0x4B5B59FF)),
|
||||
},
|
||||
},
|
||||
artist.Stroke { Weight: 1, Pattern: artist.NewUniform(hex(0x8D9894FF)) },
|
||||
artist.Stroke { Pattern: artist.NewUniform(hex(0x7f8c89FF)) })
|
||||
var pressedSelectedScrollBarPattern = artist.NewMultiBordered (
|
||||
artist.Stroke { Weight: 1, Pattern: strokePattern },
|
||||
artist.Stroke {
|
||||
Weight: 1,
|
||||
Pattern: artist.Beveled {
|
||||
artist.NewUniform(hex(0xCCD5D2FF)),
|
||||
artist.NewUniform(hex(0x4B5B59FF)),
|
||||
},
|
||||
},
|
||||
artist.Stroke { Weight: 1, Pattern: accentPattern },
|
||||
artist.Stroke { Pattern: artist.NewUniform(hex(0x7f8c89FF)) })
|
||||
var disabledScrollBarPattern = artist.NewMultiBordered (
|
||||
artist.Stroke { Weight: 1, Pattern: weakForegroundPattern },
|
||||
artist.Stroke { Pattern: backgroundPattern })
|
@ -1,21 +0,0 @@
|
||||
package theme
|
||||
|
||||
import "git.tebibyte.media/sashakoshka/tomo/artist"
|
||||
|
||||
var inputPattern = artist.NewMultiBordered (
|
||||
artist.Stroke { Weight: 1, Pattern: strokePattern },
|
||||
artist.Stroke {
|
||||
Weight: 1,
|
||||
Pattern: artist.Beveled {
|
||||
artist.NewUniform(hex(0x89925AFF)),
|
||||
artist.NewUniform(hex(0xD2CB9AFF)),
|
||||
},
|
||||
},
|
||||
artist.Stroke { Pattern: artist.NewUniform(hex(0xD2CB9AFF)) })
|
||||
var selectedInputPattern = artist.NewMultiBordered (
|
||||
artist.Stroke { Weight: 1, Pattern: strokePattern },
|
||||
artist.Stroke { Weight: 1, Pattern: accentPattern },
|
||||
artist.Stroke { Pattern: artist.NewUniform(hex(0xD2CB9AFF)) })
|
||||
var disabledInputPattern = artist.NewMultiBordered (
|
||||
artist.Stroke { Weight: 1, Pattern: weakForegroundPattern },
|
||||
artist.Stroke { Pattern: backgroundPattern })
|
42
theme/inset.go
Normal file
42
theme/inset.go
Normal file
@ -0,0 +1,42 @@
|
||||
package theme
|
||||
|
||||
import "image"
|
||||
|
||||
// Inset represents an inset amount for all four sides of a rectangle. The top
|
||||
// side is at index zero, the right at index one, the bottom at index two, and
|
||||
// the left at index three. These values may be negative.
|
||||
type Inset [4]int
|
||||
|
||||
// Apply returns the given rectangle, shrunk on all four sides by the given
|
||||
// inset. If a measurment of the inset is negative, that side will instead be
|
||||
// expanded outward. If the rectangle's dimensions cannot be reduced any
|
||||
// further, an empty rectangle near its center will be returned.
|
||||
func (inset Inset) Apply (bigger image.Rectangle) (smaller image.Rectangle) {
|
||||
smaller = bigger
|
||||
if smaller.Dx() < inset[3] + inset[1] {
|
||||
smaller.Min.X = (smaller.Min.X + smaller.Max.X) / 2
|
||||
smaller.Max.X = smaller.Min.X
|
||||
} else {
|
||||
smaller.Min.X += inset[3]
|
||||
smaller.Max.X -= inset[1]
|
||||
}
|
||||
|
||||
if smaller.Dy() < inset[0] + inset[2] {
|
||||
smaller.Min.Y = (smaller.Min.Y + smaller.Max.Y) / 2
|
||||
smaller.Max.Y = smaller.Min.Y
|
||||
} else {
|
||||
smaller.Min.Y += inset[0]
|
||||
smaller.Max.Y -= inset[2]
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// Inverse returns a negated version of the inset.
|
||||
func (inset Inset) Inverse () (prime Inset) {
|
||||
return Inset {
|
||||
inset[0] * -1,
|
||||
inset[1] * -1,
|
||||
inset[2] * -1,
|
||||
inset[3] * -1,
|
||||
}
|
||||
}
|
@ -1,43 +0,0 @@
|
||||
package theme
|
||||
|
||||
import "git.tebibyte.media/sashakoshka/tomo/artist"
|
||||
|
||||
var listPattern = artist.NewMultiBordered (
|
||||
artist.Stroke { Weight: 1, Pattern: strokePattern },
|
||||
artist.Stroke {
|
||||
Weight: 1,
|
||||
Pattern: artist.Beveled {
|
||||
uhex(0x383C3AFF),
|
||||
uhex(0x999C99FF),
|
||||
},
|
||||
},
|
||||
artist.Stroke { Pattern: uhex(0x999C99FF) })
|
||||
|
||||
var focusedListPattern = artist.NewMultiBordered (
|
||||
artist.Stroke { Weight: 1, Pattern: strokePattern },
|
||||
artist.Stroke { Weight: 1, Pattern: accentPattern },
|
||||
artist.Stroke { Pattern: uhex(0x999C99FF) })
|
||||
|
||||
var listEntryPattern = artist.Padded {
|
||||
Stroke: uhex(0x383C3AFF),
|
||||
Fill: uhex(0x999C99FF),
|
||||
Sides: []int { 0, 0, 0, 1 },
|
||||
}
|
||||
|
||||
var onListEntryPattern = artist.Padded {
|
||||
Stroke: uhex(0x383C3AFF),
|
||||
Fill: uhex(0x6e8079FF),
|
||||
Sides: []int { 0, 0, 0, 1 },
|
||||
}
|
||||
|
||||
var focusedListEntryPattern = artist.Padded {
|
||||
Stroke: accentPattern,
|
||||
Fill: uhex(0x999C99FF),
|
||||
Sides: []int { 0, 1, 0, 1 },
|
||||
}
|
||||
|
||||
var focusedOnListEntryPattern = artist.Padded {
|
||||
Stroke: accentPattern,
|
||||
Fill: uhex(0x6e8079FF),
|
||||
Sides: []int { 0, 1, 0, 1 },
|
||||
}
|
9
theme/parse.go
Normal file
9
theme/parse.go
Normal file
@ -0,0 +1,9 @@
|
||||
package theme
|
||||
|
||||
import "io"
|
||||
|
||||
// Parse parses a theme file and returns it as a Theme.
|
||||
func Parse (io.Reader) (Theme) {
|
||||
// TODO
|
||||
return Default { }
|
||||
}
|
@ -1,239 +0,0 @@
|
||||
package theme
|
||||
|
||||
import "image"
|
||||
import "git.tebibyte.media/sashakoshka/tomo/artist"
|
||||
|
||||
// Case sepecifies what kind of element is using a pattern. It contains a
|
||||
// namespace parameter and an element parameter. The element parameter does not
|
||||
// necissarily need to match an element name, but if it can, it should. Both
|
||||
// parameters should be written in camel case. Themes can change their styling
|
||||
// based on this parameter for fine-grained control over the look and feel of
|
||||
// specific elements.
|
||||
type Case struct { Namespace, Element string }
|
||||
|
||||
// C can be used as shorthand to generate a case struct as used in PatternState.
|
||||
func C (namespace, element string) (c Case) {
|
||||
return Case {
|
||||
Namespace: namespace,
|
||||
Element: element,
|
||||
}
|
||||
}
|
||||
|
||||
// PatternState lists parameters which can change the appearance of some
|
||||
// patterns. For example, passing a PatternState with Selected set to true may
|
||||
// result in a pattern that has a colored border within it.
|
||||
type PatternState struct {
|
||||
Case
|
||||
|
||||
// On should be set to true if the element that is using this pattern is
|
||||
// in some sort of "on" state, such as if a checkbox is checked or a
|
||||
// switch is toggled on. This is only necessary if the element in
|
||||
// question is capable of being toggled.
|
||||
On bool
|
||||
|
||||
// Focused should be set to true if the element that is using this
|
||||
// pattern is currently focused.
|
||||
Focused bool
|
||||
|
||||
// Pressed should be set to true if the element that is using this
|
||||
// pattern is being pressed down by the mouse. This is only necessary if
|
||||
// the element in question processes mouse button events.
|
||||
Pressed bool
|
||||
|
||||
// Disabled should be set to true if the element that is using this
|
||||
// pattern is locked and cannot be interacted with. Disabled variations
|
||||
// of patterns are typically flattened and greyed-out.
|
||||
Disabled bool
|
||||
|
||||
// Invalid should be set to true if th element that is using this
|
||||
// pattern wants to warn the user of an invalid interaction or data
|
||||
// entry. Invalid variations typically have some sort of reddish tint
|
||||
// or outline.
|
||||
Invalid bool
|
||||
}
|
||||
|
||||
// Inset represents an inset amount for all four sides of a rectangle. The top
|
||||
// side is at index zero, the right at index one, the bottom at index two, and
|
||||
// the left at index three. These values may be negative.
|
||||
type Inset [4]int
|
||||
|
||||
// Apply returns the given rectangle, shrunk on all four sides by the given
|
||||
// inset. If a measurment of the inset is negative, that side will instead be
|
||||
// expanded outward. If the rectangle's dimensions cannot be reduced any
|
||||
// further, an empty rectangle near its center will be returned.
|
||||
func (inset Inset) Apply (bigger image.Rectangle) (smaller image.Rectangle) {
|
||||
smaller = bigger
|
||||
if smaller.Dx() < inset[3] + inset[1] {
|
||||
smaller.Min.X = (smaller.Min.X + smaller.Max.X) / 2
|
||||
smaller.Max.X = smaller.Min.X
|
||||
} else {
|
||||
smaller.Min.X += inset[3]
|
||||
smaller.Max.X -= inset[1]
|
||||
}
|
||||
|
||||
if smaller.Dy() < inset[0] + inset[2] {
|
||||
smaller.Min.Y = (smaller.Min.Y + smaller.Max.Y) / 2
|
||||
smaller.Max.Y = smaller.Min.Y
|
||||
} else {
|
||||
smaller.Min.Y += inset[0]
|
||||
smaller.Max.Y -= inset[2]
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// Inverse returns a negated version of the inset.
|
||||
func (inset Inset) Inverse () (prime Inset) {
|
||||
return Inset {
|
||||
inset[0] * -1,
|
||||
inset[1] * -1,
|
||||
inset[2] * -1,
|
||||
inset[3] * -1,
|
||||
}
|
||||
}
|
||||
|
||||
// AccentPattern returns the accent pattern, which is usually just a solid
|
||||
// color.
|
||||
func AccentPattern (state PatternState) (pattern artist.Pattern, inset Inset) {
|
||||
return accentPattern, Inset { }
|
||||
}
|
||||
|
||||
// BackgroundPattern returns the main background pattern.
|
||||
func BackgroundPattern (state PatternState) (pattern artist.Pattern, inset Inset) {
|
||||
return backgroundPattern, Inset { }
|
||||
}
|
||||
|
||||
// DeadPattern returns a pattern that can be used to mark an area or gap that
|
||||
// serves no purpose, but still needs aesthetic structure.
|
||||
func DeadPattern (state PatternState) (pattern artist.Pattern, inset Inset) {
|
||||
return deadPattern, Inset { }
|
||||
}
|
||||
|
||||
// ForegroundPattern returns the color text should be.
|
||||
func ForegroundPattern (state PatternState) (pattern artist.Pattern, inset Inset) {
|
||||
if state.Disabled {
|
||||
return weakForegroundPattern, Inset { }
|
||||
} else {
|
||||
return foregroundPattern, Inset { }
|
||||
}
|
||||
}
|
||||
|
||||
// InputPattern returns a background pattern for any input field that can be
|
||||
// edited by typing with the keyboard.
|
||||
func InputPattern (state PatternState) (pattern artist.Pattern, inset Inset) {
|
||||
if state.Disabled {
|
||||
return disabledInputPattern, Inset { 1, 1, 1, 1 }
|
||||
} else {
|
||||
if state.Focused {
|
||||
return selectedInputPattern, Inset { 1, 1, 1, 1 }
|
||||
} else {
|
||||
return inputPattern, Inset { 1, 1, 1, 1 }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ListPattern returns a background pattern for a list of things.
|
||||
func ListPattern (state PatternState) (pattern artist.Pattern, inset Inset) {
|
||||
if state.Focused {
|
||||
pattern = focusedListPattern
|
||||
inset = Inset { 2, 1, 2, 1 }
|
||||
} else {
|
||||
pattern = listPattern
|
||||
inset = Inset { 2, 1, 1, 1 }
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// ItemPattern returns a background pattern for a list item.
|
||||
func ItemPattern (state PatternState) (pattern artist.Pattern, inset Inset) {
|
||||
if state.Focused {
|
||||
if state.On {
|
||||
pattern = focusedOnListEntryPattern
|
||||
} else {
|
||||
pattern = focusedListEntryPattern
|
||||
}
|
||||
} else {
|
||||
if state.On {
|
||||
pattern = onListEntryPattern
|
||||
} else {
|
||||
pattern = listEntryPattern
|
||||
}
|
||||
}
|
||||
inset = Inset { 4, 6, 4, 6 }
|
||||
return
|
||||
}
|
||||
|
||||
// ButtonPattern returns a pattern to be displayed on buttons.
|
||||
func ButtonPattern (state PatternState) (pattern artist.Pattern, inset Inset) {
|
||||
if state.Disabled {
|
||||
return disabledButtonPattern, Inset { 1, 1, 1, 1 }
|
||||
} else {
|
||||
if state.Pressed {
|
||||
if state.Focused {
|
||||
return pressedSelectedButtonPattern, Inset {
|
||||
2, 0, 0, 2 }
|
||||
} else {
|
||||
return pressedButtonPattern, Inset { 2, 0, 0, 2 }
|
||||
}
|
||||
} else {
|
||||
if state.Focused {
|
||||
return selectedButtonPattern, Inset { 1, 1, 1, 1 }
|
||||
} else {
|
||||
return buttonPattern, Inset { 1, 1, 1, 1 }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// GutterPattern returns a pattern to be used to mark a track along which
|
||||
// something slides.
|
||||
func GutterPattern (state PatternState) (pattern artist.Pattern, inset Inset) {
|
||||
if state.Disabled {
|
||||
return disabledScrollGutterPattern, Inset { 0, 0, 0, 0 }
|
||||
} else {
|
||||
return scrollGutterPattern, Inset { 0, 0, 0, 0 }
|
||||
}
|
||||
}
|
||||
|
||||
// HandlePattern returns a pattern to be displayed on a grab handle that slides
|
||||
// along a gutter.
|
||||
func HandlePattern (state PatternState) (pattern artist.Pattern, inset Inset) {
|
||||
if state.Disabled {
|
||||
return disabledScrollBarPattern, Inset { 1, 1, 1, 1 }
|
||||
} else {
|
||||
if state.Focused {
|
||||
if state.Pressed {
|
||||
return pressedSelectedScrollBarPattern, Inset { 1, 1, 1, 1 }
|
||||
} else {
|
||||
return selectedScrollBarPattern, Inset { 1, 1, 1, 1 }
|
||||
}
|
||||
} else {
|
||||
if state.Pressed {
|
||||
return pressedScrollBarPattern, Inset { 1, 1, 1, 1 }
|
||||
} else {
|
||||
return scrollBarPattern, Inset { 1, 1, 1, 1 }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// SunkenPattern returns a general purpose pattern that is sunken/engraved into
|
||||
// the background.
|
||||
func SunkenPattern (state PatternState) (pattern artist.Pattern, inset Inset) {
|
||||
return sunkenPattern, Inset { 1, 1, 1, 1 }
|
||||
}
|
||||
|
||||
// RaisedPattern returns a general purpose pattern that is raised up out of the
|
||||
// background.
|
||||
func RaisedPattern (state PatternState) (pattern artist.Pattern, inset Inset) {
|
||||
if state.Focused {
|
||||
return selectedRaisedPattern, Inset { 1, 1, 1, 1 }
|
||||
} else {
|
||||
return raisedPattern, Inset { 1, 1, 1, 1 }
|
||||
}
|
||||
}
|
||||
|
||||
// PinboardPattern returns a textured backdrop pattern. Anything drawn within it
|
||||
// should have its own background pattern.
|
||||
func PinboardPattern (state PatternState) (pattern artist.Pattern, inset Inset) {
|
||||
return texturedSunkenPattern, Inset { 1, 1, 1, 1 }
|
||||
}
|
@ -1,63 +0,0 @@
|
||||
package theme
|
||||
|
||||
import "git.tebibyte.media/sashakoshka/tomo/artist"
|
||||
|
||||
var scrollGutterPattern = artist.NewMultiBordered (
|
||||
artist.Stroke { Weight: 1, Pattern: strokePattern },
|
||||
artist.Stroke {
|
||||
Weight: 1,
|
||||
Pattern: artist.Beveled {
|
||||
artist.NewUniform(hex(0x3b534eFF)),
|
||||
artist.NewUniform(hex(0x6e8079FF)),
|
||||
},
|
||||
},
|
||||
artist.Stroke { Pattern: artist.NewUniform(hex(0x6e8079FF)) })
|
||||
var disabledScrollGutterPattern = artist.NewMultiBordered (
|
||||
artist.Stroke { Weight: 1, Pattern: weakForegroundPattern },
|
||||
artist.Stroke { Pattern: backgroundPattern })
|
||||
var scrollBarPattern = artist.NewMultiBordered (
|
||||
artist.Stroke { Weight: 1, Pattern: strokePattern },
|
||||
artist.Stroke {
|
||||
Weight: 1,
|
||||
Pattern: artist.Beveled {
|
||||
artist.NewUniform(hex(0xCCD5D2FF)),
|
||||
artist.NewUniform(hex(0x4B5B59FF)),
|
||||
},
|
||||
},
|
||||
artist.Stroke { Pattern: artist.NewUniform(hex(0x8D9894FF)) })
|
||||
var selectedScrollBarPattern = artist.NewMultiBordered (
|
||||
artist.Stroke { Weight: 1, Pattern: strokePattern },
|
||||
artist.Stroke {
|
||||
Weight: 1,
|
||||
Pattern: artist.Beveled {
|
||||
artist.NewUniform(hex(0xCCD5D2FF)),
|
||||
artist.NewUniform(hex(0x4B5B59FF)),
|
||||
},
|
||||
},
|
||||
artist.Stroke { Weight: 1, Pattern: accentPattern },
|
||||
artist.Stroke { Pattern: artist.NewUniform(hex(0x8D9894FF)) })
|
||||
var pressedScrollBarPattern = artist.NewMultiBordered (
|
||||
artist.Stroke { Weight: 1, Pattern: strokePattern },
|
||||
artist.Stroke {
|
||||
Weight: 1,
|
||||
Pattern: artist.Beveled {
|
||||
artist.NewUniform(hex(0xCCD5D2FF)),
|
||||
artist.NewUniform(hex(0x4B5B59FF)),
|
||||
},
|
||||
},
|
||||
artist.Stroke { Weight: 1, Pattern: artist.NewUniform(hex(0x8D9894FF)) },
|
||||
artist.Stroke { Pattern: artist.NewUniform(hex(0x7f8c89FF)) })
|
||||
var pressedSelectedScrollBarPattern = artist.NewMultiBordered (
|
||||
artist.Stroke { Weight: 1, Pattern: strokePattern },
|
||||
artist.Stroke {
|
||||
Weight: 1,
|
||||
Pattern: artist.Beveled {
|
||||
artist.NewUniform(hex(0xCCD5D2FF)),
|
||||
artist.NewUniform(hex(0x4B5B59FF)),
|
||||
},
|
||||
},
|
||||
artist.Stroke { Weight: 1, Pattern: accentPattern },
|
||||
artist.Stroke { Pattern: artist.NewUniform(hex(0x7f8c89FF)) })
|
||||
var disabledScrollBarPattern = artist.NewMultiBordered (
|
||||
artist.Stroke { Weight: 1, Pattern: weakForegroundPattern },
|
||||
artist.Stroke { Pattern: backgroundPattern })
|
48
theme/state.go
Normal file
48
theme/state.go
Normal file
@ -0,0 +1,48 @@
|
||||
package theme
|
||||
|
||||
// Case sepecifies what kind of element is using a pattern. It contains a
|
||||
// namespace parameter and an element parameter. The element parameter does not
|
||||
// necissarily need to match an element name, but if it can, it should. Both
|
||||
// parameters should be written in camel case. Themes can change their styling
|
||||
// based on this parameter for fine-grained control over the look and feel of
|
||||
// specific elements.
|
||||
type Case struct { Namespace, Element string }
|
||||
|
||||
// C can be used as shorthand to generate a case struct as used in PatternState.
|
||||
func C (namespace, element string) (c Case) {
|
||||
return Case {
|
||||
Namespace: namespace,
|
||||
Element: element,
|
||||
}
|
||||
}
|
||||
|
||||
// PatternState lists parameters which can change the appearance of some
|
||||
// patterns. For example, passing a PatternState with Selected set to true may
|
||||
// result in a pattern that has a colored border within it.
|
||||
type PatternState struct {
|
||||
// On should be set to true if the element that is using this pattern is
|
||||
// in some sort of "on" state, such as if a checkbox is checked or a
|
||||
// switch is toggled on. This is only necessary if the element in
|
||||
// question is capable of being toggled.
|
||||
On bool
|
||||
|
||||
// Focused should be set to true if the element that is using this
|
||||
// pattern is currently focused.
|
||||
Focused bool
|
||||
|
||||
// Pressed should be set to true if the element that is using this
|
||||
// pattern is being pressed down by the mouse. This is only necessary if
|
||||
// the element in question processes mouse button events.
|
||||
Pressed bool
|
||||
|
||||
// Disabled should be set to true if the element that is using this
|
||||
// pattern is locked and cannot be interacted with. Disabled variations
|
||||
// of patterns are typically flattened and greyed-out.
|
||||
Disabled bool
|
||||
|
||||
// Invalid should be set to true if th element that is using this
|
||||
// pattern wants to warn the user of an invalid interaction or data
|
||||
// entry. Invalid variations typically have some sort of reddish tint
|
||||
// or outline.
|
||||
Invalid bool
|
||||
}
|
199
theme/theme.go
199
theme/theme.go
@ -1,113 +1,100 @@
|
||||
package theme
|
||||
|
||||
import "image/color"
|
||||
import "image"
|
||||
import "golang.org/x/image/font"
|
||||
import "git.tebibyte.media/sashakoshka/tomo/artist"
|
||||
import "git.tebibyte.media/sashakoshka/tomo/defaultfont"
|
||||
|
||||
// none of these colors are final! TODO: generate these values from a theme
|
||||
// file at startup.
|
||||
// FontStyle specifies stylistic alterations to a font face.
|
||||
type FontStyle int; const (
|
||||
FontStyleRegular FontStyle = 0
|
||||
FontStyleBold FontStyle = 1
|
||||
FontStyleItalic FontStyle = 2
|
||||
FontStyleBoldItalic FontStyle = 1 | 2
|
||||
)
|
||||
|
||||
func hex (color uint32) (c color.RGBA) {
|
||||
c.A = uint8(color)
|
||||
c.B = uint8(color >> 8)
|
||||
c.G = uint8(color >> 16)
|
||||
c.R = uint8(color >> 24)
|
||||
return
|
||||
}
|
||||
|
||||
func uhex (color uint32) (pattern artist.Pattern) {
|
||||
return artist.NewUniform(hex(color))
|
||||
}
|
||||
|
||||
var accentPattern = artist.NewUniform(hex(0x408090FF))
|
||||
var backgroundPattern = artist.NewUniform(color.Gray16 { 0xAAAA })
|
||||
var foregroundPattern = artist.NewUniform(color.Gray16 { 0x0000 })
|
||||
var weakForegroundPattern = artist.NewUniform(color.Gray16 { 0x4444 })
|
||||
var strokePattern = artist.NewUniform(color.Gray16 { 0x0000 })
|
||||
|
||||
var sunkenPattern = artist.NewMultiBordered (
|
||||
artist.Stroke { Weight: 1, Pattern: strokePattern },
|
||||
artist.Stroke {
|
||||
Weight: 1,
|
||||
Pattern: artist.Beveled {
|
||||
artist.NewUniform(hex(0x3b534eFF)),
|
||||
artist.NewUniform(hex(0x97a09cFF)),
|
||||
},
|
||||
},
|
||||
artist.Stroke { Pattern: artist.NewUniform(hex(0x97a09cFF)) })
|
||||
|
||||
var texturedSunkenPattern = artist.NewMultiBordered (
|
||||
artist.Stroke { Weight: 1, Pattern: strokePattern },
|
||||
artist.Stroke {
|
||||
Weight: 1,
|
||||
Pattern: artist.Beveled {
|
||||
artist.NewUniform(hex(0x3b534eFF)),
|
||||
artist.NewUniform(hex(0x97a09cFF)),
|
||||
},
|
||||
},
|
||||
// artist.Stroke { Pattern: artist.Striped {
|
||||
// First: artist.Stroke {
|
||||
// Weight: 2,
|
||||
// Pattern: artist.NewUniform(hex(0x97a09cFF)),
|
||||
// },
|
||||
// Second: artist.Stroke {
|
||||
// Weight: 1,
|
||||
// Pattern: artist.NewUniform(hex(0x6e8079FF)),
|
||||
// },
|
||||
// }})
|
||||
|
||||
artist.Stroke { Pattern: artist.Noisy {
|
||||
Low: artist.NewUniform(hex(0x97a09cFF)),
|
||||
High: artist.NewUniform(hex(0x6e8079FF)),
|
||||
}})
|
||||
|
||||
var raisedPattern = artist.NewMultiBordered (
|
||||
artist.Stroke { Weight: 1, Pattern: strokePattern },
|
||||
artist.Stroke {
|
||||
Weight: 1,
|
||||
Pattern: artist.Beveled {
|
||||
artist.NewUniform(hex(0xDBDBDBFF)),
|
||||
artist.NewUniform(hex(0x383C3AFF)),
|
||||
},
|
||||
},
|
||||
artist.Stroke { Pattern: artist.NewUniform(hex(0xAAAAAAFF)) })
|
||||
|
||||
var selectedRaisedPattern = artist.NewMultiBordered (
|
||||
artist.Stroke { Weight: 1, Pattern: strokePattern },
|
||||
artist.Stroke {
|
||||
Weight: 1,
|
||||
Pattern: artist.Beveled {
|
||||
artist.NewUniform(hex(0xDBDBDBFF)),
|
||||
artist.NewUniform(hex(0x383C3AFF)),
|
||||
},
|
||||
},
|
||||
artist.Stroke { Weight: 1, Pattern: accentPattern },
|
||||
artist.Stroke { Pattern: artist.NewUniform(hex(0xAAAAAAFF)) })
|
||||
|
||||
var deadPattern = artist.NewMultiBordered (
|
||||
artist.Stroke { Weight: 1, Pattern: strokePattern },
|
||||
artist.Stroke { Pattern: artist.NewUniform(hex(0x97a09cFF)) })
|
||||
|
||||
// TODO: load fonts from an actual source instead of using defaultfont
|
||||
|
||||
// FontFaceRegular returns the font face to be used for normal text.
|
||||
func FontFaceRegular () font.Face {
|
||||
return defaultfont.FaceRegular
|
||||
}
|
||||
|
||||
// FontFaceBold returns the font face to be used for bolded text.
|
||||
func FontFaceBold () font.Face {
|
||||
return defaultfont.FaceBold
|
||||
}
|
||||
|
||||
// FontFaceItalic returns the font face to be used for italicized text.
|
||||
func FontFaceItalic () font.Face {
|
||||
return defaultfont.FaceItalic
|
||||
}
|
||||
|
||||
// FontFaceBoldItalic returns the font face to be used for text that is both
|
||||
// bolded and italicized.
|
||||
func FontFaceBoldItalic () font.Face {
|
||||
return defaultfont.FaceBoldItalic
|
||||
// FontSize specifies the general size of a font face in a semantic way.
|
||||
type FontSize int; const (
|
||||
// FontSizeNormal is the default font size that should be used for most
|
||||
// things.
|
||||
FontSizeNormal FontSize = iota
|
||||
|
||||
// FontSizeLarge is a larger font size suitable for things like section
|
||||
// headings.
|
||||
FontSizeLarge
|
||||
|
||||
// FontSizeHuge is a very large font size suitable for things like
|
||||
// titles, wizard step names, digital clocks, etc.
|
||||
FontSizeHuge
|
||||
|
||||
// FontSizeSmall is a smaller font size. Try not to use this unless it
|
||||
// makes a lot of sense to do so, because it can negatively impact
|
||||
// accessibility. It is useful for things like copyright notices at the
|
||||
// bottom of some window that the average user doesn't actually care
|
||||
// about.
|
||||
FontSizeSmall
|
||||
)
|
||||
|
||||
// Pattern lists a number of cannonical pattern types, each with its own ID.
|
||||
// This allows custom elements to follow themes, even those that do not
|
||||
// explicitly support them.
|
||||
type Pattern int; const (
|
||||
// PatternAccent is the accent color of the theme. It is safe to assume
|
||||
// that this is, by default, a solid color.
|
||||
PatternAccent Pattern = iota
|
||||
|
||||
// PatternBackground is the background color of the theme. It is safe to
|
||||
// assume that this is, by default, a solid color.
|
||||
PatternBackground
|
||||
|
||||
// PatternForeground is the foreground text color of the theme. It is
|
||||
// safe to assume that this is, by default, a solid color.
|
||||
PatternForeground
|
||||
|
||||
// PatternDead is a pattern that is displayed on a "dead area" where no
|
||||
// controls exist, but there still must be some indication of visual
|
||||
// structure (such as in the corner between two scroll bars).
|
||||
PatternDead
|
||||
|
||||
// PatternRaised is a generic raised pattern.
|
||||
PatternRaised
|
||||
|
||||
// PatternSunken is a generic sunken pattern.
|
||||
PatternSunken
|
||||
|
||||
// PatternPinboard is similar to PatternSunken, but it is textured.
|
||||
PatternPinboard
|
||||
|
||||
// PatternButton is a button pattern.
|
||||
PatternButton
|
||||
|
||||
// PatternInput is a pattern for input fields, editable text areas, etc.
|
||||
PatternInput
|
||||
|
||||
// PatternGutter is a track for things to slide on.
|
||||
PatternGutter
|
||||
|
||||
// PatternHandle is a handle that slides along a gutter.
|
||||
PatternHandle
|
||||
)
|
||||
|
||||
// Theme represents a visual style configuration,
|
||||
type Theme interface {
|
||||
// FontFace returns the proper font for a given style, size, and case.
|
||||
FontFace (FontStyle, FontSize, Case) font.Face
|
||||
|
||||
// Icon returns an appropriate icon given an icon name and case.
|
||||
Icon (string, Case) artist.Pattern
|
||||
|
||||
// Pattern returns an appropriate pattern given a pattern name, case,
|
||||
// and state.
|
||||
Pattern (Pattern, Case, PatternState) artist.Pattern
|
||||
|
||||
// Inset returns the area on all sides of a given pattern that is not
|
||||
// meant to be drawn on.
|
||||
Inset (Pattern, Case) Inset
|
||||
|
||||
// Sink returns a vector that should be added to an element's inner
|
||||
// content when it is pressed down (if applicable) to simulate a 3D
|
||||
// sinking effect.
|
||||
Sink (Pattern, Case) image.Point
|
||||
}
|
||||
|
16
theme/util.go
Normal file
16
theme/util.go
Normal file
@ -0,0 +1,16 @@
|
||||
package theme
|
||||
|
||||
import "image/color"
|
||||
import "git.tebibyte.media/sashakoshka/tomo/artist"
|
||||
|
||||
func hex (color uint32) (c color.RGBA) {
|
||||
c.A = uint8(color)
|
||||
c.B = uint8(color >> 8)
|
||||
c.G = uint8(color >> 16)
|
||||
c.R = uint8(color >> 24)
|
||||
return
|
||||
}
|
||||
|
||||
func uhex (color uint32) (pattern artist.Pattern) {
|
||||
return artist.NewUniform(hex(color))
|
||||
}
|
Reference in New Issue
Block a user