refactor: Clean up code
This commit is contained in:
parent
9698a95f16
commit
3f9492b694
6 changed files with 163 additions and 102 deletions
5
README.md
Normal file
5
README.md
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
# watchface
|
||||||
|
|
||||||
|
Custom watch face for ~~Ticwatch C2+~~ any watch running Linux with RGBA /dev/fb0 and 360x360 resolution
|
||||||
|
|
||||||
|
**Warning: this code is ugly and might be unstable**
|
27
app_clock.go
Normal file
27
app_clock.go
Normal file
|
@ -0,0 +1,27 @@
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"git.ddd.rip/ptrcnull/watchface/system"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
var ClockTime = Text(62, 162, 8, 36, LightGray)
|
||||||
|
var ClockBattery = Text(90, 240, 3, 24, LightGray)
|
||||||
|
|
||||||
|
type Clock struct{}
|
||||||
|
|
||||||
|
func (s Clock) Init(face *Face) {
|
||||||
|
s.draw(face, time.Now())
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s Clock) Render(face *Face) {
|
||||||
|
t := time.Now()
|
||||||
|
if t.Second() == 0 {
|
||||||
|
s.draw(face, t)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (Clock) draw(face *Face, t time.Time) {
|
||||||
|
face.Text(ClockTime, t.Format("15:04"))
|
||||||
|
face.Text(ClockBattery, system.GetBattery())
|
||||||
|
}
|
27
app_simpleclock.go
Normal file
27
app_simpleclock.go
Normal file
|
@ -0,0 +1,27 @@
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"git.ddd.rip/ptrcnull/watchface/system"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
var SimpleClockTime = Text(108, 162, 5, 36, LightGray)
|
||||||
|
var SimpleClockBattery = Text(90, 240, 3, 24, LightGray)
|
||||||
|
|
||||||
|
type SimpleClock struct{}
|
||||||
|
|
||||||
|
func (s SimpleClock) Init(face *Face) {
|
||||||
|
s.draw(face, time.Now())
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s SimpleClock) Render(face *Face) {
|
||||||
|
t := time.Now()
|
||||||
|
if t.Second() == 0 {
|
||||||
|
s.draw(face, t)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (SimpleClock) draw(face *Face, t time.Time) {
|
||||||
|
face.Text(SimpleClockTime, t.Format("15:04"))
|
||||||
|
face.Text(SimpleClockBattery, system.GetBattery())
|
||||||
|
}
|
119
main.go
119
main.go
|
@ -3,16 +3,9 @@ package main
|
||||||
import (
|
import (
|
||||||
"image"
|
"image"
|
||||||
"image/color"
|
"image/color"
|
||||||
"io/ioutil"
|
|
||||||
"strings"
|
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"golang.org/x/image/draw"
|
"golang.org/x/image/draw"
|
||||||
"golang.org/x/image/font"
|
|
||||||
"golang.org/x/image/math/fixed"
|
|
||||||
|
|
||||||
"github.com/golang/freetype"
|
|
||||||
"github.com/golang/freetype/truetype"
|
|
||||||
|
|
||||||
"git.ddd.rip/ptrcnull/watchface/framebuffer"
|
"git.ddd.rip/ptrcnull/watchface/framebuffer"
|
||||||
)
|
)
|
||||||
|
@ -21,110 +14,38 @@ var Gray = color.RGBA{R: 60, G: 60, B: 60, A: 60}
|
||||||
var LightGray = color.RGBA{R: 150, G: 150, B: 150, A: 150}
|
var LightGray = color.RGBA{R: 150, G: 150, B: 150, A: 150}
|
||||||
var White = color.RGBA{R: 255, G: 255, B: 255, A: 255}
|
var White = color.RGBA{R: 255, G: 255, B: 255, A: 255}
|
||||||
|
|
||||||
func addLabel(img draw.Image, face font.Face, rect image.Rectangle, label string) {
|
type App interface {
|
||||||
point := fixed.Point26_6{X: fixed.Int26_6(rect.Min.X * 64), Y: fixed.Int26_6(rect.Max.Y * 64)}
|
Init(*Face)
|
||||||
|
Render(*Face)
|
||||||
d := &font.Drawer{
|
|
||||||
Dst: img,
|
|
||||||
Src: image.NewUniform(LightGray),
|
|
||||||
Face: face,
|
|
||||||
Dot: point,
|
|
||||||
}
|
|
||||||
d.DrawString(label)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
var SecondClock = image.Rect(62, 162, 298, 198)
|
var app App = SimpleClock{}
|
||||||
var MinuteClock = image.Rect(108, 162, 253, 198)
|
var launch func(App)
|
||||||
var Battery = image.Rect(90, 240, 150, 240+32)
|
|
||||||
|
|
||||||
var notoSans *truetype.Font
|
|
||||||
|
|
||||||
func sized(size float64) font.Face {
|
|
||||||
return truetype.NewFace(notoSans, &truetype.Options{
|
|
||||||
Size: size,
|
|
||||||
Hinting: font.HintingFull,
|
|
||||||
DPI: 0,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
func main() {
|
|
||||||
fontData, _ := ioutil.ReadFile("/usr/share/fonts/noto/NotoSansMono-Regular.ttf")
|
|
||||||
notoSans, _ = freetype.ParseFont(fontData)
|
|
||||||
|
|
||||||
fb, _ := framebuffer.Open("/dev/fb0")
|
|
||||||
Fill(fb, fb.Bounds(), color.RGBA{})
|
|
||||||
|
|
||||||
face := Face{
|
|
||||||
//tmp: &framebuffer.SimpleRGBA{
|
|
||||||
// Pixels: make([]uint8, fb.Xres*fb.Yres*4),
|
|
||||||
// Stride: fb.Yres * 4,
|
|
||||||
// Xres: fb.Xres,
|
|
||||||
// Yres: fb.Yres,
|
|
||||||
//},
|
|
||||||
tmp: image.NewRGBA(fb.Bounds()),
|
|
||||||
fb: fb.SimpleRGBA,
|
|
||||||
}
|
|
||||||
|
|
||||||
simple := true
|
|
||||||
go face.MinuteClock(time.Now())
|
|
||||||
go face.Battery()
|
|
||||||
|
|
||||||
ticker := time.NewTicker(time.Second)
|
|
||||||
for {
|
|
||||||
t := time.Now()
|
|
||||||
if simple {
|
|
||||||
if t.Second() == 0 {
|
|
||||||
go face.MinuteClock(t)
|
|
||||||
go face.Battery()
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
go face.SecondClock(t)
|
|
||||||
if t.Second() == 0 {
|
|
||||||
go face.Battery()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
<-ticker.C
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
type Face struct {
|
type Face struct {
|
||||||
tmp draw.Image
|
tmp draw.Image
|
||||||
fb draw.Image
|
fb draw.Image
|
||||||
}
|
}
|
||||||
|
|
||||||
func (f *Face) Battery() {
|
func main() {
|
||||||
Fill(f.tmp, Battery, color.RGBA{})
|
fb, _ := framebuffer.Open("/dev/fb0")
|
||||||
addLabel(f.tmp, sized(32), Battery, getBattery())
|
Fill(fb, fb.Bounds(), color.RGBA{})
|
||||||
Copy(f.fb, f.tmp, Battery)
|
|
||||||
|
face := Face{
|
||||||
|
tmp: image.NewRGBA(fb.Bounds()),
|
||||||
|
fb: fb.SimpleRGBA,
|
||||||
}
|
}
|
||||||
|
|
||||||
func (f *Face) SecondClock(t time.Time) {
|
launch = func(newApp App) {
|
||||||
Fill(f.tmp, SecondClock, color.RGBA{})
|
app = newApp
|
||||||
addLabel(f.tmp, sized(48), SecondClock, t.Format("15:04:05"))
|
app.Init(&face)
|
||||||
Copy(f.fb, f.tmp, SecondClock)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (f *Face) MinuteClock(t time.Time) {
|
app.Init(&face)
|
||||||
Fill(f.tmp, MinuteClock, color.RGBA{})
|
|
||||||
addLabel(f.tmp, sized(48), MinuteClock, t.Format("15:04"))
|
|
||||||
Copy(f.fb, f.tmp, MinuteClock)
|
|
||||||
}
|
|
||||||
|
|
||||||
//func Loop(duration time.Duration, handler func()) {
|
ticker := time.NewTicker(time.Second)
|
||||||
// for {
|
for {
|
||||||
// go handler()
|
go app.Render(&face)
|
||||||
// time.Sleep(duration)
|
<-ticker.C
|
||||||
// }
|
|
||||||
//}
|
|
||||||
|
|
||||||
func getBattery() string {
|
|
||||||
res, _ := ioutil.ReadFile("/sys/class/power_supply/battery/capacity")
|
|
||||||
value := strings.Trim(string(res), "\n")
|
|
||||||
if len(value) == 1 {
|
|
||||||
value = "0" + value
|
|
||||||
}
|
}
|
||||||
if value == "100" {
|
|
||||||
return "uwu"
|
|
||||||
}
|
|
||||||
return value + "%"
|
|
||||||
}
|
}
|
||||||
|
|
18
system/battery.go
Normal file
18
system/battery.go
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
package system
|
||||||
|
|
||||||
|
import (
|
||||||
|
"io/ioutil"
|
||||||
|
"strings"
|
||||||
|
)
|
||||||
|
|
||||||
|
func GetBattery() string {
|
||||||
|
res, _ := ioutil.ReadFile("/sys/class/power_supply/battery/capacity")
|
||||||
|
value := strings.Trim(string(res), "\n")
|
||||||
|
if len(value) == 1 {
|
||||||
|
value = "0" + value
|
||||||
|
}
|
||||||
|
if value == "100" {
|
||||||
|
return "uwu"
|
||||||
|
}
|
||||||
|
return value + "%"
|
||||||
|
}
|
63
text.go
Normal file
63
text.go
Normal file
|
@ -0,0 +1,63 @@
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"image"
|
||||||
|
"image/color"
|
||||||
|
"io/ioutil"
|
||||||
|
|
||||||
|
"golang.org/x/image/font"
|
||||||
|
"golang.org/x/image/math/fixed"
|
||||||
|
|
||||||
|
"github.com/golang/freetype"
|
||||||
|
"github.com/golang/freetype/truetype"
|
||||||
|
)
|
||||||
|
|
||||||
|
const GlyphRatio = 0.85
|
||||||
|
|
||||||
|
var notoSans = loadNoto()
|
||||||
|
|
||||||
|
func sized(size float64) font.Face {
|
||||||
|
return truetype.NewFace(notoSans, &truetype.Options{
|
||||||
|
Size: size,
|
||||||
|
Hinting: font.HintingFull,
|
||||||
|
DPI: 100,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func loadNoto() *truetype.Font {
|
||||||
|
fontData, _ := ioutil.ReadFile("/usr/share/fonts/noto/NotoSansMono-Regular.ttf")
|
||||||
|
ttf, _ := freetype.ParseFont(fontData)
|
||||||
|
return ttf
|
||||||
|
}
|
||||||
|
|
||||||
|
func Text(x, y int, textLength, fontSize float64, color color.RGBA) *textData {
|
||||||
|
width := int(textLength * fontSize * GlyphRatio)
|
||||||
|
return &textData{
|
||||||
|
rect: image.Rect(x, y, x+width, y+int(fontSize)),
|
||||||
|
fontSize: fontSize,
|
||||||
|
color: color,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
type textData struct {
|
||||||
|
rect image.Rectangle
|
||||||
|
fontSize float64
|
||||||
|
color color.RGBA
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f *Face) Text(textData *textData, text string) {
|
||||||
|
Fill(f.tmp, textData.rect, color.RGBA{})
|
||||||
|
|
||||||
|
d := &font.Drawer{
|
||||||
|
Dst: f.tmp,
|
||||||
|
Src: image.NewUniform(textData.color),
|
||||||
|
Face: sized(textData.fontSize),
|
||||||
|
Dot: fixed.Point26_6{
|
||||||
|
X: fixed.Int26_6(textData.rect.Min.X * 64),
|
||||||
|
Y: fixed.Int26_6(textData.rect.Max.Y * 64),
|
||||||
|
},
|
||||||
|
}
|
||||||
|
d.DrawString(text)
|
||||||
|
|
||||||
|
Copy(f.fb, f.tmp, textData.rect)
|
||||||
|
}
|
Loading…
Reference in a new issue